Source Code Cross Referenced for Parser.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » compiler » 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 » Ajax » Laszlo 4.0.10 » org.openlaszlo.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *****************************************************************************
002:         * Parser.java
003:         * ****************************************************************************/
004:
005:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006:         * Copyright 2001-2007 Laszlo Systems, Inc.  All Rights Reserved.              *
007:         * Use is subject to license terms.                                            *
008:         * J_LZ_COPYRIGHT_END *********************************************************/
009:
010:        package org.openlaszlo.compiler;
011:
012:        import java.io.*;
013:        import java.lang.*;
014:        import java.util.*;
015:        import org.apache.log4j.Logger;
016:        import org.jdom.Attribute;
017:        import org.jdom.Document;
018:        import org.jdom.Content;
019:        import org.jdom.Element;
020:        import org.jdom.JDOMException;
021:        import org.jdom.Namespace;
022:        import org.jdom.JDOMFactory;
023:        import org.jdom.input.SAXBuilder;
024:        import org.jdom.input.SAXHandler;
025:        import org.jdom.output.SAXOutputter;
026:        import org.jdom.output.XMLOutputter;
027:        import org.xml.sax.InputSource;
028:        import org.xml.sax.SAXException;
029:        import org.xml.sax.XMLFilter;
030:        import org.xml.sax.helpers.XMLFilterImpl;
031:        import org.apache.commons.collections.LRUMap;
032:        import org.openlaszlo.server.*;
033:        import org.openlaszlo.utils.*;
034:        import org.openlaszlo.xml.internal.*;
035:
036:        import javax.xml.transform.TransformerConfigurationException;
037:        import javax.xml.transform.TransformerFactory;
038:        import javax.xml.transform.sax.SAXResult;
039:        import javax.xml.transform.sax.SAXTransformerFactory;
040:        import javax.xml.transform.sax.TransformerHandler;
041:        import javax.xml.transform.stream.StreamSource;
042:
043:        import org.xml.sax.SAXException;
044:
045:        /** Parses and validates an XML file.  XML elements are annotated with
046:         * their source locations.
047:         *
048:         * A new parser should be used for each compilation, but shared across
049:         * all XML file reads within a compilation.  This assures that the
050:         * parser caches are active during compilation, but are not reused
051:         * for subsequent compilations when the file may have been modified.
052:         */
053:        public class Parser {
054:            private static Logger mLogger = Logger.getLogger(Parser.class);
055:            private static Logger mPostTransformationLogger = Logger
056:                    .getLogger("postTransformation");
057:            private static Logger mPreValidationLogger = Logger
058:                    .getLogger("preValidation");
059:            static public Namespace sNamespace = Namespace
060:                    .getNamespace("http://www.laszlosystems.com/2003/05/lzx");
061:
062:            protected FileResolver resolver = FileResolver.DEFAULT_FILE_RESOLVER;
063:
064:            /** Map(File, Document) */
065:            protected final Map fileCache = new HashMap();
066:            /** List<String>. Pathnames in messages are reported relative to
067:             * one of these. */
068:            List basePathnames = new Vector();
069:
070:            // Stylesheet templates and generators for updating old
071:            // namespaces, and adding namespace declarations.
072:            private static javax.xml.transform.Templates sPreprocessorTemplates;
073:            private static SAXTransformerFactory sSaxFactory;
074:            private static long sPreprocessorLastModified;
075:
076:            protected static synchronized SAXTransformerFactory getSaxFactory() {
077:                String stylePath = LPS.HOME().replace('\\', '/') + "/"
078:                        + "WEB-INF" + "/" + "lps" + "/" + "schema" + "/"
079:                        + "preprocess.xsl";
080:                File styleFile = new File(stylePath);
081:                long lastModified = styleFile.lastModified();
082:
083:                if (sSaxFactory != null
084:                        && sPreprocessorLastModified == lastModified)
085:                    return sSaxFactory;
086:
087:                // name the class instead of using
088:                // TransformerFactory.newInstance(), to insure that we get
089:                // saxon and thereby work around a failure on Tomcat 5 w/ jdk
090:                // 1.4.2 Linux, and w/ Sun 1.4.1_05
091:                javax.xml.transform.TransformerFactory factory = new com.icl.saxon.TransformerFactoryImpl();
092:
093:                javax.xml.transform.Templates templates = null;
094:                try {
095:                    templates = factory.newTemplates(new StreamSource(
096:                            "file:///" + stylePath));
097:                } catch (TransformerConfigurationException e) {
098:                    throw new ChainedException(e);
099:                }
100:
101:                if (!factory.getFeature(SAXTransformerFactory.FEATURE))
102:                    throw new RuntimeException(
103:                    /* (non-Javadoc)
104:                     * @i18n.test
105:                     * @org-mes="TransformerFactory doesn't implement SAXTransformerFactory"
106:                     */
107:                    org.openlaszlo.i18n.LaszloMessages.getMessage(Parser.class
108:                            .getName(), "051018-107"));
109:
110:                SAXTransformerFactory saxFactory = (SAXTransformerFactory) factory;
111:
112:                sSaxFactory = saxFactory;
113:                sPreprocessorTemplates = templates;
114:                sPreprocessorLastModified = lastModified;
115:                return saxFactory;
116:            }
117:
118:            public Parser() {
119:            }
120:
121:            public void setResolver(FileResolver resolver) {
122:                this .resolver = resolver;
123:            }
124:
125:            /** Returns the pathname to use in user error messages.  This is
126:             * the shortest pathname relative to a directory on the search
127:             * path for this application.
128:             */
129:            public String getUserPathname(String pathname) {
130:                String sourceDir = new File(pathname).getParent();
131:                if (sourceDir == null)
132:                    sourceDir = "";
133:                sourceDir = sourceDir.replace(File.separatorChar, '/');
134:                String best = pathname.replace(File.separatorChar, '/');
135:                int bestLength = StringUtils.split(best, "/").length;
136:                for (Iterator iter = basePathnames.iterator(); iter.hasNext();) {
137:                    String item = (String) iter.next();
138:                    String base = item.replace(File.separatorChar, '/');
139:                    try {
140:                        String candidate = FileUtils.adjustRelativePath(
141:                                new File(pathname).getName(), base, sourceDir);
142:                        int candidateLength = StringUtils.split(candidate, "/").length;
143:                        if (candidateLength < bestLength) {
144:                            best = candidate;
145:                            bestLength = candidateLength;
146:                        }
147:                    } catch (FileUtils.RelativizationError e) {
148:                        // If it can't be relativized, it simply doesn't produce
149:                        // a candidate, and we do nothing.
150:                    }
151:                }
152:                return best;
153:            }
154:
155:            /** Reads an XML document and adds source location information to
156:             * the elements. */
157:            public Document read(File file) throws JDOMException, IOException {
158:                // See if we've already read the file.  This is an
159:                // optimization, and also assures that the same content is
160:                // used across passes.  We don't need to (and shouldn't) check
161:                // the date, since the cache is an instance variable, and each
162:                // compiler invocation uses a fresh parser.
163:                File key = file.getCanonicalFile();
164:                if (fileCache.containsKey(key)) {
165:                    return (Document) fileCache.get(key);
166:                }
167:
168:                // Use a custom subclass of SAXBuilder to build a JDOM tree
169:                // containing custom Elements which contain source file
170:                // location info (ElementWithLocationInfo).
171:
172:                // The following variables are used to add source location
173:                // that reflects the input name, while the system identifier
174:                // has been made absolute.
175:                final String pathname = file.getPath();
176:                final String messagePathname = getUserPathname(pathname);
177:
178:                // This is a ContentHandler which adds source location info to
179:                // our own custom class of jdom.Element
180:                class SourceLocatorHandler extends org.jdom.input.SAXHandler {
181:                    org.xml.sax.Locator locator;
182:                    int startLineNumber;
183:                    int startColumnNumber;
184:                    Element currentElement;
185:
186:                    SourceLocatorHandler() throws IOException {
187:                    }
188:
189:                    SourceLocatorHandler(JDOMFactory factory)
190:                            throws IOException {
191:                        super (factory);
192:                    }
193:
194:                    public void characters(char[] ch, int start, int length)
195:                            throws SAXException {
196:                        startLineNumber = locator.getLineNumber();
197:                        startColumnNumber = locator.getColumnNumber();
198:                        super .characters(ch, start, length);
199:                    }
200:
201:                    public void endElement(String namespaceURI,
202:                            String localName, String qName) throws SAXException {
203:                        // You can only call this.getCurrentElement() before
204:                        // super.endElement
205:
206:                        // Save source location info for reporting compilation errors
207:                        saveEndLocation(this .getCurrentElement(), pathname,
208:                                messagePathname, locator.getLineNumber(),
209:                                locator.getColumnNumber());
210:
211:                        super .endElement(namespaceURI, localName, qName);
212:                    }
213:
214:                    public void setDocumentLocator(org.xml.sax.Locator locator) {
215:                        this .locator = locator;
216:                    }
217:
218:                    public void startElement(String namespaceURI,
219:                            String localName, String qName,
220:                            org.xml.sax.Attributes atts) throws SAXException {
221:                        super 
222:                                .startElement(namespaceURI, localName, qName,
223:                                        atts);
224:
225:                        // You can only call this.getCurrentElement() after
226:                        // super.startElement
227:
228:                        // Save source location info for reporting compilation errors
229:                        saveStartLocation(this .getCurrentElement(), pathname,
230:                                messagePathname, locator.getLineNumber(),
231:                                locator.getColumnNumber());
232:                    }
233:                }
234:
235:                /* We need a SAXBuilder that uses our custom Factory and
236:                   ContentHandler classes, but the stock
237:                   org.jdom.input.SAXBuilder has no API for setting which
238:                   ContentHandler is used.
239:
240:                   To get what we need, we create a subclass of SAXBuilder
241:                   and override the createContentHandler method to
242:                   instantiate our custom handler with our custom factory . 
243:                 */
244:                class SourceLocatorSAXBuilder extends SAXBuilder {
245:                    SourceLocatorSAXBuilder(String saxDriverClass) {
246:                        super (saxDriverClass);
247:                    }
248:
249:                    SourceLocatorSAXBuilder() {
250:                        super ();
251:                    }
252:
253:                    // We need to create our own special contentHandler,
254:                    // and you *must* pass the factory to the SaxHandler
255:                    // constructor, or else you get a default JDOM
256:                    // factory, which is not what you want!
257:                    protected org.jdom.input.SAXHandler createContentHandler() {
258:                        try {
259:                            return new SourceLocatorHandler(getFactory());
260:                        } catch (IOException e) {
261:                            throw new ChainedException(e);
262:                        }
263:                    }
264:                }
265:
266:                //SAXBuilder builder = new SourceLocatorSAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
267:                SAXBuilder builder = new SourceLocatorSAXBuilder();
268:                builder.setFactory(new SourceLocatorJDOMFactory());
269:
270:                // ignore DOCTYPE declarations TODO [2004-25-05 ows]: parse
271:                // entity references from internal declarations, and either
272:                // warn about external declarations or add them to the
273:                // dependency information.  If the latter, use a library to
274:                // cache and resolve non-file sources against a catalog file.
275:                builder
276:                        .setEntityResolver(new org.xml.sax.helpers.DefaultHandler() {
277:                            public InputSource resolveEntity(String publicId,
278:                                    String systemId) {
279:                                return new InputSource(new StringReader(""));
280:                            }
281:                        });
282:
283:                // Parse the document
284:                java.io.Reader reader = FileUtils.makeXMLReaderForFile(key
285:                        .getPath(), "UTF-8");
286:                InputSource source = new InputSource(reader);
287:                source.setPublicId(messagePathname);
288:                source.setSystemId(key.getPath());
289:                Document doc = builder.build(source);
290:                reader.close();
291:                fileCache.put(key, doc);
292:                return doc;
293:            }
294:
295:            protected Document preprocess(final Document sourceDoc)
296:                    throws java.io.IOException, org.jdom.JDOMException {
297:                // Fills location information from the metasource attribute.
298:                class SourceLocatorHandler extends org.jdom.input.SAXHandler {
299:                    SourceLocatorHandler() throws IOException {
300:                    }
301:
302:                    SourceLocatorHandler(JDOMFactory factory)
303:                            throws IOException {
304:                        super (factory);
305:                    }
306:
307:                    public void endElement(String namespaceURI,
308:                            String localName, String qName) throws SAXException {
309:                        ElementWithLocationInfo element = (ElementWithLocationInfo) this 
310:                                .getCurrentElement();
311:                        Attribute attr = element
312:                                .getAttribute(SourceLocatorSAXOutputter.SOURCEINFO_ATTRIBUTE_NAME);
313:                        if (attr != null) {
314:                            SourceLocator locator = SourceLocator
315:                                    .fromString(attr.getValue());
316:                            element.initSourceLocator(locator);
317:                            element.removeAttribute(attr);
318:                        }
319:                        super .endElement(namespaceURI, localName, qName);
320:                    }
321:                }
322:
323:                // Create a transformer that implements the 'preprocess'
324:                // transformation.
325:                TransformerHandler handler;
326:                try {
327:                    handler = getSaxFactory().newTransformerHandler(
328:                            sPreprocessorTemplates);
329:                } catch (TransformerConfigurationException e) {
330:                    throw new ChainedException(e);
331:                }
332:
333:                SAXHandler resultHandler = new SourceLocatorHandler(
334:                        new SourceLocatorJDOMFactory());
335:                SAXResult result = new javax.xml.transform.sax.SAXResult(
336:                        resultHandler);
337:                handler.setResult(result);
338:
339:                SourceLocatorSAXOutputter outputter = new SourceLocatorSAXOutputter();
340:                outputter.setWriteMetaData(true);
341:                outputter.setContentHandler(handler);
342:                outputter.output(sourceDoc);
343:
344:                Document resultDoc = resultHandler.getDocument();
345:
346:                if (mPostTransformationLogger.isDebugEnabled()) {
347:                    org.jdom.output.XMLOutputter xmloutputter = new org.jdom.output.XMLOutputter();
348:                    mPostTransformationLogger.debug(xmloutputter
349:                            .outputString(resultDoc));
350:                }
351:
352:                return resultDoc;
353:            }
354:
355:            /** Reads the XML document, and modifies it by replacing each
356:             * include element by the root of the expanded document named by
357:             * the include's href attribute. Pathames are resolved relative to
358:             * the element's source location.  If a pathname resolves to the
359:             * current file or a file in the set that's passed as the second
360:             * argument, a compilation error is thrown.  A copy of the set of
361:             * pathnames that additionally includes the current file is passed
362:             * to each recursive call.  (Since the set has stacklike behavior,
363:             * a cons list would be appropriate, but I don't think Java has
364:             * one.)
365:             *
366:             * This is a helper function for parse(), which is factored out
367:             * so that expandIncludes can be apply it recursively to included
368:             * files. */
369:            protected Document readExpanded(File file, Set currentFiles,
370:                    CompilationEnvironment env) throws IOException,
371:                    JDOMException {
372:                File key = file.getCanonicalFile();
373:                if (currentFiles.contains(key)) {
374:                    throw new CompilationError(
375:                    /* (non-Javadoc)
376:                     * @i18n.test
377:                     * @org-mes=p[0] + " includes itself."
378:                     */
379:                    org.openlaszlo.i18n.LaszloMessages.getMessage(Parser.class
380:                            .getName(), "051018-394", new Object[] { file }));
381:                }
382:                Set newCurrentFiles = new HashSet(currentFiles);
383:                newCurrentFiles.add(key);
384:                Document doc = read(file);
385:                Element root = doc.getRootElement();
386:                expandIncludes(root, newCurrentFiles, env);
387:                return doc;
388:            }
389:
390:            static final String WHEN = "when";
391:            static final String OTHERWISE = "otherwise";
392:
393:            protected boolean evaluateConditions(Element element,
394:                    CompilationEnvironment env) {
395:                if (element.getAttribute("runtime") != null
396:                        && !element.getAttributeValue("runtime").equals(
397:                                env.getRuntime())) {
398:                    return false;
399:                }
400:                return true;
401:            }
402:
403:            public static String xmltostring(Element e) {
404:                org.jdom.output.XMLOutputter outputter = new org.jdom.output.XMLOutputter();
405:                return outputter.outputString(e);
406:            }
407:
408:            protected void expandChildrenIncludes(Element element,
409:                    Set currentFiles, CompilationEnvironment env)
410:                    throws IOException, JDOMException {
411:                for (Iterator iter = element.getChildren().iterator(); iter
412:                        .hasNext();) {
413:                    Element child = (Element) iter.next();
414:                    expandIncludes(child, currentFiles, env);
415:                }
416:            }
417:
418:            /*
419:              <switch>  
420:                 <when runtime="swf8">
421:                  <view .../>
422:                </when>
423:                <otherwise >
424:                  <view .../>
425:                </otherwise>
426:              </switch>
427:
428:              returns the child list of the active arm of the <switch>
429:
430:             */
431:            protected List evaluateSwitchStatement(Element elt,
432:                    CompilationEnvironment env) {
433:                Element selected = null;
434:                for (Iterator iter = elt.getChildren(WHEN, elt.getNamespace())
435:                        .iterator(); iter.hasNext();) {
436:                    Element when = (Element) iter.next();
437:                    if (evaluateConditions(when, env)) {
438:                        selected = when;
439:                        break;
440:                    }
441:                }
442:                if (selected == null) {
443:                    for (Iterator iter = elt.getChildren(OTHERWISE,
444:                            elt.getNamespace()).iterator(); iter.hasNext();) {
445:                        Element other = (Element) iter.next();
446:                        selected = other;
447:                        break;
448:                    }
449:                }
450:                if (selected == null) {
451:                    return new ArrayList();
452:                } else {
453:                    return selected.cloneContent();
454:                }
455:            }
456:
457:            // Makes a copy of the element's child list.
458:            protected List copyChildList(Element element) {
459:                ArrayList children = new ArrayList();
460:                for (Iterator iter = element.getChildren().iterator(); iter
461:                        .hasNext();) {
462:                    Element child = (Element) iter.next();
463:                    children.add(child);
464:                }
465:                return children;
466:            }
467:
468:            /** Replaces include statements by the content of the included
469:             * file.
470:             *
471:             * This is a helper function for readExpanded, which is factored
472:             * out so that readExpanded can apply it recursively to included
473:             * files. */
474:            protected void expandIncludes(Element element, Set currentFiles,
475:                    CompilationEnvironment env) throws IOException,
476:                    JDOMException {
477:                // Copy the child list, to avoid the concurrentModificationError problem
478:                // we get if we use the getChildren list directly. 
479:                List children = copyChildList(element);
480:
481:                // expand (replace) any <switch> elements with only the selected arm of the
482:                // <switch>
483:                for (Iterator iter = children.iterator(); iter.hasNext();) {
484:                    Element child = (Element) iter.next();
485:                    if (child.getName().equals("switch")) {
486:                        List goodies = evaluateSwitchStatement(child, env);
487:                        // splice these in place of the <switch>
488:                        int index = element.indexOf(child);
489:                        element.setContent(index, goodies);
490:                    }
491:                }
492:
493:                // Get a new copy of the children list, with expanded <switch> elements from above.
494:                children = copyChildList(element);
495:
496:                for (Iterator iter = children.iterator(); iter.hasNext();) {
497:                    Element child = (Element) iter.next();
498:
499:                    if (child.getName().equals("include")) {
500:                        String base = new File(getSourcePathname(element))
501:                                .getParent();
502:                        String type = XMLUtils.getAttributeValue(child, "type",
503:                                "xml");
504:                        String href = child.getAttributeValue("href");
505:                        if (href == null) {
506:                            throw new CompilationError(
507:                            /* (non-Javadoc)
508:                             * @i18n.test
509:                             * @org-mes="The <include> element requires an \"href\" attribute."
510:                             */
511:                            org.openlaszlo.i18n.LaszloMessages.getMessage(
512:                                    Parser.class.getName(), "051018-438"),
513:                                    child);
514:                        }
515:                        File target = resolver.resolve(href, base, true);
516:                        // If this file is already implicitly included, just
517:                        // leave it, don't try to expand it.  It will be
518:                        // skipped at the compilation stage.
519:                        if (resolver.getBinaryIncludes().contains(target)) {
520:                            continue;
521:                        }
522:                        if (type.equals("text")) {
523:                            List content = element.getContent();
524:                            int index = content.indexOf(child);
525:                            content.set(index, new org.jdom.Text(FileUtils
526:                                    .readFileString(target, "UTF-8")));
527:                        } else if (type.equals("xml")) {
528:                            // Pass the target, not the key, so that source
529:                            // location information is correct.
530:                            //System.err.println("including xml "+target);
531:                            Document doc = read(target);
532:                            // If it's a top-level library, the compiler will
533:                            // process it during the compilation phase.  In
534:                            // that case change it to a <library href=""/>
535:                            // element, where the href is the <include>'s
536:                            // href, so that LibraryCompiler can resolve it.
537:                            //
538:                            // Otherwise replace the <include> element with
539:                            // the included file.
540:                            if (CompilerUtils.isAtToplevel(child)
541:                                    && LibraryCompiler.isElement(doc
542:                                            .getRootElement())) {
543:                                // Modify the existing element instead of
544:                                // creating a new one, so that source location
545:                                // information is preserved.
546:                                child.setName(doc.getRootElement().getName());
547:                            } else {
548:                                doc = readExpanded(target, currentFiles, env);
549:
550:                                // replace the <include> child element with the expanded file contents
551:                                List content = element.getContent();
552:                                int index = content.indexOf(child);
553:                                Element root = doc.getRootElement();
554:                                root.detach();
555:                                content.set(index, root);
556:
557:                                File key = target.getCanonicalFile();
558:                                fileCache.remove(key);
559:                            }
560:                        } else {
561:                            throw new CompilationError(
562:                            /* (non-Javadoc)
563:                             * @i18n.test
564:                             * @org-mes="include type must be xml or text"
565:                             */
566:                            org.openlaszlo.i18n.LaszloMessages.getMessage(
567:                                    Parser.class.getName(), "051018-485"));
568:                        }
569:                    } else {
570:                        expandIncludes(child, currentFiles, env);
571:                    }
572:                }
573:            }
574:
575:            /** Reads an XML file, expands includes, and validates it.
576:             */
577:            public Document parse(File file, CompilationEnvironment env)
578:                    throws CompilationError {
579:                String pathname = file.getPath();
580:                try {
581:                    Document doc = readExpanded(file, new HashSet(), env);
582:                    // Apply the stylesheet
583:                    doc = preprocess(doc);
584:                    return doc;
585:                } catch (IOException e) {
586:                    CompilationError ce = new CompilationError(e);
587:                    ce.initPathname(pathname);
588:                    throw ce;
589:                } catch (JDOMException e) {
590:                    String solution = SolutionMessages.findSolution(e
591:                            .getMessage(), SolutionMessages.PARSER);
592:                    CompilationError ce = new CompilationError(e, solution);
593:                    throw ce;
594:
595:                }
596:            }
597:
598:            /** Cache of compiled schema verifiers.  Type Map<String,
599:             * org.iso_relax.verifier.Schema>, where the key is the string
600:             * serialization of the schema.  */
601:            private static LRUMap mSchemaCache = new LRUMap(1);
602:
603:            void saveStartLocation(Element elt, String pathname,
604:                    String messagePathname, int startLineNumber,
605:                    int startColumnNumber) {
606:                SourceLocator info = ((ElementWithLocationInfo) elt).locator;
607:                info.setPathname(pathname, messagePathname);
608:                info.startLineNumber = startLineNumber;
609:                info.startColumnNumber = startColumnNumber;
610:            }
611:
612:            void saveEndLocation(Element elt, String pathname,
613:                    String messagePathname, int endLineNumber,
614:                    int endColumnNumber) {
615:                SourceLocator info = ((ElementWithLocationInfo) elt).locator;
616:                info.setPathname(pathname, messagePathname);
617:                info.endLineNumber = endLineNumber;
618:                info.endColumnNumber = endColumnNumber;
619:            }
620:
621:            /* Implement source location, on top of metadata */
622:            static final int LINENO = 1;
623:            static final int COLNO = 2;
624:
625:            static String getSourcePathname(Element elt) {
626:                SourceLocator info = ((ElementWithLocationInfo) elt).locator;
627:                return info.pathname;
628:            }
629:
630:            static String getSourceMessagePathname(Element elt) {
631:                SourceLocator info = ((ElementWithLocationInfo) elt).locator;
632:                return info.messagePathname;
633:            }
634:
635:            static Integer getSourceLocation(Element elt, int coord,
636:                    boolean start) {
637:                if (elt == null) {
638:                    return null;
639:                    // +++ should we throw an error if elt == null?
640:                }
641:
642:                SourceLocator info = ((ElementWithLocationInfo) elt).locator;
643:
644:                if (coord == LINENO) {
645:                    return new Integer(start ? info.startLineNumber
646:                            : info.endLineNumber);
647:                } else {
648:                    return new Integer(start ? info.startColumnNumber
649:                            : info.endColumnNumber);
650:                }
651:            }
652:
653:            static Integer getSourceLocation(Element elt, int coord) {
654:                return getSourceLocation(elt, coord, true);
655:            }
656:
657:            class SourceLocatorJDOMFactory extends org.jdom.DefaultJDOMFactory {
658:
659:                public SourceLocatorJDOMFactory() {
660:                    super ();
661:                }
662:
663:                public Element element(String name) {
664:                    return new ElementWithLocationInfo(name);
665:                }
666:
667:                public Element element(String name, Namespace namespace) {
668:                    return new ElementWithLocationInfo(name, namespace);
669:                }
670:
671:                public Element element(String name, String uri) {
672:                    return new ElementWithLocationInfo(name, uri);
673:                }
674:
675:                public Element element(String name, String prefix, String uri) {
676:                    return new ElementWithLocationInfo(name, prefix, uri);
677:                }
678:            }
679:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.