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