Source Code Cross Referenced for XIncludeXMLBuilder.java in  » Installer » IzPack » net » n3 » nanoxml » 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 » Installer » IzPack » net.n3.nanoxml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2007 Volantis Systems Ltd., All Rights Reserved.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package net.n3.nanoxml;
017:
018:        import java.io.IOException;
019:        import java.io.InputStream;
020:        import java.io.InputStreamReader;
021:        import java.net.HttpURLConnection;
022:        import java.net.MalformedURLException;
023:        import java.net.URL;
024:        import java.net.URLConnection;
025:        import java.util.Iterator;
026:        import java.util.Stack;
027:        import java.util.Vector;
028:
029:        /**
030:         * Extend the XMLBuilder to add XInclude functionality
031:         */
032:        public class XIncludeXMLBuilder extends StdXMLBuilder {
033:            /**
034:             * Namespace for XInclude  (NOTE that this is not used
035:             * at the moment). The specification can be found
036:             * <a href="http://www.w3.org/TR/xinclude/">here</a>.
037:             */
038:            public static final String INCLUDE_NS = "http://www.w3.org/2001/XInclude";
039:            /**
040:             * The name of the include element (this should be "include" using the
041:             * {@link #INCLUDE_NS} but namespaces are not supported
042:             */
043:            public static final String INCLUDE_ELEMENT = "xinclude";
044:            /**
045:             * The location of the included data
046:             */
047:            public static final String HREF_ATTRIB = "href";
048:
049:            /**
050:             * The xpointer attribute. This must not be used when "parse='text'"
051:             */
052:            public static final String XPOINTER_ATTRIB = "xpointer";
053:
054:            /**
055:             * The attribute to decribe the encoding of the text include (no effect when
056:             * parse='xml')
057:             */
058:            public static final String ENCODING_ATTRIB = "encoding";
059:
060:            /**
061:             * The attribute describing the accept header that will be used with
062:             * http based includes.
063:             */
064:            public static final String ACCEPT_ENCODING = "accept";
065:
066:            /**
067:             * The element for handling fallbacks. This should be called "fallback" and
068:             * be in the {@link #INCLUDE_NS} but namespaces are not supported
069:             */
070:            public static final String FALLBACK_ELEMENT = "xfallback";
071:
072:            /**
073:             * Parse attribute. If missing this implies "xml" its other valid value
074:             * is "text"
075:             */
076:            public static final String PARSE_ATTRIB = "parse";
077:
078:            /**
079:             * Namespace for the "fragment" element used to include xml documents with
080:             * no explicit root node.
081:             */
082:            public static final String FRAGMENT_NS = "http://izpack.org/izpack/fragment";
083:
084:            /**
085:             * The fragment element is a root node element that can be
086:             * used to wrap xml fragments for inclusion. It is removed during the
087:             * include operation. This should be called "fragment" and be in the
088:             * {@link #FRAGMENT_NS} but namespaces are not supported.
089:             */
090:            public static final String FRAGMENT = "xfragment";
091:
092:            // Javadoc inherited
093:            public void endElement(String name, String nsPrefix,
094:                    String nsSystemID) {
095:                // get the current element before it gets popped from the stack
096:                XMLElement element = getCurrentElement();
097:                // let normal processing occur
098:                super .endElement(name, nsPrefix, nsSystemID);
099:                // now process the "include" element
100:                processXInclude(element);
101:            }
102:
103:            /**
104:             * This method handles XInclude elements in the code
105:             *
106:             * @param element the node currently being procesed. In this case it should
107:             *            be the {@link #INCLUDE_ELEMENT}
108:             */
109:            private void processXInclude(final XMLElement element) {
110:                if (INCLUDE_ELEMENT.equals(element.getName())) {
111:
112:                    Vector<XMLElement> fallbackChildren = element
113:                            .getChildrenNamed(FALLBACK_ELEMENT);
114:                    if (element.getChildrenCount() != fallbackChildren.size()
115:                            || fallbackChildren.size() > 1) {
116:                        throw new RuntimeException(new XMLParseException(
117:                                element.getSystemID(), element.getLineNr(),
118:                                INCLUDE_ELEMENT
119:                                        + " can optionally have a single "
120:                                        + FRAGMENT + " as a child"));
121:                    }
122:                    boolean usingFallback = false;
123:
124:                    String href = element.getAttribute(HREF_ATTRIB, "");
125:                    if (!href.equals("")) { // including an external file.
126:
127:                        IXMLReader reader = null;
128:                        try {
129:                            reader = getReader(element);
130:                        } catch (Exception e) { // yes really catch all exceptions
131:                            // ok failed to read from the location for some reason.
132:                            // see if we have a fallback
133:                            reader = handleFallback(element);
134:                            usingFallback = true;
135:                        }
136:                        String parse = element
137:                                .getAttribute(PARSE_ATTRIB, "xml");
138:                        // process as text if we are not using our fallback and the parse
139:                        // type is "text"
140:                        if ("text".equals(parse) && !usingFallback) {
141:                            includeText(element, reader);
142:                        } else if ("xml".equals(parse)) {
143:                            includeXML(element, reader);
144:                        } else {
145:                            throw new RuntimeException(
146:                                    new XMLParseException(
147:                                            element.getSystemID(),
148:                                            element.getLineNr(),
149:                                            PARSE_ATTRIB
150:                                                    + " attribute of "
151:                                                    + INCLUDE_ELEMENT
152:                                                    + " must be \"xml\" or \"text\" but was "
153:                                                    + parse));
154:                        }
155:                    } else { // including part of this file rather then an external one
156:                        if (!element.hasAttribute(XPOINTER_ATTRIB)) {
157:                            throw new RuntimeException(new XMLParseException(
158:                                    element.getSystemID(), element.getLineNr(),
159:                                    XPOINTER_ATTRIB
160:                                            + "must be specified if href is "
161:                                            + "empty or missing"));
162:                        }
163:                    }
164:                }
165:            }
166:
167:            /**
168:             * Handle the fallback if one exists. If one does not exist then throw
169:             * a runtime exception as this is a fatal error
170:             *
171:             * @param include the include element
172:             * @return a reader for the fallback
173:             */
174:            private IXMLReader handleFallback(XMLElement include) {
175:                Vector<XMLElement> fallbackChildren = include
176:                        .getChildrenNamed(FALLBACK_ELEMENT);
177:                if (fallbackChildren.size() == 1) {
178:                    // process fallback
179:
180:                    XMLElement fallback = fallbackChildren.get(0);
181:                    // fallback element can only contain a CDATA so it will not have
182:                    // its content in un-named children
183:                    String content = fallback.getContent();
184:                    if (content != null) {
185:                        content = content.trim();
186:                    }
187:
188:                    if ("".equals(content) || content == null) {
189:                        // an empty fragment requires us to just remove the "include"
190:                        // element. A nasty hack follows:
191:                        // a "fragment" with no children will just be removed along with
192:                        // the "include" element.
193:                        content = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\" ?><"
194:                                + FRAGMENT + "/>";
195:                    }
196:                    return StdXMLReader.stringReader(content);
197:                } else {
198:                    throw new RuntimeException(new XMLParseException(include
199:                            .getSystemID(), include.getLineNr(),
200:                            "could not load content"));
201:                }
202:            }
203:
204:            /**
205:             * Include the xml contained in the specified reader. This content will be
206:             * parsed and attached to the parent of the <param>element</param> node
207:             *
208:             * @param element the include element
209:             * @param reader  the reader containing the xml to parse and include.
210:             */
211:            private void includeXML(final XMLElement element, IXMLReader reader) {
212:
213:                try {
214:                    Stack<XMLElement> stack = getStack();
215:                    // set up a new parser to parse the include file.
216:                    StdXMLParser parser = new StdXMLParser();
217:                    parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
218:                    parser.setReader(reader);
219:                    parser.setValidator(new NonValidator());
220:
221:                    XMLElement childroot = (XMLElement) parser.parse();
222:                    // if the include element was the root element in the original
223:                    // document then keep the element as-is (i.e.
224:                    // don't remove the "fragment" element from the included content
225:                    if (stack.isEmpty()) {
226:                        setRootElement(childroot);
227:                    } else {
228:                        XMLElement parent = stack.peek();
229:                        // remove the include element from its parent
230:                        parent.removeChild(element);
231:
232:                        // if there was a "fragment" included remove the fragment
233:                        // element and attach its children in place of this include
234:                        // element.
235:                        if (FRAGMENT.equals(childroot.getName())) {
236:                            Vector grandchildren = childroot.getChildren();
237:                            Iterator it = grandchildren.iterator();
238:                            while (it.hasNext()) {
239:                                XMLElement grandchild = (XMLElement) it.next();
240:                                parent.addChild(grandchild);
241:                            }
242:                        } else {
243:                            // if it was a complete document included then
244:                            // just add it in place of the include element
245:                            parent.addChild(childroot);
246:                        }
247:                    }
248:                } catch (XMLException e) {
249:                    throw new RuntimeException(
250:                            new XMLParseException(element.getSystemID(),
251:                                    element.getLineNr(), e.getMessage()));
252:                }
253:            }
254:
255:            /**
256:             * Include plain text. The reader contains the content in the appropriate
257:             * encoding as determined by the {@link #ENCODING_ATTRIB} if one was
258:             * present.
259:             *
260:             * @param element the include element
261:             * @param reader  the reader containing the include text
262:             */
263:            private void includeText(XMLElement element, IXMLReader reader) {
264:
265:                if (element.getAttribute("xpointer") != null) {
266:                    throw new RuntimeException(new XMLParseException(
267:                            "xpointer cannot be used with parse='text'"));
268:                }
269:
270:                Stack<XMLElement> stack = getStack();
271:                if (stack.isEmpty()) {
272:                    throw new RuntimeException(new XMLParseException(element
273:                            .getSystemID(), element.getLineNr(),
274:                            "cannot include text as the root node"));
275:                }
276:
277:                // remove the include element from the parent
278:                XMLElement parent = stack.peek();
279:                parent.removeChild(element);
280:                StringBuffer buffer = new StringBuffer();
281:                try {
282:                    while (!reader.atEOF()) {
283:                        buffer.append(reader.read());
284:                    }
285:                } catch (IOException e) {
286:                    throw new RuntimeException(
287:                            new XMLParseException(element.getSystemID(),
288:                                    element.getLineNr(), e.getMessage()));
289:                }
290:
291:                if (parent.getChildrenCount() == 0) {
292:                    // no children so just set the content as there cannot have been
293:                    // any content there already
294:                    parent.setContent(buffer.toString());
295:                } else {
296:                    // nanoxml also claims to store #PCDATA in unnamed children
297:                    // if there was a combination of #PCDATA and child elements.
298:                    // This should put it in the correct place as we haven't finihshed
299:                    // parsing the children of includes parent yet.
300:                    XMLElement content = new XMLElement();
301:                    content.setContent(buffer.toString());
302:                    parent.addChild(content);
303:                }
304:            }
305:
306:            /**
307:             * Return a reader for the specified {@link #INCLUDE_ELEMENT}. The caller
308:             * is responsible for closing the reader produced.
309:             *
310:             * @param element the include element to obtain a reader for
311:             * @return a reader for the include element
312:             * @throws XMLParseException if a problem occurs parsing the
313:             *                           {@link #INCLUDE_ELEMENT}
314:             * @throws IOException       if the href cannot be read
315:             */
316:            private IXMLReader getReader(XMLElement element)
317:                    throws XMLParseException, IOException {
318:                String href = element.getAttribute(HREF_ATTRIB);
319:                // This is a bit nasty but is a simple way of handling files that are
320:                // not fully qualified urls
321:                URL url = null;
322:                try {
323:                    // standard URL
324:                    url = new URL(href);
325:                } catch (MalformedURLException e) {
326:                    try {
327:                        // absolute file without a protocol
328:                        if (href.charAt(0) == '/') {
329:                            url = new URL("file://" + href);
330:                        } else {
331:                            // relative file
332:                            url = new URL(new URL(element.getSystemID()), href);
333:                        }
334:                    } catch (MalformedURLException e1) {
335:                        new XMLParseException(element.getSystemID(), element
336:                                .getLineNr(), "malformed url '" + href + "'");
337:                    }
338:                }
339:
340:                URLConnection connection = url.openConnection();
341:                // special handling for http and https
342:                if (connection instanceof  HttpURLConnection
343:                        && element.hasAttribute(ENCODING_ATTRIB)) {
344:                    connection.setRequestProperty("accept", element
345:                            .getAttribute(ENCODING_ATTRIB));
346:                }
347:
348:                InputStream is = connection.getInputStream();
349:
350:                InputStreamReader reader = null;
351:                // Only pay attention to the {@link #ENCODING_ATTRIB} if parse='text'  
352:                if (element.getAttribute(PARSE_ATTRIB, "xml").equals("text")
353:                        && element.hasAttribute(ENCODING_ATTRIB)) {
354:                    reader = new InputStreamReader(is, element.getAttribute(
355:                            ENCODING_ATTRIB, ""));
356:                } else {
357:                    reader = new InputStreamReader(is);
358:                }
359:
360:                IXMLReader ireader = new StdXMLReader(reader);
361:                ireader.setSystemID(url.toExternalForm());
362:                return ireader;
363:            }
364:
365:            /**
366:             * used to record the system id for this document.
367:             *
368:             * @param systemID the system id of the document being built
369:             * @param lineNr the line number 
370:             */
371:            public void startBuilding(String systemID, int lineNr) {
372:                super.startBuilding(systemID, lineNr);
373:            }
374:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.