001 /* 002 * JBoss, Home of Professional Open Source. 003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors 004 * as indicated by the @author tags. See the copyright.txt file in the 005 * distribution for a full listing of individual contributors. 006 * 007 * This is free software; you can redistribute it and/or modify it 008 * under the terms of the GNU Lesser General Public License as 009 * published by the Free Software Foundation; either version 2.1 of 010 * the License, or (at your option) any later version. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this software; if not, write to the Free 019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 021 */ 022 package org.jboss.dna.repository.rules; 023 024 import java.io.ByteArrayInputStream; 025 import java.io.InputStreamReader; 026 import java.io.Reader; 027 import java.util.Collections; 028 import java.util.HashMap; 029 import java.util.Map; 030 import javax.rules.RuleServiceProvider; 031 import javax.rules.admin.RuleExecutionSet; 032 import javax.rules.admin.RuleExecutionSetProvider; 033 import net.jcip.annotations.Immutable; 034 import org.jboss.dna.common.component.ClassLoaderFactory; 035 import org.jboss.dna.common.component.ComponentConfig; 036 import org.jboss.dna.common.util.CheckArg; 037 038 /** 039 * A description of a set of rules compatible with a JSR-94 rule engine. 040 * @author Randall Hauch 041 */ 042 @Immutable 043 public class RuleSet extends ComponentConfig implements Cloneable { 044 045 private final String providerUri; 046 private final String ruleSetUri; 047 private final String rules; 048 private final Map<String, Object> properties; 049 050 /** 051 * Create a JSR-94 rule set definition. 052 * @param name the name of the rule set, which is considered the unique identifier 053 * @param description the description 054 * @param classname the name of the Java class used for the component 055 * @param classpath the optional classpath (defined in a way compatible with a {@link ClassLoaderFactory} 056 * @param providerUri the URI of the JSR-94 {@link RuleServiceProvider} implementation to use 057 * @param ruleSetUri the URI of the JSR-94 {@link RuleExecutionSet} represented by this object; if null, the name is used 058 * @param rules the string containing the rules in a provider-specific language 059 * @param properties the provider-specific properties, whose values should be strings or byte arrays (the latter if the 060 * provider expects an {@link Reader} with the value) 061 * @throws IllegalArgumentException if any of the name, classname, provider URI, or rules parameters are null, empty or blank, 062 * or if the classname is not a valid Java classname 063 */ 064 public RuleSet( String name, String description, String classname, String[] classpath, String providerUri, String ruleSetUri, String rules, Map<String, Object> properties ) { 065 super(name, description, System.currentTimeMillis(), classname, classpath); 066 if (ruleSetUri == null) ruleSetUri = name.trim(); 067 CheckArg.isNotEmpty(ruleSetUri, "rule set URI"); 068 CheckArg.isNotEmpty(providerUri, "provider URI"); 069 CheckArg.isNotEmpty(rules, "rules"); 070 this.providerUri = providerUri; 071 this.ruleSetUri = ruleSetUri; 072 this.rules = rules; 073 if (properties == null) properties = Collections.emptyMap(); 074 this.properties = Collections.unmodifiableMap(properties); 075 } 076 077 /** 078 * Get the URI of the JSR-94 {@link RuleServiceProvider} implementation that should be used. 079 * @return the URI of the JSR-94 implementation; never null, empty or blank 080 */ 081 public String getProviderUri() { 082 return this.providerUri; 083 } 084 085 /** 086 * Get the URI of this rule set. The value must be valid as defined by JSR-94 {@link RuleExecutionSet}. 087 * @return the rule set's URI; never null, empty or blank 088 */ 089 public String getRuleSetUri() { 090 return this.ruleSetUri; 091 } 092 093 /** 094 * Get the rules defined in terms of the language reqired by the {@link #getProviderUri() provider}. 095 * @return the rules for this rule set 096 */ 097 public String getRules() { 098 return this.rules; 099 } 100 101 /** 102 * Get this rule set's properties as an unmodifiable map. Note that the values of these properties are either strings if the 103 * value is to be {@link #getExecutionSetProperties() passed} literally, or a byte array if the value is to be 104 * {@link #getExecutionSetProperties() passed} as an InputStream. 105 * @return the unmodifiable properties; never null but possible empty 106 */ 107 public Map<String, Object> getProperties() { 108 return this.properties; 109 } 110 111 /** 112 * Get the properties for this rule set that can be passed to an {@link RuleExecutionSetProvider}'s 113 * {@link RuleExecutionSetProvider#createRuleExecutionSet(String, Map) createRuleExecutionSet} method. 114 * <p> 115 * This method converts any byte array value in the {@link #getProperties() properties} into an {@link Reader}. Since 116 * {@link ByteArrayInputStream} is used, there is no need to close these stream. 117 * </p> 118 * @return the properties; never null but possible empty 119 */ 120 public Map<Object, Object> getExecutionSetProperties() { 121 Map<Object, Object> props = new HashMap<Object, Object>(); 122 for (Map.Entry<String, Object> entry : this.properties.entrySet()) { 123 String key = entry.getKey(); 124 Object value = entry.getValue(); 125 if (value instanceof byte[]) { 126 value = new InputStreamReader(new ByteArrayInputStream((byte[])value)); 127 } 128 props.put(key, value); 129 } 130 return props; 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 @Override 137 public boolean hasChanged( ComponentConfig obj ) { 138 if (super.hasChanged(obj)) return true; 139 RuleSet that = (RuleSet)obj; 140 if (!this.providerUri.equals(that.providerUri)) return true; 141 if (!this.ruleSetUri.equals(that.ruleSetUri)) return true; 142 return false; 143 } 144 145 /** 146 * {@inheritDoc} 147 */ 148 @Override 149 public RuleSet clone() { 150 return new RuleSet(this.getName(), this.getDescription(), this.getComponentClassname(), this.getComponentClasspathArray(), this.providerUri, this.ruleSetUri, this.rules, this.properties); 151 } 152 }