All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.beigesoft.android.ajetty.AJetty Maven / Gradle / Ivy

Go to download

A-Jetty for Android. It is Jetty 9.2 adapted for Android configured as minimum server with WebAppDeployer that can deploy ordinal WAR (JSP/JSTL must be pre-compiled into servlets by A-Tomcat). It's only for tests purposes. It doesn't comply to the latest Android policy (loading executable binaries from outside)!

There is a newer version: 1.0.5
Show newest version
package org.beigesoft.android.ajetty;

/*
 * Copyright (c) 2016 Beigesoft ™
 *
 * Licensed under the GNU General Public License (GPL), Version 2.0
 * (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
 */
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.util.Map;
import java.lang.reflect.Method;

import android.content.ContextWrapper;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Build;
import android.os.Environment;
import android.os.AsyncTask;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.net.Uri;
import android.Manifest;
import android.content.pm.PackageManager;

import org.beigesoft.ajetty.BootStrap;

/**
 * 

A-Jetty activity.

* * @author Yury Demidenko */ public class AJetty extends Activity implements OnClickListener { /** *

Permissions request.

**/ public static final int PERMISSIONS_REQUESTS = 2416; /** *

JETTY BASE dir.

**/ public static final String JETTY_BASE = "A-Jetty"; /** *

Flag to refresh UI.

**/ private boolean isNeedsToRefresh; /** *

Button start.

**/ private Button btnStart; /** *

Button stop.

**/ private Button btnStop; /** *

Button start browser.

**/ private Button btnStartBrowser; /** *

Combo-Box Port.

**/ private Spinner cmbPort; /** *

TextView Status.

**/ private TextView tvStatus; /** *

Application beans map reference to lock.

**/ private Map beansMap; /** *

Called when the activity is first created or recreated.

* @param pSavedInstanceState Saved Instance State */ @Override public final void onCreate(final Bundle pSavedInstanceState) { super.onCreate(pSavedInstanceState); //Only way to publish this project in central Maven repository //cause missing Google dependencies: if (android.os.Build.VERSION.SDK_INT >= 23) { try { Class[] argTypes = new Class[] {String.class}; Method checkSelfPermission = ContextWrapper.class .getDeclaredMethod("checkSelfPermission", argTypes); Object result = checkSelfPermission.invoke(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE); Integer chSlfPer = (Integer) result; if (chSlfPer != PackageManager.PERMISSION_GRANTED) { argTypes = new Class[] {String[].class, Integer.TYPE}; Method requestPermissions = Activity.class .getDeclaredMethod("requestPermissions", argTypes); String[] args = new String[] {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET}; requestPermissions.invoke(this, (Object) args, PERMISSIONS_REQUESTS); } } catch (Exception x) { x.printStackTrace(); } } ApplicationPlus appPlus = (ApplicationPlus) getApplicationContext(); this.beansMap = appPlus.getBeansMap(); setContentView(R.layout.ajetty); this.tvStatus = (TextView) findViewById(R.id.tvStatus); this.cmbPort = (Spinner) findViewById(R.id.cmbPort); ArrayAdapter cmbAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); cmbAdapter.add(new Integer(8080)); cmbAdapter.add(new Integer(8081)); cmbAdapter.add(new Integer(8082)); cmbAdapter.add(new Integer(8083)); cmbPort.setAdapter(cmbAdapter); cmbPort.setSelection(0); this.btnStartBrowser = (Button) findViewById(R.id.btnStartBrowser); this.btnStartBrowser.setOnClickListener(this); this.btnStart = (Button) findViewById(R.id.btnStart); this.btnStop = (Button) findViewById(R.id.btnStop); this.btnStart.setOnClickListener(this); this.btnStop.setOnClickListener(this); File jettyBase = new File(Environment.getExternalStorageDirectory() .getAbsolutePath() + File.separator + JETTY_BASE); if (!jettyBase.exists()) { boolean wasMistake = false; try { Toast.makeText(getApplicationContext(), "Try to create A-Jetty directory with webapps...", Toast.LENGTH_SHORT).show(); if (!jettyBase.mkdirs()) { wasMistake = true; } copyAssets(JETTY_BASE); } catch (Exception e) { wasMistake = true; e.printStackTrace(); } if (wasMistake) { Toast.makeText(getApplicationContext(), "There was errors!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "A-Jetty directory with webapps was successfully created!", Toast.LENGTH_SHORT).show(); } } } /** *

onClick handler.

* @param pTarget button */ @Override public final void onClick(final View pTarget) { if (pTarget == this.btnStart) { BootStrap bootStrap = getOrInitBootStrap(); if (!bootStrap.getIsStarted()) { bootStrap.setPort((Integer) cmbPort.getSelectedItem()); this.btnStart.setEnabled(false); this.cmbPort.setEnabled(false); Toast.makeText(getApplicationContext(), "Sending request to start server, please wait", Toast.LENGTH_SHORT) .show(); Intent intent = new Intent(this, JettyService.class); intent.setAction(JettyService.ACTION_START); startService(intent); } } else if (pTarget == this.btnStop) { BootStrap bootStrap = getOrInitBootStrap(); if (bootStrap.getIsStarted()) { this.btnStop.setEnabled(false); this.btnStartBrowser.setEnabled(false); Intent intent = new Intent(this, JettyService.class); intent.setAction(JettyService.ACTION_STOP); startService(intent); } } else if (pTarget == this.btnStartBrowser) { startBrowser(); } } /** *

onResume handler.

*/ @Override public final void onResume() { isNeedsToRefresh = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { new Refresher().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } else { new Refresher().execute((Void[]) null); } super.onResume(); } /** *

onPause handler.

*/ @Override public final void onPause() { this.isNeedsToRefresh = false; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } super.onPause(); } /** *

Start browser.

*/ private void startBrowser() { String url = this.btnStartBrowser.getText().toString(); Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); } /** *

Refresh view.

*/ private void refreshView() { synchronized (this.beansMap) { BootStrap bootStrap = getOrInitBootStrap(); if (bootStrap.getIsStarted()) { this.cmbPort.setEnabled(false); this.btnStart.setEnabled(false); this.btnStop.setEnabled(true); this.tvStatus.setText(getResources().getString(R.string.started)); this.btnStartBrowser.setEnabled(true); String text = "http://localhost:" + String.valueOf(bootStrap.getPort()); this.btnStartBrowser.setText(text); } else { this.cmbPort.setEnabled(true); this.btnStart.setEnabled(true); this.btnStop.setEnabled(false); this.tvStatus.setText(getResources().getString(R.string.stopped)); this.btnStartBrowser.setEnabled(false); this.btnStartBrowser.setText(""); } } } /** *

Get Or Initialize BootStrap.

* @return BootStrap BootStrap */ private BootStrap getOrInitBootStrap() { BootStrap bootStrap = null; Object bootStrapO = this.beansMap .get(BootStrap.class.getCanonicalName()); if (bootStrapO != null) { bootStrap = (BootStrap) bootStrapO; } else { // initialize: synchronized (this.beansMap) { bootStrapO = this.beansMap .get(BootStrap.class.getCanonicalName()); if (bootStrapO == null) { bootStrap = new BootStrap(); bootStrap.setJettyBase(Environment .getExternalStorageDirectory().getAbsolutePath() + File.separator + JETTY_BASE); try { bootStrap.setFactoryAppBeans(new FactoryAppBeansAndroid(this)); // SERVER WILL BE CREATED BY START THREAD IN JettyService } catch (Exception e) { e.printStackTrace(); } this.beansMap .put(BootStrap.class.getCanonicalName(), bootStrap); // it will be removed from beans-map by STOP thread // in JettyService } } } return bootStrap; } /** *

Recursively copy assets.

* @param pCurrDir current directory assets * @throws Exception an Exception */ private void copyAssets(final String pCurrDir) throws Exception { AssetManager assetManager = getAssets(); String[] files = assetManager.list(pCurrDir); for (String fileName : files) { String createdPath = Environment.getExternalStorageDirectory() .getAbsolutePath() + File.separator + pCurrDir + File.separator + fileName; if (!fileName.contains(".")) { File subdir = new File(createdPath); if (subdir.mkdirs()) { copyAssets(pCurrDir + File.separator + fileName); } } else { InputStream ins = null; OutputStream outs = null; try { ins = getAssets().open(pCurrDir + File.separator + fileName); outs = new BufferedOutputStream( new FileOutputStream(createdPath)); byte[] data = new byte[1024]; int count; while ((count = ins.read(data)) != -1) { outs.write(data, 0, count); } outs.flush(); } finally { if (ins != null) { try { ins.close(); } catch (Exception e2) { e2.printStackTrace(); } } if (outs != null) { try { outs.close(); } catch (Exception e3) { e3.printStackTrace(); } } } } } } /** *

Refresher thread.

*/ private class Refresher extends AsyncTask { /** *

doInBackground check is need refresh.

*/ @Override protected final Void doInBackground(final Void... params) { while (AJetty.this.isNeedsToRefresh) { publishProgress((Void[]) null); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } /** *

onProgressUpdate call refresh.

*/ @Override protected final void onProgressUpdate(final Void... values) { AJetty.this.refreshView(); super.onProgressUpdate(values); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy