1 package org.jicengine.element; 2 3 import org.jicengine.operation.StaticValue; 4 import org.jicengine.operation.OperationException; 5 import org.jicengine.operation.VariableValueOperation; 6 import org.jicengine.operation.Operation; 7 import org.jicengine.operation.EmptyOperation; 8 import org.jicengine.expression.LJEParser; 9 import org.jicengine.expression.ClassParser; 10 import org.jicengine.expression.SyntaxException; 11 import java.util.*; 12 13 34 35 public abstract class ElementCompiler { 36 37 public static final String ATTR_NAME_ACTION = "action"; 38 public static final String ATTR_NAME_CLASS = "class"; 39 public static final String ATTR_NAME_VARIABLES = "vars"; 40 public static final String ATTR_NAME_CONSTRUCTOR_ARGUMENTS = "args"; 41 public static final String ATTR_NAME_TRACE = "trace"; 42 public static final String ATTR_NAME_TYPE = "type"; 43 public static final String ATTR_NAME_INSTANCE = "instance"; 44 public static final String ATTR_NAME_OVERRIDABLE_BY = "overridable-by"; 45 public static final String ATTR_NAME_IF = "if"; 46 47 public ElementCompiler() 48 { 49 } 50 51 private ElementImpl element; 52 private String constructorArguments; 53 private boolean constructorDerivedFromClassInformation = false; 54 55 56 public ElementCompiler(String name, Location location) 57 { 58 this.element = new ElementImpl(name, location); 59 } 60 61 public Element createElement() throws ElementException 62 { 63 return getElement().toRuntimeElement(); 64 } 65 66 public String getName() 67 { 68 return getElement().getName(); 69 } 70 71 public Location getLocation() 72 { 73 return getElement().getLocation(); 74 } 75 76 public void setOverridableBy(String overridingId) 77 { 78 getElement().setOverridableBy(overridingId); 79 } 80 81 public void setIf(String condition) throws ElementException 82 { 83 try { 84 getElement().setIf(LJEParser.getInstance().parse(condition)); 85 } catch (SyntaxException e){ 86 throw new AttributeException("[if=\"" + condition + "\"]: " + e.getMessage(), e, getName(), getLocation()); 87 } 88 } 89 90 91 94 public void setVariables(String variableExpression) throws ElementException 95 { 96 StringTokenizer tokenizer = new StringTokenizer(variableExpression, ","); 97 String [] variableNames = new String [tokenizer.countTokens()]; 98 int i = 0; 99 while(tokenizer.hasMoreElements() ){ 100 variableNames[i] = tokenizer.nextToken().trim(); 101 i++; 102 } 103 setVariables(variableNames); 104 } 105 106 public void setVariables(String [] variableNames) throws ElementException 107 { 108 getElement().setVariableNames(variableNames); 109 } 110 111 public void setConstructorArguments(String argumentExpression) 112 { 113 this.constructorArguments = argumentExpression; 114 } 115 116 public void setConstructor(String expression) throws ElementException 117 { 118 try { 119 getElement().setConstructor(LJEParser.getInstance().parse(expression)); 120 } catch (SyntaxException e){ 121 throw new AttributeException("[instance=\"" + expression + "\"]: " + e.getMessage(), e, getName(), getLocation()); 122 } 123 } 124 125 public Operation getConstructor() 126 { 127 return getElement().getConstructor(); 128 } 129 130 public void setInstanceClass(String className) throws ElementException 131 { 132 try { 133 getElement().setInstanceClass(ClassParser.INSTANCE.toClass(className)); 134 } catch(Exception e) { 135 throw new AttributeException("[class=\"" + className + "\"]: " + e.getMessage(),e, getName(), getLocation()); 136 } 137 } 138 139 156 public void setAction(String expression) throws ElementException 157 { 158 if(expression.length() == 0) { 159 getElement().setAction(EmptyOperation.INSTANCE); 160 } 161 else { 162 String preparedExpression; 163 int paramStart = expression.indexOf("("); 164 int commaIndex = -1; 165 166 if( paramStart != -1 ){ 167 commaIndex = expression.substring(0,paramStart).indexOf("."); 168 } 169 170 if(paramStart != -1 && commaIndex == -1) { 175 preparedExpression = Element.VARIABLE_NAME_PARENT_INSTANCE + "." + expression; 176 } 177 else { 178 preparedExpression = expression; 179 } 180 181 try { 182 getElement().setAction(LJEParser.getInstance().parse(preparedExpression)); 183 } catch (SyntaxException e){ 184 throw new AttributeException("[action=\"" + expression + "\"]: " + e.getMessage(), e, getName(), getLocation()); 185 } 186 } 187 } 188 189 190 200 public void setCData(String cdata, boolean syntaxBasedCdataConversionsSupported) throws ElementException 201 { 202 if( getElement().getConstructor() == null || this.constructorDerivedFromClassInformation ){ 203 208 if( getElement().getInstanceClass() == null ){ 209 211 Class instanceClass; 212 213 if( syntaxBasedCdataConversionsSupported){ 214 instanceClass = CdataHandler.resolveInstanceClassFromCdata(cdata); 216 } 217 else { 218 instanceClass = String .class; 220 } 221 222 getElement().setInstanceClass(instanceClass); 226 } 227 228 Operation constructor; 229 try { 230 constructor = CdataHandler.getClassBasedCdataConversionConstructor(getElement().getInstanceClass(), cdata); 231 } catch (Exception ex) { 232 throw new ElementException(ex, getName(), getLocation()); 233 } 234 getElement().deleteConstructor(); 235 getElement().setConstructor(constructor); 236 237 240 } 241 else { 242 244 if( getElement().isConstructorVariable(Element.VARIABLE_NAME_CDATA) ){ 245 247 VariableElement virtualElement = new StaticValueElement(Element.VARIABLE_NAME_CDATA, getLocation(), cdata); 250 handleChildElement(virtualElement); 251 } 252 else { 253 throw new ElementException("Illegal CDATA: CDATA must be used in the constructor (variable 'cdata').", getName(), getLocation()); 255 } 256 } 257 } 258 259 273 public void elementInitialized() throws ElementException 274 { 275 if(this.constructorArguments != null) { 277 if(getElement().getInstanceClass() == null) { 278 throw new AttributeException("Attribute '" + ATTR_NAME_CONSTRUCTOR_ARGUMENTS + "' must be specified together with attribute '" + ATTR_NAME_CLASS + "'", getName(), getLocation()); 279 } 280 if(getElement().getConstructor() != null) { 281 throw new AttributeException("Attributes '" + ATTR_NAME_INSTANCE + "' and '" + ATTR_NAME_CONSTRUCTOR_ARGUMENTS + "' can't be used together", getName(), getLocation()); 282 } 283 } 284 285 if( getElement().getConstructor() != null ){ 286 if( getElement().getInstanceClass() == null ){ 290 throw new AttributeException("The attribute '" + ATTR_NAME_CLASS + "' must be specified.", getName(), getLocation()); 291 } 292 } 293 294 295 deriveConstructorFromClassInformation(); 296 } 297 298 304 public void handleChildElement(Element child) throws ElementException 305 { 306 if( child instanceof VariableElement && !getElement().isUsed((VariableElement)child) ){ 307 ActionElement actionElement = handleLooseVariableElement((VariableElement)child); 311 312 getElement().addChildElement(actionElement); 314 } 315 else { 316 getElement().addChildElement(child); 317 } 318 } 319 320 protected ElementImpl getElement() 321 { 322 return this.element; 323 } 324 325 329 protected abstract ActionElement handleLooseVariableElement(VariableElement child) throws ElementException; 330 331 332 333 public String toString() 334 { 335 return "<" + getName() + ">"; 336 } 337 338 347 private void deriveConstructorFromClassInformation() throws ElementException 348 { 349 if( getElement().getConstructor() == null && getElement().getInstanceClass() != null ){ 350 352 String constructorExpression; 353 if(this.constructorArguments == null) { 354 constructorExpression = "new " + getElement().getInstanceClass().getName() + "()"; 356 this.constructorDerivedFromClassInformation = true; 360 } 361 else { 362 constructorExpression = "new " + getElement().getInstanceClass().getName() + "(" + this.constructorArguments + ")"; 364 this.constructorDerivedFromClassInformation = false; 365 } 366 367 369 try { 370 setConstructor(constructorExpression); 371 372 } catch (ElementException e){ 373 throw new ElementException("Problems creating implicit constructor.", e, getName(), getLocation()); 374 } 375 } 376 } 377 378 } 379 | Popular Tags |