KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > internal > baseadaptor > StateManager


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 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.internal.baseadaptor;
12
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
16 import org.eclipse.osgi.internal.resolver.*;
17 import org.eclipse.osgi.service.resolver.*;
18 import org.osgi.framework.BundleContext;
19 import org.osgi.framework.BundleException;
20
21 /**
22  * The StateManager manages the system state for the framework. It also provides the implementation
23  * to the PlatformAdmin service.
24  * <p>
25  * Clients may extend this class.
26  * </p>
27  * @since 3.1
28  */

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

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

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

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

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

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

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

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

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

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

103     public void shutdown(File JavaDoc stateFile, File JavaDoc lazyFile) throws IOException JavaDoc {
104         BundleDescription[] removalPendings = systemState.getRemovalPendings();
105         if (removalPendings.length > 0)
106             systemState.resolve(removalPendings);
107         writeState(systemState, stateFile, lazyFile);
108         stopDataManager();
109     }
110
111     /**
112      * Update the given target files with the state data in memory.
113      * @param stateFile
114      * @param lazyFile
115      * @throws IOException
116      */

117     public void update(File JavaDoc stateFile, File JavaDoc lazyFile) throws IOException JavaDoc {
118         BundleDescription[] removalPendings = systemState.getRemovalPendings();
119         StateImpl state = systemState;
120         if (removalPendings.length > 0) {
121             state = (StateImpl) state.getFactory().createState(systemState);
122             state.setResolver(getResolver(System.getSecurityManager() != null));
123             state.setPlatformProperties(FrameworkProperties.getProperties());
124             state.resolve(false);
125         }
126         writeState(state, stateFile, lazyFile);
127         lastTimeStamp = state.getTimeStamp();
128         // TODO consider updating the state files for lazy loading
129
}
130
131     private void readSystemState(File JavaDoc stateFile, File JavaDoc lazyFile, long expectedTimeStamp) {
132         if (stateFile == null || !stateFile.isFile())
133             return;
134         if (DEBUG_READER)
135             readStartupTime = System.currentTimeMillis();
136         try {
137             boolean lazyLoad = !Boolean.valueOf(FrameworkProperties.getProperty(PROP_NO_LAZY_LOADING)).booleanValue();
138             systemState = factory.readSystemState(stateFile, lazyFile, lazyLoad, expectedTimeStamp);
139             // problems in the cache (corrupted/stale), don't create a state object
140
if (systemState == null || !initializeSystemState()) {
141                 systemState = null;
142                 return;
143             }
144             cachedState = true;
145             try {
146                 expireTime = Long.parseLong(FrameworkProperties.getProperty(PROP_LAZY_UNLOADING_TIME, Long.toString(expireTime)));
147             } catch (NumberFormatException JavaDoc nfe) {
148                 // default to not expire
149
expireTime = 0;
150             }
151             if (lazyLoad && expireTime > 0)
152                 startDataManager();
153         } catch (IOException JavaDoc ioe) {
154             // TODO: how do we log this?
155
ioe.printStackTrace();
156         } finally {
157             if (DEBUG_READER)
158                 System.out.println("Time to read state: " + (System.currentTimeMillis() - readStartupTime)); //$NON-NLS-1$
159
}
160     }
161
162     private synchronized void startDataManager() {
163         if (dataManagerThread != null)
164             return;
165         dataManagerThread = new Thread JavaDoc(this, "State Data Manager"); //$NON-NLS-1$
166
dataManagerThread.setDaemon(true);
167         dataManagerThread.start();
168     }
169
170     /**
171      * Stops the active data manager thread which is used to unload unused
172      * state objects from memory.
173      */

