KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > PersistenceManagerFactoryImp


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

12 package com.versant.core.jdo;
13
14 import com.versant.core.common.config.ConfigInfo;
15 import com.versant.core.util.BeanUtils;
16 import com.versant.core.util.StringListParser;
17 import com.versant.core.util.PropertiesLoader;
18 import com.versant.core.util.classhelper.ClassHelper;
19 import com.versant.core.common.BindingSupportImpl;
20 import com.versant.core.metric.*;
21 import com.versant.core.metric.HasMetrics;
22 import com.versant.core.logging.LogEvent;
23 import com.versant.core.storagemanager.StorageManagerFactory;
24 import com.versant.core.storagemanager.StorageManagerFactoryBuilder;
25
26 import javax.jdo.PersistenceManagerFactory;
27 import java.util.*;
28 import java.io.IOException JavaDoc;
29
30 /**
31  * PMF implementation.
32  */

33 public class PersistenceManagerFactoryImp
34         extends PersistenceManagerFactoryBase implements HasMetrics {
35
36     protected Map hyperdriveBytecode;
37     protected int hyperdriveBytecodeMaxSize;
38     protected VersantBackgroundTask logDownloader;
39     protected Thread JavaDoc logDownloaderThread;
40     protected PMFServer[] pmfServers;
41     protected boolean releaseHyperdriveBytecode;
42
43     protected MetricSnapshotStore metricSnapshotStore;
44     protected HashMap userMetricIndexMap;
45     protected BaseMetric[] userMetrics;
46     protected int[] userMetricValues;
47
48     public static final String JavaDoc PMF_SERVER = "pmf.server";
49     public static final String JavaDoc RELEASE_HYPERDRIVE_BYTECODE =
50             "versant.releaseHyperdriveBytecode";
51
52     private static final String JavaDoc CAT_GENERAL = "General";
53
54     private final BaseMetric metricEvents =
55             new BaseMetric("Events", "Events", CAT_GENERAL,
56                     "Number of events logged", 3, Metric.CALC_DELTA_PER_SECOND);
57     private final BaseMetric metricLastEventId =
58             new BaseMetric("LastEventId", "Last Event ID", CAT_GENERAL,
59                     "Approximate ID of the last event logged", 0,
60                     Metric.CALC_RAW);
61
62     private static final String JavaDoc CAT_PM = "PM";
63
64     private final BaseMetric metricPMCreated =
65             new BaseMetric("PMCreated", "PM Created", CAT_PM,
66                     "Number of local PMs created", 3,
67                     Metric.CALC_DELTA_PER_SECOND);
68     private final BaseMetric metricPMClosed =
69             new BaseMetric("PMClosed", "PM Closed", CAT_PM,
70                     "Number of PMs closed (local and remote)", 3,
71                     Metric.CALC_DELTA_PER_SECOND);
72     private final BaseMetric metricPMClosedAuto =
73             new BaseMetric("PMClosedAuto", "PM Closed Auto", CAT_PM,
74                     "Number of PMs closed automatically (local and remote)", 0,
75                     Metric.CALC_RAW);
76     private final BaseMetric metricPMClosedAutoTx =
77             new BaseMetric("PMClosedAutoTx", "PM Closed Auto Tx", CAT_PM,
78                     "Number of PMs closed automatically with active datastore transaction (BAD)",
79                     0, Metric.CALC_RAW);
80     private final BaseMetric metricPMCount =
81             new BaseMetric("PMCount", "PM Count", CAT_PM,
82                     "Number of open PMs", 0,
83                     Metric.CALC_AVERAGE);
84
85     /**
86      * This is called by JDOHelper to construct a PM factory from a properties
87      * instance.
88      */

89     public static PersistenceManagerFactory getPersistenceManagerFactory(
90             Properties props) {
91         return new PersistenceManagerFactoryImp(props,
92                 PersistenceManagerFactoryImp.class.getClassLoader());
93     }
94     
95     public PersistenceManagerFactoryImp(Properties props,
96             ClassLoader JavaDoc loader) {
97         super(props, loader);
98         boolean ok = false;
99         try {
100             initLogDownloader(config, loader);
101             initMetrics(config);
102             if (pmfServers != null) {
103                 for (int i = 0; i < pmfServers.length; i++) {
104                     PMFServer s = pmfServers[i];
105                     s.init(this);
106                     if (s instanceof HasMetrics) {
107                         metricSnapshotStore.addSource((HasMetrics)s);
108                     }
109                 }
110             }
111             startLogDownloader(config);
112             metricSnapshotStore.start(config.url);
113             if (pmfServers != null) {
114                 for (int i = 0; i < pmfServers.length; i++) {
115                     try {
116                         pmfServers[i].start();
117                     } catch (Exception JavaDoc e) {
118                         throw handleException(e);
119                     }
120                 }
121             }
122             ok = true;
123         } finally {
124             if (!ok) {
125                 try {
126                     close();
127                 } catch (Throwable JavaDoc e) {
128                     // ignore - already busy with an exception
129
}
130             }
131         }
132     }
133
134     /**
135      * Create our StorageManagerFactory.
136      */

137     protected StorageManagerFactory createStorageManagerFactory() {
138         createPMFServers();
139         releaseHyperdriveBytecode = pmfServers == null
140                 && "true".equals(props.getProperty(RELEASE_HYPERDRIVE_BYTECODE));
141         StorageManagerFactoryBuilder b = new StorageManagerFactoryBuilder();
142         b.setLogEventStore(pes);
143         b.setConfig(config);
144         b.setLoader(loader);
145         b.setCache(cache);
146         b.setKeepHyperdriveBytecode(!releaseHyperdriveBytecode);
147         StorageManagerFactory ans = b.createStorageManagerFactory();
148         hyperdriveBytecode = b.getHyperdriveBytecode();
149         hyperdriveBytecodeMaxSize = b.getHyperdriveBytecodeMaxSize();
150         return ans;
151     }
152
153     public void addPMFServer(PMFServer pmfServer) {
154         if (releaseHyperdriveBytecode && config.hyperdrive) {
155             throw BindingSupportImpl.getInstance().invalidOperation(
156                     "Unable to add PMFServer as versant.releaseHyperdriveBytecode " +
157                     "property is true");
158         }
159         addPMFServerImp(pmfServer);
160         if (pmfServer instanceof HasMetrics) {
161             metricSnapshotStore.addSource((HasMetrics)pmfServer);
162         }
163     }
164
165     protected void addPMFServerImp(PMFServer pmfServer) {
166         if (pmfServers == null) {
167             pmfServers = new PMFServer[]{pmfServer};
168         } else {
169             int n = pmfServers.length;
170             PMFServer[] a = new PMFServer[n + 1];
171             System.arraycopy(pmfServers, 0, a, 0, n);
172             a[n] = pmfServer;
173             pmfServers = a;
174         }
175     }
176
177     /**
178      * Export us using whatever remote access protocols have been specified.
179      */

180     protected void createPMFServers() {
181         String JavaDoc ra = config.remoteAccess;
182         if (ra == null || "true".equals(ra)) {
183             ra = "socket";
184         } else if ("false".equals(ra)) {
185             return;
186         }
187         boolean defaultProtocol = "socket".equals(ra);
188         for (StringListParser lp = new StringListParser(ra);
189                 lp.hasNext(); ) {
190             String JavaDoc protocol = lp.nextString();
191             PMFServer pmfServer = createPMFServer(protocol, defaultProtocol);
192             if (pmfServer != null) {
193                 addPMFServerImp(pmfServer);
194             }
195         }
196     }
197
198     /**
199      * Create a PMFServer instance to handle the protocol. If defaultProtocol
200      * is true and the properties resource for the protocol cannot be loaded
201      * then null is returned. Otherwise an exception is thrown. This handles
202      * the case where remote access is on by default but the remote access
203      * module is not available.
204      */

205     private PMFServer createPMFServer(String JavaDoc protocol,
206             boolean defaultProtocol) {
207         Properties p;
208         try {
209             p = PropertiesLoader.loadProperties(loader,
210                     "openaccess-remote", protocol);
211         } catch (IOException JavaDoc e) {
212             if (defaultProtocol) {
213                 return null;
214             }
215             throw BindingSupportImpl.getInstance().invalidOperation(
216                     e.toString(), e);
217         }
218         String JavaDoc clsName = p.getProperty(PMF_SERVER);
219         if (clsName == null) {
220             throw BindingSupportImpl.getInstance().internal(
221                     PMF_SERVER + " not found in resource " +
222                     p.getProperty(PropertiesLoader.RES_NAME_PROP));
223         }
224         try {
225             Class JavaDoc cls = ClassHelper.get().classForName(clsName, true, loader);
226             return (PMFServer)cls.newInstance();
227         } catch (Exception JavaDoc e) {
228             throw BindingSupportImpl.getInstance().internal(e.toString(), e);
229         }
230     }
231
232     protected void initMetrics(ConfigInfo config) {
233         int n = config.userBaseMetrics.size();
234         if (n > 0) {
235             userMetricValues = new int[n];
236             userMetricIndexMap = new HashMap(n * 2);
237             userMetrics = new BaseMetric[n];
238             for (int i = 0; i < n; i++) {
239                 ConfigInfo.UserBaseMetric u =
240                         (ConfigInfo.UserBaseMetric)config.userBaseMetrics.get(i);
241                 BaseMetric m = new BaseMetric(u.name, u.displayName, u.category,
242                         u.description, u.decimals, u.defaultCalc);
243                 userMetricIndexMap.put(m.getName(), new Integer JavaDoc(i));
244                 userMetrics[i] = m;
245             }
246         }
247         metricSnapshotStore = new MetricSnapshotStore(
248                 config.metricStoreCapacity, config.metricSnapshotIntervalMs);
249         metricSnapshotStore.addSource(this);
250     }
251
252     protected void startLogDownloader(ConfigInfo config) {
253         logDownloaderThread = new Thread JavaDoc(logDownloader,
254                 "VOA Log Downloader " + config.url);
255         logDownloaderThread.setDaemon(true);
256         logDownloaderThread.start();
257     }
258
259     protected void initLogDownloader(ConfigInfo config, ClassLoader JavaDoc loader) {
260         try {
261             if (config.logDownloaderClass == null) {
262                 logDownloader = new LogDownloader();
263             } else {
264                 logDownloader = (VersantBackgroundTask)BeanUtils.newInstance(
265                         config.logDownloaderClass, loader,
266                         VersantBackgroundTask.class);
267             }
268             BeanUtils.setProperties(logDownloader, config.logDownloaderProps);
269             if (logDownloader instanceof LogDownloader) {
270                 ((LogDownloader)logDownloader).setQuiet(true);
271             }
272             logDownloader.setPmf(this);
273         } catch (Exception JavaDoc e) {
274             throw handleException(e);
275         }
276     }
277
278     public synchronized void close() {
279         super.close();
280         if (pmfServers != null) {
281             for (int i = 0; i < pmfServers.length; i++) {
282                 try {
283                     pmfServers[i].close();
284                 } catch (Throwable JavaDoc e) {
285                     // ignore
286
}
287             }
288         }
289         if (logDownloaderThread != null) {
290             logDownloader.shutdown();
291             logDownloaderThread.interrupt();
292             logDownloaderThread = null;
293         }
294         if (metricSnapshotStore != null) {
295             metricSnapshotStore.shutdown();
296             metricSnapshotStore = null;
297         }
298     }
299
300     public Metric[] getMetrics() {
301         return metricSnapshotStore.getMetrics();
302     }
303
304     public MetricSnapshotPacket getNewMetricSnapshots(int lastId) {
305         return metricSnapshotStore.getNewSnapshots(lastId);
306     }
307
308     public MetricSnapshotPacket getMostRecentMetricSnapshot(int lastId) {
309         return metricSnapshotStore.getMostRecentSnapshot(lastId);
310     }
311
312     protected int findUserMetricIndex(String JavaDoc name) {
313         Integer JavaDoc ans = (Integer JavaDoc)userMetricIndexMap.get(name);
314         if (ans == null) {
315             throw BindingSupportImpl.getInstance().invalidOperation(
316                     "Unknown user-defined Metric: '" + name + "'");
317         }
318         return ans.intValue();
319     }
320
321     public void setUserMetric(String JavaDoc name, int value) {
322         userMetricValues[findUserMetricIndex(name)] = value;
323     }
324
325     public synchronized void incUserMetric(String JavaDoc name, int delta) {
326         userMetricValues[findUserMetricIndex(name)] += delta;
327     }
328
329     public int getUserMetric(String JavaDoc name) {
330         return userMetricValues[findUserMetricIndex(name)];
331     }
332
333     public void addMetrics(List list) {
334         list.add(metricEvents);
335         list.add(metricLastEventId);
336         list.add(metricPMCreated);
337         list.add(metricPMClosed);
338         list.add(metricPMClosedAuto);
339         list.add(metricPMClosedAutoTx);
340         list.add(metricPMCount);
341         if (pmPool != null) {
342             pmPool.addMetrics(list);
343         }
344         if (smf instanceof HasMetrics) {
345             ((HasMetrics)smf).addMetrics(list);
346         }
347         if (userMetrics != null) {
348             list.addAll(Arrays.asList(userMetrics));
349         }
350     }
351
352     public void sampleMetrics(int[][] buf, int pos) {
353         buf[metricEvents.getIndex()][pos] = pes.getEventsLogged();
354         buf[metricLastEventId.getIndex()][pos] = LogEvent.getLastId();
355         buf[metricPMCreated.getIndex()][pos] = pmCreatedCount;
356         buf[metricPMClosed.getIndex()][pos] = pmClosedCount;
357         buf[metricPMClosedAuto.getIndex()][pos] = pmClosedAutoCount;
358         buf[metricPMClosedAutoTx.getIndex()][pos] = pmClosedAutoTxCount;
359         buf[metricPMCount.getIndex()][pos] = activePMs.size();
360         if (pmPool != null) {
361             pmPool.sampleMetrics(buf, pos);
362         }
363         if (smf instanceof HasMetrics) {
364             ((HasMetrics)smf).sampleMetrics(buf, pos);
365         }
366         if (userMetrics != null) {
367             for (int i = userMetrics.length - 1; i >= 0; i--) {
368                 buf[userMetrics[i].getIndex()][pos] = userMetricValues[i];
369             }
370         }
371     }
372
373     public Map getHyperdriveBytecode() {
374         return hyperdriveBytecode;
375     }
376
377     public int getHyperdriveBytecodeMaxSize() {
378         return hyperdriveBytecodeMaxSize;
379     }
380
381     public boolean isLocal() {
382         return true;
383     }
384
385 }
386
387
Popular Tags