001: package org.drools.compiler;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.Properties;
024: import java.util.Map.Entry;
025:
026: import org.drools.RuntimeDroolsException;
027: import org.drools.base.accumulators.AccumulateFunction;
028: import org.drools.util.ChainedProperties;
029:
030: /**
031: * This class configures the package compiler.
032: * Dialects and their DialectConfigurations are handled by the DialectRegistry
033: * Normally you will not need to look at this class, unless you want to override the defaults.
034: *
035: * drools.dialect.default = <String>
036: * drools.accumulate.function.<function name> = <qualified class>
037: *
038: * default dialect is java.
039: * Available preconfigured Accumulate functions are:
040: * drools.accumulate.function.average = org.drools.base.accumulators.AverageAccumulateFunction
041: * drools.accumulate.function.max = org.drools.base.accumulators.MaxAccumulateFunction
042: * drools.accumulate.function.min = org.drools.base.accumulators.MinAccumulateFunction
043: * drools.accumulate.function.count = org.drools.base.accumulators.CountAccumulateFunction
044: * drools.accumulate.function.sum = org.drools.base.accumulators.SumAccumulateFunction
045: */
046: public class PackageBuilderConfiguration {
047:
048: private static final String ACCUMULATE_FUNCTION_PREFIX = "drools.accumulate.function.";
049:
050: private Map dialects;
051:
052: private DialectRegistry dialectRegistry;
053:
054: private String defaultDialect;
055:
056: private ClassLoader classLoader;
057:
058: private ChainedProperties chainedProperties;
059:
060: private Map accumulateFunctions;
061:
062: /**
063: * Programmatic properties file, added with lease precedence
064: * @param properties
065: */
066: public PackageBuilderConfiguration(Properties properties) {
067: init(null, properties);
068: }
069:
070: /**
071: * Programmatic properties file, added with lease precedence
072: * @param classLoader
073: * @param properties
074: */
075: public PackageBuilderConfiguration(ClassLoader classLoader,
076: Properties properties) {
077: init(classLoader, properties);
078: }
079:
080: public PackageBuilderConfiguration() {
081: init(null, null);
082: }
083:
084: private void init(ClassLoader classLoader, Properties properties) {
085: if (classLoader == null) {
086: classLoader = Thread.currentThread()
087: .getContextClassLoader();
088: if (classLoader == null) {
089: classLoader = this .getClass().getClassLoader();
090: }
091: }
092: setClassLoader(classLoader);
093:
094: this .chainedProperties = new ChainedProperties(
095: this .classLoader, "packagebuilder.conf");
096:
097: if (properties != null) {
098: this .chainedProperties.addProperties(properties);
099: }
100:
101: this .dialects = new HashMap();
102: this .chainedProperties.mapStartsWith(this .dialects,
103: "drools.dialect", false);
104: setDefaultDialect((String) this .dialects
105: .remove("drools.dialect.default"));
106:
107: this .dialectRegistry = buildDialectRegistry();
108:
109: buildAccumulateFunctionsMap();
110: }
111:
112: public ChainedProperties getChainedProperties() {
113: return this .chainedProperties;
114: }
115:
116: public DialectRegistry buildDialectRegistry() {
117: DialectRegistry registry = new DialectRegistry();
118: ClassLoader classLoader = Thread.currentThread()
119: .getContextClassLoader();
120: for (Iterator it = this .dialects.entrySet().iterator(); it
121: .hasNext();) {
122: Entry entry = (Entry) it.next();
123: String str = (String) entry.getKey();
124: String dialectName = str
125: .substring(str.lastIndexOf(".") + 1);
126: String dialectClass = (String) entry.getValue();
127: try {
128: Class cls = classLoader.loadClass(dialectClass);
129: DialectConfiguration dialectConf = (DialectConfiguration) cls
130: .newInstance();
131: dialectConf.init(this );
132: registry.addDialectConfiguration(dialectName,
133: dialectConf);
134: } catch (Exception e) {
135: throw new RuntimeDroolsException(
136: "Unable to load dialect '" + dialectClass + ":"
137: + dialectName + "'", e);
138: }
139: }
140: return registry;
141: }
142:
143: public DialectRegistry getDialectRegistry() {
144: return this .dialectRegistry;
145: }
146:
147: public Dialect getDefaultDialect() {
148: return this .dialectRegistry.getDialectConfiguration(
149: this .defaultDialect).getDialect();
150: }
151:
152: public void setDefaultDialect(String defaultDialect) {
153: this .defaultDialect = defaultDialect;
154: }
155:
156: public DialectConfiguration getDialectConfiguration(String name) {
157: return (DialectConfiguration) this .dialectRegistry
158: .getDialectConfiguration(name);
159: }
160:
161: public void setDialectConfiguration(String name,
162: DialectConfiguration configuration) {
163: this .dialectRegistry.addDialectConfiguration(name,
164: configuration);
165: }
166:
167: public ClassLoader getClassLoader() {
168: return this .classLoader;
169: }
170:
171: /** Use this to override the classloader that will be used for the rules. */
172: public void setClassLoader(final ClassLoader classLoader) {
173: if (classLoader != null) {
174: this .classLoader = classLoader;
175: }
176: }
177:
178: private void buildAccumulateFunctionsMap() {
179: this .accumulateFunctions = new HashMap();
180: Map temp = new HashMap();
181: this .chainedProperties.mapStartsWith(temp,
182: ACCUMULATE_FUNCTION_PREFIX, true);
183: for (Iterator it = temp.entrySet().iterator(); it.hasNext();) {
184: Map.Entry entry = (Map.Entry) it.next();
185: String identifier = ((String) entry.getKey()).trim()
186: .substring(ACCUMULATE_FUNCTION_PREFIX.length());
187: this .accumulateFunctions.put(identifier, entry.getValue());
188: }
189: }
190:
191: public Map getAccumulateFunctionsMap() {
192: return Collections.unmodifiableMap(this .accumulateFunctions);
193: }
194:
195: public void addAccumulateFunction(String identifier,
196: String className) {
197: this .accumulateFunctions.put(identifier, className);
198: }
199:
200: public void addAccumulateFunction(String identifier, Class clazz) {
201: this .accumulateFunctions.put(identifier, clazz.getName());
202: }
203:
204: public AccumulateFunction getAccumulateFunction(String identifier) {
205: String className = (String) this .accumulateFunctions
206: .get(identifier);
207: if (className == null) {
208: throw new RuntimeDroolsException(
209: "No accumulator function found for identifier: "
210: + identifier);
211: }
212: try {
213: Class clazz = this .classLoader.loadClass(className);
214: return (AccumulateFunction) clazz.newInstance();
215: } catch (ClassNotFoundException e) {
216: throw new RuntimeDroolsException(
217: "Error loading accumulator function for identifier "
218: + identifier + ". Class " + className
219: + " not found", e);
220: } catch (InstantiationException e) {
221: throw new RuntimeDroolsException(
222: "Error loading accumulator function for identifier "
223: + identifier + ". Class " + className
224: + " not found", e);
225: } catch (IllegalAccessException e) {
226: throw new RuntimeDroolsException(
227: "Error loading accumulator function for identifier "
228: + identifier + ". Class " + className
229: + " not found", e);
230: }
231: }
232:
233: }
|