Source Code Cross Referenced for StorageManagerFactory.java in  » Database-ORM » MMBase » org » mmbase » storage » 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 » Database ORM » MMBase » org.mmbase.storage 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:        package org.mmbase.storage;
011:
012:        import java.util.*;
013:        import org.xml.sax.InputSource;
014:        import javax.servlet.ServletContext;
015:
016:        import org.mmbase.storage.search.SearchQueryHandler;
017:        import org.mmbase.storage.util.*;
018:
019:        import org.mmbase.module.core.*;
020:        import org.mmbase.clustering.ChangeManager;
021:        import org.mmbase.core.CoreField;
022:
023:        import org.mmbase.util.ResourceLoader;
024:        import org.mmbase.util.transformers.CharTransformer;
025:        import org.mmbase.util.transformers.Transformers;
026:
027:        import org.mmbase.util.logging.Logger;
028:        import org.mmbase.util.logging.Logging;
029:
030:        /**
031:         * This class contains functionality for retrieving StorageManager instances, which give access to the storage device.
032:         * It also provides functionality for setting and retrieving configuration data.
033:         * This is an abstract class. You cannot instantiate it. Use the static {@link #newInstance()} or {@link #newInstance(MMBase)}
034:         * methods to obtain a factory class.
035:         *
036:         * @author Pierre van Rooden
037:         * @since MMBase-1.7
038:         * @version $Id: StorageManagerFactory.java,v 1.33 2008/02/22 12:28:19 michiel Exp $
039:         */
040:        public abstract class StorageManagerFactory<SM extends StorageManager> {
041:
042:            private static final Logger log = Logging
043:                    .getLoggerInstance(StorageManagerFactory.class);
044:
045:            /**
046:             * A reference to the MMBase module
047:             */
048:            protected MMBase mmbase;
049:            /**
050:             * The class used to instantiate storage managers.
051:             * The classname is retrieved from the storage configuration file
052:             */
053:            protected Class<SM> storageManagerClass;
054:
055:            /**
056:             * The map with configuration data
057:             */
058:            protected Map<String, Object> attributes;
059:
060:            /**
061:             * The list with type mappings
062:             */
063:            protected List<TypeMapping> typeMappings;
064:
065:            /**
066:             * The list with objects of which binary data should not be stored in database
067:             */
068:            protected List<String> storeBinaryAsFileObjects;
069:
070:            /**
071:             * The ChangeManager object, used to register/broadcast changes to a node or set of nodes.
072:             */
073:            protected ChangeManager changeManager;
074:
075:            /**
076:             * The map with disallowed fieldnames and (if given) alternates
077:             */
078:            protected final SortedMap<String, String> disallowedFields = new TreeMap<String, String>(
079:                    String.CASE_INSENSITIVE_ORDER);
080:
081:            /**
082:             * The query handler to use with this factory.
083:             * Note: the current handler makes use of the JDBC2NodeInterface and is not optimized for storage: using it means
084:             * you call getNodeManager() TWICE.
085:             * Have to look into how this should work together.
086:             */
087:            protected SearchQueryHandler queryHandler;
088:
089:            /**
090:             * The query handler classes.
091:             * Assign a value to this class if you want to set a default query handler.
092:             */
093:            protected List<Class<?>> queryHandlerClasses = new ArrayList<Class<?>>();
094:
095:            /**
096:             * @see #getSetSurrogator()
097:             */
098:            protected CharTransformer setSurrogator = null;
099:
100:            /**
101:             * @see #getGetSurrogator()
102:             */
103:            protected CharTransformer getSurrogator = null;
104:
105:            /**
106:             * The default storage factory class.
107:             * This classname is used if you doe not spevify the clasanme in the 'storagemanagerfactory' proeprty in mmabseroot.xml.
108:             */
109:            static private final Class DEFAULT_FACTORY_CLASS = org.mmbase.storage.implementation.database.DatabaseStorageManagerFactory.class;
110:
111:            /**
112:             * Obtain the StorageManagerFactory belonging to the indicated MMBase module.
113:             * @param mmbase The MMBase module for which to retrieve the storagefactory
114:             * @return The StorageManagerFactory
115:             * @throws StorageException if the StorageManagerFactory class cannot be located, accessed, or instantiated,
116:             *         or when something went wrong during configuration of the factory
117:             */
118:            static public StorageManagerFactory newInstance(MMBase mmbase)
119:                    throws StorageException {
120:                // get the class name for the factory to instantiate
121:                String factoryClassName = mmbase
122:                        .getInitParameter("storagemanagerfactory");
123:                // instantiate and initialize the class
124:                try {
125:                    Class factoryClass = DEFAULT_FACTORY_CLASS;
126:                    if (factoryClassName != null) {
127:                        factoryClass = Class.forName(factoryClassName);
128:                    }
129:                    StorageManagerFactory factory = (StorageManagerFactory) factoryClass
130:                            .newInstance();
131:                    factory.init(mmbase);
132:                    return factory;
133:                } catch (ClassNotFoundException cnfe) {
134:                    throw new StorageFactoryException(cnfe);
135:                } catch (IllegalAccessException iae) {
136:                    throw new StorageFactoryException(iae);
137:                } catch (InstantiationException ie) {
138:                    throw new StorageFactoryException(ie);
139:                }
140:            }
141:
142:            /**
143:             * Obtain the storage manager factory belonging to the default MMBase module.
144:             * @return The StoragemanagerFactory
145:             * @throws StorageException if the StorageManagerFactory class cannot be located, accessed, or instantiated,
146:             *         or when something went wrong during configuration of the factory
147:             */
148:            static public StorageManagerFactory newInstance()
149:                    throws StorageException {
150:                // determine the default mmbase module.
151:                return newInstance(MMBase.getMMBase());
152:            }
153:
154:            /**
155:             * Initialize the StorageManagerFactory.
156:             * This method should be called after instantiation of the factory class.
157:             * It is called automatically by {@link #newInstance()} and {@link #newInstance(MMBase)}.
158:             * @param mmbase the MMBase instance to which this factory belongs
159:             * @throws StorageError when something went wrong during configuration of the factory, or when the storage cannot be accessed
160:             */
161:            protected final void init(MMBase mmbase) throws StorageError {
162:                log.service("initializing Storage Manager factory "
163:                        + this .getClass().getName());
164:                this .mmbase = mmbase;
165:                attributes = Collections
166:                        .synchronizedMap(new HashMap<String, Object>()); // ConcurrentHashMap not possible because null-values are put (TODO)
167:                typeMappings = Collections
168:                        .synchronizedList(new ArrayList<TypeMapping>()); // CopyOnWriteArrayList not possible because Collections.sort is done (TODO)
169:                storeBinaryAsFileObjects = Collections
170:                        .synchronizedList(new ArrayList<String>());
171:                changeManager = new ChangeManager();
172:                try {
173:                    log.debug("loading Storage Manager factory "
174:                            + this .getClass().getName());
175:                    load();
176:                } catch (StorageException se) {
177:                    // pass exceptions as a StorageError to signal a serious (unrecoverable) error condition
178:                    log.fatal(se.getMessage() + Logging.stackTrace(se));
179:                    throw new StorageError(se);
180:                }
181:            }
182:
183:            /**
184:             * Return the MMBase module for which the factory was instantiated
185:             * @return the MMBase instance
186:             */
187:            public MMBase getMMBase() {
188:                return mmbase;
189:            }
190:
191:            /**
192:             * Instantiate a basic handler object using the specified class.
193:             * A basic handler can be any type of class and is dependent on the
194:             * factory implementation.
195:             * For instance, the database factory expects an
196:             * org.mmbase.storage.search.implentation.database.SQLHandler class.
197:             * @param handlerClass the class to instantuate teh object with
198:             * @return the new handler class
199:             */
200:            abstract protected Object instantiateBasicHandler(Class handlerClass);
201:
202:            /**
203:             * Instantiate a chained handler object using the specified class.
204:             * A chained handler can be any type of class and is dependent on the
205:             * factory implementation.
206:             * For instance, the database factory expects an
207:             * org.mmbase.storage.search.implentation.database.ChainedSQLHandler class.
208:             * @param handlerClass the class to instantuate teh object with
209:             * @param previousHandler a handler thatw a sinstantiated previously.
210:             *        this handler should be passed to the new handler class during or
211:             *        after constrcution, so the ne whandler can 'chain' any events it cannot
212:             *        handle to this class.
213:             * @return the new handler class
214:             */
215:            abstract protected Object instantiateChainedHandler(
216:                    Class handlerClass, Object previousHandler);
217:
218:            /**
219:             * Instantiate a SearchQueryHandler object using the specified object.
220:             * The specified parameter may be an actual SearchQueryHandler object, or it may be a utility class.
221:             * For instance, the database factory expects an org.mmbase.storage.search.implentation.database.SQLHandler object,
222:             * which is used as a parameter in the construction of the actual SearchQueryHandler class.
223:             * @param data the object to instantuate a SearchQueryHandler object with
224:             */
225:            abstract protected SearchQueryHandler instantiateQueryHandler(
226:                    Object data);
227:
228:            /**
229:             * Opens and reads the storage configuration document.
230:             * Override this method to add additional configuration code before or after the configuration document is read.
231:             * @throws StorageException if the storage could not be accessed or necessary configuration data is missing or invalid
232:             */
233:            protected void load() throws StorageException {
234:                StorageReader<SM> reader = getDocumentReader();
235:                if (reader == null) {
236:                    if (storageManagerClass == null
237:                            || queryHandlerClasses.size() == 0) {
238:                        throw new StorageConfigurationException(
239:                                "No storage reader specified, and no default values available.");
240:                    } else {
241:                        log
242:                                .warn("No storage reader specified, continue using default values.");
243:                        log.debug("Default storage manager : "
244:                                + storageManagerClass.getName());
245:                        log.debug("Default query handler : "
246:                                + queryHandlerClasses.get(0).getName());
247:                        return;
248:                    }
249:                }
250:
251:                // get the storage manager class
252:                Class<SM> configuredClass = reader.getStorageManagerClass();
253:                if (configuredClass != null) {
254:                    storageManagerClass = configuredClass;
255:                } else if (storageManagerClass == null) {
256:                    throw new StorageConfigurationException(
257:                            "No StorageManager class specified, and no default available.");
258:                }
259:
260:                // get attributes
261:                setAttributes(reader.getAttributes());
262:
263:                log
264:                        .service("get objects with binary data that should not be stored in database");
265:                storeBinaryAsFileObjects.addAll(reader
266:                        .getStoreBinaryAsFileObjects());
267:
268:                // get disallowed fields, and add these to the default list
269:                disallowedFields.putAll(reader.getDisallowedFields());
270:
271:                // add default replacements when DEFAULT_STORAGE_IDENTIFIER_PREFIX is given
272:                String prefix = (String) getAttribute(Attributes.DEFAULT_STORAGE_IDENTIFIER_PREFIX);
273:                if (prefix != null) {
274:                    for (Map.Entry<String, String> e : disallowedFields
275:                            .entrySet()) {
276:                        String name = e.getKey();
277:                        String replacement = e.getValue();
278:                        if (replacement == null) {
279:                            e.setValue(prefix + "_" + name);
280:                        }
281:                    }
282:                }
283:
284:                log.service("get type mappings");
285:                typeMappings.addAll(reader.getTypeMappings());
286:                Collections.sort(typeMappings);
287:
288:                // get the queryhandler class
289:                // has to be done last, as we have to passing the disallowedfields map (doh!)
290:                // need to move this to DatabaseStorageManagerFactory
291:                List<Class<?>> configuredClasses = reader
292:                        .getSearchQueryHandlerClasses();
293:                if (configuredClasses.size() != 0) {
294:                    queryHandlerClasses = configuredClasses;
295:                } else if (queryHandlerClasses.size() == 0) {
296:                    throw new StorageConfigurationException(
297:                            "No SearchQueryHandler class specified, and no default available.");
298:                }
299:                log.service("Found queryhandlers " + queryHandlerClasses);
300:                // instantiate handler(s)
301:                Object handler = null;
302:                for (Class handlerClass : reader.getSearchQueryHandlerClasses()) {
303:                    if (handler == null) {
304:                        handler = instantiateBasicHandler(handlerClass);
305:                    } else {
306:                        handler = instantiateChainedHandler(handlerClass,
307:                                handler);
308:                    }
309:                }
310:                // initialize query handler.
311:                queryHandler = instantiateQueryHandler(handler);
312:
313:                String surr = (String) getAttribute(Attributes.SET_SURROGATOR);
314:                if (surr != null && !surr.equals("")) {
315:                    setSurrogator = Transformers.getCharTransformer(surr, null,
316:                            "StorageManagerFactory#load", false);
317:                }
318:
319:                surr = (String) getAttribute(Attributes.GET_SURROGATOR);
320:                if (surr != null && !surr.equals("")) {
321:                    getSurrogator = Transformers.getCharTransformer(surr, null,
322:                            "StorageManagerFactory#load", false);
323:                }
324:            }
325:
326:            /**
327:             * Obtains a StorageManager from the factory.
328:             * The instance represents a temporary connection to the datasource -
329:             * do not store the result of this call as a static or long-term member of a class.
330:             * @return a StorageManager instance
331:             * @throws StorageException when the storagemanager cannot be created
332:             */
333:            public SM getStorageManager() throws StorageException {
334:                try {
335:                    SM storageManager = storageManagerClass.newInstance();
336:                    storageManager.init(this );
337:                    return storageManager;
338:                } catch (InstantiationException ie) {
339:                    throw new StorageException(ie);
340:                } catch (IllegalAccessException iae) {
341:                    throw new StorageException(iae);
342:                }
343:            }
344:
345:            // javadoc inherited
346:            /**
347:             * Obtains a SearchQueryHandler from the factory.
348:             * This provides ways to query for data using the SearchQuery interface.
349:             * Note that  cannot run the querys on a transaction (since SearchQuery does not support them).
350:             *
351:             * @return a SearchQueryHandler instance
352:             * @throws StorageException when the handler cannot be created
353:             */
354:            public SearchQueryHandler getSearchQueryHandler()
355:                    throws StorageException {
356:                if (queryHandler == null) {
357:                    throw new StorageException("Cannot obtain a query handler.");
358:                } else {
359:                    return queryHandler;
360:                }
361:            }
362:
363:            /**
364:             * Locates and opens the storage configuration document, if available.
365:             * The configuration document to open can be set in mmbasereoot (using the storage property).
366:             * The property should point to a resource which is to be present in the MMBase classpath.
367:             * Overriding factories may provide ways to auto-detect the location of a configuration file.
368:             * @throws StorageException if something went wrong while obtaining the document reader
369:             * @return a StorageReader instance, or null if no reader has been configured
370:             */
371:            public StorageReader<SM> getDocumentReader()
372:                    throws StorageException {
373:                // determine storage resource.
374:                String storagePath = mmbase.getInitParameter("storage");
375:                // use the parameter set in mmbaseroot if it is given
376:                if (storagePath != null) {
377:                    try {
378:                        InputSource resource = ResourceLoader
379:                                .getConfigurationRoot().getInputSource(
380:                                        storagePath);
381:                        if (resource == null) {
382:                            throw new StorageConfigurationException(
383:                                    "Storage resource '" + storagePath
384:                                            + "' not found.");
385:                        }
386:                        return new StorageReader<SM>(this , resource);
387:                    } catch (java.io.IOException ioe) {
388:                        throw new StorageConfigurationException(ioe);
389:                    }
390:                } else {
391:                    // otherwise return null
392:                    return null;
393:                }
394:            }
395:
396:            /**
397:             * Retrieve a map of attributes for this factory.
398:             * The attributes are the configuration parameters for the factory.
399:             * You cannot change this map, though you can change the attributes themselves.
400:             * @return an unmodifiable Map
401:             */
402:            public Map getAttributes() {
403:                return Collections.unmodifiableMap(attributes);
404:            }
405:
406:            /**
407:             * Add a map of attributes for this factory.
408:             * The attributes are the configuration parameters for the factory.
409:             * The actual content the factory expects is dependent on the implementation.
410:             * The attributes are added to any attributes already knwon to the factory.
411:             * @param attributes the map of attributes to add
412:             */
413:            public void setAttributes(Map<String, Object> attributes) {
414:                this .attributes.putAll(attributes);
415:                log.debug("Database attributes " + this .attributes);
416:            }
417:
418:            /**
419:             * Obtain an attribute from this factory.
420:             * Attributes are the configuration parameters for the storagefactory.
421:             * @param key the key of the attribute
422:             * @return the attribute value, or null if it is unknown
423:             */
424:            public Object getAttribute(String key) {
425:                return attributes.get(key);
426:            }
427:
428:            /**
429:             * Set an attribute of this factory.
430:             * Attributes are the configuration parameters for the factory.
431:             * The actual content the factory expects is dependent on the implementation.
432:             * To invalidate an attribute, you can pass the <code>null</code> value.
433:             * @param key the key of the attribute
434:             * @param value the value of the attribute
435:             */
436:            public void setAttribute(String key, Object value) {
437:                attributes.put(key, value);
438:            }
439:
440:            /**
441:             * Obtain a scheme from this factory.
442:             * Schemes are special attributes, consisting of patterned strings that can be
443:             * expanded with arguments.
444:             * @param key the key of the attribute
445:             * @return the scheme value, or null if it is unknown
446:             */
447:            public Scheme getScheme(String key) {
448:                return getScheme(key, null);
449:            }
450:
451:            /**
452:             * Obtain a scheme from this factory.
453:             * Schemes are special attributes, consisting of patterned strings that can be
454:             * expanded with arguments.
455:             * If no scheme is present, the default pattern is used to create a scheme and add it to the factory.
456:             * @param key the key of the attribute
457:             * @param defaultPattern the pattern to use for the default scheme, <code>null</code> if there is no default
458:             * @return the scheme value, <code>null</code> if there is no scheme
459:             */
460:            public Scheme getScheme(String key, String defaultPattern) {
461:                Scheme scheme = (Scheme) getAttribute(key);
462:                if (scheme == null && defaultPattern != null) {
463:                    if (attributes.containsKey(key))
464:                        return null;
465:                    scheme = new Scheme(this , defaultPattern);
466:                    setAttribute(key, scheme);
467:                }
468:                return scheme;
469:            }
470:
471:            /**
472:             * Set a scheme of this factory, using a string pattern to base the Scheme on.
473:             * Schemes are special attributes, consisting of patterned strings that can be
474:             * expanded with arguments.
475:             * @param key the key of the scheme
476:             * @param pattern the pattern to use for the scheme
477:             */
478:            public void setScheme(String key, String pattern) {
479:                if (pattern == null || pattern.equals("")) {
480:                    setAttribute(key, null);
481:                } else {
482:                    setAttribute(key, new Scheme(this , pattern));
483:                }
484:            }
485:
486:            /**
487:             * Check whether an option was set.
488:             * Options are attributes that return a boolean value.
489:             * @param key the key of the option
490:             * @return <code>true</code> if the option was set
491:             */
492:            public boolean hasOption(String key) {
493:                Object o = getAttribute(key);
494:                return (o instanceof  Boolean) && ((Boolean) o).booleanValue();
495:            }
496:
497:            /**
498:             * Set an option to true or false.
499:             * @param key the key of the option
500:             * @param value the value of the option (true or false)
501:             */
502:            public void setOption(String key, boolean value) {
503:                setAttribute(key, Boolean.valueOf(value));
504:            }
505:
506:            /**
507:             * Returns a sorted list of type mappings for this storage.
508:             * @return  the list of TypeMapping objects
509:             */
510:            public List<TypeMapping> getTypeMappings() {
511:                return Collections.unmodifiableList(typeMappings);
512:            }
513:
514:            /**
515:             * Returns a list of objects of which binary data should be stored in a file.
516:             * @return the list of objects of which BLOB fields should not be stored in database.
517:             * @since MMBase-1.8.5
518:             */
519:            public List<String> getStoreBinaryAsFileObjects() {
520:                return Collections.unmodifiableList(storeBinaryAsFileObjects);
521:            }
522:
523:            /**
524:             * Returns a map of disallowed field names and their possible alternate values.
525:             * @return  A Map of disallowed field names
526:             */
527:            public Map<String, String> getDisallowedFields() {
528:                return Collections.unmodifiableSortedMap(disallowedFields);
529:            }
530:
531:            /**
532:             * Sets the map of disallowed Fields.
533:             * Unlike setAttributes(), this actually replaces the existing disallowed fields map.
534:             */
535:            protected void setDisallowedFields(Map disallowedFields) {
536:                this .disallowedFields.clear();
537:                this .disallowedFields.putAll(disallowedFields);
538:            }
539:
540:            /**
541:             * Obtains the identifier for the basic storage element.
542:             * @return the storage-specific identifier
543:             * @throws StorageException if the object cannot be given a valid identifier
544:             */
545:            public Object getStorageIdentifier() throws StorageException {
546:                return getStorageIdentifier(mmbase);
547:            }
548:
549:            /**
550:             * Obtains a identifier for an MMBase object.
551:             * The default implementation returns the following type of identifiers:
552:             * <ul>
553:             *  <li>For StorageManager: the basename</li>
554:             *  <li>For MMBase: the String '[basename]_object</li>
555:             *  <li>For MMObjectBuilder: the String '[basename]_[builder name]'</li>
556:             *  <li>For Indices: the String '[basename]_[builder name]_[index name]_idx'</li>
557:             *  <li>For MMObjectNode: the object number as a Integer</li>
558:             *  <li>For CoreField or String: the field name, or the replacement fieldfname (from the disallowedfields map)</li>
559:             * </ul>
560:             * Note that 'basename' is a property from the mmbase module, set in mmbaseroot.xml.<br />
561:             * You can override this method if you intend to use different ids.
562:             *
563:             * @see Storable
564:             * @param mmobject the MMBase objecty
565:             * @return the storage-specific identifier
566:             * @throws StorageException if the object cannot be given a valid identifier
567:             */
568:            public Object getStorageIdentifier(Object mmobject)
569:                    throws StorageException {
570:                String id;
571:                if (mmobject instanceof  StorageManager) {
572:                    id = mmbase.getBaseName();
573:                } else if (mmobject == mmbase) {
574:                    id = mmbase.getBaseName() + "_object";
575:                } else if (mmobject instanceof  MMObjectBuilder) {
576:                    id = mmbase.getBaseName() + "_"
577:                            + ((MMObjectBuilder) mmobject).getTableName();
578:                } else if (mmobject instanceof  MMObjectNode) {
579:                    return ((MMObjectNode) mmobject).getIntegerValue("number");
580:                } else if (mmobject instanceof  Index) {
581:                    id = mmbase.getBaseName() + "_"
582:                            + ((Index) mmobject).getParent().getTableName()
583:                            + "_" + ((Index) mmobject).getName() + "_idx";
584:                } else if (mmobject instanceof  String
585:                        || mmobject instanceof  CoreField) {
586:                    if (mmobject instanceof  CoreField) {
587:                        id = ((CoreField) mmobject).getName();
588:                    } else {
589:                        id = (String) mmobject;
590:                    }
591:                    String key = id;
592:                    if (!hasOption(Attributes.DISALLOWED_FIELD_CASE_SENSITIVE)) {
593:                        key = key.toLowerCase();
594:                    }
595:                    if (disallowedFields.containsKey(key)) {
596:                        String newid = disallowedFields.get(key);
597:                        if (newid == null) {
598:                            if (hasOption(Attributes.ENFORCE_DISALLOWED_FIELDS)) {
599:                                throw new StorageException(
600:                                        "The name of the field '"
601:                                                + ((CoreField) mmobject)
602:                                                        .getName()
603:                                                + "' is disallowed, and no alternate value is available.");
604:                            }
605:                        } else {
606:                            id = newid;
607:                        }
608:                    }
609:                } else {
610:                    throw new StorageException(
611:                            "Cannot obtain identifier for param of type '"
612:                                    + mmobject.getClass().getName() + ".");
613:                }
614:
615:                String maxIdentifierLength = (String) getAttribute(Attributes.MAX_IDENTIFIER_LENGTH);
616:                if (maxIdentifierLength != null
617:                        && !"".equals(maxIdentifierLength)) {
618:                    try {
619:                        int maxlength = Integer.parseInt(maxIdentifierLength);
620:                        if (id.length() > maxlength) {
621:                            // Truncate the id, leave 8 characters space to put the hashcode
622:                            String base = id.substring(0, maxlength - 8);
623:                            long hashcode = id.hashCode();
624:                            if (hashcode < 0)
625:                                hashcode = Integer.MAX_VALUE + hashcode;
626:
627:                            // This generates a 8-character hex representation of the strings hashcode
628:                            id = base
629:                                    + (new java.math.BigInteger("" + hashcode))
630:                                            .toString(16);
631:                        }
632:                    } catch (NumberFormatException e) {
633:                        log
634:                                .warn("Exception parsing the 'max-identifier-length' parameter; ignoring it!");
635:                    }
636:                }
637:
638:                String toCase = (String) getAttribute(Attributes.STORAGE_IDENTIFIER_CASE);
639:                if ("lower".equals(toCase)) {
640:                    return id.toLowerCase();
641:                } else if ("upper".equals(toCase)) {
642:                    return id.toUpperCase();
643:                } else {
644:                    return id;
645:                }
646:            }
647:
648:            /**
649:             * Returns the ChangeManager utility instance, used to register and broadcast changes to nodes
650:             * in the storage layer.
651:             * This method is for use by the StorageManager
652:             */
653:            public ChangeManager getChangeManager() {
654:                return changeManager;
655:            }
656:
657:            /**
658:             * Returns the name of the catalog used by this storage (<code>null</code> if no catalog is used).
659:             */
660:            public String getCatalog() {
661:                return null;
662:            }
663:
664:            /**
665:             * Returns the version of this factory implementation.
666:             * The factory uses this number to verify whether it can handle storage configuration files
667:             * that list version requirements.
668:             * @return the version as an integer
669:             */
670:            abstract public double getVersion();
671:
672:            /**
673:             * Returns whether transactions, and specifically rollback, is supported in the storage layer.
674:             * @return  <code>true</code> if trasnactions are supported
675:             */
676:            abstract public boolean supportsTransactions();
677:
678:            /**
679:             * Returns a filter which can be used to filter strings taken from storage or <code>null</code> if none defined.
680:             * @since MMBase-1.7.4
681:             */
682:            public CharTransformer getGetSurrogator() {
683:                return getSurrogator;
684:            }
685:
686:            /**
687:             * Returns a filter which can be used to filter strings which are to be set into storage or <code>null</code> if none defined.
688:             * @since MMBase-1.7.4
689:             */
690:            public CharTransformer getSetSurrogator() {
691:                return setSurrogator;
692:            }
693:
694:            /**
695:             * Returns the offset which must be used in the database. Currently this is based on the system's
696:             * default time zone. It is imaginable that can have configuration or database specific details later.
697:             * @param time The time at which it is evaluated (summer time issues)
698:             * @since MMBase-1.8
699:             * @todo experimental
700:             */
701:            public int getTimeZoneOffset(long time) {
702:                return TimeZone.getDefault().getOffset(time);
703:            }
704:
705:            protected String getDataDir() {
706:                String dataDir = mmbase.getInitParameter("datadir");
707:                if (dataDir == null || dataDir.equals("")) {
708:                    ServletContext sc = MMBaseContext.getServletContext();
709:                    dataDir = sc != null ? sc.getRealPath("/WEB-INF/data")
710:                            : null;
711:                    if (dataDir == null) {
712:                        dataDir = System.getProperty("user.dir")
713:                                + java.io.File.separator + "data";
714:                    }
715:                }
716:                log.info("MMBase data dir: " + dataDir);
717:                return dataDir;
718:            }
719:
720:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.