Package ch.ethz.prose

Source Code of ch.ethz.prose.ProseSystem

//
//  This file is part of the prose package.
//
//  The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (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.mozilla.org/MPL/
//
//  Software distributed under the License is distributed on an "AS IS" basis,
//  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
//  for the specific language governing rights and limitations under the
//  License.
//
//  The Original Code is prose.
//
//  The Initial Developers of the Original Code are Andrei Popovici and
//  Angela Nicoara. Portions created by Andrei Popovici and Angela Nicoara
//  are Copyright (C) 2002 Andrei Popovici and Angela Nicoara.
//  All Rights Reserved.
//
//  Contributor(s):
//  $Id: ProseSystem.java,v 1.4 2008/11/18 11:44:47 anicoara Exp $
//  =====================================================================
//

package ch.ethz.prose;

// used packages
import java.lang.reflect.Constructor;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.StringTokenizer;

import ch.ethz.jvmai.JVMAspectInterface;
import ch.ethz.inf.util.Logger;

/**
* Class ProseSystem represents the user view of the system.
* It allows to start and stop prose, and to get access
* to an code <code>AspectManager</code>Users
*  program aspects and they will insert them into the system
* using the <code>insertExtension</code> and <code>withdrawExtension</code>
* methods of the extension manager.
* <p>
* This class is also used for bootstrapping the system. Before using
* the extension system, users of this class (eventually applications)
* will have to call
* <blockquote><pre>
* ProseSystem.startup();
* Another way to start this system happens over the <code>RootComponent<code/>
* module.
* </pre></blockquote>
* this will setup the system, according to special system properties too,
* like
* <ul>
* <li> <code>ch.ethz.prose.EXManager</code>
* </ul>
* <P>
* Known Properties:
* <UL>
* <LI><CODE>ch.ethz.prose.JVMAIProvider</CODE>  <b>Values:class names</b>      <br>
*                              <b>Usage:</b> controlls the creation of the JVMAI</LI>
* <LI><CODE>ch.ethz.prose.EXManager</CODE> <B>Values:class name</B>     <BR>
*       <B>Usage:</B> controlls the creation of the extension manager (<CODE>AspectManager</CODE>)</LI>
* <LI><CODE>ch.ethz.prose.HotSwapClassWeaver</CODE> <B>Values: class Name</B>     <BR>
*       <B>Usage:</B> controlls which class weaver implementation should be used
*       (only for HotSwap <CODE>JVMAIProvider</CODE> and <CODE>EXManager</CODE>)</LI>
* <LI><CODE>ch.ethz.prose.JVMAIPackagePrefixes</CODE>  <b>Values: package prefixes</b>      <br>
*      <b>Usage:</b> controlls the package prefixes eliminated or used by jvmai</LI>
* <LI><CODE>ch.ethz.prose.JVMAIOpenWorldAssumption</CODE>  <b>Values:true or false</b>      <br>
*      <b>Usage:</b> controlls whether prose uses an open world (excludes package prefixes) or
*                       a closed world (includes package prefixes)</LI>
* <LI><CODE>prose.port</CODE> <B>Values: port number (integer with value from 1 to 65535)</B>     <BR>
*       <B>Usage:</B> enables prose clients to connect to specified port</LI>
* </UL>
*
*
* @version  $Revision: 1.4 $
* @author  Andrei Popovici
* @author  Angela Nicoara
*/
public class ProseSystem implements Component {

  static private AspectManager currentExtM = null;
  static private AspectManager testExtM = null;
  static private JVMAspectInterface aspectInterface = null;
  static boolean systemUp = false;
  static ProsePermission permission = new ProsePermission("startupExtensionSystem");

  // caching Variables as input to function <JoinPointManager>.connectToJVMAI
  static ch.ethz.jvmai.Provider provider = null;
  static String[] packagePrefixes = null;
  static boolean openWorldAssumption;


  /** Start up application-specific functionality.
   * This method should be called before using the extension system.

   * <p><em>Note:this method is idempotent. Successive, successful calls to
   * <code>startup</code> have the same effect as a single call.
   * Use <code>teardown</code> in between to actually re-do the startup. NOT YET IMPLEMENTED.</em><p>
   *
   * Note: in case that the ProsePermission "startupExtensionSystem" is granted to the
   *       caller, this method is executed as privileged only restricted
   *       by the permissions not granted to RUNES classes
   *
   * @exception SystemStartupException one of the specified properties did
   * not comply to the startup/teardown naming convention or one of the
   * startup methods of additional systems failed.
   *
   */
  public synchronized static void startup() throws SystemStartupException {
    if (systemUp)
      return;

    // ATENTION!
    // Because the JVM 1.4.1 blocks, we run "RemoteProseComponent" before "ProseSystem".
    if (!System.getProperty("prose.port","UNKNOWN").equals("UNKNOWN"))
      ch.ethz.prose.tools.RemoteProseComponent.startup();
    try { Thread.sleep(500); } catch (InterruptedException e) {}

    try {
      // security check
      //AccessController.checkPermission(permission);  // FIXME : uncomment this line.

      // if no exception occurred, we can perform the startup under priv. rights
      AccessController.doPrivileged(new PrivilegedExceptionAction() {
        public Object run() throws SystemStartupException {
          doStartup();
          return null;
        }
      });

    } catch (AccessControlException e) {
      // we start the system in the standard way
      doStartup();

    } catch (PrivilegedActionException e) {
      e.printStackTrace();
      throw new SystemStartupException(e.toString());
    }

    /* ATENTION!
     * Because the JVM 1.4.1 blocks, we run "RemoteProseComponent" before "ProseSystem".
           if (!System.getProperty("prose.port","UNKNOWN").equals("UNKNOWN"))
         ch.ethz.prose.tools.RemoteProseComponent.startup();
     */

    systemUp=true;
  }

