001: package org.drools.rule.builder.dialect.java;
002:
003: import java.util.Arrays;
004: import java.util.Properties;
005:
006: import org.drools.RuntimeDroolsException;
007: import org.drools.compiler.Dialect;
008: import org.drools.compiler.DialectConfiguration;
009: import org.drools.compiler.PackageBuilder;
010: import org.drools.compiler.PackageBuilderConfiguration;
011:
012: /**
013: *
014: * There are options to use various flavours of runtime compilers.
015: * Apache JCI is used as the interface to all the runtime compilers.
016: *
017: * You can also use the system property "drools.compiler" to set the desired compiler.
018: * The valid values are "ECLIPSE" and "JANINO" only.
019: *
020: * drools.dialect.java.compiler = <ECLIPSE|JANINO>
021: * drools.dialect.java.lngLevel = <1.4|1.5|1.6>
022: *
023: * The default compiler is Eclipse and the default lngLevel is 1.4.
024: * The lngLevel will attempt to autodiscover your system using the
025: * system property "java.version"
026: *
027: * The JavaDialectConfiguration will attempt to validate that the specified compiler
028: * is in the classpath, using ClassLoader.loasClass(String). If you intented to
029: * just Janino sa the compiler you must either overload the compiler property before
030: * instantiating this class or the PackageBuilder, or make sure Eclipse is in the
031: * classpath, as Eclipse is the default.
032: *
033: */
034: public class JavaDialectConfiguration implements DialectConfiguration {
035: public static final int ECLIPSE = 0;
036: public static final int JANINO = 1;
037:
038: public static final String[] LANGUAGE_LEVELS = new String[] {
039: "1.4", "1.5", "1.6" };
040:
041: private String languageLevel;
042:
043: private PackageBuilderConfiguration conf;
044:
045: private int compiler;
046:
047: private JavaDialect dialect;
048:
049: public JavaDialectConfiguration() {
050: }
051:
052: public void init(final PackageBuilderConfiguration conf) {
053: this .conf = conf;
054:
055: setCompiler(getDefaultCompiler());
056:
057: setJavaLanguageLevel(getDefaultLanguageLevel());
058: }
059:
060: public PackageBuilderConfiguration getPackageBuilderConfiguration() {
061: return this .conf;
062: }
063:
064: public Dialect getDialect() {
065: if (this .dialect == null) {
066: this .dialect = new JavaDialect();
067: }
068: return this .dialect;
069: }
070:
071: public String getJavaLanguageLevel() {
072: return this .languageLevel;
073: }
074:
075: /**
076: * You cannot set language level below 1.5, as we need static imports, 1.5 is now the default.
077: * @param level
078: */
079: public void setJavaLanguageLevel(final String languageLevel) {
080: if (Arrays.binarySearch(LANGUAGE_LEVELS, languageLevel) < 0) {
081: throw new RuntimeDroolsException("value '" + languageLevel
082: + "' is not a valid language level");
083: }
084: this .languageLevel = languageLevel;
085: }
086:
087: /**
088: * Set the compiler to be used when building the rules semantic code blocks.
089: * This overrides the default, and even what was set as a system property.
090: */
091: public void setCompiler(final int compiler) {
092: // check that the jar for the specified compiler are present
093: if (compiler == ECLIPSE) {
094: try {
095: getClass().getClassLoader().loadClass(
096: "org.eclipse.jdt.internal.compiler.Compiler");
097: } catch (ClassNotFoundException e) {
098: throw new RuntimeException(
099: "The Eclipse JDT Core jar is not in the classpath");
100: }
101: } else if (compiler == JANINO) {
102: try {
103: getClass().getClassLoader().loadClass(
104: "org.codehaus.janino.Parser");
105: } catch (ClassNotFoundException e) {
106: throw new RuntimeException(
107: "The Janino jar is not in the classpath");
108: }
109: }
110:
111: switch (compiler) {
112: case JavaDialectConfiguration.ECLIPSE:
113: this .compiler = JavaDialectConfiguration.ECLIPSE;
114: break;
115: case JavaDialectConfiguration.JANINO:
116: this .compiler = JavaDialectConfiguration.JANINO;
117: break;
118: default:
119: throw new RuntimeDroolsException("value '" + compiler
120: + "' is not a valid compiler");
121: }
122: }
123:
124: public int getCompiler() {
125: return this .compiler;
126: }
127:
128: /**
129: * This will attempt to read the System property to work out what default to set.
130: * This should only be done once when the class is loaded. After that point, you will have
131: * to programmatically override it.
132: */
133: private int getDefaultCompiler() {
134: try {
135: final String prop = this .conf.getChainedProperties()
136: .getProperty("drools.dialect.java.compiler",
137: "ECLIPSE");
138: if (prop.equals("ECLIPSE".intern())) {
139: return JavaDialectConfiguration.ECLIPSE;
140: } else if (prop.equals("JANINO")) {
141: return JavaDialectConfiguration.JANINO;
142: } else {
143: System.err
144: .println("Drools config: unable to use the drools.compiler property. Using default. It was set to:"
145: + prop);
146: return JavaDialectConfiguration.ECLIPSE;
147: }
148: } catch (final SecurityException e) {
149: System.err
150: .println("Drools config: unable to read the drools.compiler property. Using default.");
151: return JavaDialectConfiguration.ECLIPSE;
152: }
153: }
154:
155: private String getDefaultLanguageLevel() {
156: String level = this .conf.getChainedProperties().getProperty(
157: "drools.dialect.java.compiler.lnglevel", null);
158:
159: if (level == null) {
160: String version = System.getProperty("java.version");
161: if (version.startsWith("1.4")) {
162: level = "1.4";
163: } else if (version.startsWith("1.5")) {
164: level = "1.5";
165: } else if (version.startsWith("1.6")) {
166: level = "1.6";
167: } else {
168: level = "1.4";
169: }
170: }
171:
172: if (Arrays.binarySearch(LANGUAGE_LEVELS, level) < 0) {
173: throw new RuntimeDroolsException("value '" + level
174: + "' is not a valid language level");
175: }
176:
177: return level;
178: }
179:
180: }
|