Source Code Cross Referenced for XmlObjectFactory.java in  » UML » AndroMDA-3.2 » org » andromda » core » common » 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 » UML » AndroMDA 3.2 » org.andromda.core.common 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.andromda.core.common;
002:
003:        import java.io.IOException;
004:        import java.io.InputStream;
005:        import java.io.Reader;
006:        import java.io.StringReader;
007:
008:        import java.net.URL;
009:
010:        import java.util.HashMap;
011:        import java.util.Map;
012:
013:        import org.apache.commons.digester.Digester;
014:        import org.apache.commons.digester.xmlrules.DigesterLoader;
015:        import org.apache.commons.lang.StringUtils;
016:        import org.apache.log4j.Logger;
017:        import org.xml.sax.EntityResolver;
018:        import org.xml.sax.InputSource;
019:        import org.xml.sax.SAXException;
020:        import org.xml.sax.SAXParseException;
021:
022:        /**
023:         * <p>
024:         * Creates and returns Objects based on a set of Apache Digester rules in a consistent manner, providing validation in
025:         * the process.
026:         * </p>
027:         * <p>
028:         * This XML object factory allows us to define a consistent/clean of configuring java objects from XML configuration
029:         * files (i.e. it uses the class name of the java object to find what rule file and what XSD file to use). It also
030:         * allows us to define a consistent way in which schema validation is performed.
031:         * <p/>
032:         * <p>
033:         * It seperates each concern into one file, for example: to configure and perform validation on the MetafacadeMappings
034:         * class, we need 3 files 1.) the java object (MetafacadeMappings.java), 2.) the rules file which tells the apache
035:         * digester how to populate the java object from the XML configuration file (MetafacadeMappings-Rules.xml), and 3.) the
036:         * XSD schema validation file (MetafacadeMappings.xsd). Note that each file is based on the name of the java object:
037:         * 'java object name'.xsd and 'java object name'-Rules.xml'. After you have these three files then you just need to call
038:         * the method #getInstance(java.net.URL objectClass) in this class from the java object you want to configure. This
039:         * keeps the dependency to digester (or whatever XML configuration tool we are using at the time) to this single file.
040:         * </p>
041:         * <p>
042:         * In order to add/modify an existing element/attribute in your configuration file, first make the modification in your
043:         * java object, then modify it's rules file to instruct the digester on how to configure your new attribute/method in
044:         * the java object, and then modify your XSD file to provide correct validation for this new method/attribute. Please
045:         * see the org.andromda.core.metafacade.MetafacadeMappings* files for an example on how to do this.
046:         * </p>
047:         *
048:         * @author Chad Brandon
049:         */
050:        public class XmlObjectFactory {
051:            /**
052:             * The class logger. Note: visibility is protected to improve access within {@link XmlObjectValidator}
053:             */
054:            protected static final Logger logger = Logger
055:                    .getLogger(XmlObjectFactory.class);
056:
057:            /**
058:             * The expected suffixes for rule files.
059:             */
060:            private static final String RULES_SUFFIX = "-Rules.xml";
061:
062:            /**
063:             * The expected suffix for XSD files.
064:             */
065:            private static final String SCHEMA_SUFFIX = ".xsd";
066:
067:            /**
068:             * The digester instance.
069:             */
070:            private Digester digester = null;
071:
072:            /**
073:             * The class of which the object we're instantiating.
074:             */
075:            private Class objectClass = null;
076:
077:            /**
078:             * The URL to the object rules.
079:             */
080:            private URL objectRulesXml = null;
081:
082:            /**
083:             * The URL of the schema.
084:             */
085:            private URL schemaUri = null;
086:
087:            /**
088:             * Whether or not validation should be turned on by default when using this factory to load XML configuration
089:             * files.
090:             */
091:            private static boolean defaultValidating = true;
092:
093:            /**
094:             * Cache containing XmlObjectFactory instances which have already been configured for given objectRulesXml
095:             */
096:            private static final Map factoryCache = new HashMap();
097:
098:            /**
099:             * Creates an instance of this XmlObjectFactory with the given <code>objectRulesXml</code>
100:             *
101:             * @param objectRulesXml
102:             */
103:            private XmlObjectFactory(final URL objectRulesXml) {
104:                ExceptionUtils.checkNull("objectRulesXml", objectRulesXml);
105:                this .digester = DigesterLoader.createDigester(objectRulesXml);
106:                this .digester.setUseContextClassLoader(true);
107:            }
108:
109:            /**
110:             * Gets an instance of this XmlObjectFactory using the digester rules belonging to the <code>objectClass</code>.
111:             *
112:             * @param objectClass the Class of the object from which to configure this factory.
113:             * @return the XmlObjectFactoy instance.
114:             */
115:            public static XmlObjectFactory getInstance(final Class objectClass) {
116:                ExceptionUtils.checkNull("objectClass", objectClass);
117:
118:                XmlObjectFactory factory = (XmlObjectFactory) factoryCache
119:                        .get(objectClass);
120:                if (factory == null) {
121:                    final URL objectRulesXml = XmlObjectFactory.class
122:                            .getResource('/'
123:                                    + objectClass.getName().replace('.', '/')
124:                                    + RULES_SUFFIX);
125:                    if (objectRulesXml == null) {
126:                        throw new XmlObjectFactoryException(
127:                                "No configuration rules found for class --> '"
128:                                        + objectClass + "'");
129:                    }
130:                    factory = new XmlObjectFactory(objectRulesXml);
131:                    factory.objectClass = objectClass;
132:                    factory.objectRulesXml = objectRulesXml;
133:                    factory.setValidating(defaultValidating);
134:                    factoryCache.put(objectClass, factory);
135:                }
136:
137:                return factory;
138:            }
139:
140:            /**
141:             * Allows us to set default validation to true/false for all instances of objects instantiated by this factory. This
142:             * is necessary in some cases where the underlying parser doesn't support schema validation (such as when performing
143:             * JUnit tests)
144:             *
145:             * @param validating true/false
146:             */
147:            public static void setDefaultValidating(final boolean validating) {
148:                defaultValidating = validating;
149:            }
150:
151:            /**
152:             * Sets whether or not the XmlObjectFactory should be validating, default is <code>true</code>. If it IS set to be
153:             * validating, then there needs to be a schema named objectClass.xsd in the same package as the objectClass that
154:             * this factory was created from.
155:             *
156:             * @param validating true/false
157:             */
158:            public void setValidating(final boolean validating) {
159:                this .digester.setValidating(validating);
160:                if (validating) {
161:                    if (this .schemaUri == null) {
162:                        final String schemaLocation = '/'
163:                                + this .objectClass.getName().replace('.', '/')
164:                                + SCHEMA_SUFFIX;
165:                        this .schemaUri = XmlObjectFactory.class
166:                                .getResource(schemaLocation);
167:                        try {
168:                            if (this .schemaUri != null) {
169:                                InputStream stream = this .schemaUri
170:                                        .openStream();
171:                                stream.close();
172:                                stream = null;
173:                            }
174:                        } catch (final IOException exception) {
175:                            this .schemaUri = null;
176:                        }
177:                        if (this .schemaUri == null) {
178:                            logger
179:                                    .warn("WARNING! Was not able to find schemaUri --> '"
180:                                            + schemaLocation
181:                                            + "' continuing in non validating mode");
182:                        }
183:                    }
184:                    if (this .schemaUri != null) {
185:                        try {
186:                            this .digester.setSchema(this .schemaUri.toString());
187:                            this .digester
188:                                    .setErrorHandler(new XmlObjectValidator());
189:
190:                            // also set the JAXP properties in case we're using a parser that needs those
191:                            this .digester.setProperty(JAXP_SCHEMA_LANGUAGE,
192:                                    this .digester.getSchemaLanguage());
193:                            this .digester.setProperty(JAXP_SCHEMA_SOURCE,
194:                                    this .digester.getSchema());
195:                        } catch (final Exception exception) {
196:                            logger
197:                                    .warn(
198:                                            "WARNING! Your parser does NOT support the "
199:                                                    + " schema validation continuing in non validation mode",
200:                                            exception);
201:                        }
202:                    }
203:                }
204:            }
205:
206:            /**
207:             * The JAXP 1.2 property required to set up the schema location.
208:             */
209:            protected static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
210:
211:            /**
212:             * The JAXP 1.2 property to set up the schemaLanguage used.
213:             */
214:            protected String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
215:
216:            /**
217:             * Returns a configured Object based on the objectXml configuration file
218:             *
219:             * @param objectXml the path to the Object XML config file.
220:             * @return Object the created instance.
221:             */
222:            public Object getObject(final URL objectXml) {
223:                return this .getObject(objectXml != null ? ResourceUtils
224:                        .getContents(objectXml) : null, objectXml);
225:            }
226:
227:            /**
228:             * Returns a configured Object based on the objectXml configuration reader.
229:             *
230:             * @param objectXml the path to the Object XML config file.
231:             * @return Object the created instance.
232:             */
233:            public Object getObject(final Reader objectXml) {
234:                return getObject(ResourceUtils.getContents(objectXml));
235:            }
236:
237:            /**
238:             * Returns a configured Object based on the objectXml configuration file passed in as a String.
239:             *
240:             * @param objectXml the path to the Object XML config file.
241:             * @return Object the created instance.
242:             */
243:            public Object getObject(String objectXml) {
244:                return this .getObject(objectXml, null);
245:            }
246:
247:            /**
248:             * Returns a configured Object based on the objectXml configuration file passed in as a String.
249:             *
250:             * @param objectXml the path to the Object XML config file.
251:             * @param resource the resource from which the objectXml was retrieved (this is needed to resolve
252:             *        any relative references; like XML entities).
253:             * @return Object the created instance.
254:             */
255:            public Object getObject(String objectXml, final URL resource) {
256:                ExceptionUtils.checkNull("objectXml", objectXml);
257:                Object object = null;
258:                try {
259:                    this .digester
260:                            .setEntityResolver(new XmlObjectEntityResolver(
261:                                    resource));
262:                    object = this .digester.parse(new StringReader(objectXml));
263:                    objectXml = null;
264:                    if (object == null) {
265:                        final String message = "Was not able to instantiate an object using objectRulesXml '"
266:                                + this .objectRulesXml
267:                                + "' with objectXml '"
268:                                + objectXml
269:                                + "', please check either the objectXml "
270:                                + "or objectRulesXml file for inconsistencies";
271:                        throw new XmlObjectFactoryException(message);
272:                    }
273:                } catch (final SAXException exception) {
274:                    final Throwable cause = ExceptionUtils
275:                            .getRootCause(exception);
276:                    if (cause instanceof  SAXException) {
277:                        final String message = "VALIDATION FAILED for --> '"
278:                                + objectXml + "' against SCHEMA --> '"
279:                                + this .schemaUri + "' --> message: '"
280:                                + exception.getMessage() + "'";
281:                        throw new XmlObjectFactoryException(message);
282:                    }
283:                    throw new XmlObjectFactoryException(cause);
284:                } catch (final Throwable throwable) {
285:                    final String message = "XML resource could not be loaded --> '"
286:                            + objectXml + "'";
287:                    throw new XmlObjectFactoryException(message, throwable);
288:                }
289:                return object;
290:            }
291:
292:            /**
293:             * Handles the validation errors.
294:             */
295:            static final class XmlObjectValidator implements 
296:                    org.xml.sax.ErrorHandler {
297:                /**
298:                 * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
299:                 */
300:                public final void error(final SAXParseException exception)
301:                        throws SAXException {
302:                    throw new SAXException(this .getMessage(exception));
303:                }
304:
305:                /**
306:                 * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
307:                 */
308:                public final void fatalError(final SAXParseException exception)
309:                        throws SAXException {
310:                    throw new SAXException(this .getMessage(exception));
311:                }
312:
313:                /**
314:                 * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
315:                 */
316:                public final void warning(final SAXParseException exception) {
317:                    logger.warn("WARNING!: " + this .getMessage(exception));
318:                }
319:
320:                /**
321:                 * Constructs and returns the appropriate error message.
322:                 *
323:                 * @param exception the exception from which to extract the message.
324:                 * @return the message.
325:                 */
326:                private String getMessage(final SAXParseException exception) {
327:                    final StringBuffer message = new StringBuffer();
328:                    if (exception != null) {
329:                        message.append(exception.getMessage());
330:                        message.append(", line: ");
331:                        message.append(exception.getLineNumber());
332:                        message.append(", column: ").append(
333:                                exception.getColumnNumber());
334:                    }
335:                    return message.toString();
336:                }
337:            }
338:
339:            /**
340:             * The prefix that the systemId should start with when attempting
341:             * to resolve it within a jar.
342:             */
343:            private static final String SYSTEM_ID_FILE = "file:";
344:
345:            /**
346:             * Provides the resolution of external entities from the classpath.
347:             */
348:            private static final class XmlObjectEntityResolver implements 
349:                    EntityResolver {
350:                private URL xmlResource;
351:
352:                XmlObjectEntityResolver(final URL xmlResource) {
353:                    this .xmlResource = xmlResource;
354:                }
355:
356:                /**
357:                 * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
358:                 */
359:                public InputSource resolveEntity(final String publicId,
360:                        final String systemId) throws SAXException, IOException {
361:                    InputSource source = null;
362:                    if (this .xmlResource != null) {
363:                        String path = systemId;
364:                        if (path != null && path.startsWith(SYSTEM_ID_FILE)) {
365:                            final String xmlResource = this .xmlResource
366:                                    .toString();
367:                            path = path.replaceFirst(SYSTEM_ID_FILE, "");
368:
369:                            // - remove any extra starting slashes
370:                            path = ResourceUtils.normalizePath(path);
371:
372:                            // - if we still have one starting slash, remove it
373:                            if (path.startsWith("/")) {
374:                                path = path.substring(1, path.length());
375:                            }
376:                            final String xmlResourceName = xmlResource
377:                                    .replaceAll(".*(\\+|/)", "");
378:                            URL uri = null;
379:                            InputStream inputStream = null;
380:                            try {
381:                                uri = ResourceUtils.toURL(StringUtils.replace(
382:                                        xmlResource, xmlResourceName, path));
383:                                if (uri != null) {
384:                                    inputStream = uri.openStream();
385:                                }
386:                            } catch (final IOException exception) {
387:                                // - ignore
388:                            }
389:                            if (inputStream == null) {
390:                                try {
391:                                    uri = ResourceUtils.getResource(path);
392:                                    if (uri != null) {
393:                                        inputStream = uri.openStream();
394:                                    }
395:                                } catch (final IOException exception) {
396:                                    // - ignore
397:                                }
398:                            }
399:                            if (inputStream != null) {
400:                                source = new InputSource(inputStream);
401:                                source.setPublicId(publicId);
402:                                source.setSystemId(uri.toString());
403:                            }
404:                        }
405:                    }
406:                    return source;
407:                }
408:            }
409:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.