//======================================================================== //$Id: InstallerActivity.java 408 2011-07-21 02:06:54Z janb.webtide $ //Copyright 2011 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, 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.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. //======================================================================== package org.mortbay.ijetty.console; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import org.eclipse.jetty.util.IO; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.text.Html; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; /** * InstallerActivity * * */ public class InstallerActivity extends Activity { private static final String TAG = "Console.Inst"; public static final String WEBAPPS = "webapps"; public static final String CONSOLE = "console"; public static final String JETTY = "jetty"; public static final int CONFIRM_DIALOG_ID = 1; public static final int ERROR_DIALOG_ID = 2; public static final int PROGRESS_DIALOG_ID = 3; public static final int FINISH_DIALOG_ID = 4; private Button installButton; private TextView versionView; private ProgressDialog progressDialog; private String error; private boolean cleanInstall = false; /** * InstallerThread * * Perform the installation. * */ class InstallerThread extends Thread { private Handler handler; private boolean cleanInstall; public InstallerThread(Handler h) { handler = h; } public void sendProgressUpdate (int prog) { Message msg = handler.obtainMessage(); Bundle b = new Bundle(); b.putInt("prog", prog); msg.setData(b); handler.sendMessage(msg); } public void run () { if (cleanInstall) delete(getWebApp()); sendProgressUpdate(50); try { extract (getResources().openRawResource(R.raw.console)); sendProgressUpdate(100); } catch (Exception e) { error = getString(R.string.errorExtracting)+" "+e.getMessage(); sendProgressUpdate(100); return; } } } public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.installer); installButton = (Button)findViewById(R.id.install); versionView = (TextView)findViewById(R.id.version); progressDialog = null; //version info try { PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0); versionView.setText(Html.fromHtml(String.format("Version %s (%s)",pi.versionName,pi.versionCode))); } catch (NameNotFoundException e) { versionView.setText("Version ? (?)"); } //install button installButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { File jettyDir = getJettyInstallDir(); if (jettyDir == null) showError(getString(R.string.notInstalled)); else { //if the webapp does not already exist, go ahead and install it File webapp = getWebApp(); if (webapp == null) install(); else { //existing console webapp installed, check if the user wants to reinstall showDialog(CONFIRM_DIALOG_ID); } } } }); } /** * Set up an instance of a Dialog * * @see android.app.Activity#onPrepareDialog(int, android.app.Dialog) */ @Override protected void onPrepareDialog(int id, Dialog dialog) { switch (id) { case CONFIRM_DIALOG_ID: { ((AlertDialog)dialog).setMessage(getString(R.string.alreadyInstalled)); break; } case ERROR_DIALOG_ID: { ((AlertDialog)dialog).setMessage((error == null?getString(R.string.defaultError):error)); break; } } } /** * Create an appropriate dialog. * * @see android.app.Activity#onCreateDialog(int) */ @Override protected Dialog onCreateDialog(int id) { Dialog dialog = null; switch (id) { case CONFIRM_DIALOG_ID: { //Dialog asking user to confirm to proceed with the installation after finding an already existing webapp AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Stuff"); builder.setCancelable(false); builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { cleanInstall = true; install(); } }); builder.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); dialog = builder.create(); break; } case ERROR_DIALOG_ID: { //Dialog informing user a fatal error has occurred. AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(""); builder.setCancelable(false); builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { error = null; dialog.dismiss(); } }); dialog = builder.create(); break; } case PROGRESS_DIALOG_ID: { //Dialog showing user progress of installation. progressDialog = new ProgressDialog(this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage(getString(R.string.installing)); dialog = progressDialog; break; } case FINISH_DIALOG_ID: { //Dialog showing user install complete AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(getResources().getString(R.string.success)); builder.setCancelable(false); builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog = builder.create(); break; } } return dialog; } /** * Inform the user an error has occurred. * @param string */ public void showError (String string) { error = ""+string; Log.e(TAG, error); showDialog(ERROR_DIALOG_ID); } /** * Check to see if jetty has been installed. * @return File of jetty install dir or null if not installed */ public File getJettyInstallDir () { File jettyDir = new File(Environment.getExternalStorageDirectory(), JETTY); if (!jettyDir.exists()) return null; return jettyDir; } /** * @return the File of the existing unpacked webapp or null */ public File getWebApp () { File jettyDir = getJettyInstallDir(); if (jettyDir == null) return null; File webappsDir = new File(jettyDir, WEBAPPS); if (!webappsDir.exists()) return null; File webapp = new File (webappsDir, CONSOLE); if (!webapp.exists()) return null; return webapp; } /** * Delete the existing unpacked console webapp * @param webapp */ public void delete (File webapp) { if (webapp.isDirectory()) { File[] files = webapp.listFiles(); for (File f:files) { delete(f); } webapp.delete(); } else webapp.delete(); } /** * Begin the installation */ public void install () { showDialog(PROGRESS_DIALOG_ID); InstallerThread thread = new InstallerThread(new Handler() { public void handleMessage(Message msg) { int total = msg.getData().getInt("prog"); progressDialog.setProgress(total); if (total >= 100) { progressDialog.dismiss(); if (error == null) showDialog(FINISH_DIALOG_ID); else showDialog(ERROR_DIALOG_ID); } }; }); thread.start(); } /** * Extract the war. * * @param warStream * @throws IOException */ public void extract (InputStream warStream) throws IOException { if (warStream == null) throw new IllegalArgumentException ("No war file found"); File jettyDir = getJettyInstallDir(); if (jettyDir == null) { throw new IllegalStateException (getString(R.string.jettyNotInstalled)); } File webappsDir = new File (jettyDir, "webapps"); if (!webappsDir.exists()) { throw new IllegalStateException (getString(R.string.jettyNotInstalled)); } File webapp = new File (webappsDir, "console"); JarInputStream jin = new JarInputStream(warStream); JarEntry entry; while((entry=jin.getNextJarEntry())!=null) { String entryName = entry.getName(); File file=new File(webapp,entryName); if (entry.isDirectory()) { // Make directory if (!file.exists()) file.mkdirs(); } else { // make directory (some jars don't list dirs) File dir = new File(file.getParent()); if (!dir.exists()) dir.mkdirs(); // Make file FileOutputStream fout = null; try { fout = new FileOutputStream(file); IO.copy(jin,fout); } finally { IO.close(fout); } // touch the file. if (entry.getTime()>=0) file.setLastModified(entry.getTime()); } } IO.close(jin); } }