Main.java

00001 /*
00002  * Copyright (c) 2003-2005, KNOPFLERFISH project
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following
00007  * conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above
00013  *   copyright notice, this list of conditions and the following
00014  *   disclaimer in the documentation and/or other materials
00015  *   provided with the distribution.
00016  *
00017  * - Neither the name of the KNOPFLERFISH project nor the names of its
00018  *   contributors may be used to endorse or promote products derived
00019  *   from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00030  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00032  * OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package org.knopflerfish.framework;
00036 
00037 import java.io.*;
00038 import java.util.Properties;
00039 import java.util.List;
00040 import java.util.Vector;
00041 import java.util.Enumeration;
00042 import java.net.URL;
00043 import java.net.HttpURLConnection;
00044 import java.net.MalformedURLException;
00045 import org.osgi.framework.*;
00046 
00047 import java.lang.reflect.Constructor;
00048 
00056 public class Main {
00057 
00058   static Framework framework;
00059 
00060   static long bootMgr/* = 0*/;
00061 
00062   // Verbosity level of printouts. 0 is low.
00063   static int verbosity /*= 0*/;
00064 
00065   // Will be filled in from manifest entry during startup
00066   static String version = "<unknown>";
00067 
00068   // Top directory (including any trailing /)
00069   static String topDir              = "";
00070 
00071   // Xargs to use for FW init
00072   static String defaultXArgsInit    = "init.xargs";
00073 
00074   // Xargs to use for FW init
00075   static final String defaultXArgsInit2   = "remote-init.xargs";
00076 
00077   // Xargs to use for FW restart
00078   static final String defaultXArgsStart   = "restart.xargs";
00079 
00080 
00081   // Set to true if JVM is started without any arguments
00082   static boolean bZeroArgs     /*     = false*/;
00083 
00084   // will be initialized by main() - up for anyone for grabbing
00085   public static String bootText = "";
00086 
00087   static final String JARDIR_PROP    = "org.knopflerfish.gosg.jars";
00088   static final String JARDIR_DEFAULT = "file:";
00089 
00090   static final String FWDIR_PROP    = "org.osgi.framework.dir";
00091   static final String FWDIR_DEFAULT = "fwdir";
00092   static final String CMDIR_PROP    = "org.knopflerfish.bundle.cm.store";
00093   static final String CMDIR_DEFAULT = "cmdir";
00094 
00095   static final String VERBOSITY_PROP    = "org.knopflerfish.verbosity";
00096   static final String VERBOSITY_DEFAULT = "0";
00097 
00098 
00099   static final String XARGS_DEFAULT     = "default";
00100 
00101   static final String PRODVERSION_PROP     = "org.knopflerfish.prodver";
00102   static final String EXITONSHUTDOWN_PROP  = "org.knopflerfish.framework.exitonshutdown";
00103 
00104   static final String USINGWRAPPERSCRIPT_PROP = "org.knopflerfish.framework.usingwrapperscript";
00105 
00106   static boolean restarting = false;
00107     
00111   public static void main(String[] args) {
00112     try {
00113       verbosity =
00114         Integer.parseInt(System.getProperty(VERBOSITY_PROP, VERBOSITY_DEFAULT));
00115     } catch (Exception ignored) { }
00116 
00117     version = readVersion();
00118 
00119 
00120     bootText = 
00121       "Knopflerfish OSGi framework, version " + version + "\n" + 
00122       "Copyright 2003-2006 Knopflerfish. All Rights Reserved.\n\n" + 
00123       "See http://www.knopflerfish.org for more information.";
00124 
00125     System.out.println(bootText);
00126 
00127     // Check if framework is started with no args at all.
00128     // This typically happens when starting with "java -jar framework.jar"
00129     // or similar (e.g by double-clicking on framework.jar)
00130     bZeroArgs = (args.length == 0);
00131 
00132     // Check if there is a default xargs file
00133     // Uses "init" variant if fwdir exists, otherwise
00134     // uses "restart" variant.
00135     String xargsPath = getDefaultXArgs(args);
00136     if(xargsPath != null) {
00137 
00138       if(bZeroArgs) {
00139         args = new String[] {"-xargs", xargsPath};
00140       } else if(args.length == 1 && "-init".equals(args[0])) {
00141         args = new String[] {"-init", "-xargs", xargsPath};
00142       }
00143     }
00144 
00145 
00146     // expand all -xargs options
00147     args = expandArgs(args);
00148 
00149     if(verbosity > 5) {
00150       for(int i = 0; i < args.length; i++) {
00151         println("argv[" + i + "]=" + args[i], 5);
00152       }
00153     }
00154 
00155     // redo this since it might have changed
00156     try {
00157       verbosity =
00158         Integer.parseInt(System.getProperty(VERBOSITY_PROP, VERBOSITY_DEFAULT));
00159     } catch (Exception ignored) { }
00160 
00161     if(bZeroArgs) {
00162       // Make sure we have a minimal setup of args
00163       args = sanityArgs(args);
00164     }
00165 
00166     // Set default values to something reasonable if not supplied
00167     // on the command line (or in xargs)
00168     setDefaultSysProps();
00169 
00170     String[] base = getJarBase();
00171 
00172     // Handle -init option before we create the FW, otherwise
00173     // we might shoot ourself in the foot. Hard.
00174     for(int i = 0; i < args.length; i++) {
00175       if("-init".equals(args[i])) {
00176         doInit();
00177       }
00178     }
00179 
00180     try {
00181       framework = new Framework(new Main());
00182     } catch (Exception e) {
00183       e.printStackTrace();
00184       error("New Framework failed!");
00185     }
00186 
00187     // Save these for possible restart()
00188     initArgs    = args;
00189     initOffset  = 0;
00190     initBase    = base;
00191 
00192     handleArgs(args, initOffset, base);
00193   }
00194 
00195   static String[] initArgs   = null;
00196   static int      initOffset = 0;
00197   static String[] initBase   = null;
00198 
00199   static void doInit() {
00200     String d = System.getProperty(FWDIR_PROP);
00201 
00202     FileTree dir = (d != null) ? new FileTree(d) : null;
00203     if (dir != null) {
00204       if(dir.exists()) {
00205         boolean bOK = dir.delete();
00206         if(bOK) {
00207           println("Removed existing fwdir " + dir.getAbsolutePath(), 0);
00208         } else {
00209           println("Failed to remove existing fwdir " + dir.getAbsolutePath(), 0);
00210         }
00211       }
00212     }
00213   }
00214 
00215   static String[] getJarBase() {
00216     String jars = System.getProperty(JARDIR_PROP, JARDIR_DEFAULT);
00217 
00218     String[] base = Util.splitwords(jars, ";");
00219     for (int i=0; i<base.length; i++) {
00220       try {
00221         base[i] = new URL(base[i]).toString();
00222       } catch (Exception ignored) {
00223       }
00224       println("jar base[" + i + "]=" + base[i], 3);
00225     }
00226 
00227     return base;
00228   }
00229 
00236   private static void handleArgs(String[] args,
00237                                  int startOffset,
00238                                  String[] base) {
00239     boolean doNotLaunch = false;
00240 
00241     for (int i = startOffset; i < args.length; i++) {
00242       try {
00243         if ("-exit".equals(args[i])) {
00244           println("Exit.", 0);
00245           System.exit(0);
00246         } else if ("-init".equals(args[i])) {
00247           // This is done in an earlier pass, otherwise we
00248           // shoot the FW in the foot
00249         } else if ("-version".equals(args[i])) {
00250           printResource("/tstamp");
00251           printResource("/revision");
00252           System.exit(0);
00253         } else if ("-help".equals(args[i])) {
00254           printResource("/help.txt");
00255           System.exit(0);
00256         } else if ("-readme".equals(args[i])) {
00257           printResource("/readme.txt");
00258           System.exit(0);
00259         } else if ("-jvminfo".equals(args[i])) {
00260           printJVMInfo();
00261           System.exit(0);
00262         } else if ("-install".equals(args[i])) {
00263           if (i+1 < args.length) {
00264             String bundle = args[i+1];
00265             long id = framework.installBundle(completeLocation(base,bundle), null);
00266             println("Installed: " + framework.getBundleLocation(id) + " (id#" + id + ")", 0);
00267             i++;
00268           } else {
00269             error("No URL for install command");
00270           }
00271         } else if ("-istart".equals(args[i])) {
00272           if (i+1 < args.length) {
00273             String bundle = args[i+1];
00274             long id = framework.installBundle(completeLocation(base,bundle), null);
00275             framework.startBundle(id);
00276             println("Installed and started: " + framework.getBundleLocation(id) + " (id#" + id + ")", 0);
00277             i++;
00278           } else {
00279             error("No URL for install command");
00280           }
00281         } else if ("-launch".equals(args[i])) {
00282           if (i+1 < args.length && !args[i+1].startsWith("-")) {
00283             bootMgr = Long.parseLong(args[i+1]);
00284             framework.launch(bootMgr);
00285             i++;
00286           } else {
00287             framework.launch(0);
00288           }
00289           doNotLaunch = true;
00290           println("Framework launched", 0);
00291         } else if ("-shutdown".equals(args[i])) {
00292           doNotLaunch = true;
00293           framework.shutdown();
00294           println("Framework shutdown", 0);
00295         } else if ("-sleep".equals(args[i])) {
00296           if (i+1 < args.length) {
00297             long t = Long.parseLong(args[i+1]);
00298             try {
00299               println("Sleeping " + t + " seconds...", 0);
00300               Thread.sleep(t * 1000);
00301             } catch (InterruptedException e) {
00302               error("Sleep interrupted.");
00303             }
00304             i++;
00305           } else {
00306             error("No time for sleep command");
00307           }
00308         } else if ("-start".equals(args[i])) {
00309           if (i+1 < args.length) {
00310             long id = getBundleID(base,args[i+1]);
00311             framework.startBundle(id);
00312             println("Started: " + framework.getBundleLocation(id) + " (id#" + id + ")", 0);
00313             i++;
00314           } else {
00315             error("No ID for start command");
00316           }
00317         } else if ("-stop".equals(args[i])) {
00318           if (i+1 < args.length) {
00319             long id = getBundleID(base,args[i+1]);
00320             framework.stopBundle(id);
00321             println("Stopped: " + framework.getBundleLocation(id) + " (id#" + id + ")", 0);
00322             i++;
00323           } else {
00324             error("No ID for stop command");
00325           }
00326         } else if ("-uninstall".equals(args[i])) {
00327           if (i+1 < args.length) {
00328             long id = getBundleID(base,args[i+1]);
00329             String loc = framework.getBundleLocation(id);
00330             framework.uninstallBundle(id);
00331             println("Uninstalled: " + loc + " (id#" + id + ")", 0);
00332             i++;
00333           } else {
00334             error("No id for uninstall command");
00335           }
00336         } else if ("-update".equals(args[i])) {
00337           if (i+1 < args.length) {
00338             long[] ids = null;
00339             if("ALL".equals(args[i+1])) {
00340               List bl = framework.bundles.getBundles();
00341               ids = new long[bl.size()];
00342               for(int n = bl.size() - 1; n >= 0; n--) {
00343                 ids[n] = ((BundleImpl)bl.get(n)).getBundleId();
00344               }
00345             } else {
00346               ids = new long[] { getBundleID(base,args[i+1]) };
00347             }
00348             for(int n = 0; n < ids.length; n++) {
00349               long id = ids[n];
00350               if(id != 0) {
00351                 framework.updateBundle(id);
00352                 println("Updated: " + framework.getBundleLocation(id) + " (id#" + id + ")", 0);
00353               }
00354             }
00355             i++;
00356           } else {
00357             error("No id for update command");
00358           }
00359         } else if ("-initlevel".equals(args[i])) {
00360           if (i+1 < args.length) {
00361             int n = Integer.parseInt(args[i+1]);
00362             if(framework.startLevelService != null) {
00363               framework.startLevelService.setInitialBundleStartLevel(n);
00364             } else {
00365               println("No start level service - ignoring init bundle level " + n, 0);
00366             }
00367             i++;
00368           } else {
00369             error("No integer level for initlevel command");
00370           }
00371         } else if ("-startlevel".equals(args[i])) {
00372           if (i+1 < args.length) {
00373             int n = Integer.parseInt(args[i+1]);
00374             if(framework.startLevelService != null) {
00375               if(n == 1) {
00376                 if(Debug.startlevel) {
00377                   Debug.println("Entering startlevel compatibility mode, all bundles will have startlevel == 1");
00378                 }
00379                 framework.startLevelService.bCompat = true;
00380               }
00381 
00382               framework.startLevelService.setStartLevel(n);
00383             } else {
00384               println("No start level service - ignoring start level " + n, 0);
00385             }
00386             i++;
00387           } else {
00388             error("No integer level for startlevel command");
00389           }
00390         } else {
00391           error("Unknown option: " + args[i] +
00392                 "\nUse option -help to see all options");
00393         }
00394       } catch (BundleException e) {
00395         Throwable ne = e.getNestedException();
00396         if (ne != null) {
00397           e.getNestedException().printStackTrace(System.err);
00398         } else {
00399           e.printStackTrace(System.err);
00400         }
00401         error("Command \"" + args[i] +
00402               ((i+1 < args.length && !args[i+1].startsWith("-")) ?
00403                " " + args[i+1] :
00404                "") +
00405               "\" failed, " + e.getMessage());
00406       } catch (Exception e) {
00407         e.printStackTrace(System.err);
00408         error("Command \"" + args[i] +
00409               ((i+1 < args.length && !args[i+1].startsWith("-")) ?
00410                " " + args[i+1] :
00411                "") +
00412               "\" failed, " + e.getMessage());
00413       }
00414     }
00415 
00416     if (!framework.active && !doNotLaunch) {
00417       try {
00418         framework.launch(0);
00419         println("Framework launched", 0);
00420       } catch (Throwable t) {
00421         if (t instanceof BundleException) {
00422           BundleException be = (BundleException) t;
00423           Throwable ne = be.getNestedException();
00424           if (ne != null) t = ne;
00425         }
00426         t.printStackTrace(System.err);
00427         error("Framework launch failed, " + t.getMessage());
00428       }
00429     }
00430   }
00431 
00432 
00440   static private long getBundleID(String[] base, String idLocation ) {
00441     try {
00442       return Long.parseLong(idLocation);
00443     } catch (NumberFormatException nfe) {
00444       long id = framework.getBundleId( completeLocation( base, idLocation ) );
00445       if (id!=-1) {
00446         return id;
00447       }
00448       throw new IllegalArgumentException
00449         ("Invalid bundle id/location: " +idLocation);
00450     }
00451   }
00452 
00458   static private String completeLocation( String[] base, String location )
00459   {
00460     // Handle file: case where topDir is not ""
00461     if(bZeroArgs && location.startsWith("file:jars/") && !topDir.equals("")) {
00462       location = ("file:" + topDir + location.substring(5)).replace('\\', '/');
00463       println("mangled bundle location to " + location, 2);
00464     }
00465     int ic = location.indexOf(":");
00466     if (ic<2 || ic>location.indexOf("/")) {
00467       println("location=" + location, 2);
00468       // URL without protocol complete it.
00469       for (int i=0; i<base.length; i++) {
00470         println("base[" + i + "]=" + base[i], 2);
00471         try {
00472           URL url = new URL( new URL(base[i]), location );
00473 
00474           println("check " + url, 2);
00475           if ("file".equals(url.getProtocol())) {
00476             File f = new File(url.getFile());
00477             if (!f.exists() || !f.canRead()) {
00478               continue; // Noope; try next.
00479             }
00480           } else if ("http".equals(url.getProtocol())) {
00481             HttpURLConnection uc = (HttpURLConnection) url.openConnection();
00482             uc.connect();
00483             int rc = uc.getResponseCode();
00484             uc.disconnect();
00485             if (rc!=HttpURLConnection.HTTP_OK) {
00486               println("Can't access HTTP bundle: " + url + ", response code=" + rc, 0);
00487               continue; // Noope; try next.
00488             }
00489           } else {
00490             // Generic case; Check if we can read data from this URL
00491             InputStream is = null;
00492             try {
00493               is = url.openStream();
00494             } finally {
00495               if (is!=null) is.close();
00496             }
00497           }
00498           location = url.toString();
00499           println("found location=" + location, 5);
00500           break; // Found.
00501         } catch (Exception _e) {
00502         }
00503       }
00504     }
00505     return location;
00506   }
00507 
00508 
00517   static public void shutdown(final int exitcode) {
00518     if (restarting) return;
00519     Thread t = new Thread() {
00520         public void run() {
00521           if (bootMgr != 0) {
00522             try {
00523               framework.stopBundle(bootMgr);
00524             } catch (BundleException e) {
00525               System.err.println("Stop of BootManager failed, " +
00526                                  e.getNestedException());
00527             }
00528           }
00529           framework.shutdown();
00530           if("true".equals(System.getProperty(EXITONSHUTDOWN_PROP, "true"))) {
00531             System.exit(exitcode);
00532           } else {
00533             println("Framework shutdown, skipped System.exit()", 0);
00534           }
00535         }
00536       };
00537     t.setDaemon(false);
00538     t.start();
00539   }
00540 
00541 
00548   static public void restart() {
00549     restarting = true;
00550     Thread t = new Thread() {
00551         public void run() {
00552           try {
00553             if (bootMgr != 0) {
00554               try {
00555                 framework.stopBundle(bootMgr);
00556               } catch (BundleException e) {
00557                 System.err.println("Stop of BootManager failed, " +
00558                                    e.getNestedException());
00559               }
00560             }
00561             framework.shutdown();
00562   
00563             try {
00564               if (bootMgr != 0) {
00565                 framework.launch(bootMgr);
00566               } else {
00567                 framework.launch(0);
00568               }
00569             } catch (Exception e) {
00570               println("Failed to restart framework", 0);
00571             }
00572           } finally {
00573             restarting = false;
00574           }
00575         }
00576       };
00577     t.setDaemon(false);
00578     t.start();
00579   }
00580 
00585   static String[] expandArgs(String[] argv) {
00586     Vector v = new Vector();
00587     int i = 0;
00588     while(i < argv.length) {
00589       if ("-xargs".equals(argv[i])) {
00590         if (i+1 < argv.length) {
00591           String   xargsPath = argv[i+1];
00592           String[] moreArgs = loadArgs(xargsPath, argv);
00593           i++;
00594           String[] r = expandArgs(moreArgs);
00595           for(int j = 0; j < r.length; j++) {
00596             v.addElement(r[j]);
00597           }
00598         } else {
00599           throw new IllegalArgumentException("-xargs without argument");
00600         }
00601       } else {
00602         v.addElement(argv[i]);
00603       }
00604       i++;
00605     }
00606     String[] r = new String[v.size()];
00607 
00608     v.copyInto(r);
00609     return r;
00610   }
00611 
00615   static void printResource(String name) {
00616     try {
00617       System.out.println(new String(Util.readResource(name)));
00618     } catch (Exception e) {
00619       System.out.println("No resource '" + name + "' available");
00620     }
00621   }
00622 
00623   public static final String[] FWPROPS = new String[] {
00624     Constants.FRAMEWORK_VENDOR,
00625     Constants.FRAMEWORK_VERSION,
00626     Constants.FRAMEWORK_LANGUAGE,
00627     Constants.FRAMEWORK_OS_NAME ,
00628     Constants.FRAMEWORK_OS_VERSION,
00629     Constants.FRAMEWORK_PROCESSOR,
00630     Constants.FRAMEWORK_EXECUTIONENVIRONMENT,
00631   };
00632 
00636   static void printJVMInfo() {
00637 
00638     try {
00639       Properties props = System.getProperties();
00640       System.out.println("--- System properties ---");
00641       for(Enumeration e = props.keys(); e.hasMoreElements(); ) {
00642         String key = (String)e.nextElement();
00643         System.out.println(key + ": " + props.get(key));
00644       }
00645       System.out.println("\n--- Framework properties ---");
00646       for(int i = 0; i < FWPROPS.length; i++) {
00647         System.out.println(FWPROPS[i] + ": " + framework.getProperty(FWPROPS[i]));
00648       }
00649     } catch (Exception e) {
00650       e.printStackTrace();
00651     }
00652   }
00653 
00654   // Read version info from manifest
00655   static String readVersion() {
00656     try {
00657       return (new String(Util.readResource("/version"))).trim();
00658     } catch (Exception e) {
00659       return "<no version found>";
00660     }
00661   }
00662 
00666   static String getDefaultXArgs(String[] oldArgs) {
00667     boolean bInit = false;
00668 
00669     // If the old args has an -init somewhere, make sure
00670     // we don't use the restart default xargs
00671     for(int i = 0; i < oldArgs.length; i++) {
00672       if("-init".equals(oldArgs[i])) {
00673         bInit = true;
00674       }
00675     }
00676 
00677     String fwDirStr = System.getProperty(FWDIR_PROP, FWDIR_DEFAULT);
00678     File fwDir      = new File(fwDirStr);
00679     File xargsFile  = null;
00680 
00681     // avoid getParentFile since some profiles don't have this
00682     String defDirStr = (new File(fwDir.getAbsolutePath())).getParent();
00683     File   defDir    = defDirStr != null ? new File(defDirStr) : null;
00684 
00685     println("fwDir="+ fwDir, 2);
00686     println("defDir="+ defDir, 2);
00687     println("bInit=" + bInit, 2);
00688 
00689     // ..and select appropiate xargs file
00690     if(defDir != null) {
00691 
00692       topDir = defDir + File.separator;
00693 
00694       try {
00695         String osName = (String)Alias.unifyOsName(System.getProperty("os.name")).get(0);
00696         File f = new File(defDir, "init_" + osName + ".xargs");
00697         if(f.exists()) {
00698           defaultXArgsInit = f.getName();
00699           println("found OS specific xargs=" + defaultXArgsInit, 1);
00700         }
00701       } catch (Exception ignored) {
00702         // No OS specific xargs found
00703       }
00704 
00705 
00706       if(!bInit && (fwDir.exists() && fwDir.isDirectory())) {
00707         println("found fwdir at " + fwDir.getAbsolutePath(), 1);
00708         xargsFile = new File(defDir, defaultXArgsStart);
00709         if(xargsFile.exists()) {
00710           println("\n" +
00711                   "Default restart xargs file: " + xargsFile +
00712                   "\n" +
00713                   "To reinitialize, remove the " + fwDir.toString() +
00714                   " directory\n",
00715                   5);
00716         } else {
00717           File xargsFile2 = new File(defDir, defaultXArgsInit);
00718           println("No restart xargs file " + xargsFile +
00719                   ", trying " + xargsFile2 + " instead.", 0);
00720           xargsFile = xargsFile2;
00721         }
00722       } else {
00723         println("no fwdir at " + fwDir.getAbsolutePath(), 1);
00724         xargsFile = new File(defDir, defaultXArgsInit);
00725         if(xargsFile.exists()) {
00726           println("\n" +
00727                   "Default init xargs file: " + xargsFile +
00728                   "\n",
00729                   5);
00730         } else {
00731           xargsFile = new File(defDir, defaultXArgsInit2);
00732           if(xargsFile.exists()) {
00733             println("\n" +
00734                     "Deafult secondary init xargs file: " + xargsFile +
00735                     "\n",
00736                     5);
00737           }
00738         }
00739       }
00740     } else {
00741       // No parent dir to fwdir
00742     }
00743     return xargsFile != null
00744       ?  xargsFile.getAbsolutePath()
00745       : null;
00746   }
00747 
00751   static String[][] defaultSysProps = new String[][] {
00752     {Constants.FRAMEWORK_SYSTEMPACKAGES, "javax.accessibility,javax.net,javax.net.ssl,javax.swing,javax.swing.border,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.table,javax.swing.text,javax.swing.tree"},
00753     {FWDIR_PROP,    FWDIR_DEFAULT},
00754     {CMDIR_PROP,    CMDIR_DEFAULT},
00755     //    { "oscar.repository.url", "http://www.knopflerfish.org/repo/repository.xml" },
00756   };
00757 
00758 
00759 
00772   static void setDefaultSysProps() {
00773 
00774     // Make modifications to temporary dictionary and write
00775     // it back in end of this method
00776     Properties sysProps = System.getProperties();
00777 
00778     println("setDefaultSysProps", 1);
00779     for(int i = 0; i < defaultSysProps.length; i++) {
00780       if(null == System.getProperty(defaultSysProps[i][0])) {
00781         println("Using default " + defaultSysProps[i][0] + "=" +
00782                 defaultSysProps[i][1], 1);
00783         sysProps.put(defaultSysProps[i][0], defaultSysProps[i][1]);
00784       } else {
00785         println("system prop " + defaultSysProps[i][0] + "=" + System.getProperty(defaultSysProps[i][0]), 1);
00786       }
00787     }
00788 
00789     // Set version info
00790     if(null == System.getProperty(PRODVERSION_PROP)) {
00791       sysProps.put(PRODVERSION_PROP, version);
00792     }
00793 
00794 
00795     // If jar dir is not specified, default to "file:jars/" and its
00796     // subdirs
00797     String jars = System.getProperty(JARDIR_PROP, null);
00798 
00799     if(jars == null || "".equals(jars)) {
00800       String jarBaseDir = topDir + "jars";
00801       println("jarBaseDir=" + jarBaseDir, 1);
00802 
00803       File jarDir = new File(jarBaseDir);
00804       if(jarDir.exists() && jarDir.isDirectory()) {
00805 
00806         // avoid FileNameFilter since some profiles don't have it
00807         String [] names = jarDir.list();
00808         Vector v = new Vector();
00809         for(int i = 0; i < names.length; i++) {
00810           File f = new File(jarDir, names[i]);
00811           if(f.isDirectory()) {
00812             v.addElement(names[i]);
00813           }
00814         }
00815         String [] subdirs = new String[v.size()];
00816         v.copyInto(subdirs);
00817 
00818         StringBuffer sb = new StringBuffer();
00819         sb.append("file:" + jarBaseDir + "/");
00820         for(int i = 0; i < subdirs.length; i++) {
00821           sb.append(";file:" + jarBaseDir + "/" + subdirs[i] + "/");
00822         }
00823         jars = sb.toString().replace('\\', '/');
00824         sysProps.put(JARDIR_PROP, jars);
00825         println("scanned org.knopflerfish.gosg.jars=" + jars, 1);
00826       }
00827     }
00828 
00829     // Write back system properties
00830     System.setProperties(sysProps);
00831   }
00832 
00844   static String [] sanityArgs(String[] args) {
00845     Vector v = new Vector();
00846 
00847     // First, clone everything
00848     for(int i = 0; i < args.length; i++) {
00849       v.addElement(args[i]);
00850     }
00851 
00852     // ...since this is really annoying
00853     if(!v.contains("-launch")) {
00854       println("adding last -launch command", 1);
00855       v.addElement("-launch");
00856     }
00857 
00858     // ...and copy back into array
00859     String [] arg2 = new String[v.size()];
00860     v.copyInto(arg2);
00861     return arg2;
00862   }
00863 
00864 
00899   static String [] loadArgs(String xargsPath, String[] oldArgs) {
00900 
00901     if(XARGS_DEFAULT.equals(xargsPath)) {
00902       xargsPath = getDefaultXArgs(oldArgs);
00903     }
00904 
00905 
00906 
00907     // out result
00908     Vector v = new Vector();
00909 
00910     try {
00911       BufferedReader in = null;
00912 
00913       // Check as file first, then as a URL
00914 
00915       File f = new File(xargsPath);
00916       if(f.exists()) {
00917         println("Loading xargs file " + f.getAbsolutePath(), 0);
00918         in = new BufferedReader(new FileReader(f));
00919       }
00920 
00921 
00922       if(in == null) {
00923         try {
00924           URL url = new URL(xargsPath);
00925           println("Loading xargs url " + url, 0);
00926           in = new BufferedReader(new InputStreamReader(url.openStream()));
00927         } catch (MalformedURLException e)  {
00928           throw new IllegalArgumentException("Bad xargs URL " + xargsPath +
00929                                              ": " + e);
00930         }
00931       }
00932 
00933 
00934       Properties   sysProps = System.getProperties();
00935       StringBuffer contLine = new StringBuffer();
00936       String       line     = null;
00937       String       tmpline  = null;
00938       int          lineno   = 0;
00939       for(tmpline = in.readLine(); tmpline != null;
00940           tmpline = in.readLine()) {
00941         lineno++;
00942         tmpline = tmpline.trim();
00943 
00944         // check for line continuation char and
00945         // build up line until aline without such a mark is found.
00946         if(tmpline.endsWith("\\")) {
00947           // found continuation mark, store actual line to
00948           // buffered continuation line
00949           tmpline = tmpline.substring(0, tmpline.length() - 1);
00950           if(contLine == null) {
00951             contLine = new StringBuffer(tmpline);
00952           } else {
00953             contLine.append(tmpline);
00954           }
00955           // read next line
00956           continue;
00957         } else {
00958           // No continuation mark, gather stored line + newly read line
00959           if(contLine != null) {
00960             contLine.append(tmpline);
00961             line     = contLine.toString();
00962             contLine = null;
00963           } else {
00964             // this is the normal case if no continuation char is found
00965             // or any buffered line is found
00966             line = tmpline;
00967           }
00968         }
00969 
00970         if(line.startsWith("-D")) {
00971           // Set system property
00972           int ix = line.indexOf("=");
00973           if(ix != -1) {
00974             String name = line.substring(2, ix);
00975             String val  = line.substring(ix + 1);
00976 
00977             // replace "${syspropname}" with system prop value if found
00978             if(-1 != val.indexOf("${")) {
00979               for(Enumeration e = sysProps.keys(); e.hasMoreElements();) {
00980                 String k = (String)e.nextElement();
00981                 if(-1 != val.indexOf(k)) {
00982                   String sv = (String)sysProps.get(k);
00983                   val = Util.replace(val, "${" + k + "}", sv);
00984                 }
00985               }
00986             }
00987             sysProps.put(name, val);
00988           }
00989         } else if(line.startsWith("#")) {
00990           // Ignore comments
00991         } else if(line.startsWith("-")) {
00992           int i = line.indexOf(' ');
00993           if (i != -1) {
00994             v.addElement(line.substring(0,i));
00995             line = line.substring(i).trim();
00996             if(line.length() > 0) {
00997               v.addElement(line);
00998             }
00999           } else {
01000             v.addElement(line);
01001           }
01002         } else if(line.length() > 0) {
01003           // Add argument
01004           v.addElement(line);
01005         }
01006       }
01007       setSecurityManager(sysProps);
01008       System.setProperties(sysProps);
01009     } catch (Exception e) {
01010       throw new IllegalArgumentException("xargs loading failed: " + e);
01011     }
01012     String [] args2 = new String[v.size()];
01013 
01014     v.copyInto(args2);
01015 
01016     return args2;
01017   }
01018 
01025   static void println(String s, int level) {
01026     if(verbosity >= level) {
01027       System.out.println((level > 0 ? ("#" + level + ": ") : "") + s);
01028     }
01029   }
01030 
01031   static void setSecurityManager(Properties props) {
01032     try {
01033       String manager  = (String)props.get("java.security.manager");
01034       String policy   = (String)props.get("java.security.policy");
01035 
01036 
01037       if(manager != null) {
01038         if(System.getSecurityManager() == null) {
01039           println("Setting security manager=" + manager +
01040                   ", policy=" + policy, 1);
01041           System.setProperty("java.security.manager", manager);
01042           if(policy != null) {
01043             System.setProperty("java.security.policy",  policy);
01044           }
01045           SecurityManager sm = null;
01046           if("".equals(manager)) {
01047             sm = new SecurityManager();
01048           } else {
01049             Class       clazz = Class.forName(manager);
01050             Constructor cons  = clazz.getConstructor(new Class[0]);
01051 
01052             sm = (SecurityManager)cons.newInstance(new Object[0]);
01053           }
01054           System.setSecurityManager(sm);
01055         }
01056       }
01057     } catch (Exception e) {
01058       error("Failed to set security manager", e);
01059     }
01060   }
01061 
01065   static void error(String s) {
01066     error(s, null);
01067   }
01068 
01069   static void error(String s, Exception e) {
01070     System.err.println("Error: " + s);
01071     if(e != null) {
01072       e.printStackTrace();
01073     }
01074     System.exit(1);
01075   }
01076 }

Generated on Mon Jan 11 21:19:15 2010 for OpenMobileIS by  doxygen 1.5.4