001: package biz.hammurapi.rules.jsr94;
002:
003: import java.io.IOException;
004: import java.net.MalformedURLException;
005: import java.net.URL;
006: import java.util.ArrayList;
007: import java.util.Iterator;
008: import java.util.List;
009: import java.util.Map;
010: import java.util.Map.Entry;
011:
012: import javax.rules.RuleExecutionSetNotFoundException;
013: import javax.rules.RuleSession;
014: import javax.rules.RuleSessionCreateException;
015: import javax.rules.RuleSessionTypeUnsupportedException;
016:
017: import biz.hammurapi.config.ConfigurationException;
018: import biz.hammurapi.config.Context;
019: import biz.hammurapi.config.DomConfigFactory;
020: import biz.hammurapi.rules.jsr94.FileRuleServiceProvider.Registration;
021: import biz.hammurapi.util.Attributable;
022:
023: /**
024: * Loads rules from configuration file.
025: * @author Pavel Vlasov
026: * @revision $Revision$
027: */
028: class FileRuleRuntime implements javax.rules.RuleRuntime {
029:
030: /**
031: *
032: */
033: private static final long serialVersionUID = 7086685393129078091L;
034: private Map registrations;
035:
036: /**
037: * Constructs rule runtime from registrations.
038: */
039: FileRuleRuntime(Map registrations) {
040: this .registrations = registrations;
041: }
042:
043: /**
044: * Creates rule session.
045: * @param uri Registration name for rule set. If uri starts with <code>direct:</code> then the rest is treated as direct URI of rule set definition.
046: * If URI tail starts with <code>resource:</code> then rule set definition is loaded from classloader resource, otherwise it is loaded from URL.
047: * If URI tails starts with <code>property:</code> then rule set is read from a property. Property value can be of type InputStream, Reader, org.w3c.Element, String, File or URL.
048: * @param properties Vendor-specific properties.
049: * @param type Session type.
050: */
051: public RuleSession createRuleSession(String uri, Map properties,
052: int type) throws RuleSessionTypeUnsupportedException,
053: RuleSessionCreateException,
054: RuleExecutionSetNotFoundException {
055:
056: DomConfigFactory factory = new DomConfigFactory();
057: Object container;
058:
059: try {
060: if (uri == null) {
061: throw new NullPointerException("URI is null");
062: } else if (uri.startsWith("direct:")) {
063: String ss = uri.substring("direct:".length());
064: if (ss.startsWith("resource:")) {
065: container = factory.create(
066: getClass().getClassLoader()
067: .getResourceAsStream(
068: ss.substring("resource:"
069: .length())), null);
070: } else {
071: container = factory.create(new URL(ss), null);
072: }
073: } else
074: synchronized (registrations) {
075: FileRuleServiceProvider.Registration registration = (Registration) registrations
076: .get(uri);
077: if (registration == null) {
078: throw new RuleExecutionSetNotFoundException(
079: "Rule execution set is not found for URI: "
080: + uri);
081: }
082:
083: if (registration.getRef() != null) {
084: if (registration.getRef().startsWith(
085: "resource:")) {
086: container = factory
087: .create(
088: getClass()
089: .getClassLoader()
090: .getResourceAsStream(
091: registration
092: .getRef()
093: .substring(
094: "resource:"
095: .length())),
096: null);
097: } else {
098: container = factory.create(new URL(
099: registration.getRef()), null);
100: }
101: } else if (registration.getValue() != null) {
102: try {
103: container = factory.create(registration
104: .getValue());
105: } catch (ConfigurationException e) {
106: throw new RuleSessionCreateException(
107: "Could instantiate rule set: " + e,
108: e);
109: }
110: } else {
111: throw new RuleSessionCreateException(
112: "Could instantiate rule set because neither reference nor definition is specified for URI: "
113: + uri);
114: }
115:
116: if (registration.getProperties() != null) {
117: setAttributes(registration.getProperties(),
118: container);
119: }
120: }
121: } catch (ConfigurationException e) {
122: throw new RuleSessionCreateException(
123: "Could instantiate rule set: " + e, e);
124: } catch (MalformedURLException e) {
125: throw new RuleSessionCreateException(
126: "Malformed rule set URL: " + e, e);
127: } catch (IOException e) {
128: throw new RuleSessionCreateException(
129: "Could load rule set: " + e, e);
130: }
131:
132: setAttributes(properties, container);
133: biz.hammurapi.rules.jsr94.RuleSession ret = new biz.hammurapi.rules.jsr94.RuleSession(
134: (Context) container, type, uri);
135:
136: // Injecting rule session into container as "*" attribute, which will be addressable as "/@*"
137: if (container instanceof Attributable) {
138: ((Attributable) container).setAttribute("*", ret);
139: }
140: return ret;
141:
142: }
143:
144: private void setAttributes(Map properties, Object container)
145: throws RuleSessionCreateException {
146: if (properties != null && !properties.isEmpty()) {
147: if (container instanceof Attributable) {
148: Iterator it = properties.entrySet().iterator();
149: while (it.hasNext()) {
150: Map.Entry entry = (Entry) it.next();
151: ((Attributable) container).setAttribute(entry
152: .getKey(), entry.getValue());
153: }
154: } else {
155: throw new RuleSessionCreateException(container
156: .getClass().getName()
157: + " must implement " + Attributable.class);
158: }
159: }
160: }
161:
162: /**
163: * Returns list of registrations.
164: */
165: public List getRegistrations() {
166: return new ArrayList(registrations.keySet());
167: }
168:
169: }
|