1 4 5 9 10 package org.openlaszlo.compiler; 11 import java.io.*; 12 import java.util.*; 13 import org.apache.log4j.*; 14 import org.jdom.Element; 15 import org.openlaszlo.xml.internal.XMLUtils; 16 import org.openlaszlo.xml.internal.MissingAttributeException; 17 import org.openlaszlo.xml.internal.Schema; 18 import org.openlaszlo.xml.internal.Schema.Type; 19 import org.openlaszlo.sc.ScriptCompiler; 20 import org.openlaszlo.utils.ChainedException; 21 import org.openlaszlo.css.CSSParser; 22 23 25 class ClassCompiler extends ViewCompiler { 26 45 static final String DEFAULT_SUPERCLASS_NAME = "view"; 46 47 ClassCompiler(CompilationEnvironment env) { 48 super(env); 49 } 50 51 55 static boolean isElement(Element element) { 56 return element.getName().equals("class"); 57 } 58 59 65 void updateSchema(Element element, ViewSchema schema, Set visited) { 66 Element elt = element; 67 68 String classname = elt.getAttributeValue("name"); 69 String superclass = elt.getAttributeValue("extends"); 70 71 if (classname == null || !ScriptCompiler.isIdentifier(classname)) { 72 CompilationError cerr = new CompilationError("The classname attribute, \"name\" must be a valid identifier for a class definition", elt); 73 throw(cerr); 74 } 75 76 if (superclass != null && !ScriptCompiler.isIdentifier(superclass)) { 77 mEnv.warn("The value for the 'extends' attribute on a class definition must be a valid identifier", elt); 78 superclass = null; 79 } 80 if (superclass == null) { 81 superclass = ClassCompiler.DEFAULT_SUPERCLASS_NAME; 83 } 84 85 ClassModel superclassinfo = schema.getClassModel(superclass); 86 if (superclassinfo == null) { 87 throw new CompilationError("undefined superclass " + superclass + " for class "+classname, elt); 88 } 89 90 List attributeDefs = new ArrayList(); 92 Iterator iterator = element.getContent().iterator(); 93 94 while (iterator.hasNext()) { 95 Object o = iterator.next(); 96 if (o instanceof Element) { 97 Element child = (Element) o; 98 if (child.getName().equals("attribute")) { 101 String attrName; 102 try { 103 attrName = requireIdentifierAttributeValue(child, "name"); 104 } catch (MissingAttributeException e) { 105 throw new CompilationError( 106 "'name' is a required attribute of <" + child.getName() + "> and must be a valid identifier", child); 107 } 108 109 String attrTypeName = child.getAttributeValue("type"); 110 String attrDefault = child.getAttributeValue("default"); 111 String attrSetter = child.getAttributeValue("setter"); 112 String attrRequired = child.getAttributeValue("required"); 113 114 ViewSchema.Type attrType; 115 if (attrTypeName == null) { 116 attrType = superclassinfo.getAttributeType(attrName); 119 if (attrType == null) { 120 attrType = ViewSchema.EXPRESSION_TYPE; 122 } 123 } else { 124 attrType = schema.getTypeForName(attrTypeName); 125 } 126 127 if (attrType == null) { 128 throw new CompilationError("In class "+classname+ " type '"+attrTypeName +"', declared for attribute '"+ 129 attrName + "' is not a known data type.", element); 130 } 131 132 AttributeSpec attrSpec = 133 new AttributeSpec(attrName, attrType, attrDefault, 134 attrSetter, child); 135 if (attrName.equals("text") && attrTypeName != null) { 136 if ("text".equals(attrTypeName)) 137 attrSpec.contentType = attrSpec.TEXT_CONTENT; 138 else if ("html".equals(attrTypeName)) 139 attrSpec.contentType = attrSpec.HTML_CONTENT; 140 } 141 attributeDefs.add(attrSpec); 142 } 143 } 144 } 145 146 schema.addElement(element, classname, superclass, attributeDefs); 148 } 149 150 public void compile(Element elt) { 151 String className; 152 try { 153 className = requireIdentifierAttributeValue(elt, "name"); 154 } catch (MissingAttributeException e) { 155 throw new CompilationError("'name' is a required attribute of <" + elt.getName() + "> and must be a valid identifier", elt); 156 } 157 158 String extendsName = XMLUtils.getAttributeValue( 159 elt, "extends", DEFAULT_SUPERCLASS_NAME); 160 161 ViewSchema schema = mEnv.getSchema(); 162 ClassModel classModel = schema.getClassModel(className); 163 164 String linedir = CompilerUtils.sourceLocationDirective(elt, true); 165 ViewCompiler.preprocess(elt, mEnv); 166 167 FontInfo fontInfo = new FontInfo(mEnv.getCanvas().getFontInfo()); 168 if (mEnv.getSWFVersion().equals("swf5")) { 169 ViewCompiler.collectInputFonts(elt, mEnv, fontInfo, new HashSet()); 170 } 171 172 NodeModel model = NodeModel.elementAsModel(elt, schema, mEnv); 176 model = model.expandClassDefinitions(); 177 model.removeAttribute("name"); 178 classModel.setNodeModel(model); 179 Map viewMap = model.asMap(); 180 181 viewMap.put("name", ScriptCompiler.quote(className)); 183 184 String initobj; 186 try { 187 java.io.Writer writer = new java.io.StringWriter (); 188 ScriptCompiler.writeObject(viewMap, writer); 189 initobj = writer.toString(); 190 } catch (java.io.IOException e) { 191 throw new ChainedException(e); 192 } 193 StringBuffer buffer = new StringBuffer (); 195 buffer.append(VIEW_INSTANTIATION_FNAME + 196 "({name: 'userclass', attrs: " + 197 "{parent: " + 198 ScriptCompiler.quote(extendsName) + 199 ", initobj: " + initobj + 200 "}}" + 201 ", " + ((ElementWithLocationInfo)elt).model.totalSubnodes() + 202 ");\n"); 203 if (!classModel.getInline()) { 204 ClassModel superclassModel = classModel.getSuperclassModel(); 205 mEnv.compileScript(buffer.toString(), elt); 206 } 207 208 boolean tracexml = 210 mEnv.getProperties().getProperty("trace.xml", "false") == "true"; 211 if (tracexml) { 212 Logger mXMLLogger = Logger.getLogger("trace.xml"); 213 mXMLLogger.info("compiling class definition:"); 214 org.jdom.output.XMLOutputter outputter = 215 new org.jdom.output.XMLOutputter(); 216 outputter.setTextNormalize(true); 217 mXMLLogger.info(outputter.outputString(elt)); 218 mXMLLogger.info("compiled to:\n" + buffer.toString() + "\n"); 219 } 220 } 221 } 222 | Popular Tags |