Source Code Cross Referenced for XMLEntityResolver.java in  » Database-ORM » MMBase » org » mmbase » util » 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.util 
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.util;
011:
012:        import java.io.InputStream;
013:        import java.io.InputStreamReader;
014:        import java.io.ByteArrayInputStream;
015:        import java.util.*;
016:        import java.util.concurrent.*;
017:
018:        import java.lang.reflect.*;
019:
020:        import org.mmbase.util.xml.ApplicationReader;
021:        import org.mmbase.util.xml.BuilderReader;
022:        import org.mmbase.util.xml.ModuleReader;
023:        import org.mmbase.util.logging.*;
024:
025:        import org.xml.sax.EntityResolver;
026:        import org.xml.sax.InputSource;
027:
028:        /**
029:         * Take the systemId and converts it into a local file, using the MMBase config path
030:         *
031:         * @move org.mmbase.util.xml
032:         * @rename EntityResolver
033:         * @author Gerard van Enk
034:         * @author Michiel Meeuwissen
035:         * @version $Id: XMLEntityResolver.java,v 1.68 2007/12/06 08:19:29 michiel Exp $
036:         */
037:        public class XMLEntityResolver implements  EntityResolver {
038:
039:            public static final String DOMAIN = "http://www.mmbase.org/";
040:            public static final String DTD_SUBPATH = "dtd/";
041:            public static final String XMLNS_SUBPATH = "xmlns/";
042:            private static final String XSD_SUBPATH = "xsd/"; // deprecated
043:
044:            private static Logger log = Logging
045:                    .getLoggerInstance(XMLEntityResolver.class);
046:            static {
047:                //log.setLevel(Level.DEBUG);
048:            }
049:
050:            private static final String MMRESOURCES = "/org/mmbase/resources/";
051:
052:            private static Map<String, Resource> publicIDtoResource = new ConcurrentHashMap<String, Resource>();
053:            // This maps public id's to classes which are know to be able to parse this XML's.
054:            // The package of these XML's will also contain the resources with the DTD.
055:
056:            /**
057:             * XSD's have only system ID
058:             */
059:            private static Map<String, Resource> systemIDtoResource = new ConcurrentHashMap<String, Resource>();
060:
061:            /**
062:             * Container for dtd resources information
063:             */
064:            static abstract class Resource {
065:                abstract InputStream getStream();
066:            }
067:
068:            static class StringResource extends Resource {
069:                private String string;
070:
071:                StringResource(String s) {
072:                    string = s;
073:                }
074:
075:                InputStream getStream() {
076:                    return new ByteArrayInputStream(string.getBytes());
077:                }
078:            }
079:
080:            static class FileResource extends Resource {
081:                private final Class<?> clazz;
082:                private final String file;
083:
084:                FileResource(Class<?> c, String f) {
085:                    clazz = c;
086:                    file = f;
087:                }
088:
089:                String getResource() {
090:                    return "resources/" + file;
091:                }
092:
093:                String getFileName() {
094:                    return file;
095:                }
096:
097:                InputStream getStream() {
098:                    InputStream stream = null;
099:                    if (file != null) {
100:                        stream = ResourceLoader.getConfigurationRoot()
101:                                .getResourceAsStream(
102:                                        DTD_SUBPATH + getFileName());
103:                        if (stream == null) {
104:                            stream = ResourceLoader.getConfigurationRoot()
105:                                    .getResourceAsStream(
106:                                            XMLNS_SUBPATH + getFileName());
107:                        }
108:                        if (stream == null) {
109:                            // XXX I think this was deprecated in favour in xmlns/ (all in 1.8), so perhaps this can be dropped
110:                            stream = ResourceLoader.getConfigurationRoot()
111:                                    .getResourceAsStream(
112:                                            XSD_SUBPATH + getFileName());
113:                        }
114:                    }
115:                    if (stream == null && clazz != null) {
116:                        stream = clazz.getResourceAsStream(getResource());
117:                    }
118:
119:                    return stream;
120:                }
121:
122:                public String toString() {
123:                    return file + ": " + clazz;
124:                }
125:
126:            }
127:
128:            static {
129:                // ask known (core) xml readers to register their public ids and dtds
130:                // the advantage of doing it this soon, is that the 1DTD are know as early as possible.
131:                org.mmbase.util.xml.DocumentReader.registerPublicIDs();
132:                BuilderReader.registerPublicIDs();
133:                BuilderReader.registerSystemIDs();
134:                ApplicationReader.registerPublicIDs();
135:                ModuleReader.registerPublicIDs();
136:                org.mmbase.util.xml.UtilReader.registerPublicIDs();
137:                org.mmbase.bridge.util.xml.query.QueryReader
138:                        .registerSystemIDs();
139:
140:                registerSystemID("http://www.w3.org/2001/03/xml.xsd",
141:                        "xml.xsd", null);
142:                registerSystemID("http://www.w3.org/2001/03/XMLSchema.dtd",
143:                        "XMLSchema.dtd", null);
144:                registerSystemID("http://www.w3.org/2001/03/datatypes.dtd",
145:                        "datatypes.dtd", null);
146:
147:                //registerSystemID("http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd", "docbookx.dtd", null);
148:                //registerSystemID("http://www.oasis-open.org/docbook/xml/4.1.2/dbnotnx.mod", "dbnotnx.mod", null);
149:            }
150:
151:            /**
152:             * Register a given publicID, binding it to a resource determined by a given class and resource filename
153:             * @param publicID the Public ID to register
154:             * @param dtd the name of the resourcefile
155:             * @param c the class indicating the location of the resource in the pacakage structure. The
156:             *          resource is to be found in the 'resources' package under the package of the class.
157:             * @since MMBase-1.7
158:             */
159:            public static void registerPublicID(String publicID, String dtd,
160:                    Class<?> c) {
161:                publicIDtoResource.put(publicID, new FileResource(c, dtd));
162:                if (log.isDebugEnabled())
163:                    log.debug("publicIDtoResource: " + publicID + " " + dtd
164:                            + c.getName());
165:            }
166:
167:            /**
168:             * It seems that in XSD's you don't have public id's. So, this makes it possible to use system id.
169:             * @todo EXPERIMENTAL
170:             * @since MMBase-1.8
171:             */
172:            public static void registerSystemID(String systemID, String xsd,
173:                    Class<?> c) {
174:                systemIDtoResource.put(systemID, new FileResource(c, xsd));
175:            }
176:
177:            private String definitionPath;
178:
179:            private boolean hasDefinition; // tells whether or not a DTD/XSD is set - if not, no validition can take place
180:
181:            private boolean validate;
182:            private Class<?> resolveBase;
183:
184:            /**
185:             * empty constructor
186:             */
187:            public XMLEntityResolver() {
188:                this (true);
189:            }
190:
191:            public XMLEntityResolver(boolean v) {
192:                this (v, null);
193:            }
194:
195:            public XMLEntityResolver(boolean v, Class<?> base) {
196:                hasDefinition = false;
197:                definitionPath = null;
198:                validate = v;
199:                resolveBase = base;
200:            }
201:
202:            protected static StringBuilder camelAppend(StringBuilder sb,
203:                    String s) {
204:                for (int i = 0; i < s.length(); i++) {
205:                    char c = s.charAt(i);
206:                    if (Character.isUpperCase(c)) {
207:                        sb.append(Character.toLowerCase(c));
208:                    } else {
209:                        sb.append(s.substring(i));
210:                        break;
211:                    }
212:                }
213:                return sb;
214:            }
215:
216:            protected static void appendEntities(StringBuilder sb, Object o,
217:                    String prefix, int level, Set<Object> os) {
218:                os.add(o);
219:                org.mmbase.util.transformers.Identifier identifier = new org.mmbase.util.transformers.Identifier();
220:                if (o instanceof  Map) {
221:                    Set<Map.Entry<?, ?>> map = ((Map) o).entrySet();
222:                    for (Map.Entry<?, ?> entry : map) {
223:                        Object value = entry.getValue();
224:                        if (value != null
225:                                && Casting.isStringRepresentable(value
226:                                        .getClass())
227:                                && entry.getKey() instanceof  String) {
228:                            sb.append("<!ENTITY ");
229:                            sb.append(prefix);
230:                            sb.append('.');
231:                            String k = identifier.transform((String) entry
232:                                    .getKey());
233:                            k = k.replaceAll("\\s", "");
234:                            sb.append(k);
235:                            sb
236:                                    .append(" \""
237:                                            + org.mmbase.util.transformers.Xml
238:                                                    .XMLAttributeEscape(""
239:                                                            + value, '"')
240:                                            + "\">\n");
241:                        }
242:                        if (level < 3
243:                                && value != null
244:                                && !os.contains(value)
245:                                && !value.getClass().getName().startsWith(
246:                                        "java.lang")) { // recursion to acces also properties of this
247:                            appendEntities(sb, value, prefix + "."
248:                                    + entry.getKey(), level + 1, os);
249:                        }
250:                    }
251:                } else {
252:                    for (Method m : o.getClass().getMethods()) {
253:                        String name = m.getName();
254:                        if (m.getParameterTypes().length == 0
255:                                && !name.equals("getNodes")
256:                                && !name.equals("getConnection")
257:                                && // see  	 MMB-1490, we should not call
258:                                // getConnection, while we won't close it.
259:                                name.length() > 3 && name.startsWith("get")
260:                                && Character.isUpperCase(name.charAt(3))) {
261:                            try {
262:                                Class<?> rt = m.getReturnType();
263:                                boolean invoked = false;
264:                                Object value = null;
265:                                if (Casting.isStringRepresentable(rt)) {
266:                                    if (!Map.class.isAssignableFrom(rt)
267:                                            && !Collection.class
268:                                                    .isAssignableFrom(rt)) {
269:                                        value = m.invoke(o);
270:                                        invoked = true;
271:                                        sb.append("<!ENTITY ");
272:                                        sb.append(prefix);
273:                                        sb.append('.');
274:                                        camelAppend(sb, name.substring(3));
275:                                        sb
276:                                                .append(" \""
277:                                                        + org.mmbase.util.transformers.Xml
278:                                                                .XMLAttributeEscape(
279:                                                                        ""
280:                                                                                + value,
281:                                                                        '"')
282:                                                        + "\">\n");
283:                                    }
284:                                }
285:                                if (!rt.getName().startsWith("java.lang")) {
286:                                    if (!invoked)
287:                                        value = m.invoke(o);
288:                                    if (level < 3 && value != null
289:                                            && !os.contains(value)) {
290:                                        appendEntities(sb, value, prefix
291:                                                + "."
292:                                                + camelAppend(
293:                                                        new StringBuilder(),
294:                                                        name.substring(3)),
295:                                                level + 1, os);
296:                                    }
297:                                }
298:                            } catch (IllegalAccessException ia) {
299:                                log.debug(ia);
300:                            } catch (InvocationTargetException ite) {
301:                                log.debug(ite);
302:                            } catch (AbstractMethodError ame) {
303:                                log.debug(ame);
304:                            }
305:                        }
306:                    }
307:                }
308:            }
309:
310:            protected static String ents = null;
311:            protected static boolean logEnts = true;
312:
313:            protected static synchronized String getMMEntities() {
314:                if (ents == null) {
315:                    StringBuilder sb = new StringBuilder();
316:                    try {
317:                        org.mmbase.module.Module mmbase = org.mmbase.module.Module
318:                                .getModule("mmbaseroot", false);
319:                        if (mmbase != null) {
320:                            appendEntities(sb, mmbase, "mmbase", 0,
321:                                    new HashSet<Object>());
322:                        } else {
323:                            return sb.toString();
324:                        }
325:                    } catch (Throwable ie) {
326:                        log.warn(ie.getMessage());
327:                        return sb.toString();
328:                    }
329:                    ents = sb.toString();
330:                    if (logEnts) {
331:                        log.debug("Using entities\n" + ents);
332:                    }
333:                }
334:                return ents;
335:            }
336:
337:            public static void clearMMEntities(boolean le) {
338:                ents = null;
339:                logEnts = le;
340:            }
341:
342:            /**
343:             * Takes the systemId and returns the local location of the dtd/xsd
344:             */
345:            public InputSource resolveEntity(final String publicId,
346:                    final String systemId) {
347:                if (log.isDebugEnabled()) {
348:                    log.debug("resolving PUBLIC " + publicId + " SYSTEM "
349:                            + systemId);
350:                }
351:
352:                InputStream definitionStream = null;
353:
354:                if ("http://www.mmbase.org/mmentities.ent".equals(systemId)) {
355:                    //StringBuilder sb = new StringBuilder();
356:                    //Class c = org.mmbase.framework.Framework.class;
357:                    String ents = getMMEntities();
358:                    if (log.isDebugEnabled()) {
359:                        log.debug("Using entities\n" + ents);
360:                    }
361:                    definitionStream = new StringResource(ents).getStream();
362:                } else if (publicId != null) {
363:                    // first try with publicID or namespace
364:                    Resource res = publicIDtoResource.get(publicId);
365:                    log.debug("Found publicId " + publicId + " -> " + res);
366:                    definitionStream = res == null ? null : res.getStream();
367:                }
368:
369:                log.debug("Get definition stream by public id: "
370:                        + definitionStream);
371:
372:                if (definitionStream == null) {
373:                    Resource res = systemIDtoResource.get(systemId);
374:                    if (res != null) {
375:                        definitionStream = res.getStream();
376:                    }
377:                }
378:
379:                if (definitionStream == null) { // not succeeded with publicid, go trying with systemId
380:
381:                    //does systemId contain a mmbase-dtd
382:                    if ((systemId == null) || (!systemId.startsWith(DOMAIN))) {
383:                        // it's a systemId we can't do anything with,
384:                        // so let the parser decide what to do
385:
386:                        if (validate) {
387:                            log
388:                                    .debug("Cannot resolve "
389:                                            + systemId
390:                                            + ", but needed for validation leaving to parser.");
391:                            log.debug("Find culpit: ", new Exception());
392:                            return null;
393:                        } else {
394:                            // perhaps this should not be done if it is about resolving _entities_ rather then dtd.
395:                            log
396:                                    .debug("Not validating, no need to resolve DTD (?), returning empty resource for "
397:                                            + systemId);
398:                            return new InputSource(new ByteArrayInputStream(
399:                                    new byte[0]));
400:                        }
401:                    } else {
402:                        log.debug("mmbase resource");
403:                        String mmResource = systemId.substring(22);
404:                        // first, try MMBase config directory (if initialized)
405:                        definitionStream = ResourceLoader
406:                                .getConfigurationRoot().getResourceAsStream(
407:                                        mmResource);
408:                        if (definitionStream == null) {
409:                            Class<?> base = resolveBase; // if resolveBase was specified, use that.
410:                            Resource res = null;
411:                            if (base != null) {
412:                                if (mmResource.startsWith("xmlns/")) {
413:                                    res = new FileResource(base, mmResource
414:                                            .substring(6));
415:                                } else {
416:                                    res = new FileResource(base, mmResource
417:                                            .substring(4)); // dtd or xsd
418:                                }
419:                            }
420:                            if (res != null) {
421:                                definitionStream = res.getStream();
422:                                if (definitionStream == null) {
423:                                    log.warn("Could not find " + res.toString()
424:                                            + " in " + base.getName()
425:                                            + ", falling back to "
426:                                            + MMRESOURCES + " while resolving "
427:                                            + systemId + " " + publicId);
428:                                    base = null; // try it in org.mmbase.resources too.
429:                                }
430:                            }
431:
432:                            if (base == null) {
433:                                String resource = MMRESOURCES + mmResource;
434:                                if (log.isDebugEnabled())
435:                                    log
436:                                            .debug("Getting document definition as resource "
437:                                                    + resource);
438:                                definitionStream = getClass()
439:                                        .getResourceAsStream(resource);
440:                            }
441:                        }
442:                        if (definitionStream == null) {
443:                            if (resolveBase != null) {
444:                                log
445:                                        .error("Could not find MMBase entity '"
446:                                                + publicId
447:                                                + " "
448:                                                + systemId
449:                                                + "' (did you make a typo?), returning null, system id will be used (needing a connection, or put in config dir)");
450:                            } else {
451:                                log
452:                                        .service("Could not find MMBase entity '"
453:                                                + publicId
454:                                                + " "
455:                                                + systemId
456:                                                + "' (did you make a typo?), returning null, system id will be used (needing a connection, or put in config dir)");
457:                            }
458:                            // not sure, probably should return 'null' after all, then it will be resolved with internet.
459:                            // but this can not happen, in fact...
460:                            //return new InputSource(new StringReader(""));
461:                            // FAILED
462:                            return null;
463:                        }
464:                    }
465:                }
466:                hasDefinition = true;
467:
468:                InputStreamReader definitionInputStreamReader = new InputStreamReader(
469:                        definitionStream);
470:                InputSource definitionInputSource = new InputSource();
471:                if (systemId != null) {
472:                    definitionInputSource.setSystemId(systemId);
473:                }
474:                if (publicId != null) {
475:                    definitionInputSource.setPublicId(publicId);
476:                }
477:                definitionInputSource
478:                        .setCharacterStream(definitionInputStreamReader);
479:                return definitionInputSource;
480:            }
481:
482:            /**
483:             * @return whether the resolver has determined a DTD
484:             */
485:            public boolean hasDTD() {
486:                return hasDefinition;
487:            }
488:
489:            /**
490:             * @return The actually used path to the DTD
491:             */
492:            public String getDTDPath() {
493:                return definitionPath;
494:            }
495:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.