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)!

The newest version!
/*
BSD 2-Clause License

Copyright (c) 2019, Beigesoft™
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.beigesoft.android.ajetty;

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); 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 FctAppAndr(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 - 2025 Weber Informatics LLC | Privacy Policy