--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/utils/javasrc/com/nokia/mj/impl/rt/support/ApplicationUtils.java Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,313 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.mj.impl.rt.support;
+
+import com.nokia.mj.impl.utils.Uid;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.security.Permission;
+import java.security.AccessControlException;
+
+/**
+ * ApplicationUtils is an abstract base class for API implementations,
+ * which allows them to use miscellanous utilities related to the running
+ * application.
+ * <p>
+ * The class provides a static getter method for getting an instance of
+ * the running application. In those runtimes that are always running only
+ * one instance (like MIDP) returns always the same instance of the
+ * ApplicationUtils. However those runtimes (like eRCP), that may run several
+ * application in the same JVM instance, will return an application specific
+ * instance.
+ * <p>
+ * The runtime implementation hides the solving of the correct application
+ * when method <code>getInstace</code> is called. However it must be noted
+ * that if the call is made some common thread, the <code>getInstace</code>
+ * might not able to solve the correct application.
+ * <p>
+ * Example how to register a shutdown listener.
+ * <pre>
+ * package com.nokia.mj.impl.mypackage;
+ *
+ * import com.nokia.mj.impl.rt.support.ApplicationUtils;
+ * public void myClass()
+ * {
+ * public void myMethod()
+ * {
+ * // Get the insatnce of ApplicationUtils.
+ * ApplicationUtils appUtils = ApplicationUtils.getInstance();
+ *
+ * // Get the name of the application.
+ * appUtils.addShutdownListener(new ShutdownListener()
+ * {
+ * public void shuttingDown()
+ * {
+ * //Do cleaning...
+ * }
+ *
+ * });
+ *
+ *
+ * // My implementation...
+ * }
+ * }
+ *</pre>
+ * @author Nokia Corporation
+ * @version 1.0
+ */
+
+public abstract class ApplicationUtils
+{
+
+
+ /**
+ * Name of the runtime specific class that extends this base class.
+ */
+ private static final String PORTCLASS = ".ApplicationUtilsImpl";
+
+ /**
+ * A singleton instance of runtime dependent instance of class extending
+ * the ApplicationUtils base class.
+ */
+ protected static ApplicationUtils sInstance = null;
+
+ /**
+ * A set of listeners who wants to receive notification when the
+ * application is abaout to close.
+ */
+ private Vector mListeners;
+
+ /**
+ * A lock for synchronizing the thw start up waiting feature.
+ */
+ private Object mApplicationStartLock = new Object();
+
+ /**
+ * Information wheteher to continue start up or cancel it.
+ */
+ private Boolean mStartCmd;
+
+
+ /**
+ * When this class is first loaded the static initializer will create a
+ * singleton instance of runtime dependent instance of class extending the
+ * ApplicationUtils base class. The class is created using dynamic
+ * instantiation (<code>Class.forname & Class.newInstance</code>) and
+ * the name of the class is a combination of PACKAGE_PREFIX +
+ * <value of system property PACKAGE_END_PROPERTY_NAME >
+ * + .<value of PORTCLASS member variable >.
+ */
+ static
+ {
+ //Get the system proptery defining the end of package.
+ String packageEnd =
+ System.getProperty(ApplicationInfo.PACKAGE_END_PROPERTY_NAME);
+
+ if (packageEnd == null)
+ {
+ throw new RuntimeException
+ ("Not able to load " + PORTCLASS + "class since " +
+ ApplicationInfo.PACKAGE_END_PROPERTY_NAME +
+ " system property is undefined");
+ }
+
+ //Construct the class
+ String className = ApplicationInfo.PACKAGE_PREFIX +
+ packageEnd + PORTCLASS;
+ try
+ {
+ Class clazz = Class.forName(className);
+ sInstance = (ApplicationUtils)clazz.newInstance();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new RuntimeException("Not able to instantiate class " +
+ className+". Reason is: " + e);
+ }
+ }
+
+ /**
+ * Returns an instace of ApplicationUtils class which provides access to
+ * application related runtime services.
+ *
+ * @return the ApplicationUtils object, null if the construction of the
+ * object has faild
+ */
+ public static ApplicationUtils getInstance()
+ {
+ return sInstance;
+ }
+
+ /**
+ * Notifies the runtime that an exit command has been received and the
+ * application is being tried to close nicely. The runtime is responsible
+ * for killing the application if it doesn't close itself nicely after
+ * specified grace time. The specified grace time is runtime dependent.
+ * <p>
+ * This method is meant ONLY for the UI and no other API are allowed
+ * to use it. The UI must use this API ONLY when the user explicitly
+ * wants to close the application using some platform depedent feataure
+ * (e.g. red key in S60). If the user tries to close the application
+ * using the mechanism provided by the application itself, this method
+ * must not be called.
+ * <p>
+ * This method is a problematic in such runtimes that may run more than one
+ * application in same JVM instance (e.g. eRCP). If the application
+ * doesn't close nicely the runtime may have to terminate
+ * the whole JVM process, which leads closing all the running applications
+ * and the runtime itself.
+ *
+ */
+ public abstract void notifyExitCmd();
+
+ /**
+ * Determines whether the access request indicated by the specified
+ * permission should be allowed or denied, based on the security policy
+ * currently in effect. This method quietly returns if the access request
+ * is permitted, or throws a suitable AccessControlException otherwise.
+ * <p>
+ * The design decision was that all the API implementation should use this
+ * method for making security checkings and avoid using the
+ * <code>checkPermission</code> method <code>AccessController</code> class,
+ * which is left for application usage only.
+ * <p>
+ * The runtime implementation is responsible for forwarding security
+ * checking to correct securty handler. In MIDP this would be Midp security
+ * component while in 'main' type of application the handler would be the
+ * <code>AccessController</code> class.
+ *
+ * @param p the requested permission.
+ * @throws AccessControlException if the specified permission is not
+ * permitted, based on the current security policy.
+ * @throws NullPointerException if the specified permission is null.
+ */
+ public abstract void checkPermission(Permission p)
+ throws AccessControlException,
+ NullPointerException;
+
+ public abstract void checkPermission(Uid appUid,Permission p)
+ throws AccessControlException,
+ NullPointerException;
+
+ /**
+ * Adds a shutdown notifications listener to receive notifications when
+ * the application is about to close.
+ * <p>
+ * When the runtime receives information that the application is closing
+ * (either from the application itself or from the system) the runtime
+ * will send a notification to all registered listeners by calling
+ * {@link ShutdownListener#shuttingDown() shuttingDown} method. All the
+ * calls are made in a loop in one thread, so if some listener blocks the
+ * call the rest of the listeners don't get the notification.
+ * <p>
+ * There can be more than one listener.
+ *
+ * @param listener the new listener.
+ */
+ public void addShutdownListener(ShutdownListener listener)
+{
+ if (mListeners == null)
+ {
+ mListeners = new Vector();
+ }
+ mListeners.addElement(listener);
+ }
+
+
+ /**
+ * Waits (if needed) until the application to be started is known.
+ * This method can be used for pre-warming features. If the runtime is in
+ * pre-warmed state where the application to be launched is not yet known,
+ * this method will block. It is safe to call this method if the application
+ * is already known - in that case the method won't block. Once the
+ * application is known all the waiters will be released. Knowing the
+ * application doesn't necessarily mean that the application it self
+ * has been created (might happen later). The method will provide info
+ * whether to continue or cancel the start up as a return value.
+ * @return true if the user should continue starting, otherwise the user
+ * should do the required shut down proceures.
+ */
+ public boolean waitStart()
+ {
+ synchronized (mApplicationStartLock)
+ {
+ if (mStartCmd == null)
+ {
+ try
+ {
+ mApplicationStartLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ }
+ }
+ return mStartCmd == null ? false : mStartCmd.booleanValue();
+ }
+ }
+
+ /**
+ * Can be used to inform the runtime to pause the running application. The
+ * origin could be e.g. flip close or application going to back ground.
+ */
+ public void pauseApplication()
+ {
+ // Empty implementation as default.
+ }
+
+ /**
+ * Can be used to inform the runtime to resume the paused application. The
+ * origin could be e.g. flip open or application going to fore ground.
+ */
+ public void resumeApplication()
+ {
+ // Empty implementation as default.
+ }
+
+ /**
+ * Releases the start waiters.
+ */
+ protected void releaseStartWaiter(boolean doStart)
+ {
+ if (mApplicationStartLock != null)
+ {
+ synchronized (mApplicationStartLock)
+ {
+ mStartCmd = new Boolean(doStart);
+ mApplicationStartLock.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Sends shutdown notification to all the registered listeners.
+ */
+ protected void doShutdown()
+ {
+ if (mListeners != null)
+ {
+ Enumeration enumer = mListeners.elements();
+ while (enumer.hasMoreElements())
+ {
+ ShutdownListener listener =
+ (ShutdownListener)enumer.nextElement();
+ listener.shuttingDown();
+ }
+ }
+ }
+}