Source Code Cross Referenced for AbstractConfigurationProxy.java in  » Inversion-of-Control » carbon » org » sape » carbon » core » config » format » 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 » Inversion of Control » carbon » org.sape.carbon.core.config.format 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * The contents of this file are subject to the Sapient Public License
003:         * Version 1.0 (the "License"); you may not use this file except in compliance
004:         * with the License. You may obtain a copy of the License at
005:         * http://carbon.sf.net/License.html.
006:         *
007:         * Software distributed under the License is distributed on an "AS IS" basis,
008:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009:         * the specific language governing rights and limitations under the License.
010:         *
011:         * The Original Code is The Carbon Component Framework.
012:         *
013:         * The Initial Developer of the Original Code is Sapient Corporation
014:         *
015:         * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016:         */
017:
018:        package org.sape.carbon.core.config.format;
019:
020:        import java.beans.BeanInfo;
021:        import java.beans.IntrospectionException;
022:        import java.beans.Introspector;
023:        import java.beans.PropertyDescriptor;
024:        import java.io.Serializable;
025:        import java.lang.reflect.Array;
026:        import java.lang.reflect.Field;
027:        import java.lang.reflect.InvocationTargetException;
028:        import java.lang.reflect.Method;
029:        import java.util.Map;
030:
031:        import org.jdom.Document;
032:        import org.jdom.Element;
033:
034:        import org.apache.commons.logging.Log;
035:        import org.apache.commons.logging.LogFactory;
036:
037:        import org.sape.carbon.core.config.Configuration;
038:        import org.sape.carbon.core.config.InvalidConfigurationException;
039:        import org.sape.carbon.core.exception.InvalidParameterException;
040:        import org.sape.carbon.core.util.reflection.GenericProxy;
041:        import org.sape.carbon.core.util.string.StringUtil;
042:
043:        /**
044:         * <p>This abstract class includes basic support for configuration objects
045:         * in XML. This class implements the Dynamic Proxy
046:         * <class>InvocationHandler</class> interface. By utilizing Dynamic Proxies this
047:         * class can implement any subclass of
048:         * {@link org.sape.carbon.core.config.Configuration} and automatically support
049:         * reading and writing the data of that object to XML.
050:         * </p>
051:         *
052:         * <P>This abstract class implements the basic functionality for managing a
053:         * JDOM {@link org.jdom.Document}. It also provides abstract method declarations
054:         * that allow a subclass to choose exactly the format for that XML and how it
055:         * is treated by a Configuration object.
056:         * </P>
057:         *
058:         * Copyright 2002 Sapient
059:         * @since carbon 1.0
060:         * @author Greg Hinkle, January 2002
061:         * @version $Revision: 1.58 $($Author: dvoet $ / $Date: 2003/11/26 20:30:18 $)
062:         */
063:        public abstract class AbstractConfigurationProxy extends GenericProxy
064:                implements  Configuration, Serializable {
065:
066:            /**
067:             * Provides a handle to Apache-commons logger
068:             */
069:            private Log log = LogFactory.getLog(this .getClass());
070:
071:            /** Prefix for config values that reference other configs. */
072:            protected static final String REF_PREFIX = "ref://";
073:
074:            /** Holds the length of reference prefix. */
075:            protected static final int REF_PREFIX_LENGTH = REF_PREFIX.length();
076:
077:            /**
078:             * JDOM Document object that holds the xml version of this configuration
079:             * object's data.
080:             */
081:            protected Document document;
082:
083:            /**
084:             * The root element of this configuration object. May represent the root
085:             * node of the document or it may be a sub-element for included object
086:             * types.
087:             */
088:            protected Element element;
089:
090:            /**
091:             * The Class of object that this configuration object is implementing.
092:             */
093:            protected Class documentType;
094:
095:            /**
096:             * The fully qualified configuration name for this configuration object
097:             */
098:            protected String name;
099:
100:            /** The root XML tag for configuration documnts */
101:            private static final String ROOT_TAG = "Configuration";
102:
103:            /**
104:             * True if this object may be altered, false if it should throw exceptions
105:             * when attempts are made to alter it.
106:             */
107:            private boolean writable = true;
108:
109:            /**
110:             * Constructs an AbstractConfigurationProxy for the supplied document.
111:             *
112:             * @param document The JDOM document object representing the XML for this
113:             *   configuration object
114:             * @param root The root element of this configuration object, not
115:             *   necessarily the root of the document
116:             * @param documentType the Class of object represented by the DynamicProxy
117:             *   form of this object
118:             */
119:            protected AbstractConfigurationProxy(Document document,
120:                    Element root, Class documentType) {
121:
122:                this .document = document;
123:                this .element = root;
124:                this .documentType = documentType;
125:
126:                this .element.setAttribute("ConfigurationInterface",
127:                        this .documentType.getName());
128:            }
129:
130:            /**
131:             * Constructs an AbstractConfigurationProxy for the supplied document.
132:             *
133:             * @param documentType the Class of object represented by the DynamicProxy
134:             *   form of this object
135:             */
136:            protected AbstractConfigurationProxy(Class documentType) {
137:
138:                this .element = new Element(ROOT_TAG);
139:
140:                this .documentType = documentType;
141:
142:                this .element.setAttribute("ConfigurationInterface",
143:                        this .documentType.getName());
144:
145:                this .document = new Document(this .element);
146:            }
147:
148:            /**
149:             * Retrieves this configuration object's name
150:             *
151:             * @return the fully qualified path name for this configuration object in
152:             *  the configuration service; <code>null</code> if this configuration
153:             *  object has not yet been stored in the configuration service
154:             */
155:            public String getConfigurationName() {
156:                return this .name;
157:            }
158:
159:            /**
160:             * Sets the name of this configuration object
161:             *
162:             * @param name the fully qualified name of this configuration in the
163:             *   configuration service
164:             */
165:            public void setConfigurationName(String name) {
166:                this .name = name;
167:            }
168:
169:            /**
170:             * Retrieves the primary type of this configuration
171:             * @return the type of this configuration object. This is the primary
172:             *  class type of the DynamicProxy that was built to support the storage
173:             *  and retrieval of configurations for that interface
174:             */
175:            public Class getDocumentType() {
176:                return this .documentType;
177:            }
178:
179:            /**
180:             * <P>This method provides the basic implementation of invocations
181:             * from the standpoint of DynamicProxies. The base proxy class,
182:             * <code>GenericProxy</code> provides a default implemenetation
183:             * of an InvocationHandler and basic handling for the standad
184:             * <code>Object</code> methods. Other methods are passed to this
185:             * method for invocation.</P>
186:             *
187:             * <P>This <code>AbstractConfigurationProxy</code> will handle basic
188:             * bean based calls into an object graph and utilize method name
189:             * and JavaBean based naming standards to determine the proper data
190:             * item to query.</P>
191:             *
192:             * <P>Sublcasses of <code>AbstractConfigurationProxy</code> will be able
193:             * to provide specific implementations of these methods based on what
194:             * the underlying datastore type is.</P>
195:             *
196:             * @param proxy the proxy object on which the method was called
197:             * @param m the method which was called to be executed
198:             * @param args the array of arguments to the specified method call
199:             * @throws Throwable when an invoke fails with any exception -
200:             *  this is cast by standard dynamic proxy functionality into an
201:             *  appropriate exception for the type of method that was actually called.
202:             * @return the object value returned from the real delegated method call
203:             */
204:            protected Object handleInvoke(Object proxy, Method m, Object[] args)
205:                    throws Throwable {
206:                String methodName = m.getName();
207:                Object returnObject = null;
208:
209:                if (m.getDeclaringClass() == Configuration.class) {
210:                    // all methods defined by the Configuration interface are handled
211:                    // by this class
212:                    try {
213:                        returnObject = m.invoke(this , args);
214:                    } catch (InvocationTargetException ite) {
215:                        // unwrap exception and throw it
216:                        throw ite.getTargetException();
217:                    }
218:
219:                } else if (methodName.startsWith("get")) {
220:                    String attrName = m.getName().substring(3);
221:                    Class returnType = m.getReturnType();
222:
223:                    if (returnType.isArray()) {
224:                        returnObject = getArray(attrName, m.getReturnType()
225:                                .getComponentType());
226:
227:                    } else if (returnType.equals(Map.class)) {
228:
229:                        returnObject = getMap(attrName,
230:                                getCollectionComponentType(attrName));
231:                    } else {
232:
233:                        if ((args == null) || (args.length == 0)) {
234:                            // Simple get retrieval
235:                            returnObject = lookupAttribute(attrName, m
236:                                    .getReturnType());
237:
238:                        } else if (args.length == 1) {
239:                            // Could be an array or a map lookup
240:                            if (isMapAttribute(attrName)) {
241:                                returnObject = getMap(attrName,
242:                                        getCollectionComponentType(attrName))
243:                                        .get(args[0]);
244:
245:                            } else {
246:                                // Array retrieval
247:                                returnObject = getArrayValue(attrName, m
248:                                        .getReturnType(), ((Integer) args[0])
249:                                        .intValue());
250:                            }
251:                        }
252:                    }
253:
254:                } else if (methodName.startsWith("is")) {
255:                    String attrName = m.getName().substring(2);
256:                    returnObject = lookupAttribute(attrName, m.getReturnType());
257:
258:                } else if (methodName.startsWith("set")) {
259:                    // Only allow if document is writable
260:                    if (!this .isConfigurationWritable()) {
261:                        throw new java.lang.UnsupportedOperationException(this 
262:                                .getClass().getName()
263:                                + "Configuration Document is read-only, write "
264:                                + "not supported.");
265:                    }
266:
267:                    String attrName = m.getName().substring(3);
268:                    if (args.length == 1) {
269:                        // Simple value set
270:                        alterAttribute(attrName, m.getParameterTypes()[0],
271:                                args[0]);
272:
273:                    } else if (args.length == 2) {
274:
275:                        if (isMapAttribute(attrName)) {
276:                            //Set the map value
277:                            setMapValue(attrName,
278:                                    getCollectionComponentType(attrName),
279:                                    args[0], args[1]);
280:
281:                        } else {
282:                            // Array index value set
283:                            setArrayValue(attrName, m.getParameterTypes()[1],
284:                                    ((Integer) args[0]).intValue(), args[1]);
285:                        }
286:                    }
287:
288:                } else if (methodName.startsWith("add")) {
289:                    // Only allow if document is writable
290:                    if (!this .isConfigurationWritable()) {
291:                        throw new java.lang.UnsupportedOperationException(this 
292:                                .getClass().getName()
293:                                + "Configuration Document is read-only, write "
294:                                + "not supported.");
295:                    }
296:
297:                    String attrName = m.getName().substring(3);
298:                    addAttribute(attrName, m.getParameterTypes()[0], args[0]);
299:
300:                } else {
301:                    throw new UnsupportedOperationException(
302:                            this .getClass().getName()
303:                                    + ": Method named ["
304:                                    + methodName
305:                                    + "] in configuration "
306:                                    + "interface ["
307:                                    + m.getDeclaringClass()
308:                                    + "] is not a supported "
309:                                    + "method within a Configuration interface.  Methods must "
310:                                    + "conform to the JavaBeans specification.");
311:                }
312:
313:                return returnObject;
314:            }
315:
316:            /**
317:             * Gets the value from an configuration array.
318:             *
319:             * @param attributeName the name of the attribute that holds the array
320:             * @param type the type of class within the array
321:             * @param index the index of the value to retreive
322:             * @return the object at the given index in the array
323:             * @throws InvalidParameterException indicates there was an error
324:             *         accessing the give index in the array such as an
325:             *         IndexOutOfBoundsException
326:             */
327:            protected Object getArrayValue(String attributeName, Class type,
328:                    int index) {
329:
330:                Object array = getArray(attributeName, type);
331:
332:                Object returnObject = null;
333:                try {
334:                    returnObject = Array.get(array, index);
335:                } catch (IndexOutOfBoundsException ioobe) {
336:                    throw new InvalidParameterException(this .getClass(),
337:                            "Indexed configuration out of bounds on document ["
338:                                    + this .getConfigurationName()
339:                                    + "] attribute [" + attributeName
340:                                    + "] index [" + index + "]", ioobe);
341:                }
342:                return returnObject;
343:            }
344:
345:            /**
346:             * Checks if the given attribute contains a map.
347:             *
348:             * @param attrName the attribute to test for being a map
349:             * @return true if the given attribute is for a map
350:             */
351:            protected boolean isMapAttribute(String attrName) {
352:                boolean isMapAttribute = false;
353:
354:                try {
355:                    Method readMethod = this .documentType.getMethod("get"
356:                            + attrName, new Class[0]);
357:
358:                    isMapAttribute = readMethod.getReturnType().equals(
359:                            Map.class);
360:                } catch (NoSuchMethodException e) {
361:                    // read method does not exist, so leave isMapAttribute as false
362:                }
363:
364:                return isMapAttribute;
365:            }
366:
367:            /**
368:             * Gets the type of class contained within a map.
369:             *
370:             * @param attrName the name of the attribute to determine the
371:             *        class type of
372:             * @return the type of class contained within the array or null
373:             *         if it is unable to determine the type.
374:             */
375:            protected Class getCollectionComponentType(String attrName) {
376:                Class componentType = null;
377:
378:                try {
379:                    Method readMethod = this .documentType.getMethod("get"
380:                            + attrName, new Class[] { String.class });
381:
382:                    componentType = readMethod.getReturnType();
383:                } catch (NoSuchMethodException e) {
384:                    // read method does not exist, so leave componentType as null
385:                }
386:
387:                return componentType;
388:            }
389:
390:            /**
391:             * Retrieves the type of a JavaBean attribute by introspecting for its
392:             * retrieval method and checking its return type.
393:             * @param attributeName the name of the attribute to get the type of
394:             * @return the class type of the attribute
395:             */
396:            public Class getChildType(String attributeName) {
397:                attributeName = StringUtil.capitalize(attributeName);
398:                try {
399:                    Method method = this .documentType.getMethod("get"
400:                            + attributeName, new Class[0]);
401:                    return method.getReturnType();
402:                } catch (NoSuchMethodException nsme) {
403:                    throw new InvalidParameterException(this .getClass(),
404:                            "Unknown attribute [" + attributeName
405:                                    + "] on configuration ["
406:                                    + this .getConfigurationName() + "]");
407:                }
408:            }
409:
410:            /**
411:             * Retrieves the default value for a requested configuration attribute
412:             * from an interface static variable with the same name as the
413:             * requested attribute.
414:             *
415:             * @param type the Class of the configuration interface that may
416:             *   contain a default value
417:             * @param attributeName the name of the attribute being looked for
418:             * @param returnType the return type of the method
419:             * @return  the default value of the specified attribute
420:             */
421:            protected Object lookupDefaultAttributeValue(Class type,
422:                    String attributeName, Class returnType) {
423:
424:                try {
425:
426:                    Field field = type.getField(attributeName);
427:                    Object val = field.get(null);
428:
429:                    if (val == null) {
430:                        return null;
431:                    } else {
432:                        if (field.getType().equals(returnType)) {
433:                            // The attribute has a default and it is the right type
434:                            return val;
435:                        } else {
436:                            // Default value has the wrong type
437:                            StringBuffer buf = new StringBuffer();
438:                            buf
439:                                    .append("The Default value in the configuration of [");
440:                            buf.append(type.getName());
441:                            buf.append("] was of type [");
442:                            buf.append(field.getType());
443:                            buf
444:                                    .append("], but the configuration interface requires a ");
445:                            buf.append(" default of type [");
446:                            buf.append(returnType);
447:                            buf.append("].");
448:
449:                            throw new InvalidConfigurationException(this 
450:                                    .getClass(), this .getConfigurationName(),
451:                                    buf.toString());
452:
453:                        }
454:                    }
455:                } catch (NoSuchFieldException nsfe) {
456:                    // No field, no problem
457:                    // search super interfaces (depth first search)
458:                    Class[] super Interfaces = type.getInterfaces();
459:                    Object val = null;
460:                    for (int i = 0; ((i < super Interfaces.length) && (val == null)); i++) {
461:
462:                        val = lookupDefaultAttributeValue(super Interfaces[i],
463:                                attributeName, returnType);
464:                    }
465:                    return val;
466:                } catch (IllegalAccessException iae) {
467:                    throw new InvalidConfigurationException(this .getClass(),
468:                            this .getConfigurationName(), attributeName,
469:                            "Could not access the default variable named ["
470:                                    + attributeName
471:                                    + "] in the configuration interface ["
472:                                    + type.getName() + "].", iae);
473:                } catch (IllegalArgumentException iae) {
474:                    throw new InvalidConfigurationException(this .getClass(),
475:                            this .getConfigurationName(), attributeName,
476:                            "Could not access the default variable named ["
477:                                    + attributeName
478:                                    + "] in the configuration interface ["
479:                                    + type.getName() + "].", iae);
480:                }
481:
482:            }
483:
484:            /**
485:             * <P>Implementations of this method should provide the ability to alter an
486:             * attribute within the configuration object setting its value to the
487:             * provide <code>newValue</code>.
488:             *
489:             * @param attributeName the name of the attribute to be altered
490:             * @param attributeType the type of the attribute
491:             * @param newValue the new value to change that attribute to
492:             */
493:            public abstract void alterAttribute(String attributeName,
494:                    Class attributeType, Object newValue);
495:
496:            /**
497:             * <P>Implementations of this method should retrieve a value from the
498:             * configuration object with the specified name and Type. The Type
499:             * information is gleaned from the providing configuration interface
500:             * and allows the system to determine the proper mechanism for
501:             * instantiating this value. This may involve the usage of the
502:             * micro-level formatting for configuration values.</P>
503:             *
504:             * @return the object representing the specified confuguration value
505:             * @param attributeName the name of the attribute to retrieve
506:             * @param returnType the class type of the object that should be returned
507:             */
508:            public abstract Object lookupAttribute(String attributeName,
509:                    Class returnType);
510:
511:            /**
512:             * <P>Retrieves an array of objects of the specified type that have
513:             * the specified name. This might get a list of dependent objects or
514:             * a list of string values.</P>
515:             *
516:             * @param attributeName the name of the array to retrieve
517:             * @param componentType the type of the objects that should be retrieved
518:             *  within the array
519:             * @return an array of objects that match the name and type specified
520:             */
521:            public abstract Object getArray(String attributeName,
522:                    Class componentType);
523:
524:            /**
525:             * <P>Retrieves a java.util.Map of objects of the specified type that have
526:             * the specified name. This might get a list of dependent objects or
527:             * a list of string values.</P>
528:             *
529:             * @param attributeName the name of the array to retrieve
530:             * @param contentType the type of the objects that should be retrieved
531:             *      within the Map
532:             * @return a Map of objects that match the name and type specified
533:             */
534:            public abstract Map getMap(String attributeName, Class contentType);
535:
536:            /**
537:             * <P>Sets the value of a specific index in an array of data in this
538:             * configuration object. Implementing classes must set the specified index
539:             * of the array named by <code>attributeName</code> to the specified value.
540:             * </P>
541:             *
542:             * @param attributeName the name of the array to alter
543:             * @param attributeType the type of the objects in the array
544:             * @param index the indicie of the array to alter
545:             * @param value the Object to set as the value of this indicie
546:             */
547:            public abstract void setArrayValue(String attributeName,
548:                    Class attributeType, int index, Object value);
549:
550:            /**
551:             * <P>Sets the value of a specific index in an array of data in this
552:             * configuration object. Implementing classes must set the specified index
553:             * of the array named by <code>attributeName</code> to the specified value.
554:             * </P>
555:             *
556:             * @param attributeName the name of the array to alter
557:             * @param attributeType the type of the objects in the map
558:             * @param key the key within the map to set
559:             * @param value the Object to set as the value of this indicie
560:             */
561:            public abstract void setMapValue(String attributeName,
562:                    Class attributeType, Object key, Object value);
563:
564:            /**
565:             * This method should add a child entity to this configuration entity
566:             *
567:             * @param entityName the name of the array on which to add a particular
568:             *   value
569:             * @param type type of class of the child entity
570:             * @param obj The object to be added as a configuration entity
571:             * @return the element representing the added attribute
572:             */
573:            public abstract Element addAttribute(String entityName, Class type,
574:                    Object obj);
575:
576:            /**
577:             * <P>Returns the simple class name without the prepended package
578:             * structure</P>
579:             *
580:             * @param theClass the class whose name is returned
581:             * @return the unqualifiedclass name of the supplied class
582:             */
583:            public static String getSimpleClassName(Class theClass) {
584:                String className = theClass.getName();
585:                if (className.lastIndexOf('.') > className.lastIndexOf('$')) {
586:                    return className.substring(className.lastIndexOf('.') + 1);
587:                } else {
588:                    return className.substring(className.lastIndexOf('$') + 1);
589:                }
590:            }
591:
592:            /**
593:             * @see Configuration#getConfigurationInterface()
594:             */
595:            public Class getConfigurationInterface() {
596:                try {
597:                    String configurationInterfaceName = this .element
598:                            .getAttributeValue("ConfigurationInterface");
599:
600:                    if (configurationInterfaceName == null) {
601:                        throw new InvalidConfigurationException(
602:                                this .getClass(), getConfigurationName(),
603:                                "ConfigurationInterface", "No value specifed");
604:                    }
605:
606:                    return Class.forName(configurationInterfaceName);
607:                } catch (ClassNotFoundException cnfe) {
608:                    throw new InvalidConfigurationException(this .getClass(),
609:                            getConfigurationName(), "ConfigurationInterface",
610:                            "Specifed class not found", cnfe);
611:                }
612:            }
613:
614:            /**
615:             * @see Configuration#getDataStructure()
616:             */
617:            public Document getDataStructure() {
618:                return this .document;
619:            }
620:
621:            /**
622:             * Retrieves the root element of the data being currently mapped by this
623:             * configuration object. Child structures will have a different root then
624:             * the root of the "Document" object.
625:             *
626:             * @return the root element being proxied by this object
627:             */
628:            public Element getRootElement() {
629:                return this .element;
630:            }
631:
632:            /**
633:             * @see Object#clone()
634:             */
635:            public abstract Object clone();
636:
637:            /**
638:             * Checks whether or not childElement is a child configuration or not
639:             *
640:             * @param childElement element to be tested.
641:             * @return boolean true if childElement is a configuration
642:             */
643:            public boolean isChildConfiguration(Element childElement) {
644:                return (childElement.getAttribute("ConfigurationInterface") != null || isReference(childElement));
645:            }
646:
647:            /**
648:             * Checks whether or not element is a reference to another configuration.
649:             *
650:             * @param element element to check if it is a reference
651:             * @return true is the text of element starts with REF_PREFIX
652:             */
653:            public boolean isReference(Element element) {
654:                String textValue = element.getTextTrim();
655:                return textValue.startsWith(REF_PREFIX);
656:            }
657:
658:            /**
659:             * Gets the ConfigurationInterface specifed in an element.  If the
660:             * ConfigurationInterface is not defined by the element of the class
661:             * specified is not found, defaultInterface is returned.
662:             *
663:             * @param element the element to retreive the configuration element from
664:             * @param defaultInterface the default interface if there is no
665:             *        configuration interface defined by the element
666:             * @return ConfigurationInterface from the element or default
667:             */
668:            protected Class getConfigurationInterface(Element element,
669:                    Class defaultInterface) {
670:
671:                Class configurationInterface = defaultInterface;
672:
673:                try {
674:                    String configTypeName = element
675:                            .getAttributeValue("ConfigurationInterface");
676:
677:                    if (configTypeName != null) {
678:                        configurationInterface = Class.forName(configTypeName);
679:                    }
680:
681:                    if (!Configuration.class
682:                            .isAssignableFrom(configurationInterface)) {
683:                        throw new InvalidConfigurationException(
684:                                this .getClass(),
685:                                this .getConfigurationName(),
686:                                this .element.getName(),
687:                                "The configured configuration interface does not extend "
688:                                        + "[org.sape.carbon.core.config.Configuration] and "
689:                                        + "therefore can not be instantiated. Please correct "
690:                                        + "the class ["
691:                                        + configurationInterface.getName()
692:                                        + "]");
693:                    }
694:
695:                } catch (ClassNotFoundException cnfe) {
696:                    throw new InvalidConfigurationException(
697:                            this .getClass(),
698:                            this .getConfigurationName(),
699:                            element.getName(),
700:                            "The child configuration has defined a configuration interface "
701:                                    + "class which can not be found. Check the configuration document "
702:                                    + "to ensure the class name is correct.",
703:                            cnfe);
704:                } catch (ExceptionInInitializerError eiie) {
705:                    if (log.isTraceEnabled()) {
706:                        log.trace("Caught ExceptionInInitializerError [" + eiie
707:                                + "], returning default interface");
708:                    }
709:                }
710:
711:                return configurationInterface;
712:            }
713:
714:            /**
715:             * @see org.sape.carbon.core.util.reflection.GenericProxy#proxyEquals(Object, Object)
716:             */
717:            protected Boolean proxyEquals(Object proxy, Object other) {
718:                try {
719:                    Element proxyElement = ((Configuration) proxy)
720:                            .getRootElement();
721:                    Element otherElement = ((Configuration) other)
722:                            .getRootElement();
723:
724:                    if (proxyElement == otherElement) {
725:                        return Boolean.TRUE;
726:                    } else {
727:                        return Boolean.FALSE;
728:                    }
729:                } catch (ClassCastException cce) {
730:                    return Boolean.FALSE;
731:                }
732:            }
733:
734:            /**
735:             * @see org.sape.carbon.core.util.reflection.GenericProxy#proxyHashCode(Object)
736:             */
737:            protected Integer proxyHashCode(Object proxy) {
738:                Element proxyElement = ((Configuration) proxy).getRootElement();
739:                return new Integer(System.identityHashCode(proxyElement));
740:            }
741:
742:            /**
743:             * Is this configuration document writable or is it read-only. Shared cache
744:             * instances of configuration objects should either be synchronized or
745:             * marked not writable. When a configuration object is not writable, it
746:             * should throw an exception if an attempt is made to modify it.
747:             *
748:             * @return true if this cofiguration object may be altered.
749:             * @since carbon 1.1
750:             */
751:            public boolean isConfigurationWritable() {
752:                return this .writable;
753:            }
754:
755:            /**
756:             * Sets whether this configuration may be altered.
757:             * @since carbon 1.1
758:             */
759:            public void setConfigurationReadOnly() {
760:                this .writable = false;
761:            }
762:
763:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.