1 package net.sourceforge.jenesis4java; 2 3 /* 4 * #%L 5 * Jenesis 4 Java Code Generator 6 * %% 7 * Copyright (C) 2000 - 2015 jenesis4java 8 * %% 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU Lesser General Public License as 11 * published by the Free Software Foundation, either version 3 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Lesser Public License for more details. 18 * 19 * You should have received a copy of the GNU General Lesser Public 20 * License along with this program. If not, see 21 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 22 * #L% 23 */ 24 25 /** 26 * Copyright (C) 2008, 2010 Richard van Nieuwenhoven - ritchie [at] gmx [dot] at 27 * Copyright (C) 2000, 2001 Paul Cody Johnston - pcj@inxar.org <br> 28 * This file is part of Jenesis4java. Jenesis4java is free software: you can 29 * redistribute it and/or modify it under the terms of the GNU Lesser General 30 * Public License as published by the Free Software Foundation, either version 3 31 * of the License, or (at your option) any later version.<br> 32 * Jenesis4java is distributed in the hope that it will be useful, but WITHOUT 33 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 34 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 35 * details.<br> 36 * You should have received a copy of the GNU Lesser General Public License 37 * along with Jenesis4java. If not, see <http://www.gnu.org/licenses/>. 38 */ 39 import java.io.BufferedInputStream; 40 import java.io.File; 41 import java.io.FileInputStream; 42 import java.io.IOException; 43 import java.io.InputStream; 44 import java.util.Comparator; 45 import java.util.Properties; 46 import java.util.logging.Level; 47 import java.util.logging.Logger; 48 49 /** 50 * The {@code VirtualMachine} acts as a factory method for 51 * {@code CompilationUnit}, {@code Type}, {@code Literal}, and 52 * {@code Expression} objects. Most {@code Statement} factory methods are 53 * located on {@code Block}; most {@code Declaration} factory methods are 54 * located on the objects that contain them. 55 */ 56 public abstract class VirtualMachine { 57 58 private static final Logger LOGGER = Logger.getLogger(VirtualMachine.class.getName()); 59 60 private static final String JENESIS_PROPERTY_PREFIX = "jenesis."; 61 62 /** 63 * The default {@code VirtualMachine} implementation. 64 */ 65 private static VirtualMachine virtualMachine; 66 67 /** 68 * Returns the default {@code VirtualMachine} implementation previously set 69 * using the static {@code setVirtualMachine(VirtualMachine)} method OR 70 * returns the reference implementation ( {@code com.inxar.jenesis.MVM}. <br> 71 * <br> 72 * The settings for the coding style are read from the file specified by the 73 * system property "jenesis.blockstyle-properties-filename" (a real file or 74 * available in the classpath). If there was non specified, a fall back to 75 * /META-INF/blockstyle.properties will be used.<br> 76 * <br> 77 * All properties may be overwritten by specifying them in the system 78 * properties with a "jenesis." prefix.<br> 79 * For example you can specify to use the 80 * net.sourceforge.jenesis4java.jaloppy.JenesisJalopyEncoder encoder by 81 * setting the property "jenesis.encoder" and "jenesis.encoder.jalopyconfig" 82 */ 83 public static VirtualMachine getVirtualMachine() { 84 if (VirtualMachine.virtualMachine == null) { 85 86 InputStream in = null; 87 BufferedInputStream bufferedStream = null; 88 try { 89 String filename = System.getProperty("jenesis.blockstyle-properties-filename"); 90 if (filename != null) { 91 if (new File(filename).exists()) { 92 in = new FileInputStream(filename); 93 } else { 94 in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename); 95 } 96 } else { 97 filename = "blockstyle.properties"; 98 in = net.sourceforge.jenesis4java.VirtualMachine.class.getClassLoader().getResourceAsStream(filename); 99 } 100 101 if (in == null) { 102 throw new RuntimeException("Cannot instantiate VirtualMachine: " // 103 + "Could not find blockstyle.properties file in system classpath " // 104 + "or from -Djenesis.blockstyle-properties-filename!"); 105 } 106 107 Properties p = new Properties(); 108 bufferedStream = new BufferedInputStream(in); 109 p.load(bufferedStream); 110 bufferedStream.close(); 111 in.close(); 112 in = null; 113 114 Properties systemproperties = System.getProperties(); 115 for (String systemProperty : systemproperties.stringPropertyNames()) { 116 if (systemProperty.startsWith(VirtualMachine.JENESIS_PROPERTY_PREFIX)) { 117 p.put(systemProperty.substring(VirtualMachine.JENESIS_PROPERTY_PREFIX.length()), systemproperties.get(systemProperty)); 118 } 119 } 120 VirtualMachine.virtualMachine = new net.sourceforge.jenesis4java.impl.MVM(p); 121 122 } catch (IOException ioex) { 123 RuntimeException rex = new RuntimeException("Could not load VirtualMachine blockstyles: " + ioex.getMessage()); 124 ioex.printStackTrace(); 125 throw rex; 126 } finally { 127 Exception exception = null; 128 if (bufferedStream != null) { 129 try { 130 bufferedStream.close(); 131 } catch (Exception ex) { 132 exception = ex; 133 } 134 } 135 if (in != null) { 136 try { 137 in.close(); 138 } catch (Exception ex) { 139 exception = ex; 140 } 141 } 142 if (exception != null) { 143 LOGGER.log(Level.SEVERE, "Exception during InputStreamReader.close(). ", exception); 144 } 145 } 146 } 147 148 return VirtualMachine.virtualMachine; 149 } 150 151 /** 152 * Sets the default {@code VirtualMachine} implementation. 153 */ 154 public static VirtualMachine setVirtualMachine(VirtualMachine vm) { 155 VirtualMachine.virtualMachine = vm; 156 return vm; 157 } 158 159 /** 160 * Removes all cached compilationUnits. 161 */ 162 public abstract VirtualMachine clear(); 163 164 /** 165 * Writes out the source code to all enclosed {@code CompilationUnit} 166 * instances. 167 */ 168 public abstract VirtualMachine encode(); 169 170 /** 171 * @return the current active encoder. 172 */ 173 public abstract CompilationUnitEncoder getEncoder(); 174 175 public abstract FieldAccess newAccess(Class<?> qualifierClass, Object object); 176 177 /** 178 * {@code Expression} factory method which returns a new field access with 179 * the given qualifier and name. 180 */ 181 public abstract FieldAccess newAccess(Expression qualifier, String name); 182 183 /** 184 * {@code Expression} factory method which returns a new field access with 185 * the given qualifier and name. 186 */ 187 public abstract FieldAccess newAccess(String name); 188 189 /** 190 * {@code Expression} factory method which returns a new field access with 191 * the given qualifier and name. 192 */ 193 public abstract FieldAccess newAccess(String qualifier, String name); 194 195 public abstract Annotation newAnnotation(Class<?> annotationClass); 196 197 /** 198 * Creates a new annotation with the given name. For a given name "Example" 199 * this will result in an annotation {@code @Example}. 200 * 201 * @param text 202 * The name of the annotation. Must not start with "@". 203 * @return The newly created Annotation. 204 */ 205 public abstract Annotation newAnnotation(String text); 206 207 /** 208 * Creates a new annotation attribute with the given name and the given 209 * value. 210 * 211 * @return The newly created annotation attribute. 212 */ 213 public abstract AnnotationAttribute newAnnotationAttribute(String key, Expression value, Expression... additionalValues); 214 215 /** 216 * {@code Expression} factory method which returns a new anonymous class 217 * instance creation expression for the given type. 218 */ 219 public abstract NewAnonymousClass newAnon(Type type); 220 221 public abstract NewAnonymousClass newAnon(Type type, Comparator comparator); 222 223 public abstract NewAnonymousClass newAnonymousClass(String className, String... genericTypes); 224 225 public abstract NewAnonymousClass newAnonymousClass(String className, Comparator comparator, String... genericTypes); 226 227 /** 228 * {@code Type} factory method which returns an array of primitive type with 229 * the given constant and dimensions. 230 */ 231 public abstract ArrayType newArray(int type, int dims); 232 233 /** 234 * {@code Type} factory method which returns an array of class type with the 235 * given name and dimensions. 236 */ 237 public abstract ArrayType newArray(String type, int dims); 238 239 /** 240 * {@code Expression} factory method which returns a new array instance 241 * creation expression for the given type. 242 */ 243 public abstract NewArray newArray(Type type); 244 245 /** 246 * {@code Expression} factory method which returns a new array access 247 * expression with the given qualifier and name. 248 */ 249 public abstract ArrayAccess newArrayAccess(Expression qual, String name); 250 251 /** 252 * {@code Expression} factory method which returns a new array access 253 * expression with the given qualifier and name. 254 */ 255 public abstract ArrayAccess newArrayAccess(String name); 256 257 /** 258 * {@code Expression} factory method which returns a new array access 259 * expression with the given qualifier and name. 260 */ 261 public abstract ArrayAccess newArrayAccess(String qual, String name); 262 263 /** 264 * {@code Expression} factory method which returns a new array initializer 265 * with the given arguments. 266 */ 267 public abstract ArrayInitializer newArrayInit(Expression[] expressions); 268 269 /** 270 * {@code Expression} factory method which returns a new array initializer 271 * with the given arguments. 272 */ 273 public abstract ArrayInitializer newArrayInit(Object o); 274 275 /** 276 * {@code Expression} factory method which returns a new assignment of the 277 * given type. 278 */ 279 public abstract Assign newAssign(int type, Variable left, Expression right); 280 281 /** 282 * {@code Expression} factory method which returns a new assignment of the 283 * SIMPLE type. This is a convenience * method. 284 */ 285 public abstract Assign newAssign(Variable left, Expression right); 286 287 /** 288 * {@code Expression} factory method which returns a new unary function of 289 * the given type. 290 */ 291 public abstract Binary newBinary(int type, Expression left, Expression right); 292 293 /** 294 * {@code Expression} factory method which returns the blank expression. 295 */ 296 public abstract Blank newBlank(); 297 298 /** 299 * {@code Literal} factory method which returns a new {@code boolean} 300 * literal. 301 */ 302 public abstract BooleanLiteral newBoolean(boolean value); 303 304 /** 305 * {@code Expression} factory method which returns a new expression that 306 * wraps brackets around the expression. 307 */ 308 public abstract Cast newBrackets(Expression value); 309 310 /** 311 * {@code Literal} factory method which returns a new {@code byte} literal. 312 */ 313 public abstract ByteLiteral newByte(byte val); 314 315 /** 316 * {@code Type} factory method which returns a calendar type with the given 317 * pattern as representation storage. 318 */ 319 public abstract CalendarClassType newCalendarType(String pattern); 320 321 /** 322 * {@code Expression} factory method which returns a new cast function 323 * having the given type and value. 324 */ 325 public abstract Cast newCast(Type type, Expression value); 326 327 /** 328 * {@code Literal} factory method which returns a new {@code char} literal. 329 */ 330 public abstract CharLiteral newChar(char val); 331 332 /** 333 * {@code Expression} factory method which returns a new class instance 334 * creation expression for the given type. 335 */ 336 public abstract NewClass newClass(Type type); 337 338 /** 339 * {@code Literal} factory method which returns a new {@code Class} literal. 340 */ 341 public abstract ClassLiteral newClassLiteral(ClassType type); 342 343 /** 344 * {@code Literal} factory method which returns a new {@code Class} literal. 345 */ 346 public abstract ClassLiteral newClassLiteral(String className); 347 348 /** 349 * Creates a new {@code CompilationUnit} in this {@code Machine} and returns 350 * it. 351 */ 352 public abstract CompilationUnit newCompilationUnit(String sourcepath); 353 354 /** 355 * Creates a new {@code CompilationUnit} in this {@code Machine} sets the 356 * namespace and returns it. 357 */ 358 public abstract CompilationUnit newCompilationUnit(String sourceDirectory, String packageName); 359 360 /** 361 * {@code Literal} factory method which returns a new {@code double} 362 * literal. 363 */ 364 public abstract DoubleLiteral newDouble(double val); 365 366 /** 367 * {@code Literal} factory method which returns the boolean {@code false} 368 * literal. 369 */ 370 public abstract False newFalse(); 371 372 /** 373 * {@code Literal} factory method which returns a new {@code float} literal. 374 */ 375 public abstract FloatLiteral newFloat(float val); 376 377 /** 378 * {@code Expression} factory method which returns a new freeform expression 379 * with the given code. 380 */ 381 public abstract Freeform newFree(String code); 382 383 /** 384 * {@code Literal} factory method which returns a new {@code int} literal. 385 */ 386 public abstract IntLiteral newInt(int val); 387 388 public abstract Invoke newInvoke(Class<?> qualifyingClass, String name); 389 390 /** 391 * {@code Expression} factory method which returns a new method invocation 392 * with the given qualifier and name. 393 */ 394 public abstract Invoke newInvoke(Expression qualifier, String name); 395 396 /** 397 * {@code Expression} factory method which returns a new method invocation 398 * with the given qualifier and name. 399 */ 400 public abstract Invoke newInvoke(String name); 401 402 /** 403 * {@code Expression} factory method which returns a new method invocation 404 * with the given qualifier and name. 405 */ 406 public abstract Invoke newInvoke(String qualifier, String name); 407 408 /** 409 * {@code Literal} factory method which returns a new {@code long} literal. 410 */ 411 public abstract LongLiteral newLong(long val); 412 413 /** 414 * {@code Literal} factory method which returns the {@code null} literal. 415 */ 416 public abstract Null newNull(); 417 418 /** 419 * {@code Literal} factory method which returns a new octal {@code char} 420 * literal. 421 */ 422 public abstract OctalLiteral newOctal(char val); 423 424 /** 425 * {@code Literal} factory method which returns a new scientific floating 426 * point {@code char} literal. 427 */ 428 public abstract ScientificLiteral newScientific(int precision, int scale, int exponent); 429 430 /** 431 * {@code Literal} factory method which returns a new {@code short} literal. 432 */ 433 public abstract ShortLiteral newShort(short val); 434 435 public abstract ClassType newSimpleType(Class<?> type); 436 437 /** 438 * {@code Literal} factory method which returns a new {@code String} 439 * literal. 440 */ 441 public abstract StringLiteral newString(String val); 442 443 /** 444 * {@code Expression} factory method which returns a new unary function of 445 * the given type. 446 */ 447 public abstract Ternary newTernary(int type, Expression one, Expression two, Expression three); 448 449 /** 450 * {@code Literal} factory method which returns the boolean {@code true} 451 * literal. 452 */ 453 public abstract True newTrue(); 454 455 /** 456 * {@code Type} factory method which returns a class type named with the 457 * given {@code Class}. 458 */ 459 public abstract ClassType newType(Class<?> clazz); 460 461 /** 462 * {@code Type} factory method which returns a primitive type named by the 463 * given {@code int} as allowed by the constants listed in the {@code Type} 464 * interface. 465 * 466 * @param type 467 * A primitive type constant. Must not be array or class. 468 */ 469 public abstract PrimitiveType newType(int type); 470 471 /** 472 * {@code Type} factory method which returns a class type named with the 473 * given {@code String}. 474 */ 475 public abstract ClassType newType(String name); 476 477 /** 478 * {@code Expression} factory method which returns a new unary function of 479 * the given type. 480 */ 481 public abstract Unary newUnary(int type, Expression value); 482 483 /** 484 * {@code Literal} factory method which returns a new unicode {@code char} 485 * literal. 486 */ 487 public abstract UnicodeLiteral newUnicode(char val); 488 489 /** 490 * {@code Expression} factory method which returns a new variable with the 491 * given name. 492 */ 493 public abstract Variable newVar(String name); 494 495 /** 496 * {@code Expression} factory method which returns a new variable with the 497 * given name. 498 */ 499 public abstract Variable newVar(Type type); 500 501 public abstract This newThis(); 502 503 public abstract This newThis(ClassType typeOfOuterClass); 504 505 /** 506 * @return type representing: 507 */ 508 public abstract Type type_boolean(); 509 510 /** 511 * @return type representing: 512 */ 513 public abstract Type type_byte(); 514 515 /** 516 * @return type representing: 517 */ 518 public abstract Type type_char(); 519 520 /** 521 * @return type representing: 522 */ 523 public abstract Type type_double(); 524 525 /** 526 * @return type representing: 527 */ 528 public abstract Type type_float(); 529 530 /** 531 * @return type representing: 532 */ 533 public abstract Type type_int(); 534 535 /** 536 * @return type representing: 537 */ 538 public abstract Type type_long(); 539 540 /** 541 * @return type representing: 542 */ 543 public abstract Type type_short(); 544 545 /** 546 * @return type representing: 547 */ 548 public abstract Type type_void(); 549 550 /** 551 * @return type representing: 552 */ 553 public abstract ClassType typeBigDecimal(); 554 555 /** 556 * @return type representing: 557 */ 558 public abstract ClassType typeBoolean(); 559 560 /** 561 * @return type representing: 562 */ 563 public abstract ClassType typeCalendar(); 564 565 /** 566 * @return type representing: 567 */ 568 public abstract ClassType typeInteger(); 569 570 /** 571 * @return type representing: 572 */ 573 public abstract ClassType typeLong(); 574 575 /** 576 * @return type representing: 577 */ 578 public abstract ClassType typeString(); 579 580 public abstract Super newSuper(); 581 }