  /**
   * The real startup method
   */
  private synchronized static void doStartup() throws SystemStartupException {

    try {
      // get the jvmai-provider
      String providerClassName = System.getProperty("ch.ethz.prose.JVMAIProvider");
      if(providerClassName==null)
        providerClassName = "ch.ethz.inf.iks.jvmai.jvmdi.DebuggerProvider";

      Class providerClass = Class.forName(providerClassName);
      provider = (ch.ethz.jvmai.Provider)providerClass.newInstance();

      packagePrefixes = new String[0];
      openWorldAssumption = true;

      String packageList = System.getProperty("ch.ethz.prose.JVMAIPackagePrefixes");
      String openWorldParam = System.getProperty("ch.ethz.prose.JVMAIOpenWorldAssumption");

      if(packageList==null && openWorldParam==null) {
        packagePrefixes = new String[] {"ch.ethz.prose."};
        openWorldAssumption = true;
      }
      else {
        if(packageList==null) {
          packagePrefixes = new String[0];
        }
        else {
          StringTokenizer tokenizer = new StringTokenizer(packageList,",");
          packagePrefixes = new String[tokenizer.countTokens()];
          for(int p=0; p<packagePrefixes.length; p++) {
            packagePrefixes[p] = tokenizer.nextToken();
          }
        }
        if(openWorldParam==null) {
          openWorldAssumption = true;
        }
        else {
          openWorldAssumption = openWorldParam.toUpperCase().equals("TRUE");
        }

      }
      // initialize the aspect interface and the info interface
      aspectInterface = provider.getAspectInterface();

      // start the aspect interface!
      aspectInterface.startup(packagePrefixes,openWorldAssumption);

      aspectInterface.suspendNotification(Thread.currentThread());

      // set the default extension manager
      String extMName = System.getProperty("ch.ethz.prose.EXManager");
      if (extMName != null) {
        Class[] paramTypes = new Class[] {boolean.class, JVMAspectInterface.class};
        Object[] params = new Object[] {Boolean.TRUE, aspectInterface};
        Class extMClass = Class.forName(extMName);
        Constructor extMConstructor = extMClass.getConstructor(paramTypes);
        currentExtM = (AspectManager)extMConstructor.newInstance(params);
        params[0] = Boolean.FALSE;
        testExtM = (AspectManager)extMConstructor.newInstance(params);
      }
      else {
        currentExtM = new LocalAspectManager(true, aspectInterface);
        testExtM = new LocalAspectManager(false, aspectInterface);
      }
      currentExtM.startup();
      testExtM.startup();

      systemUp = true;
    }
    catch(Throwable e) {
      e.printStackTrace();
      if (currentExtM != null) {
        currentExtM.teardown();
        currentExtM = null;
      }

      if (testExtM != null) {
        currentExtM.teardown();
        testExtM = null;
      }
      if (aspectInterface != null)
        aspectInterface.teardown();
      aspectInterface = null;

      if (e instanceof SystemStartupException)
        throw (SystemStartupException)e;

      throw new SystemStartupException(e.toString());
    }
    finally {
      // start doing aspects
      if (aspectInterface != null)
        aspectInterface.resumeNotification(Thread.currentThread());
    }
    Logger.message("ProseComponent.startup: succeeded! ");
  }


  /**
   * Tear down prose functionality. Withdraw all existing aspects and remove the
   * current AspectManager and JoinPointManager.
   *
   * <p><em>Note:this method is idempotent. Successive, successful calls to
   * <code>teardown</code> have the same effect as a single call.
   * </em>.
   *
   * @exception SystemTeardownException  if the teardown fails
   */
  public static void teardown() throws SystemTeardownException {
    if (!systemUp)
      return;
    if (getAspectManager() != null) {
      currentExtM.teardown();
      currentExtM = null;
    }

    if (getTestAspectManager() != null)  {
      testExtM.teardown();
      testExtM = null;
    }

    if (aspectInterface != null)
      aspectInterface.teardown();

    aspectInterface = null;

    systemUp = false;
  }


  /**
   * Returns <code>true</code> if the local AspectManager
   * is set up and running.
   */
  public static boolean isActive() {
    return systemUp;
  }


  /**
   * Return the aspect manager currently in use.
   */
  public static AspectManager getAspectManager() {
    try { startup(); } catch (Exception e) {}
    return currentExtM;
  }

  /**
   * Return the currently used extension manager for testing aspects. This
   * extension manager is not attached to the JVMAI System.
   */
  public static AspectManager getTestAspectManager() {
    try { startup(); } catch (Exception e) {}
    return testExtM;
  }
}
TOP

Related Classes of ch.ethz.prose.ProseSystem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.