001: /*
002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.midp.jump.push.executive;
026:
027: import com.sun.jump.common.JUMPAppModel;
028: import com.sun.jump.common.JUMPApplication;
029: import com.sun.jump.module.contentstore.JUMPContentStore;
030: import com.sun.jump.module.contentstore.JUMPStore;
031: import com.sun.jump.module.contentstore.JUMPStoreFactory;
032: import com.sun.jump.module.contentstore.JUMPStoreHandle;
033: import com.sun.jump.module.installer.JUMPInstallerModuleFactory;
034: import com.sun.jump.module.lifecycle.JUMPApplicationLifecycleModule;
035: import com.sun.jump.module.lifecycle.JUMPApplicationLifecycleModuleFactory;
036: import com.sun.jump.module.serviceregistry.JUMPServiceRegistryModule;
037: import com.sun.jump.module.serviceregistry.JUMPServiceRegistryModuleFactory;
038: import com.sun.midp.jump.installer.MIDLETInstallerImpl;
039: import com.sun.midp.jump.push.executive.ota.InstallerInterface;
040: import com.sun.midp.jump.push.executive.persistence.Store;
041: import com.sun.midp.jump.push.executive.persistence.StoreOperationManager;
042: import com.sun.midp.jump.push.share.Configuration;
043: import com.sun.midp.push.gcf.ReservationDescriptorFactory;
044: import java.io.IOException;
045: import java.rmi.AccessException;
046: import java.rmi.AlreadyBoundException;
047: import java.rmi.NotBoundException;
048: import java.rmi.RemoteException;
049: import java.util.Map;
050:
051: final class PushContentStore extends JUMPContentStore implements
052: StoreOperationManager.ContentStore {
053:
054: protected JUMPStore getStore() {
055: return JUMPStoreFactory.getInstance().getModule(
056: JUMPStoreFactory.TYPE_FILE);
057: }
058:
059: public JUMPStoreHandle open(final boolean accessExclusive) {
060: return openStore(accessExclusive);
061: }
062:
063: public void close(final JUMPStoreHandle storeHandle) {
064: closeStore(storeHandle);
065: }
066:
067: public void load(final Map map) {
068: }
069:
070: public void unload() {
071: }
072: }
073:
074: final class PushModule implements JUMPPushModule {
075:
076: static final class PushSystem {
077: /** Installer-to-Push interface impl. */
078: private final InstallerInterface installerInterfaceImpl;
079:
080: /** Push controller instance. */
081: private final PushController pushController;
082:
083: PushSystem(final StoreOperationManager storeManager)
084: throws IOException, RemoteException,
085: AlreadyBoundException {
086: final Store store = new Store(storeManager);
087:
088: final ReservationDescriptorFactory reservationDescriptorFactory = Configuration
089: .getReservationDescriptorFactory();
090:
091: pushController = new PushController(store,
092: createLifecycleAdapter(),
093: reservationDescriptorFactory);
094:
095: final MIDPContainerInterfaceImpl midpContainerInterfaceImpl = new MIDPContainerInterfaceImpl(
096: pushController);
097: getJUMPServiceRegistry().registerService(
098: Configuration.MIDP_CONTAINER_INTERFACE_IXC_URI,
099: midpContainerInterfaceImpl);
100:
101: installerInterfaceImpl = new InstallerInterfaceImpl(
102: pushController, reservationDescriptorFactory);
103: }
104:
105: /**
106: * Creates a lifecycle adapter for Push system.
107: *
108: * @return an instance of LifecycleAdapter (cannot be <code>null</code>)
109: */
110: private LifecycleAdapter createLifecycleAdapter() {
111: /*
112: * IMPL_NOTE: not an ideal solution as it introduces
113: * implementation dependencies. However pragmatically good enough
114: */
115: final MIDLETInstallerImpl midletInstaller = (MIDLETInstallerImpl) JUMPInstallerModuleFactory
116: .getInstance().getModule(JUMPAppModel.MIDLET);
117: if (midletInstaller == null) {
118: throw new RuntimeException(
119: "failed to obtain midlet installer");
120: }
121:
122: final String policy = JUMPApplicationLifecycleModuleFactory.POLICY_ONE_LIVE_INSTANCE_ONLY;
123:
124: final JUMPApplicationLifecycleModule lifecycleModule = JUMPApplicationLifecycleModuleFactory
125: .getInstance().getModule(policy);
126: if (lifecycleModule == null) {
127: throw new RuntimeException(
128: "failed to obtain lifecycle module");
129: }
130:
131: return new LifecycleAdapter() {
132: public void launchMidlet(final int midletSuiteID,
133: final String midlet) {
134: final JUMPApplication app = midletInstaller
135: .getMIDletApplication(midletSuiteID, midlet);
136: if (app == null) {
137: logError("failed to convert to MIDP application");
138: }
139:
140: // TBD: push-launch dialogs
141:
142: lifecycleModule.launchApplication(app,
143: new String[0]);
144: }
145: };
146: }
147:
148: /**
149: * Gets a reference to service registry for IXC.
150: *
151: * @return <code>JUMPServiceRegistryModule</code> instance
152: */
153: private JUMPServiceRegistryModule getJUMPServiceRegistry() {
154: return JUMPServiceRegistryModuleFactory.getInstance()
155: .getModule();
156: }
157:
158: void close() {
159: // Best effort service unregistration...
160: try {
161: getJUMPServiceRegistry().unregisterService(
162: Configuration.MIDP_CONTAINER_INTERFACE_IXC_URI);
163: } catch (AccessException ex) {
164: logError("failed to unbound IXC MIDP interface");
165: } catch (NotBoundException ex) {
166: logError("failed to unbound IXC MIDP interface");
167: }
168:
169: pushController.dispose();
170: }
171: }
172:
173: private PushSystem pushSystem = null;
174:
175: /** {@inheritDoc} */
176: public void load(final Map map) {
177: // assert pushSystem == null; // I hope we cannot get to load's without unload
178: final PushContentStore contentStore = new PushContentStore();
179: final StoreOperationManager storeOperationManager = new StoreOperationManager(
180: contentStore);
181: try {
182: pushSystem = new PushSystem(storeOperationManager);
183: } catch (AlreadyBoundException ex) {
184: logError("Failed to read push persistent data: " + ex);
185: throw new RuntimeException("Failed to load Push module", ex);
186: } catch (IOException ex) {
187: logError("Failed to read push persistent data: " + ex);
188: throw new RuntimeException("Failed to load Push module", ex);
189: }
190: }
191:
192: /** {@inheritDoc} */
193: public void unload() {
194: pushSystem.close();
195: pushSystem = null;
196: }
197:
198: /**
199: * Logs an error message.
200: *
201: * TBD: common logging mechanism.
202: *
203: * @param msg message to log
204: */
205: private static void logError(final String msg) {
206: System.err.println("[error in " + PushModule.class + "]: "
207: + msg);
208: }
209:
210: /** {@inheritDoc} */
211: public InstallerInterface getInstallerInterfaceImpl() {
212: return pushSystem.installerInterfaceImpl;
213: }
214: }
215:
216: /**
217: * Factory to initialize Push subsystem in the Executive.
218: *
219: * IMPL_NOTE: as currently PushRegistry module has no public
220: * API the factory is used for initialization only.
221: */
222: public final class PushRegistryModuleFactoryImpl extends
223: JUMPPushModuleFactory {
224: private final JUMPPushModule pushModule = new PushModule();
225:
226: /** {@inheritDoc} */
227: public void load(final Map map) {
228: pushModule.load(map);
229: }
230:
231: /** {@inheritDoc} */
232: public void unload() {
233: pushModule.unload();
234: }
235:
236: /** {@inheritDoc} */
237: public JUMPPushModule getPushModule() {
238: return pushModule;
239: }
240: }
|