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.io.Reader;
020: import java.io.StringReader;
021: import java.util.ArrayList;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import org.drools.ruleflow.common.core.Process;
026: import org.drools.ruleflow.core.Connection;
027: import org.drools.ruleflow.core.MilestoneNode;
028: import org.drools.ruleflow.core.Node;
029: import org.drools.ruleflow.core.RuleFlowProcess;
030: import org.drools.ruleflow.core.RuleFlowProcessValidationError;
031: import org.drools.ruleflow.core.RuleFlowProcessValidator;
032: import org.drools.ruleflow.core.Split;
033: import org.drools.ruleflow.core.impl.RuleFlowProcessImpl;
034: import org.drools.ruleflow.core.impl.RuleFlowProcessValidatorImpl;
035:
036: import com.thoughtworks.xstream.XStream;
037:
038: /**
039: * A ProcessBuilder can be used to build processes based on XML files
040: * containing a process definition.
041: *
042: * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a>
043: */
044: public class ProcessBuilder {
045:
046: private PackageBuilder packageBuilder;
047: private final List processes = new ArrayList();
048: private final List errors = new ArrayList();
049:
050: public ProcessBuilder(PackageBuilder packageBuilder) {
051: this .packageBuilder = packageBuilder;
052: }
053:
054: public Process[] getProcesses() {
055: return (Process[]) this .processes
056: .toArray(new Process[this .processes.size()]);
057: }
058:
059: public List getErrors() {
060: return errors;
061: }
062:
063: public void addProcess(final Process process) {
064: if (process instanceof RuleFlowProcess) {
065: RuleFlowProcessValidator validator = RuleFlowProcessValidatorImpl
066: .getInstance();
067: RuleFlowProcessValidationError[] errors = validator
068: .validateProcess((RuleFlowProcess) process);
069: if (errors.length != 0) {
070: for (int i = 0; i < errors.length; i++) {
071: this .errors.add(new ParserError(errors[i]
072: .toString(), -1, -1));
073: }
074: } else {
075: this .processes.add(process);
076: // generate and add rule for process
077: String rules = generateRules(process);
078: if (rules != null && rules.length() != 0) {
079: try {
080: packageBuilder
081: .addPackageFromDrl(new StringReader(
082: rules));
083: } catch (Throwable t) {
084: // should never occur
085: }
086: }
087: }
088: }
089: }
090:
091: public void addProcessFromFile(final Reader reader)
092: throws Exception {
093: final XStream stream = new XStream();
094: stream.setMode(XStream.ID_REFERENCES);
095:
096: final ClassLoader oldLoader = Thread.currentThread()
097: .getContextClassLoader();
098: final ClassLoader newLoader = this .getClass().getClassLoader();
099: try {
100: Thread.currentThread().setContextClassLoader(newLoader);
101: final RuleFlowProcess process = (RuleFlowProcess) stream
102: .fromXML(reader);
103: addProcess(process);
104: } catch (final Exception t) {
105: t.printStackTrace();
106: throw t;
107: } finally {
108: Thread.currentThread().setContextClassLoader(oldLoader);
109: }
110: reader.close();
111: }
112:
113: private String generateRules(final Process process) {
114: String result = "";
115: if (process instanceof RuleFlowProcessImpl) {
116: RuleFlowProcessImpl ruleFlow = (RuleFlowProcessImpl) process;
117: List imports = ruleFlow.getImports();
118: if (imports != null) {
119: for (Iterator iterator = imports.iterator(); iterator
120: .hasNext();) {
121: result += "import " + iterator.next() + ";\n";
122: }
123: }
124: Node[] nodes = ruleFlow.getNodes();
125: for (int i = 0; i < nodes.length; i++) {
126: if (nodes[i] instanceof Split) {
127: Split split = (Split) nodes[i];
128: if (split.getType() == Split.TYPE_XOR
129: || split.getType() == Split.TYPE_OR) {
130: for (Iterator iterator = split
131: .getOutgoingConnections().iterator(); iterator
132: .hasNext();) {
133: Connection connection = (Connection) iterator
134: .next();
135: result += createSplitRule(process,
136: connection, split.getConstraint(
137: connection).getConstraint());
138: }
139: }
140: } else if (nodes[i] instanceof MilestoneNode) {
141: MilestoneNode milestone = (MilestoneNode) nodes[i];
142: result += createMilestoneRule(process, milestone);
143: }
144: }
145: }
146: return result;
147: }
148:
149: private String createSplitRule(Process process,
150: Connection connection, String constraint) {
151: return "rule \"RuleFlow-" + process.getId() + "-"
152: + connection.getFrom().getId() + "-"
153: + connection.getTo().getId() + "\" \n"
154: + " ruleflow-group \"DROOLS_SYSTEM\" \n"
155: + " when \n" + " " + constraint + "\n"
156: + " then \n" + "end \n\n";
157: }
158:
159: private String createMilestoneRule(Process process,
160: MilestoneNode milestone) {
161: return "rule \"RuleFlow-" + process.getId() + "-"
162: + milestone.getId() + "\" \n"
163: + " ruleflow-group \"DROOLS_SYSTEM\" \n"
164: + " when \n" + " " + milestone.getConstraint()
165: + "\n" + " then \n" + "end \n\n";
166: }
167: }
|