KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > persistence > PersistenceAC


1 /*
2   Copyright (C) 2001-2004 Laurent Martelli <laurent@aopsys.com>
3                           Renaud Pawlak <renaud@aopsys.com>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as
7   published by the Free Software Foundation; either version 2 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

18
19 package org.objectweb.jac.aspects.persistence;
20
21 import gnu.regexp.RE;
22 import gnu.regexp.REException;
23 import java.util.Arrays JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Vector JavaDoc;
31 import org.apache.log4j.Logger;
32 import org.objectweb.jac.core.AspectComponent;
33 import org.objectweb.jac.core.BaseProgramListener;
34 import org.objectweb.jac.core.Collaboration;
35 import org.objectweb.jac.core.MethodPointcut;
36 import org.objectweb.jac.core.NameRepository;
37 import org.objectweb.jac.core.Naming;
38 import org.objectweb.jac.core.ObjectRepository;
39 import org.objectweb.jac.core.SerializedJacObject;
40 import org.objectweb.jac.core.Wrappee;
41 import org.objectweb.jac.core.Wrapper;
42 import org.objectweb.jac.core.Wrapping;
43 import org.objectweb.jac.core.rtti.ClassItem;
44 import org.objectweb.jac.core.rtti.CollectionItem;
45 import org.objectweb.jac.core.rtti.FieldItem;
46 import org.objectweb.jac.util.ExtArrays;
47
48 /**
49  * This AC defines a generic and configurable persistence aspect.<p>
50  */

