001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.servicemix.drools;
018:
019: import java.io.InputStream;
020: import java.io.InputStreamReader;
021: import java.net.URL;
022: import java.util.List;
023: import java.util.Map;
024:
025: import javax.jbi.JBIException;
026: import javax.jbi.management.DeploymentException;
027: import javax.jbi.messaging.ExchangeStatus;
028: import javax.jbi.messaging.MessageExchange;
029: import javax.jbi.servicedesc.ServiceEndpoint;
030: import javax.xml.namespace.NamespaceContext;
031: import javax.xml.namespace.QName;
032:
033: import org.apache.servicemix.common.DefaultComponent;
034: import org.apache.servicemix.common.ServiceUnit;
035: import org.apache.servicemix.common.endpoints.ProviderEndpoint;
036: import org.apache.servicemix.drools.model.JbiHelper;
037: import org.drools.RuleBase;
038: import org.drools.WorkingMemory;
039: import org.drools.compiler.RuleBaseLoader;
040: import org.springframework.core.io.Resource;
041:
042: /**
043: *
044: * @author gnodet
045: * @org.apache.xbean.XBean element="endpoint"
046: */
047: public class DroolsEndpoint extends ProviderEndpoint {
048:
049: private RuleBase ruleBase;
050: private Resource ruleBaseResource;
051: private URL ruleBaseURL;
052: private NamespaceContext namespaceContext;
053: private QName defaultTargetService;
054: private String defaultTargetURI;
055: private Map<String, Object> globals;
056: private List<Object> assertedObjects;
057:
058: public DroolsEndpoint() {
059: super ();
060: }
061:
062: public DroolsEndpoint(DefaultComponent component,
063: ServiceEndpoint endpoint) {
064: super (component, endpoint);
065: }
066:
067: public DroolsEndpoint(ServiceUnit su, QName service, String endpoint) {
068: super (su, service, endpoint);
069: }
070:
071: /**
072: * @return the ruleBase
073: */
074: public RuleBase getRuleBase() {
075: return ruleBase;
076: }
077:
078: /**
079: * @param ruleBase the ruleBase to set
080: */
081: public void setRuleBase(RuleBase ruleBase) {
082: this .ruleBase = ruleBase;
083: }
084:
085: /**
086: * @return the ruleBaseResource
087: */
088: public Resource getRuleBaseResource() {
089: return ruleBaseResource;
090: }
091:
092: /**
093: * @param ruleBaseResource the ruleBaseResource to set
094: */
095: public void setRuleBaseResource(Resource ruleBaseResource) {
096: this .ruleBaseResource = ruleBaseResource;
097: }
098:
099: /**
100: * @return the ruleBaseURL
101: */
102: public URL getRuleBaseURL() {
103: return ruleBaseURL;
104: }
105:
106: /**
107: * @param ruleBaseURL the ruleBaseURL to set
108: */
109: public void setRuleBaseURL(URL ruleBaseURL) {
110: this .ruleBaseURL = ruleBaseURL;
111: }
112:
113: /**
114: * @return the namespaceContext
115: */
116: public NamespaceContext getNamespaceContext() {
117: return namespaceContext;
118: }
119:
120: /**
121: * @param namespaceContext the namespaceContext to set
122: */
123: public void setNamespaceContext(NamespaceContext namespaceContext) {
124: this .namespaceContext = namespaceContext;
125: }
126:
127: /**
128: * @return the variables
129: */
130: public Map<String, Object> getGlobals() {
131: return globals;
132: }
133:
134: /**
135: * @param variables the variables to set
136: */
137: public void setGlobals(Map<String, Object> variables) {
138: this .globals = variables;
139: }
140:
141: public void validate() throws DeploymentException {
142: super .validate();
143: if (ruleBase == null && ruleBaseResource == null
144: && ruleBaseURL == null) {
145: throw new DeploymentException(
146: "Property ruleBase, ruleBaseResource or ruleBaseURL must be set");
147: }
148: }
149:
150: public void start() throws Exception {
151: super .start();
152: if (ruleBase == null) {
153: InputStream is = null;
154: try {
155: if (ruleBaseResource != null) {
156: is = ruleBaseResource.getInputStream();
157: } else if (ruleBaseURL != null) {
158: is = ruleBaseURL.openStream();
159: } else {
160: throw new IllegalArgumentException(
161: "Property ruleBase, ruleBaseResource "
162: + "or ruleBaseURL must be set");
163: }
164: RuleBaseLoader loader = RuleBaseLoader.getInstance();
165: ruleBase = loader.loadFromReader(new InputStreamReader(
166: is));
167: } catch (Exception e) {
168: throw new JBIException(e);
169: } finally {
170: if (is != null) {
171: is.close();
172: }
173: }
174: }
175: }
176:
177: /* (non-Javadoc)
178: * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#process(
179: * javax.jbi.messaging.MessageExchange, javax.jbi.messaging.NormalizedMessage)
180: */
181: public void process(MessageExchange exchange) throws Exception {
182: drools(exchange);
183: }
184:
185: protected void drools(MessageExchange exchange) throws Exception {
186: WorkingMemory memory = createWorkingMemory(exchange);
187: populateWorkingMemory(memory, exchange);
188: memory.fireAllRules();
189: postProcess(exchange, memory);
190: }
191:
192: protected void postProcess(MessageExchange exchange,
193: WorkingMemory memory) throws Exception {
194: if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
195: String uri = getDefaultRouteURI();
196: if (uri != null) {
197: JbiHelper helper = (JbiHelper) memory.getGlobal("jbi");
198: helper.route(uri);
199: }
200: }
201: if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
202: fail(
203: exchange,
204: new Exception(
205: "No rules have handled the exchange. Check your rule base."));
206: }
207: }
208:
209: protected WorkingMemory createWorkingMemory(MessageExchange exchange)
210: throws Exception {
211: return ruleBase.newWorkingMemory();
212: }
213:
214: protected void populateWorkingMemory(WorkingMemory memory,
215: MessageExchange exchange) throws Exception {
216: memory.setGlobal("jbi", new JbiHelper(this , exchange, memory));
217: if (assertedObjects != null) {
218: for (Object o : assertedObjects) {
219: memory.assertObject(o);
220: }
221: }
222: if (globals != null) {
223: for (Map.Entry<String, Object> e : globals.entrySet()) {
224: memory.setGlobal(e.getKey(), e.getValue());
225: }
226: }
227: }
228:
229: public QName getDefaultTargetService() {
230: return defaultTargetService;
231: }
232:
233: public void setDefaultTargetService(QName defaultTargetService) {
234: this .defaultTargetService = defaultTargetService;
235: }
236:
237: public String getDefaultTargetURI() {
238: return defaultTargetURI;
239: }
240:
241: public void setDefaultTargetURI(String defaultTargetURI) {
242: this .defaultTargetURI = defaultTargetURI;
243: }
244:
245: public List<Object> getAssertedObjects() {
246: return assertedObjects;
247: }
248:
249: public void setAssertedObjects(List<Object> assertedObjects) {
250: this .assertedObjects = assertedObjects;
251: }
252:
253: public String getDefaultRouteURI() {
254: if (defaultTargetURI != null) {
255: return defaultTargetURI;
256: } else if (defaultTargetService != null) {
257: String nsURI = defaultTargetService.getNamespaceURI();
258: String sep = (nsURI.indexOf("/") > 0) ? "/" : ":";
259: return "service:" + nsURI + sep
260: + defaultTargetService.getLocalPart();
261: } else {
262: return null;
263: }
264: }
265: }
|