174     public synchronized void stopDataManager() {
175         if (dataManagerThread == null)
176             return;
177         dataManagerThread.interrupt();
178         dataManagerThread = null;
179     }
180
181     private void writeState(StateImpl state, File JavaDoc stateFile, File JavaDoc lazyFile) throws IOException JavaDoc {
182         if (state == null)
183             return;
184         if (cachedState && !saveNeeded())
185             return;
186         state.fullyLoad(); // make sure we are fully loaded before saving
187
factory.writeState(state, stateFile, lazyFile);
188     }
189
190     private boolean initializeSystemState() {
191         systemState.setResolver(getResolver(System.getSecurityManager() != null));
192         lastTimeStamp = systemState.getTimeStamp();
193         return !systemState.setPlatformProperties(FrameworkProperties.getProperties());
194     }
195
196     /**
197      * Creates a new State used by the system. If the system State already
198      * exists then a new system State is not created.
199      * @return the State used by the system.
200      */

201     public synchronized State createSystemState() {
202         if (systemState == null) {
203             systemState = factory.createSystemState();
204             initializeSystemState();
205         }
206         return systemState;
207     }
208
209     /**
210      * Reads the State used by the system. If the system State already
211      * exists then the system State is not read from a cache. If the State could
212      * not be read from a cache then <code>null</code> is returned.
213      * @return the State used by the system or <code>null</code> if the State
214      * could not be read from a cache.
215      */

216     public synchronized State readSystemState() {
217         if (systemState == null)
218             readSystemState(stateFile, lazyFile, expectedTimeStamp);
219         return systemState;
220     }
221
222     /**
223      * Returns the State used by the system. If the system State does
224      * not exist then <code>null</code> is returned.
225      * @return the State used by the system or <code>null</code> if one
226      * does not exist.
227      */

228     public State getSystemState() {
229         return systemState;
230     }
231
232     /**
233      * Returns the cached time stamp of the system State. This value is the
234      * original time stamp of the system state when it was created or read from
235      * a cache.
236      * @see State#getTimeStamp()
237      * @return the cached time stamp of the system State
238      */

239     public long getCachedTimeStamp() {
240         return lastTimeStamp;
241     }
242
243     public boolean saveNeeded() {
244         return systemState.getTimeStamp() != lastTimeStamp || systemState.dynamicCacheChanged();
245     }
246
247     /**
248      * @see PlatformAdmin#getState(boolean)
249      */

250     public State getState(boolean mutable) {
251         return mutable ? factory.createState(systemState) : new ReadOnlyState(systemState);
252     }
253
254     /**
255      * @see PlatformAdmin#getState()
256      */

257     public State getState() {
258         return getState(true);
259     }
260
261     /**
262      * @see PlatformAdmin#getFactory()
263      */

264     public StateObjectFactory getFactory() {
265         return factory;
266     }
267
268     /**
269      * @see PlatformAdmin#commit(State)
270      */

271     public synchronized void commit(State state) throws BundleException {
272         throw new IllegalArgumentException JavaDoc("PlatformAdmin.commit() not supported"); //$NON-NLS-1$
273
}
274
275     /**
276      * @see PlatformAdmin#getResolver()
277      */

278     public Resolver getResolver() {
279         return getResolver(false);
280     }
281
282     private Resolver getResolver(boolean checkPermissions) {
283         return new org.eclipse.osgi.internal.module.ResolverImpl(context, checkPermissions);
284     }
285
286     /**
287      * @see PlatformAdmin#getStateHelper()
288      */

289     public StateHelper getStateHelper() {
290         return StateHelperImpl.getInstance();
291     }
292
293     public void run() {
294         long timeStamp = lastTimeStamp; // cache the original timestamp incase of updates
295
while (true) {
296             try {
297                 Thread.sleep(expireTime);
298             } catch (InterruptedException JavaDoc e) {
299                 return;
300             }
301             if (systemState != null)
302                 synchronized (systemState) {
303                     if (timeStamp == systemState.getTimeStamp() && !systemState.dynamicCacheChanged())
304                         systemState.unloadLazyData(expireTime);
305                 }
306         }
307     }
308 }
309
Popular Tags