Source Code Cross Referenced for Store.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » jump » push » executive » persistence » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.jump.push.executive.persistence 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:        package com.sun.midp.jump.push.executive.persistence;
025:
026:        import com.sun.jump.module.contentstore.JUMPNode;
027:        import com.sun.jump.module.contentstore.JUMPStoreHandle;
028:        import com.sun.midp.jump.push.executive.JUMPConnectionInfo;
029:        import java.io.IOException;
030:        import java.util.Arrays;
031:        import java.util.HashMap;
032:        import java.util.Iterator;
033:        import java.util.Map;
034:        import java.util.Vector;
035:
036:        /**
037:         * Persistent store class for <code>PushRegistry</code> module.
038:         *
039:         * <p>
040:         * IMPORTANT_NOTE:  The clients of this class should ensure that content store
041:         *  manager passed into the constructor doesn't have exclusive lock when
042:         *  methods are invoked.  Otherwise we'll face deadlocks.
043:         * <p>
044:         *
045:         * <p><strong>NB</strong>: method <code>getConnections</code> guarantees
046:         * that <code>MIDlet suite</code> without connections won't be listed,
047:         * i.e. <code>MIDletSuiteConnections.connections</code>
048:         * array is not empty</p>
049:         *
050:         * <p><strong>NB</strong>: this class has no intellegence of connection
051:         * semantics, e.g. it doesn't handle connection conflicts.  It's a simplistic
052:         * database.</p>
053:         *
054:         * <p><strong>Implementation notice</strong>: as for now if <code>MIDlet
055:         * suite</code> removes all the connections, the file with suite connections
056:         * is not removed and the suite is filtered in {@line getConnections} method.
057:         * Another option might be to remove the file.</p>
058:         */
059:        public final class Store {
060:            /** PushRegistry root dir. */
061:            private static final String ROOT_DIR = "./push/";
062:
063:            /** Dir to store connections. */
064:            static final String CONNECTIONS_DIR = ROOT_DIR + "connections";
065:
066:            /** Dir to store alarms. */
067:            static final String ALARMS_DIR = ROOT_DIR + "alarms";
068:
069:            /** PushRegistry connections. */
070:            private final AppSuiteDataStore connectionsStore;
071:
072:            /** PushRegistry alarms. */
073:            private final AppSuiteDataStore alarmsStore;
074:
075:            /**
076:             * Constructs a Store and reads the data.
077:             *
078:             * @param storeManager JUMP content store manager to use
079:             *
080:             * @throws IOException if IO fails
081:             */
082:            public Store(final StoreOperationManager storeManager)
083:                    throws IOException {
084:                if (storeManager == null) {
085:                    throw new IllegalArgumentException("storeManager is null");
086:                }
087:
088:                ensureStoreStructure(storeManager);
089:
090:                connectionsStore = new AppSuiteDataStore(storeManager,
091:                        CONNECTIONS_DIR, CONNECTIONS_CONVERTER);
092:
093:                alarmsStore = new AppSuiteDataStore(storeManager, ALARMS_DIR,
094:                        ALARMS_CONVERTER);
095:            }
096:
097:            /**
098:             * Ensures presence of store layout requested for the
099:             *  store to function correctly.
100:             *
101:             * @param storeManager JUMP content store manager to use
102:             *
103:             * @throws IOException in case of IO errors
104:             */
105:            private static void ensureStoreStructure(
106:                    final StoreOperationManager storeManager)
107:                    throws IOException {
108:                storeManager.doOperation(true,
109:                        new StoreOperationManager.Operation() {
110:                            public Object perform(
111:                                    final JUMPStoreHandle storeHandle)
112:                                    throws IOException {
113:                                ensureDir(storeHandle, CONNECTIONS_DIR);
114:                                ensureDir(storeHandle, ALARMS_DIR);
115:                                return null;
116:                            }
117:                        });
118:            }
119:
120:            /**
121:             * Ensures presence of the given dir.
122:             *
123:             * @param storeHandle handle to content store to use
124:             * @param dir name of directory to check
125:             *
126:             * @throws IOException in case of IO troubles
127:             */
128:            private static void ensureDir(final JUMPStoreHandle storeHandle,
129:                    final String dir) throws IOException {
130:                final JUMPNode node = storeHandle.getNode(dir);
131:                if (node == null) {
132:                    logWarning("Directory " + dir + " is missing: recreating");
133:                    storeHandle.createNode(dir);
134:                    return;
135:                }
136:                if (!(node instanceof  JUMPNode.List)) {
137:                    logWarning("Node " + dir
138:                            + " is a data node: trying to erase and recreate");
139:                    storeHandle.deleteNode(dir);
140:                    storeHandle.createNode(dir);
141:                    return;
142:                }
143:            }
144:
145:            private static void logWarning(final String msg) {
146:                // TBD: use common logging
147:                System.out.println("[warning] " + Store.class + ": " + msg);
148:            }
149:
150:            /** Connections consumer. */
151:            public static interface ConnectionsConsumer {
152:                /**
153:                 * COnsumes app suite connections.
154:                 *
155:                 * @param suiteId app suite ID
156:                 * @param connections app suite connections
157:                 */
158:                void consume(int suiteId, JUMPConnectionInfo[] connections);
159:            }
160:
161:            /**
162:             * Lists all registered connections.
163:             *
164:             * @param connectionsLister connection lister
165:             */
166:            public synchronized void listConnections(
167:                    final ConnectionsConsumer connectionsLister) {
168:                connectionsStore.listData(new AppSuiteDataStore.DataConsumer() {
169:                    public void consume(final int suiteId,
170:                            final Object suiteData) {
171:                        final Vector v = (Vector) suiteData;
172:                        final JUMPConnectionInfo[] cns = new JUMPConnectionInfo[v
173:                                .size()];
174:                        v.toArray(cns);
175:                        connectionsLister.consume(suiteId, cns);
176:                    }
177:                });
178:            }
179:
180:            /**
181:             * Adds new registered connection.
182:             *
183:             * <p><strong>Precondition</strong>: <code>connection</code> MUST not be
184:             * already registered (the method doesn't check it)</p>
185:             *
186:             * @param midletSuiteID ID of <code>MIDlet suite</code> to register
187:             *   connection for
188:             *
189:             * @param connection Connection to register
190:             *
191:             * @throws IOException if the content store failed to perform operation
192:             */
193:            public synchronized void addConnection(final int midletSuiteID,
194:                    final JUMPConnectionInfo connection) throws IOException {
195:                Vector cns = (Vector) connectionsStore
196:                        .getSuiteData(midletSuiteID);
197:                if (cns == null) {
198:                    cns = new Vector();
199:                }
200:                cns.add(connection);
201:                connectionsStore.updateSuiteData(midletSuiteID, cns);
202:            }
203:
204:            /**
205:             * Adds connections for the suite being installed.
206:             *
207:             * <p><strong>Preconditin</strong>: <code>connection</code> MUST not be
208:             * already registered (the method doesn't check it)</p>
209:             *
210:             * @param midletSuiteID ID of <code>MIDlet suite</code> to register
211:             *   connection for
212:             *
213:             * @param connections Connections to register
214:             *
215:             * @throws IOException if the content store failed to perform operation
216:             */
217:            public synchronized void addConnections(final int midletSuiteID,
218:                    final JUMPConnectionInfo[] connections) throws IOException {
219:                final Vector cns = new Vector(Arrays.asList(connections));
220:                connectionsStore.updateSuiteData(midletSuiteID, cns);
221:            }
222:
223:            /**
224:             * Removes registered connection.
225:             *
226:             * <p><strong>Preconditin</strong>: <code>connection</code> MUST have been
227:             * already registered (the method doesn't check it)</p>
228:             *
229:             * <p><strong>NB</strong>: <code>throws IOException</code> was intentionally
230:             * removed from the signature: it's resonsibility of <code>Store</code>
231:             * to ensure removal of all connections.</p>
232:             *
233:             * @param midletSuiteID ID of <code>MIDlet suite</code> to remove
234:             *   connection for
235:             *
236:             * @param connection Connection to remove
237:             *
238:             * @throws IOException if the content store failed to perform operation
239:             */
240:            public synchronized void removeConnection(final int midletSuiteID,
241:                    final JUMPConnectionInfo connection) throws IOException {
242:                Vector cns = (Vector) connectionsStore
243:                        .getSuiteData(midletSuiteID);
244:                // assert cns != null : "cannot be null";
245:                cns.remove(connection);
246:                if (!cns.isEmpty()) {
247:                    connectionsStore.updateSuiteData(midletSuiteID, cns);
248:                } else {
249:                    connectionsStore.removeSuiteData(midletSuiteID);
250:                }
251:            }
252:
253:            /**
254:             * Removes all registered connections.
255:             *
256:             * <p><strong>Preconditin</strong>: <code>connection</code> MUST have been
257:             * already registered (the method doesn't check it)</p>
258:             *
259:             * <p><strong>NB</strong>: <code>throws IOException</code> was intentionally
260:             * removed from the signature: it's resonsibility of <code>Store</code>
261:             * to ensure removal of all connections.</p>
262:             *
263:             * @param midletSuiteID ID of <code>MIDlet suite</code> to remove
264:             *   connections for
265:             *
266:             * @throws IOException if the content store failed
267:             */
268:            public synchronized void removeConnections(final int midletSuiteID)
269:                    throws IOException {
270:                connectionsStore.removeSuiteData(midletSuiteID);
271:            }
272:
273:            /** Alarms lister. */
274:            public static interface AlarmsConsumer {
275:                /**
276:                 * Lists app suite alarms.
277:                 *
278:                 * @param suiteId app suite ID
279:                 * @param alarms alarms mappings from <code>MIDlet</code> class name
280:                 *  to the scheduled time
281:                 */
282:                void consume(int suiteId, Map alarms);
283:            }
284:
285:            /**
286:             * Lists all alarms.
287:             *
288:             * @param alarmsLister connection lister
289:             */
290:            public synchronized void listAlarms(
291:                    final AlarmsConsumer alarmsLister) {
292:                alarmsStore.listData(new AppSuiteDataStore.DataConsumer() {
293:                    public void consume(final int suiteId,
294:                            final Object suiteData) {
295:                        alarmsLister.consume(suiteId, (Map) suiteData);
296:                    }
297:                });
298:            }
299:
300:            /**
301:             * Adds an alarm.
302:             *
303:             * @param midletSuiteID <code>MIDlet suite</code> to add alarm for
304:             * @param midlet <code>MIDlet</code> class name
305:             * @param time alarm time
306:             *
307:             * @throws IOException if the content store failed
308:             */
309:            public synchronized void addAlarm(final int midletSuiteID,
310:                    final String midlet, final long time) throws IOException {
311:                HashMap as = (HashMap) alarmsStore.getSuiteData(midletSuiteID);
312:                if (as == null) {
313:                    as = new HashMap();
314:                }
315:                as.put(midlet, new Long(time));
316:                alarmsStore.updateSuiteData(midletSuiteID, as);
317:            }
318:
319:            /**
320:             * Removes an alarm.
321:             *
322:             * @param midletSuiteID <code>MIDlet suite</code> to remove alarm for
323:             * @param midlet <code>MIDlet</code> class name
324:             *
325:             * @throws IOException if the content store failed
326:             */
327:            public synchronized void removeAlarm(final int midletSuiteID,
328:                    final String midlet) throws IOException {
329:                final HashMap as = (HashMap) alarmsStore
330:                        .getSuiteData(midletSuiteID);
331:                // assert as != null;
332:                as.remove(midlet);
333:                if (!as.isEmpty()) {
334:                    alarmsStore.updateSuiteData(midletSuiteID, as);
335:                } else {
336:                    alarmsStore.removeSuiteData(midletSuiteID);
337:                }
338:            }
339:
340:            /** Connections converter. */
341:            private static final AppSuiteDataStore.DataConverter CONNECTIONS_CONVERTER = new ConnectionConverter();
342:
343:            /** Implements conversion interface for connections. */
344:            private static final class ConnectionConverter implements 
345:                    AppSuiteDataStore.DataConverter {
346:                /**
347:                 * Separator to use.
348:                 *
349:                 * <p>
350:                 * <strong>NB</strong>: Separator shouldn't be valid character
351:                 * for <code>connection</code>, <code>midlet</code> or
352:                 * <code>filter</code> fields of <code>JUMPConnectionInfo</code>
353:                 */
354:                static final char SEPARATOR = '\n';
355:
356:                /**
357:                 * Number of strings per record.
358:                 */
359:                static final int N_STRINGS_PER_RECORD = 3;
360:
361:                /**
362:                 * Converts a <code>Vector</code> of <code>JUMPConnectionInfo</code>
363:                 *  into a string.
364:                 *
365:                 * @param data data to convert
366:                 * @return string with all connections
367:                 */
368:                public String dataToString(final Object data) {
369:                    final Vector connections = (Vector) data;
370:                    if (connections == null) {
371:                        throw new IllegalArgumentException(
372:                                "connections vector is null");
373:                    }
374:
375:                    final StringBuffer sb = new StringBuffer();
376:
377:                    for (Iterator it = connections.iterator(); it.hasNext();) {
378:                        JUMPConnectionInfo connection = (JUMPConnectionInfo) it
379:                                .next();
380:                        sb.append(connection.connection);
381:                        sb.append(SEPARATOR);
382:                        sb.append(connection.midlet);
383:                        sb.append(SEPARATOR);
384:                        sb.append(connection.filter);
385:                        sb.append(SEPARATOR);
386:                    }
387:
388:                    return sb.toString();
389:                }
390:
391:                /**
392:                 * Converts a string into a <code>Vector</code> of
393:                 *  <code>JUMPConnectionInfo</code>.
394:                 *
395:                 * @param string string to convert
396:                 * @return <code>Vector</code> of connections
397:                 */
398:                public Object stringToData(final String string) {
399:                    if (string == null) {
400:                        throw new IllegalArgumentException("string is null");
401:                    }
402:
403:                    Vector split = splitString(string);
404:                    String[] ss = new String[split.size()];
405:                    split.toArray(ss);
406:
407:                    // assert (strings.length % N_STRINGS_PER_RECORD == 0)
408:                    //  : "Broken data";
409:
410:                    Vector v = new Vector();
411:                    for (int i = 0; i < ss.length; i += N_STRINGS_PER_RECORD) {
412:                        v.add(new JUMPConnectionInfo(ss[i], ss[i + 1],
413:                                ss[i + 2]));
414:                    }
415:                    return v;
416:                }
417:
418:                /**
419:                 * Splits a string into <code>Vector</code> of strings.
420:                 *
421:                 * @param string string to split
422:                 *
423:                 * @return <code>Vector</code> of strings splitted by
424:                 *  <code>SEPARATOR</code>
425:                 */
426:                private Vector splitString(final String string) {
427:                    Vector v = new Vector();
428:                    int start = 0;
429:                    while (true) {
430:                        int i = string.indexOf(SEPARATOR, start);
431:                        if (i == -1) {
432:                            // assert start == string.length();
433:                            return v;
434:                        }
435:                        v.add(string.substring(start, i));
436:                        start = i + 1;
437:                    }
438:                }
439:            };
440:
441:            /** Alarms converter. */
442:            private static final AppSuiteDataStore.DataConverter ALARMS_CONVERTER = new AlarmsConverter();
443:
444:            /** Implements conversion interface for alarms. */
445:            private static final class AlarmsConverter implements 
446:                    AppSuiteDataStore.DataConverter {
447:                /** Char to seprate midlet class name from time. */
448:                private static final char FIELD_SEP = ':';
449:
450:                /**
451:                 * Converts data into a string.
452:                 *
453:                 * @param data data to convert
454:                 *
455:                 * @return string representation
456:                 */
457:                public String dataToString(final Object data) {
458:                    final Map m = (Map) data;
459:
460:                    final StringBuffer sb = new StringBuffer();
461:                    for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
462:                        final Map.Entry entry = (Map.Entry) it.next();
463:                        final String midlet = (String) entry.getKey();
464:                        final Long time = (Long) entry.getValue();
465:                        sb.append(midlet);
466:                        sb.append(FIELD_SEP);
467:                        sb.append(time);
468:                        sb.append('\n');
469:                    }
470:
471:                    return sb.toString();
472:                }
473:
474:                /**
475:                 * Converts a string into data.
476:                 *
477:                 * @param s string to convert
478:                 *
479:                 * @return data
480:                 */
481:                public Object stringToData(final String s) {
482:                    final HashMap data = new HashMap();
483:                    int pos = 0;
484:                    for (;;) {
485:                        final int p = s.indexOf('\n', pos);
486:                        if (p == -1) {
487:                            // assert pos == s.length() - 1 : "unprocessed chars!";
488:                            return data;
489:                        }
490:                        final String record = s.substring(pos, p);
491:
492:                        // Parse record
493:                        final int sepPos = record.indexOf(FIELD_SEP);
494:                        // assert sepPos != -1 : "wrong record";
495:                        final String midlet = record.substring(0, sepPos);
496:                        final String timeString = record.substring(sepPos + 1);
497:                        data.put(midlet, Long.valueOf(timeString));
498:
499:                        pos = p + 1;
500:                    }
501:                }
502:            }
503:        }
w_w_w__.___jav__a___2__s__.c_om__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.