Source Code Cross Referenced for ViewSchema.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:         * ViewSchema.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.util.*;
014:        import org.apache.oro.text.regex.*;
015:        import org.jdom.Document;
016:        import org.jdom.Attribute;
017:        import org.jdom.Element;
018:        import org.jdom.Namespace;
019:        import org.jdom.output.XMLOutputter;
020:        import org.jdom.input.SAXBuilder;
021:        import org.jdom.JDOMException;
022:        import org.openlaszlo.xml.internal.Schema;
023:        import org.openlaszlo.xml.internal.XMLUtils;
024:        import org.openlaszlo.utils.ChainedException;
025:        import org.openlaszlo.server.*;
026:
027:        /** A schema that describes a Laszlo XML file. */
028:        public class ViewSchema extends Schema {
029:            private static final Set sInputTextElements = new HashSet();
030:            private static final Set sHTMLContentElements = new HashSet();
031:
032:            /** The location of the Laszlo LFC bootstrap interface declarations file  */
033:            private final String SCHEMA_PATH = LPS.HOME() + File.separator
034:                    + "WEB-INF" + File.separator + "lps" + File.separator
035:                    + "schema" + File.separator + "lfc.lzx";
036:
037:            private Document schemaDOM = null;
038:
039:            private static Document sCachedSchemaDOM;
040:            private static long sCachedSchemaLastModified;
041:
042:            /** Default table of attribute name -> typecode */
043:            private static final Map sAttributeTypes = new HashMap();
044:
045:            /** Mapping of RNG type names -> LPS Types */
046:            private static final Map sRNGtoLPSTypeMap = new HashMap();
047:
048:            /** {String} */
049:            private static final Set sMouseEventAttributes;
050:
051:            /** Maps a class (name) to its ClassModel. Holds info about
052:             * attribute/types for each class, as well as pointer to the
053:             * superclass if any.
054:             */
055:            private final Map mClassMap = new HashMap();
056:
057:            /**
058:             * If true, requires class names to be valid javascript identifiers.
059:             * We disable this when defining LZX builtin tags such as "import"
060:             * which are reserved javascript tokens.
061:             */
062:            public boolean enforceValidIdentifier = false;
063:
064:            /** Type of script expressions. */
065:            public static final Type EXPRESSION_TYPE = newType("expression");
066:
067:            /** 'boolean' is compiled the same as an expression type */
068:            public static final Type BOOLEAN_TYPE = newType("boolean");
069:
070:            public static final Type REFERENCE_TYPE = newType("reference");
071:            /** Type of event handler bodies. */
072:            public static final Type EVENT_HANDLER_TYPE = newType("script");
073:
074:            /** Type of attribute setter function */
075:            public static final Type SETTER_TYPE = newType("setter");
076:
077:            /** Type of tokens. */
078:            public static final Type TOKEN_TYPE = newType("token");
079:            public static final Type COLOR_TYPE = newType("color");
080:            public static final Type NUMBER_EXPRESSION_TYPE = newType("numberExpression");
081:            public static final Type SIZE_EXPRESSION_TYPE = newType("size");
082:            public static final Type CSS_TYPE = newType("css");
083:            public static final Type INHERITABLE_BOOLEAN_TYPE = newType("inheritableBoolean");
084:            public static final Type XML_LITERAL = newType("xmlLiteral");
085:            public static final Type METHOD_TYPE = newType("method");
086:
087:            static {
088:
089:                sHTMLContentElements.add("text");
090:                sInputTextElements.add("inputtext");
091:
092:                // from http://www.w3.org/TR/REC-html40/interact/scripts.html
093:                String[] mouseEventAttributes = { "onclick", "ondblclick",
094:                        "onmousedown", "onmouseup", "onmouseover",
095:                        "onmousemove", "onmouseout" };
096:                String[] eventAttributes = { "onkeypress", "onstart", "onstop",
097:                        "onfocus", "onblur", "onkeydown", "onkeyup",
098:                        "onsubmit", "onreset", "onselect", "onchange",
099:                        "oninit", "onerror", "ondata", "ontimeout",
100:                        "oncommand", "onapply", "onremove" };
101:                setAttributeTypes(mouseEventAttributes, EVENT_HANDLER_TYPE);
102:                setAttributeTypes(eventAttributes, EVENT_HANDLER_TYPE);
103:                sMouseEventAttributes = new HashSet(Arrays
104:                        .asList(mouseEventAttributes));
105:            }
106:
107:            private static final String AUTOINCLUDES_PROPERTY_FILE = LPS
108:                    .getMiscDirectory()
109:                    + File.separator + "lzx-autoincludes.properties";
110:            public static final Properties sAutoincludes = new Properties();
111:
112:            static {
113:                try {
114:                    InputStream is = new FileInputStream(
115:                            AUTOINCLUDES_PROPERTY_FILE);
116:                    try {
117:                        sAutoincludes.load(is);
118:                    } finally {
119:                        is.close();
120:                    }
121:                } catch (java.io.IOException e) {
122:                    throw new ChainedException(e);
123:                }
124:            }
125:
126:            /** Set the attributes to the type.
127:             * @param attributes a list of attributes
128:             * @param type a type
129:             */
130:            private static void setAttributeTypes(String[] attributes, Type type) {
131:                for (int i = 0; i < attributes.length; i++) {
132:                    sAttributeTypes.put(attributes[i].intern(), type);
133:                }
134:            }
135:
136:            public AttributeSpec findSimilarAttribute(String className,
137:                    String attributeName) {
138:                ClassModel info = getClassModel(className);
139:
140:                if (info != null) {
141:                    return info.findSimilarAttribute(attributeName);
142:                } else {
143:                    // Check other classes....
144:                    return null;
145:                }
146:            }
147:
148:            /** Set the attribute to the given type, for a specific element */
149:            public void setAttributeType(Element elt, String classname,
150:                    String attrName, AttributeSpec attrspec) {
151:                ClassModel classModel = getClassModel(classname);
152:                if (classModel == null) {
153:                    throw new RuntimeException(
154:                    /* (non-Javadoc)
155:                     * @i18n.test
156:                     * @org-mes="undefined class: " + p[0]
157:                     */
158:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
159:                            ViewSchema.class.getName(), "051018-168",
160:                            new Object[] { classname }));
161:                }
162:                if (classModel.attributeSpecs.get(attrName) != null) {
163:                    throw new CompilationError(
164:                    /* (non-Javadoc)
165:                     * @i18n.test
166:                     * @org-mes="duplicate definition of attribute " + p[0] + "." + p[1]
167:                     */
168:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
169:                            ViewSchema.class.getName(), "051018-178",
170:                            new Object[] { classname, attrName }), elt);
171:                }
172:                classModel.attributeSpecs.put(attrName, attrspec);
173:
174:                if (attrName.equals("text")) {
175:                    classModel.supportsTextAttribute = true;
176:                }
177:            }
178:
179:            /** Checks to do when declaring a method on a class;
180:             * Does the class exist?
181:             * Is this a duplicate of another method declaration on this class?
182:             * Does the superclass allow overriding of this method?
183:             */
184:            public void checkMethodDeclaration(Element elt, String classname,
185:                    String methodName, CompilationEnvironment env) {
186:                ClassModel classModel = getClassModel(classname);
187:                if (classModel == null) {
188:                    throw new RuntimeException(
189:                    /* (non-Javadoc)
190:                     * @i18n.test
191:                     * @org-mes="undefined class: " + p[0]
192:                     */
193:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
194:                            ViewSchema.class.getName(), "051018-168",
195:                            new Object[] { classname }));
196:                }
197:                AttributeSpec localAttr = classModel
198:                        .getLocalAttribute(methodName);
199:                if (localAttr != null) {
200:                    if (localAttr.type == METHOD_TYPE) {
201:                        env.warn(
202:                        /* (non-Javadoc)
203:                         * @i18n.test
204:                         * @org-mes="duplicate definition of method " + p[0] + "." + p[1]
205:                         */
206:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
207:                                ViewSchema.class.getName(), "051018-207",
208:                                new Object[] { classname, methodName }), elt);
209:                    } else {
210:                        env.warn("Method named " + methodName + " on class "
211:                                + classname
212:                                + " conflicts with attribute with named "
213:                                + methodName + " and type " + localAttr.type,
214:                                elt);
215:                    }
216:                }
217:
218:                if (!methodOverrideAllowed(classname, methodName)) {
219:                    env
220:                            .warn(
221:                                    "Method "
222:                                            + classname
223:                                            + "."
224:                                            + methodName
225:                                            + " is overriding a superclass method"
226:                                            + " of the same name which has been declared non-overridable",
227:                                    elt);
228:                }
229:            }
230:
231:            /** Checks to do when declaring a method on an instance;
232:             * Does the class exist?
233:             * Does the superclass allow overriding of this method?
234:             */
235:            public void checkInstanceMethodDeclaration(Element elt,
236:                    String classname, String methodName,
237:                    CompilationEnvironment env) {
238:                ClassModel classModel = getClassModel(classname);
239:                if (classModel == null) {
240:                    throw new RuntimeException(
241:                    /* (non-Javadoc)
242:                     * @i18n.test
243:                     * @org-mes="undefined class: " + p[0]
244:                     */
245:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
246:                            ViewSchema.class.getName(), "051018-168",
247:                            new Object[] { classname }));
248:                }
249:                AttributeSpec attrspec = classModel.getAttribute(methodName);
250:                if (attrspec != null) {
251:                    if (attrspec.type != METHOD_TYPE) {
252:                        env.warn("Method named " + methodName + " on class "
253:                                + classname
254:                                + " conflicts with attribute with named "
255:                                + methodName + " and type " + attrspec.type,
256:                                elt);
257:                    }
258:                }
259:
260:                if (!methodOverrideAllowed(classname, methodName)) {
261:                    env
262:                            .warn(
263:                                    "Method "
264:                                            + classname
265:                                            + "."
266:                                            + methodName
267:                                            + " is overriding a superclass method"
268:                                            + " of the same name which has been declared non-overridable",
269:                                    elt);
270:                }
271:            }
272:
273:            public String getSuperclassName(String className) {
274:                ClassModel model = getClassModel(className);
275:                if (model == null)
276:                    return null;
277:                return model.getSuperclassName();
278:            }
279:
280:            /**
281:             * @return the base class of a user defined class
282:             */
283:            public String getBaseClassname(String className) {
284:                String ancestor = getSuperclassName(className);
285:                String super class = ancestor;
286:
287:                while (ancestor != null) {
288:                    if (ancestor.equals(className)) {
289:                        throw new CompilationError(
290:                        /* (non-Javadoc)
291:                         * @i18n.test
292:                         * @org-mes="recursive class definition on " + p[0]
293:                         */
294:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
295:                                ViewSchema.class.getName(), "051018-235",
296:                                new Object[] { className }));
297:                    }
298:                    super class = ancestor;
299:                    ancestor = getSuperclassName(ancestor);
300:                }
301:                return super class;
302:            }
303:
304:            /** Does this class or its ancestors have this attribute declared for it? */
305:            AttributeSpec getClassAttribute(String classname, String attrName) {
306:                // OK, walk up the superclasses, checking for existence of this attribute
307:                ClassModel info = getClassModel(classname);
308:                if (info == null) {
309:                    return null;
310:                } else {
311:                    return info.getAttribute(attrName);
312:                }
313:            }
314:
315:            /**
316:             * Add a new element to the attribute type map.
317:             *
318:             * @param elt the element to add to the map
319:             * @param superclassName an element to inherit attribute to type info from. May be null.
320:             * @param attributeDefs list of attribute name/type defs
321:             */
322:            public void addElement(Element elt, String className,
323:                    String super className, List attributeDefs,
324:                    CompilationEnvironment env) {
325:                ClassModel super class = getClassModel(super className);
326:
327:                if (super class == null) {
328:                    throw new CompilationError(
329:                    /* (non-Javadoc)
330:                     * @i18n.test
331:                     * @org-mes="undefined superclass " + p[0] + " for class " + p[1]
332:                     */
333:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
334:                            ViewSchema.class.getName(), "051018-417",
335:                            new Object[] { super className, className }));
336:                }
337:
338:                if (mClassMap.get(className) != null) {
339:                    String builtin = "builtin ";
340:                    String also = "";
341:                    Element other = getClassModel(className).definition;
342:                    if (other != null) {
343:                        builtin = "";
344:                        also = "; also defined at "
345:                                + Parser.getSourceMessagePathname(other)
346:                                + ":"
347:                                + Parser
348:                                        .getSourceLocation(other, Parser.LINENO);
349:                    }
350:                    throw new CompilationError(
351:                    /* (non-Javadoc)
352:                     * @i18n.test
353:                     * @org-mes="duplicate class definitions for " + p[0] + p[1] + p[2]
354:                     */
355:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
356:                            ViewSchema.class.getName(), "051018-435",
357:                            new Object[] { builtin, className, also }), elt);
358:                }
359:                ClassModel info = new ClassModel(className, super class, this ,
360:                        elt);
361:                mClassMap.put(className, info);
362:
363:                if (sInputTextElements.contains(super className)) {
364:                    info.isInputText = true;
365:                    info.hasInputText = true;
366:                } else {
367:                    info.isInputText = super class.isInputText;
368:                    info.hasInputText = super class.hasInputText;
369:                }
370:
371:                info.supportsTextAttribute = super class.supportsTextAttribute;
372:
373:                // Loop over containsElements tags, adding to containment table in classmodel
374:                Iterator iterator = elt.getChildren().iterator();
375:                while (iterator.hasNext()) {
376:                    Element child = (Element) iterator.next();
377:                    if (child.getName().equals("containsElements")) {
378:                        // look for <element>tagname</element> 
379:                        Iterator iter1 = child.getChildren().iterator();
380:                        while (iter1.hasNext()) {
381:                            Element etag = (Element) iter1.next();
382:                            if (etag.getName().equals("element")) {
383:                                String tagname = etag.getText();
384:                                info.addContainsElement(tagname);
385:                            } else {
386:                                throw new CompilationError(
387:                                        "containsElement block must only contain <element> tags",
388:                                        etag);
389:                            }
390:                        }
391:                    }
392:                }
393:
394:                // Add in the attribute declarations
395:                addAttributeDefs(elt, className, attributeDefs, env);
396:            }
397:
398:            /**
399:             * Add this list of attribute name/type info to the in-core model of the class definitions.
400:             *
401:             * @param sourceElement the user's LZX source file element that holds class LZX definition 
402:             * @param classname the class we are defining
403:             * @param attributeDefs list of AttributeSpec attribute info to add to the Schema
404:             *
405:             */
406:            void addAttributeDefs(Element sourceElement, String classname,
407:                    List attributeDefs, CompilationEnvironment env) {
408:                if (!attributeDefs.isEmpty()) {
409:                    for (Iterator iter = attributeDefs.iterator(); iter
410:                            .hasNext();) {
411:                        AttributeSpec attr = (AttributeSpec) iter.next();
412:
413:                        // If this attribute does not already occur someplace
414:                        // in an ancestor, then let's add it to the schema.
415:                        //
416:                        // While we're here, we need to check that we aren't
417:                        // redefining an attribute of a parent class with a
418:                        // different type.
419:
420:                        Type parentType = null;
421:                        if (getClassAttribute(classname, attr.name) != null) {
422:                            // Check that the overriding type is the same as the superclass' type
423:                            parentType = getAttributeType(classname, attr.name);
424:
425:                            // Does the parent attribute definition assert override=true?
426:                            // If so, we're not going to warn if the types mismatch.
427:                            AttributeSpec parentAttrSpec = getAttributeSpec(
428:                                    classname, attr.name);
429:                            boolean forceOverride = parentAttrSpec != null
430:                                    && "true".equals(parentAttrSpec.override);
431:
432:                            if (!forceOverride && (parentType != attr.type)) {
433:                                // get the parent attribute, so we can see if it says override is allowed
434:
435:                                env.warn(/* (non-Javadoc)
436:                                 * @i18n.test
437:                                 * @org-mes="In class '" + p[0] + "' attribute '" + p[1] + "' with type '" + p[2] + "' is overriding superclass attribute with same name but different type: " + p[3]
438:                                 */
439:                                org.openlaszlo.i18n.LaszloMessages.getMessage(
440:                                        ViewSchema.class.getName(),
441:                                        "051018-364", new Object[] { classname,
442:                                                attr.name,
443:                                                attr.type.toString(),
444:                                                parentType.toString() }),
445:                                        sourceElement);
446:                            }
447:                        }
448:
449:                        if (attr.type == ViewSchema.METHOD_TYPE
450:                                && !("true".equals(attr.override))) {
451:                            checkMethodDeclaration(sourceElement, classname,
452:                                    attr.name, env);
453:                        }
454:
455:                        // Update the in-memory attribute type table
456:                        setAttributeType(sourceElement, classname, attr.name,
457:                                attr);
458:                    }
459:                }
460:            }
461:
462:            public Type getTypeForName(String name) {
463:                if (name.equals("text") || name.equals("html"))
464:                    name = "string";
465:                return super .getTypeForName(name);
466:            }
467:
468:            /** Adds a ClassModel entry into the class table for CLASSNAME. */
469:            private void makeNewStaticClass(String classname) {
470:                ClassModel info = new ClassModel(classname, this );
471:                if (sInputTextElements.contains(classname)) {
472:                    info.isInputText = true;
473:                    info.hasInputText = true;
474:                }
475:                if (mClassMap.get(classname) == null) {
476:                    mClassMap.put(classname, info);
477:                } else {
478:                    throw new CompilationError(
479:                            "makeNewStaticClass: `duplicate definition for static class "
480:                                    + classname);
481:                }
482:            }
483:
484:            static Type getAttributeType(String attrName) {
485:                return (Type) sAttributeTypes.get(attrName);
486:            }
487:
488:            /**
489:             * Returns a value representing the type of an attribute within an
490:             * XML element. Unknown attributes have Expression type.
491:             *
492:             * @param e an Element
493:             * @param attrName an attribute name
494:             * @return a value represting the type of the attribute's
495:             */
496:            public Type getAttributeType(Element e, String attrName) {
497:                return getAttributeType(e.getName(), attrName);
498:            }
499:
500:            /**
501:             * Returns a value representing the type of an attribute within an
502:             * XML element. Unknown attributes have Expression type.
503:             *
504:             * @param elt an Element name
505:             * @param attrName an attribute name
506:             * @return a value represting the type of the attribute's
507:             */
508:            public Type getAttributeType(String elt, String attrName)
509:                    throws UnknownAttributeException {
510:                String elementName = elt.intern();
511:                // +++ This special-case stuff will go away when the RELAX schema
512:                // is automatically translated to ViewSchema initialization
513:                // code.
514:
515:                if (elementName.equals("canvas")) {
516:                    // override NUMBER_EXPRESSION_TYPE, on view
517:                    if (attrName.equals("width") || attrName.equals("height")) {
518:                        return NUMBER_TYPE;
519:                    }
520:                }
521:
522:                Type type = null;
523:
524:                // Look up attribute in type map for this element
525:                ClassModel classModel = getClassModel(elementName);
526:
527:                if (classModel != null) {
528:                    try {
529:                        type = classModel.getAttributeTypeOrException(attrName);
530:                    } catch (UnknownAttributeException e) {
531:                        e.setName(attrName);
532:                        e.setElementName(elt);
533:                        throw e;
534:                    }
535:                } else {
536:                    type = getAttributeType(attrName);
537:                    if (type == null) {
538:                        throw new UnknownAttributeException(elt, attrName);
539:                        //type = EXPRESSION_TYPE;
540:                    }
541:                }
542:                return type;
543:            }
544:
545:            /**
546:             * Finds the AttributeSpec definition of an attribute, on a class
547:             * or by searching up it's parent class chain.
548:             *
549:             * @param elt an Element name
550:             * @param attrName an attribute name
551:             * @return the AttributeSpec or null
552:             */
553:            public AttributeSpec getAttributeSpec(String elt, String attrName) {
554:                String elementName = elt.intern();
555:
556:                // Look up attribute in type map for this element
557:                ClassModel classModel = getClassModel(elementName);
558:
559:                if (classModel != null) {
560:                    return classModel.getAttribute(attrName);
561:                } else {
562:                    return null;
563:                }
564:            }
565:
566:            /**
567:             * checks whether a method with a given method is allowed to be overridden
568:             * @param elt an Element name
569:             * @param methodName a method name
570:             * @return boolean if the method exists on the class or superclass
571:             */
572:            public boolean methodOverrideAllowed(String classname,
573:                    String methodName) {
574:                AttributeSpec methodspec = getClassAttribute(classname,
575:                        methodName);
576:                if (methodspec == null) {
577:                    return true;
578:                } else {
579:                    return !("false".equals(methodspec.override));
580:                }
581:            }
582:
583:            boolean isMouseEventAttribute(String name) {
584:                return sMouseEventAttributes.contains(name);
585:            }
586:
587:            ClassModel getClassModel(String elementName) {
588:                return (ClassModel) mClassMap.get(elementName);
589:            }
590:
591:            public String toLZX() {
592:                return toLZX("");
593:            }
594:
595:            public String toLZX(String indent) {
596:                String lzx = "";
597:                for (Iterator i = (new TreeSet(mClassMap.values())).iterator(); i
598:                        .hasNext();) {
599:                    ClassModel model = (ClassModel) i.next();
600:                    if (model.hasNodeModel()) {
601:                        lzx += model.toLZX(indent);
602:                        lzx += "\n";
603:                    }
604:                }
605:                return lzx;
606:            }
607:
608:            public void loadSchema(CompilationEnvironment env)
609:                    throws JDOMException, IOException {
610:                String schemaPath = SCHEMA_PATH;
611:                // Load the schema if it hasn't been.
612:                // Reload it if it's been touched, to make it easier for developers.
613:                while (sCachedSchemaDOM == null
614:                        || new File(schemaPath).lastModified() != sCachedSchemaLastModified) {
615:                    // using 'while' and reading the timestamp *first* avoids a
616:                    // race condition --- although since this doesn't happen in
617:                    // production code, this isn't critical
618:                    sCachedSchemaLastModified = new File(schemaPath)
619:                            .lastModified();
620:                    sCachedSchemaDOM = new Parser().read(new File(schemaPath));
621:                }
622:
623:                // This is the base class from which all classes derive unless otherwise
624:                // specified. It has no attributes.
625:                makeNewStaticClass("Object");
626:
627:                schemaDOM = (Document) sCachedSchemaDOM.clone();
628:                Element docroot = schemaDOM.getRootElement();
629:                ToplevelCompiler ec = (ToplevelCompiler) Compiler
630:                        .getElementCompiler(docroot, env);
631:                Set visited = new HashSet();
632:                ec.updateSchema(docroot, this , visited);
633:                /** From here on, user-defined classes must not use reserved javascript identifiers */
634:                this .enforceValidIdentifier = true;
635:            }
636:
637:            /** Check if a child element can legally be contained in a parent element.
638:                This works with the class hierarchy as follows:
639:
640:                + Look up the ClassModel corresponding to the parentTag
641:
642:                + Check the containsElements table to see if child tag is in there
643:
644:                + If not, look up the ClassModel of the child tag, and follow up the chain
645:                  checking if that name is present in the table
646:
647:
648:                   + If not, ascend up the parent classmodel, and call canContainElement recursively
649:                  
650:             */
651:            public boolean canContainElement(String parentTag, String childTag) {
652:                // Get list of legally nestable tags
653:                ClassModel parent = getClassModel(parentTag);
654:
655:                // TODO [hqm 2007-09]: CHECK FOR NULL HERE 
656:
657:                Set tagset = parent.getContainsSet();
658:                if (tagset.contains(childTag)) {
659:                    return true;
660:                }
661:                // check all superclasses of the childTag
662:                ClassModel childclass = getClassModel(childTag);
663:
664:                // TODO [hqm 2007-09]: CHECK FOR NULL HERE         
665:
666:                while (childclass != null) {
667:                    String super classname = childclass.getSuperclassName();
668:                    if (tagset.contains(super classname)) {
669:                        return true;
670:                    }
671:                    childclass = childclass.getSuperclassModel();
672:                }
673:
674:                String parentSuperclassname = parent.getSuperclassName();
675:                if (parentSuperclassname != null) {
676:                    return canContainElement(parentSuperclassname, childTag);
677:                }
678:
679:                return false;
680:            }
681:
682:            /** @return true if this element is an input text field */
683:            boolean isInputTextElement(Element e) {
684:                String classname = e.getName();
685:                ClassModel info = getClassModel(classname);
686:                if (info != null) {
687:                    return info.isInputText;
688:                }
689:                return sInputTextElements.contains(classname);
690:            }
691:
692:            boolean supportsTextAttribute(Element e) {
693:                String classname = e.getName();
694:                ClassModel info = getClassModel(classname);
695:                if (info != null) {
696:                    return info.supportsTextAttribute;
697:                } else {
698:                    return false;
699:                }
700:            }
701:
702:            /** @return true if this element content is interpreted as text */
703:            boolean hasTextContent(Element e) {
704:                // input text elements can have text
705:                return isInputTextElement(e) || supportsTextAttribute(e);
706:            }
707:
708:            /** @return true if this element's content is HTML. */
709:            boolean hasHTMLContent(Element e) {
710:                String name = e.getName().intern();
711:                // TBD: return sHTMLContentElements.contains(name). Currently
712:                // uses a blacklist instead of a whitelist because the parser
713:                // doesn't tell the schema about user-defined classes.
714:                // XXX Since any view can have a text body, this implementation
715:                // is actually correct.  That is, blacklist rather than whitelist
716:                // is the way to go here.
717:                return name != "class" && name != "method"
718:                        && name != "property" && name != "script"
719:                        && name != "attribute" && !isHTMLElement(e)
720:                        && !isInputTextElement(e);
721:            }
722:
723:            /** @return true if this element is an HTML element, that should
724:             * be included in the text content of an element that tests true
725:             * with hasHTMLContent. */
726:            static boolean isHTMLElement(Element e) {
727:                String name = e.getName();
728:                return name.equals("a") || name.equals("b")
729:                        || name.equals("img") || name.equals("br")
730:                        || name.equals("font") || name.equals("i")
731:                        || name.equals("p") || name.equals("pre")
732:                        || name.equals("u");
733:            }
734:
735:            static boolean isDocElement(Element e) {
736:                String name = e.getName();
737:                return name.equals("doc");
738:            }
739:
740:            /* Constants for parsing CSS colors. */
741:            static final PatternMatcher sMatcher = new Perl5Matcher();
742:            static final Pattern sRGBPattern;
743:            static final Pattern sHex3Pattern;
744:            static final Pattern sHex6Pattern;
745:            static final HashMap sColorValues = new HashMap();
746:            static {
747:                try {
748:                    Perl5Compiler compiler = new Perl5Compiler();
749:                    String s = "\\s*(-?\\d+(?:(?:.\\d*)%)?)\\s*"; // component
750:                    String hexDigit = "[0-9a-fA-F]";
751:                    String hexByte = hexDigit + hexDigit;
752:                    sRGBPattern = compiler.compile("\\s*rgb\\(" + s + "," + s
753:                            + "," + s + "\\)\\s*");
754:                    sHex3Pattern = compiler.compile("\\s*#\\s*(" + hexDigit
755:                            + hexDigit + hexDigit + ")\\s*");
756:                    sHex6Pattern = compiler.compile("\\s*#\\s*(" + hexByte
757:                            + hexByte + hexByte + ")\\s*");
758:                } catch (MalformedPatternException e) {
759:                    throw new ChainedException(e);
760:                }
761:
762:                String[] colorNameValues = { "black", "000000", "green",
763:                        "008000", "silver", "C0C0C0", "lime", "00FF00", "gray",
764:                        "808080", "olive", "808000", "white", "FFFFFF",
765:                        "yellow", "FFFF00", "maroon", "800000", "navy",
766:                        "000080", "red", "FF0000", "blue", "0000FF", "purple",
767:                        "800080", "teal", "008080", "fuchsia", "FF00FF",
768:                        "aqua", "00FFFF" };
769:                for (int i = 0; i < colorNameValues.length;) {
770:                    String name = colorNameValues[i++];
771:                    String value = colorNameValues[i++];
772:                    sColorValues.put(name, new Integer(Integer.parseInt(value,
773:                            16)));
774:                }
775:            }
776:
777:            static class ColorFormatException extends RuntimeException {
778:                ColorFormatException(String message) {
779:                    super (message);
780:                }
781:            }
782:
783:            /** Parse according to http://www.w3.org/TR/2001/WD-css3-color-20010305,
784:             * but also allow 0xXXXXXX */
785:            public static int parseColor(String str) {
786:                {
787:                    Object value = sColorValues.get(str);
788:                    if (value != null) {
789:                        return ((Integer) value).intValue();
790:                    }
791:                }
792:                if (str.startsWith("0x")) {
793:                    try {
794:                        return Integer.parseInt(str.substring(2), 16);
795:                    } catch (java.lang.NumberFormatException e) {
796:                        // fall through
797:                    }
798:                }
799:                if (sMatcher.matches(str, sHex3Pattern)) {
800:                    int r1g1b1 = Integer.parseInt(sMatcher.getMatch().group(1),
801:                            16);
802:                    int r = (r1g1b1 >> 8) * 17;
803:                    int g = ((r1g1b1 >> 4) & 0xf) * 17;
804:                    int b = (r1g1b1 & 0xf) * 17;
805:                    return (r << 16) + (g << 8) + b;
806:                }
807:                if (sMatcher.matches(str, sHex6Pattern)) {
808:                    return Integer.parseInt(sMatcher.getMatch().group(1), 16);
809:                }
810:                if (sMatcher.matches(str, sRGBPattern)) {
811:                    int v = 0;
812:                    for (int i = 0; i < 3; i++) {
813:                        String s = sMatcher.getMatch().group(i + 1);
814:                        int c;
815:                        if (s.charAt(s.length() - 1) == '%') {
816:                            s = s.substring(0, s.length() - 1);
817:                            float f = Float.parseFloat(s);
818:                            c = (int) f * 255 / 100;
819:                        } else {
820:                            c = Integer.parseInt(s);
821:                        }
822:                        if (c < 0)
823:                            c = 0;
824:                        if (c > 255)
825:                            c = 255;
826:                        v = (v << 8) | c;
827:                    }
828:                    return v;
829:                }
830:                throw new ColorFormatException(str);
831:            }
832:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.