KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > adaptor > core > StateManager


1 /*******************************************************************************
2  * Copyright (c) 2003, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.osgi.framework.adaptor.core;
12
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import org.eclipse.osgi.internal.resolver.*;
16 import org.eclipse.osgi.service.resolver.*;
17 import org.osgi.framework.BundleContext;
18 import org.osgi.framework.BundleException;
19
20 /**
21  * The StateManager manages the system state for the framework. It also provides the implementation
22  * to the PlatformAdmin service.
23  * <p>
24  * Clients may extend this class.
25  * </p>
26  * @since 3.1
27  */

28 public class StateManager implements PlatformAdmin, Runnable JavaDoc {
29     /**
30      * General debug flag
31      */

32     public static boolean DEBUG = false;
33     /**
34      * Reader debug flag
35      */

36     public static boolean DEBUG_READER = false;
37     /**
38      * PlatformAdmin debug flag
39      */

40     public static boolean DEBUG_PLATFORM_ADMIN = false;
41     /**
42      * PlatformAdmin resolver debug flag
43      */

44     public static boolean DEBUG_PLATFORM_ADMIN_RESOLVER = false;
45     /**
46      * Monitor PlatformAdmin debug flag
47      */

48     public static boolean MONITOR_PLATFORM_ADMIN = false;
49     /**
50      * System property used to disable lazy state loading
51      */

52     public static String JavaDoc PROP_NO_LAZY_LOADING = "osgi.noLazyStateLoading"; //$NON-NLS-1$
53
/**
54      * System property used to specify to amount time before lazy data can be flushed from memory
55      */

56     public static String JavaDoc PROP_LAZY_UNLOADING_TIME = "osgi.lazyStateUnloadingTime"; //$NON-NLS-1$
57
private long expireTime = 300000; // default to five minutes
58
private long readStartupTime;
59     private StateImpl systemState;
60     private StateObjectFactoryImpl factory;
61     private long lastTimeStamp;
62     private BundleInstaller installer;
63     private boolean cachedState = false;
64     private File JavaDoc stateFile;
65     private File JavaDoc lazyFile;
66     private long expectedTimeStamp;
67     private BundleContext context;
68
69     /**
70      * Constructs a StateManager using the specified files and context
71      * @param stateFile a file with the data required to persist in memory
72      * @param lazyFile a file with the data that may be lazy loaded and can be flushed from memory
73      * @param context the bundle context of the system bundle
74      */

75     public StateManager(File JavaDoc stateFile, File JavaDoc lazyFile, BundleContext context) {
76         // a negative timestamp means no timestamp checking
77
this(stateFile, lazyFile, context, -1);
78     }
79
80     /**
81      * Constructs a StateManager using the specified files and context
82      * @param stateFile a file with the data required to persist in memory
83      * @param lazyFile a file with the data that may be lazy loaded and can be flushed from memory
84      * @param context the bundle context of the system bundle
85      * @param expectedTimeStamp the expected timestamp of the persisted system state. A negative
86      * value indicates that no timestamp checking is done
87      */

88     public StateManager(File JavaDoc stateFile, File JavaDoc lazyFile, BundleContext context, long expectedTimeStamp) {
89         this.stateFile = stateFile;
90         this.lazyFile = lazyFile;
91         this.context = context;
92         this.expectedTimeStamp = expectedTimeStamp;
93         factory = new StateObjectFactoryImpl();
94     }
95
96     /**
97      * Shutsdown the state manager. If the timestamp of the system state has changed
98      * @param stateFile
99      * @param lazyFile
100      * @throws IOException
101      */

102     public void shutdown(File JavaDoc stateFile, File JavaDoc lazyFile) throws IOException JavaDoc {
103         BundleDescription[] removalPendings = systemState.getRemovalPendings();
104         if (removalPendings.length > 0)
105             systemState.resolve(removalPendings);
106         writeState(stateFile, lazyFile);
107     }
108
109     private void readSystemState(File JavaDoc stateFile, File JavaDoc lazyFile, long expectedTimeStamp) {
110         if (stateFile == null || !stateFile.isFile())
111             return;
112         if (DEBUG_READER)
113             readStartupTime = System.currentTimeMillis();
114         try {
115             boolean lazyLoad = !Boolean.valueOf(System.getProperty(PROP_NO_LAZY_LOADING)).booleanValue();
116             systemState = factory.readSystemState(stateFile, lazyFile, lazyLoad, expectedTimeStamp);
117             // problems in the cache (corrupted/stale), don't create a state object
118
if (systemState == null || !initializeSystemState()) {
119                 systemState = null;
120                 return;
121             }
122             cachedState = true;
123             try {
124                 expireTime = Long.parseLong(System.getProperty(PROP_LAZY_UNLOADING_TIME, Long.toString(expireTime)));
125             } catch (NumberFormatException JavaDoc nfe) {
126                 // default to not expire
127
expireTime = 0;
128             }
129             if (lazyLoad && expireTime > 0) {
130                 Thread JavaDoc t = new Thread JavaDoc(this, "State Data Manager"); //$NON-NLS-1$
131
t.setDaemon(true);
132                 t.start();
133             }
134         } catch (IOException JavaDoc ioe) {
135             // TODO: how do we log this?
136
ioe.printStackTrace();
137         } finally {
138             if (DEBUG_READER)
139                 System.out.println("Time to read state: " + (System.currentTimeMillis() - readStartupTime)); //$NON-NLS-1$
140
}
141     }
142
143     private void writeState(File JavaDoc stateFile, File JavaDoc lazyFile) throws IOException JavaDoc {
144         if (systemState == null)
145             return;
146         if (cachedState && lastTimeStamp == systemState.getTimeStamp())
147             return;
148         systemState.fullyLoad(); // make sure we are fully loaded before saving
149
factory.writeState(systemState, stateFile, lazyFile);
150     }
151
152     private boolean initializeSystemState() {
153         systemState.setResolver(getResolver(System.getSecurityManager() != null));
154         lastTimeStamp = systemState.getTimeStamp();
155         return !systemState.setPlatformProperties(System.getProperties());
156     }
157
158     /**
159      * Creates a new State used by the system. If the system State already
160      * exists then a new system State is not created.
161      * @return the State used by the system.
162      */

163     public synchronized State createSystemState() {
164         if (systemState == null) {
165             systemState = factory.createSystemState();
166             initializeSystemState();
167         }
168         return systemState;
169     }
170
171     /**
172      * Reads the State used by the system. If the system State already
173      * exists then the system State is not read from a cache. If the State could
174      * not be read from a cache then <code>null</code> is returned.
175      * @return the State used by the system or <code>null</code> if the State
176      * could not be read from a cache.
177      */

178     public synchronized State readSystemState() {
179         if (systemState == null)
180             readSystemState(stateFile, lazyFile, expectedTimeStamp);
181         return systemState;
182     }
183
184     /**
185      * Returns the State used by the system. If the system State does
186      * not exist then <code>null</code> is returned.
187      * @return the State used by the system or <code>null</code> if one
188      * does not exist.
189      */

190     public State getSystemState() {
191         return systemState;
192     }
193
194     /**
195      * Returns the cached time stamp of the system State. This value is the
196      * original time stamp of the system state when it was created or read from
197      * a cache.
198      * @see State#getTimeStamp()
199      * @return the cached time stamp of the system State
200      */

201     public long getCachedTimeStamp() {
202         return lastTimeStamp;
203     }
204
205     /**
206      * @see PlatformAdmin#getState(boolean)
207      */

208     public State getState(boolean mutable) {
209         return mutable ? factory.createState(systemState) : new ReadOnlyState(systemState);
210     }
211
212     /**
213      * @see PlatformAdmin#getState()
214      */

215     public State getState() {
216         return getState(true);
217     }
218
219     /**
220      * @see PlatformAdmin#getFactory()
221      */

222     public StateObjectFactory getFactory() {
223         return factory;
224     }
225
226     /**
227      * @see PlatformAdmin#commit(State)
228      */

229     public synchronized void commit(State state) throws BundleException {
230         // no installer have been provided - commit not supported
231
if (installer == null)
232             throw new IllegalArgumentException JavaDoc("PlatformAdmin.commit() not supported"); //$NON-NLS-1$
233
if (!(state instanceof UserState))
234             throw new IllegalArgumentException JavaDoc("Wrong state implementation"); //$NON-NLS-1$
235
if (state.getTimeStamp() != systemState.getTimeStamp())
236             throw new BundleException(StateMsg.COMMIT_INVALID_TIMESTAMP);
237         StateDelta delta = state.compare(systemState);
238         BundleDelta[] changes = delta.getChanges();
239         for (int i = 0; i < changes.length; i++)
240             if ((changes[i].getType() & BundleDelta.ADDED) > 0)
241                 installer.installBundle(changes[i].getBundle());
242             else if ((changes[i].getType() & BundleDelta.REMOVED) > 0)
243                 installer.uninstallBundle(changes[i].getBundle());
244             else if ((changes[i].getType() & BundleDelta.UPDATED) > 0)
245                 installer.updateBundle(changes[i].getBundle());
246             else {
247                 // bug in StateDelta#getChanges
248
}
249     }
250
251     /**
252      * @see PlatformAdmin#getResolver()
253      */

254     public Resolver getResolver() {
255         return getResolver(false);
256     }
257
258     private Resolver getResolver(boolean checkPermissions) {
259         return new org.eclipse.osgi.internal.module.ResolverImpl(context, checkPermissions);
260     }
261
262     /**
263      * @see PlatformAdmin#getStateHelper()
264      */

265     public StateHelper getStateHelper() {
266         return StateHelperImpl.getInstance();
267     }
268
269     /**
270      * Returns the bundle installer.
271      * @return the bundle installer
272      */

273     public BundleInstaller getInstaller() {
274         return installer;
275     }
276
277     /**
278      * Sets the bundle installer. The bundle installer will be used when a state is commited
279      * using the commit(State) method.
280      * @param installer the bundle installer
281      */

282     public void setInstaller(BundleInstaller installer) {
283         this.installer = installer;
284     }
285
286     public void run() {
287         while (true) {
288             try {
289                 Thread.sleep(expireTime);
290             } catch (InterruptedException JavaDoc e) {
291                 return;
292             }
293             if (systemState != null && lastTimeStamp == systemState.getTimeStamp())
294                 systemState.unloadLazyData(expireTime);
295         }
296     }
297 }
298
Popular Tags