51
52 public class PersistenceAC extends AspectComponent implements PersistenceConf {
53
54     static Logger logger = Logger.getLogger("persistence");
55     static Logger loggerCache = Logger.getLogger("persistence.cache");
56     static Logger loggerNaming = Logger.getLogger("persistence.naming");
57
58     /** The global identifier for a persistence root class in the
59         RTTI. */

60     public static final String JavaDoc ROOT = "root";
61
62     /** The global identifier for a persistent class in the RTTI. */
63     public static final String JavaDoc PERSISTENT = "persistent";
64
65     public static final String JavaDoc VALUE_CONVERTER = "valueConverter";
66     public static final String JavaDoc PRELOAD_FIELD = "preloadField";
67
68     public static final String JavaDoc DISABLE_PRELOAD = "PersistenceAC.DISABLE_PRELOAD";
69     public static final String JavaDoc NO_CACHE = "PersistenceAC.NO_CACHE";
70     public static final String JavaDoc RESTORE = "PersistenceAC.RESTORE";
71
72     // Object -> OID
73
Hashtable JavaDoc oids = new Hashtable JavaDoc();
74     // OID -> Object
75
Hashtable JavaDoc objects = new Hashtable JavaDoc();
76
77     private boolean connected = false;
78
79     /**
80      * The default storage. */

81     protected StorageSpec defaultStorage = null;
82     /** List of StorageSpec */
83     protected Vector JavaDoc storages = new Vector JavaDoc();
84     class StorageSpec {
85         StorageSpec(String JavaDoc id,
86                     ClassItem storageClass, String JavaDoc[] parameters)
87         {
88             this.id = id;
89             this.storageClass = storageClass;
90             this.parameters = parameters;
91         }
92         public void addClasses(String JavaDoc classExpr) throws REException {
93             classExprs = (RE[])
94                 ExtArrays.add(
95                     MethodPointcut.buildRegexp(classExpr),
96                     classExprs);
97         }
98         private RE[] classExprs = new RE[0];
99         private Storage storage;
100         private String JavaDoc[] parameters;
101         private ClassItem storageClass;
102         private String JavaDoc id;
103         synchronized Storage getStorage() {
104             if (storage == null) {
105                 if (storageClass == null) {
106                     throw new RuntimeException JavaDoc("Persistence: storage is not configured");
107                 }
108                 logger.debug(
109                     getClass().getName() + ".connectStorage("
110                     + storageClass + ","
111                     + (parameters != null
112                        ? Arrays.asList(parameters).toString()
113                        : "null")
114                     + ")");
115                 try {
116                     storage =
117                         (Storage)storageClass.newInstance(
118                             ExtArrays.add(0,PersistenceAC.this,parameters,Object JavaDoc.class));
119                 } catch (Exception JavaDoc e) {
120                     logger.error("Failed to connect to storage ", e);
121                 }
122             }
123             return storage;
124         }
125         /**
126          * Tells wether instances of class should be stored on this storage.
127          */

128         boolean match(ClassItem cli) {
129             if (classExprs==null)
130                 return false;
131             String JavaDoc className = cli.getName();
132             for (int i=0; i<classExprs.length; i++) {
133                 if (classExprs[i].isMatch(className))
134                     return true;
135             }
136             return false;
137         }
138         String JavaDoc getId() {
139             return id;
140         }
141     }
142
143     /**
144      * Gets the storage with a given id, or null.
145      * @param id id of the storage to get. If null, returns the defaultStorage.
146      */

147     protected Storage getStorage(String JavaDoc id) {
148         if (id==null) {
149             return defaultStorage.getStorage();
150         } else {
151             Iterator JavaDoc it = storages.iterator();
152             while (it.hasNext()) {
153                 StorageSpec storageSpec = (StorageSpec)it.next();
154                 if (id.equals(storageSpec.getId()))
155                     return storageSpec.getStorage();
156             }
157             logger.error("No such storage: "+id);
158             return null;
159         }
160     }
161
162     protected Storage[] getStorages() {
163         Storage[] result =
164             new Storage[storages.size()+ (defaultStorage!=null ? 1 : 0)];
165         Iterator JavaDoc it = storages.iterator();
166         int i=0;
167         while (it.hasNext()) {
168             StorageSpec storageSpec = (StorageSpec)it.next();
169             result[i] = storageSpec.getStorage();
170             i++;
171         }
172         if (defaultStorage!=null)
173             result[i] = defaultStorage.getStorage();
174         return result;
175     }
176
177     /**
178      * The loaded objects from the storage. */

179     // protected Hashtable objects = new Hashtable();
180

181     /**
182      * Close every storage
183      */

184     public void onExit() {
185         Storage[] storages = getStorages();
186         for (int i=0; i<storages.length; i++){
187             storages[i].close();
188         }
189     }
190
191     //private HashSet statics = new HashSet();
192

193     // ---- PersistenceConf interface
194

195     public void setValueConverter(ClassItem cl, ClassItem converterClass) {
196         StringConverter converter;
197         try {
198             converter = (StringConverter)converterClass.newInstance();
199         } catch (ClassCastException JavaDoc e) {
200             error("Converter class "+converterClass.getName()+
201                   " does not implement StringConverter");
202             return;
203         } catch (Exception JavaDoc e) {
204             error("Failed to instantiate value converter "+converterClass.getName());
205             return;
206         }
207         cl.setAttribute(VALUE_CONVERTER, converter);
208     }
209
210     /**
211      * This method is a callback for the timer that defines the max
212      * idle time.
213      *
214      * <p>For all the collections that have a max idle time, it checks
215      * that this time is not reached. If it is reached, it unloads the
216      * collection.
217      *
218      * @see #defineMaxIdleCheckPeriod(long)
219      * @see #maxIdle(CollectionItem,long) */

220
221     public void checkUnload() {
222
223         Iterator JavaDoc it = collectionIdles.entrySet().iterator();
224         while (it.hasNext()) {
225             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
226
227             CollectionItem coll = (CollectionItem) entry.getKey();
228             long idle = ((Long JavaDoc) entry.getValue()).longValue();
229
230             loggerCache.debug("checking collection " + coll + " (idle=" + idle + ")");
231             ClassItem cl = coll.getClassItem();
232             Object JavaDoc[] objects = ObjectRepository.getMemoryObjects(cl);
233             for (int i = 0; i < objects.length; i++) {
234                 Wrappee wrappee = (Wrappee) coll.get(objects[i]);
235                 loggerCache.debug("checking wrappee "
236                           + NameRepository.get().getName(objects[i])
237                           + "." + wrappee);
238                 Date JavaDoc useDate =
239                     (Date JavaDoc) Wrapping.invokeRoleMethod(
240                         wrappee,
241                         CollectionWrapper.class,
242                         "getUseDate",
243                         ExtArrays.emptyObjectArray);
244                 Date JavaDoc now = new Date JavaDoc();
245                 long lastUsed = now.getTime() - useDate.getTime();
246                 loggerCache.debug("last used=" + lastUsed + " ms ago");
247                 if (lastUsed > idle) {
248                     loggerCache.debug("unloading collection "
249                               + NameRepository.get().getName(objects[i])
250                               + "." + coll);
251                     Wrapping.invokeRoleMethod(
252                         wrappee,
253                         CollectionWrapper.class,
254                         "unload",
255                         ExtArrays.emptyObjectArray);
256                 }
257             }
258         }
259     }
260
261     long checkPeriod = -1;
262
263     public void defineMaxIdleCheckPeriod(long period) {
264         checkPeriod = period;
265     }
266
267     HashMap JavaDoc collectionIdles = new HashMap JavaDoc();
268
269     public void maxIdle(CollectionItem collection, long maxIdle) {
270         collectionIdles.put(collection, new Long JavaDoc(maxIdle));
271     }
272
273     public void whenConfigured() {
274         if (checkPeriod == -1) {
275             checkPeriod = 200000;
276         }
277         defineTimer(
278             checkPeriod,
279             cr.getClass(PersistenceAC.class).getMethod(
280                 "checkUnload"),
281             new Object JavaDoc[] {
282             });
283     }
284
285     public void configureStorage(ClassItem storageClass,
286                                  String JavaDoc[] storageParameters)
287     {
288         try {
289             this.defaultStorage =
290                 new StorageSpec(null,storageClass,storageParameters);
291             this.defaultStorage.addClasses("ALL");
292         } catch (REException e) {
293             error(e.toString());
294         }
295     }
296
297     public void configureStorage(String JavaDoc id,
298                                  ClassItem storageClass,
299                                  String JavaDoc[] storageParameters)
300     {
301         storages.add(
302             new StorageSpec(id,storageClass,storageParameters));
303     }
304
305     public void setStorage(String JavaDoc classExpr, String JavaDoc storageId) {
306         try {
307             getStorageSpec(storageId).addClasses(classExpr);
308         } catch (REException e) {
309             error(e.toString());
310         }
311     }
312
313     /** MethodPointcuts for static objects */
314     Vector JavaDoc staticPointcuts = new Vector JavaDoc();
315
316     public void registerStatics(String JavaDoc classExpr, String JavaDoc nameExpr) {
317         /* Wrap constructors with PersistenceWrapper.handleStatic() */
318         logger.debug("registerStatics " + classExpr + " " + nameExpr);
319         staticPointcuts.add(
320             pointcut(
321                 nameExpr,
322                 classExpr,
323                 "CONSTRUCTORS",
324                 PersistenceWrapper.class.getName(),
325                 null,
326                 SHARED));
327     }
328
329     /** Pointcuts for persistent objects */
330     Vector JavaDoc persistentPointcuts = new Vector JavaDoc();
331
332     public void makePersistent(String JavaDoc classExpr, String JavaDoc nameExpr) {
333         // Wrap modifiers, collection accessors, reference accessors
334
// (but not constructors) with PersistenceWrapper.applyPersistence()
335
persistentPointcuts.add(
336             pointcut(
337                 nameExpr,
338                 classExpr,
339                 "MODIFIERS({!transient}) || COLACCESSORS({!transient}) || REFACCESSORS({!transient}) && !CONSTRUCTORS",
340                 PersistenceWrapper.class.getName(),
341                 null,
342                 NOT_SHARED));
343     }
344
345     /**
346      * Tells wether a wrappee is persistent or not.
347      * @param wrappee the wrappee
348      * @see #makePersistent(String,String)
349      */

350     boolean isPersistent(Wrappee wrappee) {
351         Iterator JavaDoc it = persistentPointcuts.iterator();
352         ClassItem cli = cr.getClass(wrappee);
353         while (it.hasNext()) {
354             MethodPointcut pointcut = (MethodPointcut) it.next();
355             if (pointcut.isClassMatching(wrappee, cli))
356                 return true;
357         }
358         return false;
359     }
360
361     /**
362      * Tells wether a wrappee is static or not.
363      * @param wrappee the wrapee
364      * @param objName name of the wrappee
365      * @see #makePersistent(String,String)
366      */

367     boolean isStatic(Wrappee wrappee, String JavaDoc objName) {
368         ClassItem cli = cr.getClass(wrappee);
369         // check the statics
370
Iterator JavaDoc it = staticPointcuts.iterator();
371         while (it.hasNext()) {
372             MethodPointcut pointcut = (MethodPointcut) it.next();
373             if (pointcut.isClassMatching(wrappee, cli)
374                 && pointcut.isNameMatching(wrappee, objName))
375                 return true;
376         }
377         return false;
378     }
379
380     // ---- end of PersistenceConf
381

382     /**
383      * Returns the storage for a given class
384      *
385      * @param cli a class
386      * @return the storage of the class
387      */

388     public Storage getStorage(ClassItem cli) {
389         Iterator JavaDoc it = storages.iterator();
390         while (it.hasNext()) {
391             StorageSpec storageSpec = (StorageSpec)it.next();
392             if (storageSpec.match(cli)) {
393                 return storageSpec.getStorage();
394             }
395         }
396         if (defaultStorage!=null)
397             return defaultStorage.getStorage();
398         throw new RuntimeException JavaDoc(
399             "Cannot find storage for class "+cli.getName());
400     }
401
402     public StorageSpec getStorageSpec(String JavaDoc storageId) {
403         Iterator JavaDoc it = storages.iterator();
404         while (it.hasNext()) {
405             StorageSpec storageSpec = (StorageSpec)it.next();
406             if (storageSpec.getId().equals(storageId)) {
407                 return storageSpec;
408             }
409         }
410         throw new RuntimeException JavaDoc();
411     }
412
413     /**
414      * Returns the storage for a given object
415      *
416      * @param obj object to get the storage for
417      * @return the storage of the class
418      */

419     public Storage getStorage(Object JavaDoc obj) {
420         return getStorage(cr.getClass(obj));
421     }
422
423     /**
424      * The persistence aspect checks whether an object was in the
425      * storage when a <code>NameRepository.getObject</code> call
426      * failed.
427      * @see BaseProgramListener#whenObjectMiss(String)
428      */

429     public void whenObjectMiss(String JavaDoc name) {
430         loggerNaming.debug("whenObjectMiss " + name);
431         // Loop through all the storages
432
Storage[] storages = getStorages();
433         for (int i=0; i<storages.length; i++){
434             try {
435                 OID oid = storages[i].getOIDFromName(name);
436                 if (oid != null) {
437                     loggerNaming.debug("found name " + name + " -> " + oid);
438                     attrdef(BaseProgramListener.FOUND_OBJECT, getObject(oid, null));
439                     return;
440                 }
441             } catch (Exception JavaDoc e) {
442                 logger.error("whenObjectMiss "+name,e);
443             }
444         }
445     }
446
447     /**
448      * Delegates naming to the storage
449      */

450     public String JavaDoc whenNameObject(Object JavaDoc object, String JavaDoc name) {
451         loggerNaming.debug("whenNameObject " + object + " <- " + name);
452         if (!(object instanceof Wrappee))
453             return name;
454         Wrappee wrappee = (Wrappee) object;
455         if (isPersistent(wrappee) && !isStatic(wrappee, name)) {
456             try {
457                 name = getStorage(object).newName(object.getClass().getName());
458             } catch (Exception JavaDoc e) {
459                 logger.error("Failed to name object "+object,e);
460             }
461             loggerNaming.debug(" -> " + name);
462         }
463         return name;
464     }
465
466     public void getNameCounters(Map JavaDoc counters) {
467         try {
468             Storage[] storages = getStorages();
469             for(int i=0; i<storages.length; i++) {
470                 counters.putAll(storages[i].getNameCounters());
471             }
472         } catch (Exception JavaDoc e) {
473             logger.error("getNameCounters failed",e);
474         }
475     }
476
477     public synchronized void updateNameCounters(Map JavaDoc counters) {
478         try {
479             Storage[] storages = getStorages();
480             for(int i=0; i<storages.length; i++) {
481                 storages[i].updateNameCounters(counters);
482             }
483         } catch (Exception JavaDoc e) {
484             logger.error("updateNameCounters failed",e);
485         }
486     }
487
488     /**
489      * Add an object in the list of persistent objects.
490      *
491      * @param oid the OID of the object
492      * @param object the object
493      */

494     protected void registerObject(OID oid, Object JavaDoc object) {
495         logger.debug("registerObject(" + oid + "," + object.getClass() + ")");
496         Object JavaDoc currentObject = objects.get(oid);
497         if (currentObject!=null) {
498             if (currentObject!=object) {
499                 logger.error("registerObject "+oid+","+object,new Exception JavaDoc());
500                 throw new Error JavaDoc(
501                     "PersistenceAC.registerObject("+oid+","+object+"): an object "+
502                     currentObject+" is already registered with this oid");
503             } else {
504                 logger.warn("PersistenceAC.registerObject("+oid+","+object+
505                             "): already registered");
506             }
507         }
508         objects.put(oid, object);
509         oids.put(object, oid);
510         logger.debug("object " + oid + " added");
511     }
512
513     /**
514      * Returns a reference to an object with a given OID.
515      *
516      * <p>Loads the object from a storage if necessary, or returns a
517      * cached object.</p>
518      *
519      * @param oid OID of the object
520      * @param newObject use this object instead of instanciating a new one
521      */

522     synchronized Object JavaDoc getObject(OID oid, Object JavaDoc newObject) {
523         Object JavaDoc result = objects.get(oid);
524         try {
525             if (result != null) {
526                 logger.debug("Object " + oid + " found in cache -> " + result);
527                 return result;
528             } else {
529                 logger.debug(this + ".Object " + oid
530                           + " NOT found in cache; Loading from storage\n");
531                 Storage storage = oid.getStorage();
532                 String JavaDoc lClassID = storage.getClassID(oid);
533                 if (lClassID == null)
534                     logger.error("getClassID(" + oid + ") -> NULL");
535                 ClassItem lClass = cr.getClass(lClassID);
536                 logger.debug("Class = " + lClass.getName());
537                 if (newObject == null) {
538                     Naming.setName(storage.getNameFromOID(oid));
539                     Collaboration collab = Collaboration.get();
540                     collab.addAttribute(RESTORE, Boolean.TRUE);
541                     try {
542                         newObject = lClass.newInstance();
543                     } finally {
544                         collab.removeAttribute(RESTORE);
545                     }
546                 }
547                 Wrappee wrappee = (Wrappee) newObject;
548                 //PersistenceWrapper wrapper = wrap(wrappee,oid);
549
registerObject(oid, wrappee);
550                 // load the new object's fields
551
Wrapping
552                     .invokeRoleMethod(
553                         wrappee,
554                         PersistenceWrapper.class,
555                         "loadAllFields",
556                         new Object JavaDoc[] {oid});
557                 // wrap its collections
558
Wrapping.invokeRoleMethod(
559                     wrappee,
560                     PersistenceWrapper.class,
561                     "wrapCollections",
562                     new Object JavaDoc[] { oid, Boolean.FALSE });
563                 logger.debug("New object " + oid + " : " + newObject);
564                 logger.debug("Object loaded");
565                 result = newObject;
566             }
567         } catch (Exception JavaDoc e) {
568             logger.error("getObject "+oid,e);
569         }
570         return result;
571     }
572
573     public OID getOID(Wrappee wrappee) {
574         return (OID) oids.get(wrappee);
575     }
576
577     /**
578      * This method allows the deserialization of the OID of a
579      * persistent object.<p>
580      *
581      * @param orgObject the JAC object structure that is beeing
582      * deserialized
583      * @see #whenSerialized(SerializedJacObject) */

584
585     public void whenDeserialized(SerializedJacObject orgObject) {
586         /*
587         OID oid = (OID) orgObject.getACInfos( "persistence" );
588         if ( oid != null ) {
589                 Wrappee finalObject = (Wrappee)attr("finalObject");
590                 PersistenceWrapper pw = wrap( finalObject, oid, false );
591                 //pw.setOid( oid );
592         }
593         */

594     }
595
596     /**
597      * This method add the OID info to the serialized JAC object when a
598      * serialization is requested by another aspect.<p>
599      *
600      * This adding allows, for instance, the OID to be transmitted to
601      * remote containers.<p>
602      *
603      * @param finalObject the object that is being serialized */

604
605     public void whenSerialized(SerializedJacObject finalObject) {
606         /*
607             Wrappee orgObject = (Wrappee)attr("orgObject");
608             if ( orgObject.isExtendedBy( PersistenceWrapper.class ) ) {
609             finalObject.setACInfos(
610             "persistence", orgObject.invokeRoleMethod( "getOid", ExtArrays.emptyObjectArray ) );
611             }
612         */

613     }
614
615     /**
616      * Load objects from the storage when required.
617      */

618     public void whenGetObjects(Collection JavaDoc objects, ClassItem cl) {
619         logger.debug("PersistenceAC.whenGetObjects " + cl);
620         if (cl == null)
621             return;
622         try {
623             logger.debug("PersistenceAC.whenGetObjects " + cl);
624             Collection JavaDoc oids = getStorage(cl).getObjects(cl);
625             Iterator JavaDoc i = oids.iterator();
626             while (i.hasNext()) {
627                 OID oid = (OID) i.next();
628                 Object JavaDoc object = getObject(oid, null);
629                 if (!objects.contains(object))
630                     objects.add(object);
631             }
632         } catch (Exception JavaDoc e) {
633             e.printStackTrace();
634         }
635     }
636
637     public boolean beforeRunningWrapper(
638         Wrapper wrapper,
639         String JavaDoc wrappingMethod) {
640         if (attr("Persistence.disabled") != null) {
641             return false;
642         } else {
643             return true;
644         }
645     }
646
647     public void whenDeleted(Wrappee object) {
648         try {
649             OID oid = getOID(object);
650             Storage storage = oid.getStorage();
651             if (storage != null) {
652                 if (oid != null)
653                     storage.deleteObject(oid);
654                 whenFree(object);
655             }
656         } catch (Exception JavaDoc e) {
657             logger.error("whenDeleted "+object+" failed",e);
658         }
659     }
660
661     public void whenFree(Wrappee object) {
662         try {
663             OID oid = getOID(object);
664             Storage storage = oid.getStorage();
665             if (storage != null) {
666                 if (oid != null)
667                     oids.remove(oid);
668                 if (objects.contains(object))
669                     objects.remove(object);
670             }
671         } catch (Exception JavaDoc e) {
672             logger.error("whenFree "+object+" failed",e);
673         }
674     }
675
676     public void preloadField(FieldItem field) {
677         field.setAttribute(PRELOAD_FIELD, Boolean.TRUE);
678     }
679
680     public void preloadAllFields(ClassItem cl) {
681         FieldItem[] fields = cl.getFields();
682         if (fields != null) {
683             for (int i = 0; i < fields.length; i++) {
684                 fields[i].setAttribute(PRELOAD_FIELD, Boolean.TRUE);
685             }
686         }
687     }
688
689     public static boolean isFieldPreloaded(FieldItem field) {
690         Boolean JavaDoc value = (Boolean JavaDoc) field.getAttribute(PRELOAD_FIELD);
691         return value != null && value.booleanValue();
692     }
693
694     public void disableCache(CollectionItem collection) {
695         collection.setAttribute(NO_CACHE, "true");
696     }
697
698     public String JavaDoc[] getDefaultConfigs() {
699         return new String JavaDoc[] {
700             "org/objectweb/jac/aspects/persistence/persistence.acc",
701             "org/objectweb/jac/aspects/user/persistence.acc" };
702     }
703
704     public static class NoSuchWrapperException extends RuntimeException JavaDoc {
705     }
706
707     /**
708      * Converts a String into a LongOID.
709      * @param str the string representing the OID. If it's like
710      * "<number>@<string>", the "<string>" must be a storage
711      * id. Otherwise, the defaultStorage is used
712      * @param defaultStorage storage to use to build the OID if the
713      * string does not contain an OID part.
714      */

715     public LongOID parseLongOID(String JavaDoc str, Storage defaultStorage) {
716         int index = str.indexOf('@');
717         if (index==-1) {
718             return
719                 new LongOID(defaultStorage,Long.parseLong(str));
720         } else {
721             return
722                 new LongOID(
723                     getStorage(str.substring(index+1)),
724                     Long.parseLong(str.substring(0,index)));
725         }
726     }
727 }
728
Popular Tags