| /* |
| * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved. |
| * |
| * 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.osgi.service.application; |
| |
| import org.osgi.framework.Constants; |
| |
| /** |
| * ApplicationHandle is an OSGi service interface which represents an instance |
| * of an application. It provides the functionality to query and manipulate the |
| * lifecycle state of the represented application instance. It defines constants |
| * for the lifecycle states. |
| * |
| * @version $Revision: 1.6 $ |
| */ |
| public abstract class ApplicationHandle { |
| /* |
| * NOTE: An implementor may also choose to replace this class in |
| * their distribution with a class that directly interfaces with the |
| * org.osgi.service.application implementation. This replacement class MUST NOT alter the |
| * public/protected signature of this class. |
| */ |
| |
| /** |
| * The property key for the unique identifier (PID) of the application |
| * instance. |
| */ |
| public static final String APPLICATION_PID = Constants.SERVICE_PID; |
| |
| /** |
| * The property key for the pid of the corresponding application descriptor. |
| */ |
| public final static String APPLICATION_DESCRIPTOR = "application.descriptor"; |
| |
| /** |
| * The property key for the state of this application instance. |
| */ |
| public final static String APPLICATION_STATE = "application.state"; |
| |
| /** |
| * The property key for the supports exit value property of this application |
| * instance. |
| * |
| * @since 1.1 |
| */ |
| public final static String APPLICATION_SUPPORTS_EXITVALUE = "application.supports.exitvalue"; |
| |
| /** |
| * The application instance is running. This is the initial state of a newly |
| * created application instance. |
| */ |
| public final static String RUNNING = "RUNNING"; |
| |
| /** |
| * The application instance is being stopped. This is the state of the |
| * application instance during the execution of the {@code destroy()} |
| * method. |
| */ |
| public final static String STOPPING = "STOPPING"; |
| |
| private final String instanceId; |
| |
| private final ApplicationDescriptor descriptor; |
| |
| /** |
| * Application instance identifier is specified by the container when the |
| * instance is created. The instance identifier must remain static for the |
| * lifetime of the instance, it must remain the same even across framework |
| * restarts for the same application instance. This value must be the same |
| * as the {@code service.pid} service property of this application |
| * handle. |
| * <p> |
| * The instance identifier should follow the following scheme: |
| * <<i>application descriptor PID</i>>.<<i>index</i>> |
| * where <<i>application descriptor PID</i>> is the PID of the |
| * corresponding {@code ApplicationDescriptor} and <<i>index</i>> |
| * is a unique integer index assigned by the application container. |
| * Even after destroying the application index the same index value should not |
| * be reused in a reasonably long timeframe. |
| * |
| * @param instanceId the instance identifier of the represented application |
| * instance. It must not be null. |
| * |
| * @param descriptor the {@code ApplicationDescriptor} of the represented |
| * application instance. It must not be null. |
| * |
| * @throws NullPointerException if any of the arguments is null. |
| */ |
| protected ApplicationHandle(String instanceId, ApplicationDescriptor descriptor) { |
| if ((null == instanceId) || (null == descriptor)) { |
| throw new NullPointerException("Parameters must not be null!"); |
| } |
| |
| this.instanceId = instanceId; |
| this.descriptor = descriptor; |
| } |
| |
| /** |
| * Retrieves the {@code ApplicationDescriptor} to which this |
| * {@code ApplicationHandle} belongs. |
| * |
| * @return The corresponding {@code ApplicationDescriptor} |
| */ |
| public final ApplicationDescriptor getApplicationDescriptor() { |
| return descriptor; |
| } |
| |
| /** |
| * Get the state of the application instance. |
| * |
| * @return the state of the application. |
| * |
| * @throws IllegalStateException |
| * if the application handle is unregistered |
| */ |
| public abstract String getState(); |
| |
| /** |
| * Returns the exit value for the application instance. The timeout |
| * specifies how the method behaves when the application has not yet |
| * terminated. A negative, zero or positive value may be used. |
| * <ul> |
| * <li> negative - The method does not wait for termination. If the |
| * application has not terminated then an {@code ApplicationException} |
| * is thrown.</li> |
| * |
| * <li> zero - The method waits until the application terminates.</li> |
| * |
| * <li> positive - The method waits until the application terminates or the |
| * timeout expires. If the timeout expires and the application has not |
| * terminated then an {@code ApplicationException} is thrown.</li> |
| * </ul> |
| * <p> |
| * The default implementation throws an |
| * {@code UnsupportedOperationException}. The application model should |
| * override this method if exit values are supported. |
| * </p> |
| * |
| * @param timeout The maximum time in milliseconds to wait for the |
| * application to timeout. |
| * @return The exit value for the application instance. The value is |
| * application specific. |
| * @throws UnsupportedOperationException If the application model does not |
| * support exit values. |
| * @throws InterruptedException If the thread is interrupted while waiting |
| * for the timeout. |
| * @throws ApplicationException If the application has not terminated. The |
| * error code will be |
| * {@link ApplicationException#APPLICATION_EXITVALUE_NOT_AVAILABLE}. |
| * |
| * @since 1.1 |
| */ |
| public Object getExitValue(long timeout) throws ApplicationException, InterruptedException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Returns the unique identifier of this instance. This value is also |
| * available as a service property of this application handle's service.pid. |
| * |
| * @return the unique identifier of the instance |
| */ |
| public final String getInstanceId() { |
| return instanceId; |
| } |
| |
| /** |
| * The application instance's lifecycle state can be influenced by this |
| * method. It lets the application instance perform operations to stop |
| * the application safely, e.g. saving its state to a permanent storage. |
| * <p> |
| * The method must check if the lifecycle transition is valid; a STOPPING |
| * application cannot be stopped. If it is invalid then the method must |
| * exit. Otherwise the lifecycle state of the application instance must be |
| * set to STOPPING. Then the destroySpecific() method must be called to |
| * perform any application model specific steps for safe stopping of the |
| * represented application instance. |
| * <p> |
| * At the end the {@code ApplicationHandle} must be unregistered. |
| * This method should free all the resources related to this |
| * {@code ApplicationHandle}. |
| * <p> |
| * When this method is completed the application instance has already made |
| * its operations for safe stopping, the ApplicationHandle has been |
| * unregistered and its related resources has been freed. Further calls on |
| * this application should not be made because they may have unexpected |
| * results. |
| * |
| * @throws SecurityException |
| * if the caller doesn't have "lifecycle" |
| * {@code ApplicationAdminPermission} for the corresponding application. |
| * |
| * @throws IllegalStateException |
| * if the application handle is unregistered |
| */ |
| public final void destroy() { |
| if (STOPPING.equals(getState())) |
| return; |
| SecurityManager sm = System.getSecurityManager(); |
| if (sm != null) |
| sm.checkPermission(new ApplicationAdminPermission(getApplicationDescriptor(), ApplicationAdminPermission.LIFECYCLE_ACTION)); |
| destroySpecific(); |
| } |
| |
| /** |
| * Called by the destroy() method to perform application model specific |
| * steps to stop and destroy an application instance safely. |
| * |
| * @throws IllegalStateException |
| * if the application handle is unregistered |
| */ |
| protected abstract void destroySpecific(); |
| |
| } |