aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jwr...@apache.org
Subject svn commit: r1703631 [2/3] - in /aries/trunk/subsystem: subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/capabilityset/ subsystem-core/src/main/java/org/apache/aries/subs...
Date Thu, 17 Sep 2015 14:12:24 GMT
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java Thu Sep 17 14:12:21 2015
@@ -21,140 +21,63 @@ package org.apache.aries.subsystem.core.
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.aries.subsystem.core.capabilityset.SimpleFilter;
 import org.osgi.framework.Constants;
 import org.osgi.framework.namespace.PackageNamespace;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 
-public class ImportPackageHeader implements RequirementHeader<ImportPackageHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
-		private static final String REGEX = "\\((" + PackageNamespace.PACKAGE_NAMESPACE + ")(=)([^\\)]+)\\)";
-		private static final String REGEX1 = '(' + Grammar.PACKAGENAMES + ")(?=;|\\z)";
-		private static final String REGEX2 = '(' + Grammar.PARAMETER + ")(?=;|\\z)";
-		private static final Pattern PATTERN = Pattern.compile(REGEX);
-		private static final Pattern PATTERN1 = Pattern.compile(REGEX1);
-		private static final Pattern PATTERN2 = Pattern.compile(REGEX2);
-
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(Constants.VERSION_ATTRIBUTE);
-			if (parameter == null)
-				parameters.put(Constants.VERSION_ATTRIBUTE, new VersionRangeAttribute());
-		}
-		
-		private final Map<String, Parameter> myParameters = new HashMap<String, Parameter>();
-		private final String myPath;
-		
-		public Clause(Requirement requirement) {
-			if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace()))
-				throw new IllegalArgumentException("Requirement must be in the '" + PackageNamespace.PACKAGE_NAMESPACE + "' namespace");
-			String filter = requirement.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE);
-			String packageName = null;
-			Matcher matcher = PATTERN.matcher(filter);
-			while (matcher.find()) {
-				String name = matcher.group(1);
-				String operator = matcher.group(2);
-				String value = matcher.group(3);
-				if (PackageNamespace.PACKAGE_NAMESPACE.equals(name)) {
-					packageName = value;
-				}
-				else if (PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE.equals(name)) {
-					// TODO Parse the version range from the filter.
+public class ImportPackageHeader extends AbstractClauseBasedHeader<ImportPackageHeader.Clause> implements RequirementHeader<ImportPackageHeader.Clause> {
+    public static class Clause extends AbstractClause {
+    	private static final Collection<Parameter> defaultParameters = 
+    			generateDefaultParameters(VersionRangeAttribute.DEFAULT_VERSION, ResolutionDirective.MANDATORY);
+    	
+		public static Clause valueOf(Requirement requirement) {
+			String namespace = requirement.getNamespace();
+			if (!ImportPackageRequirement.NAMESPACE.equals(namespace)) {
+				throw new IllegalArgumentException("Invalid namespace:" + namespace);
+			}
+			Map<String, String> directives = requirement.getDirectives();
+			String filter = directives.get(ImportPackageRequirement.DIRECTIVE_FILTER);
+			Map<String, Object> attributes = SimpleFilter.attributes(filter);
+			Map<String, Parameter> parameters = new HashMap<String, Parameter>(directives.size() + attributes.size());
+			for (Map.Entry<String, String> entry : directives.entrySet()) {
+				String key = entry.getKey();
+				if (ImportPackageRequirement.DIRECTIVE_FILTER.equals(key)) {
+					continue;
 				}
+				parameters.put(key, DirectiveFactory.createDirective(key, entry.getValue()));
 			}
-			if (packageName == null)
-				throw new IllegalArgumentException("Missing filter key: " + PackageNamespace.PACKAGE_NAMESPACE);
-			myPath = packageName;
-		}
-		
-		public Clause(String clause) {
-			Matcher matcher = PATTERN1.matcher(clause);
-			if (matcher.find())
-				myPath = matcher.group().replaceAll("\\s", "");
-			else
-				throw new IllegalArgumentException("Invalid " + Constants.IMPORT_PACKAGE + " header clause: " + clause);
-			matcher.usePattern(PATTERN2);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				// TODO Revisit the following fix.
-				// All version attributes on an ImportPackage header are ranges. The ParameterFactory will return
-				// a VersionAttribute when the value is a single version (e.g., version=1.0.0). This causes a
-				// ClassCastException in getVersionRangeAttribute().
-				if (parameter instanceof VersionAttribute)
-					parameter = new VersionRangeAttribute(String.valueOf(parameter.getValue()));
-				myParameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(myParameters);
-		}
-		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = myParameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-		
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(myParameters.size());
-			for (Parameter parameter : myParameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
+			for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+				String key = entry.getKey();
+				if (ImportPackageRequirement.NAMESPACE.equals(key)) {
+					continue;
 				}
+				parameters.put(key, AttributeFactory.createAttribute(key, String.valueOf(entry.getValue())));
 			}
-			attributes.trimToSize();
-			return attributes;
+			String path = String.valueOf(attributes.get(ImportPackageRequirement.NAMESPACE));
+			return new Clause(path, parameters, defaultParameters);
 		}
 		
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = myParameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
-			}
-			return null;
+		public Clause(String path, Map<String, Parameter> parameters, Collection<Parameter> defaultParameters) {
+			super(path, parameters, defaultParameters);
 		}
 		
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(myParameters.size());
-			for (Parameter parameter : myParameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
+		public Clause(String clause) {
+            super(
+            		parsePath(clause, Patterns.PACKAGE_NAMES, true),
+            		parseParameters(clause, true), 
+            		defaultParameters);
 		}
 		
 		public Collection<String> getPackageNames() {
-			return Arrays.asList(myPath.split(";"));
+			return Arrays.asList(path.split(";"));
 		}
 		
-		@Override
-		public Parameter getParameter(String name) {
-			return myParameters.get(name);
-		}
-		
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(myParameters.values());
-		}
-		
-		@Override
-		public String getPath() {
-			return myPath;
-		}
 		
 		public VersionRangeAttribute getVersionRangeAttribute() {
 			return (VersionRangeAttribute)getAttribute(Constants.VERSION_ATTRIBUTE);
@@ -163,16 +86,6 @@ public class ImportPackageHeader impleme
 		public ImportPackageRequirement toRequirement(Resource resource) {
 			return new ImportPackageRequirement(this, resource);
 		}
-		
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
 	}
 	
 	public static final String ATTRIBUTE_BUNDLE_SYMBOLICNAME = PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE;
@@ -183,30 +96,24 @@ public class ImportPackageHeader impleme
 	public static final String RESOLUTION_MANDATORY = PackageNamespace.RESOLUTION_MANDATORY;
 	public static final String RESOLUTION_OPTIONAL = PackageNamespace.RESOLUTION_OPTIONAL;
 	
-	private static Collection<Clause> processHeader(String header) {
-		Set<Clause> clauses = new HashSet<Clause>();
-		for (String clause : new ClauseTokenizer(header).getClauses())
-			clauses.add(new Clause(clause));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
-	
 	public ImportPackageHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("An Import-Package header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
+	    super(clauses);
 	}
 	
-	public ImportPackageHeader(String header) {
-		this(processHeader(header));
+	public ImportPackageHeader(String value) {
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
-	public Collection<ImportPackageHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
 
-	public String getName() {
+	@Override
+    public String getName() {
 		return Constants.IMPORT_PACKAGE;
 	}
 	
@@ -224,15 +131,4 @@ public class ImportPackageHeader impleme
 		}
 		return result;
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/OsgiExecutionEnvironmentRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/OsgiExecutionEnvironmentRequirement.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/OsgiExecutionEnvironmentRequirement.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/OsgiExecutionEnvironmentRequirement.java Thu Sep 17 14:12:21 2015
@@ -37,18 +37,32 @@ public class OsgiExecutionEnvironmentReq
 	}
 	
 	public OsgiExecutionEnvironmentRequirement(Collection<BundleRequiredExecutionEnvironmentHeader.Clause> clauses, Resource resource) {
-		StringBuilder filter = new StringBuilder("(|");
+		if (clauses.isEmpty()) {
+			throw new IllegalArgumentException();
+		}
+		if (resource == null) {
+			throw new NullPointerException();
+		}
+		StringBuilder filter = new StringBuilder();
+		if (clauses.size() > 1) {
+			filter.append("(|");
+		}
 		for (BundleRequiredExecutionEnvironmentHeader.Clause clause : clauses) {
 			ExecutionEnvironment ee = clause.getExecutionEnvironment();
-			filter.append("(&(").append(NAMESPACE).append('=').append(ee.getName()).append(')');
 			Version version = ee.getVersion();
-			if (version != null)
-				filter.append('(').append(ATTRIBUTE_VERSION).append('=')
-						.append(version).append(')');
+			if (version != null) {
+				filter.append("(&");
+			}
+			filter.append("(").append(NAMESPACE).append('=').append(ee.getName()).append(')');
+			if (version != null) {
+				filter.append('(').append(ATTRIBUTE_VERSION).append('=').append(version).append("))");
+			}
+		}
+		if (clauses.size() > 1) {
 			filter.append(')');
 		}
 		directives = new HashMap<String, String>(1);
-		directives.put(DIRECTIVE_FILTER, filter.append(')').toString());
+		directives.put(DIRECTIVE_FILTER, filter.toString());
 		this.resource = resource;
 	}
 	

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Patterns.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Patterns.java?rev=1703631&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Patterns.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Patterns.java Thu Sep 17 14:12:21 2015
@@ -0,0 +1,21 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.regex.Pattern;
+
+import org.osgi.framework.namespace.PackageNamespace;
+
+public class Patterns {
+	public static final Pattern NAMESPACE = Pattern.compile('(' + Grammar.NAMESPACE + ")(?=;|\\z)");
+	public static final Pattern OBJECTCLASS_OR_STAR = Pattern.compile("((" + Grammar.OBJECTCLASS + ")|[*])(?=;|\\z)");
+	public static final Pattern PACKAGE_NAMES = Pattern.compile('(' + Grammar.PACKAGENAMES + ")(?=;|\\z)");
+	public static final Pattern PACKAGE_NAMESPACE = Pattern.compile("\\((" + PackageNamespace.PACKAGE_NAMESPACE + ")(=)([^\\)]+)\\)");
+	public static final Pattern PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
+	public static final Pattern PATHS = Pattern.compile('(' + Grammar.PATH + "\\s*(?:\\;\\s*" + Grammar.PATH + ")*)(?=;|\\z)");
+	public static final Pattern SUBSYSTEM_TYPE = Pattern.compile('(' + SubsystemTypeHeader.TYPE_APPLICATION + '|' + SubsystemTypeHeader.TYPE_COMPOSITE + '|' + SubsystemTypeHeader.TYPE_FEATURE + ")(?=;|\\z)");
+	public static final Pattern SYMBOLIC_NAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
+	public static final Pattern WILDCARD_NAMES = Pattern.compile('(' + Grammar.WILDCARD_NAMES + ")(?=;|\\z)");
+	
+	private static final String DIRECTIVE = '(' + Grammar.EXTENDED + ")(:=)(" + Grammar.ARGUMENT + ')';
+	private static final String TYPED_ATTR = '(' + Grammar.EXTENDED + ")(?:(\\:)(" + Grammar.TYPE + "))?=(" + Grammar.ARGUMENT + ')';
+	public static final Pattern TYPED_PARAMETER = Pattern.compile("(?:(?:" + DIRECTIVE + ")|(?:" + TYPED_ATTR + "))(?=;|\\z)");
+}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java Thu Sep 17 14:12:21 2015
@@ -15,53 +15,25 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.apache.aries.subsystem.core.internal.ResourceHelper;
 import org.osgi.framework.VersionRange;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class PreferredProviderHeader implements RequirementHeader<PreferredProviderHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class PreferredProviderHeader extends AbstractClauseBasedHeader<PreferredProviderHeader.Clause> implements RequirementHeader<PreferredProviderHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String ATTRIBUTE_TYPE = TypeAttribute.NAME;
-		public static final String ATTRIBUTE_VERSION = VersionAttribute.NAME;
-		
-		private static final Pattern PATTERN_SYMBOLICNAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(ATTRIBUTE_VERSION);
-			if (parameter == null)
-				parameters.put(ATTRIBUTE_VERSION, VersionRangeAttribute.DEFAULT);
-			parameter = parameters.get(ATTRIBUTE_TYPE);
-			if (parameter == null)
-				parameters.put(ATTRIBUTE_TYPE, TypeAttribute.newInstance(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE));
-		}
-		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+		public static final String ATTRIBUTE_VERSION = VersionRangeAttribute.NAME_VERSION;
 		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_SYMBOLICNAME.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing resource path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				if (parameter instanceof VersionAttribute)
-					parameter = new VersionRangeAttribute(new VersionRange(String.valueOf(parameter.getValue())));
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
+			super(
+					parsePath(clause, Patterns.SYMBOLIC_NAME, false), 
+					parseParameters(clause, true),
+					generateDefaultParameters(
+							VersionRangeAttribute.DEFAULT_VERSION,
+							TypeAttribute.newInstance(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE)));
 		}
 		
 		public boolean contains(Resource resource) {
@@ -73,63 +45,6 @@ public class PreferredProviderHeader imp
 							ResourceHelper.getTypeAttribute(resource));
 		}
 		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
-				}
-			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
 		public String getSymbolicName() {
 			return path;
 		}
@@ -144,7 +59,7 @@ public class PreferredProviderHeader imp
 				return ((VersionRangeAttribute)attribute).getVersionRange();
 			return new VersionRange(attribute.getValue().toString());
 		}
-		
+        
 		public PreferredProviderRequirement toRequirement(Resource resource) {
 			return new PreferredProviderRequirement(this, resource);
 		}
@@ -161,27 +76,20 @@ public class PreferredProviderHeader imp
 	}
 	
 	public static final String NAME = SubsystemConstants.PREFERRED_PROVIDER;
-
-	private static final Pattern PATTERN = Pattern.compile('(' + Grammar.RESOURCE + ")(?=,|\\z)");
-	
-	private static Collection<Clause> processHeader(String header) {
-		Matcher matcher = PATTERN.matcher(header);
-		Set<Clause> clauses = new HashSet<Clause>();
-		while (matcher.find())
-			clauses.add(new Clause(matcher.group()));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
 	
 	public PreferredProviderHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
+		super(clauses);
 	}
 	
 	public PreferredProviderHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	public boolean contains(Resource resource) {
@@ -192,11 +100,6 @@ public class PreferredProviderHeader imp
 	}
 	
 	@Override
-	public Collection<PreferredProviderHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
-
-	@Override
 	public String getName() {
 		return NAME;
 	}
@@ -213,15 +116,4 @@ public class PreferredProviderHeader imp
 			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java Thu Sep 17 14:12:21 2015
@@ -14,35 +14,18 @@
 package org.apache.aries.subsystem.core.archive;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.osgi.framework.Constants;
 import org.osgi.resource.Resource;
 
-public class ProvideCapabilityHeader implements CapabilityHeader<ProvideCapabilityHeader.Clause> {	
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class ProvideCapabilityHeader extends AbstractClauseBasedHeader<ProvideCapabilityHeader.Clause> implements CapabilityHeader<ProvideCapabilityHeader.Clause> {	
+    public static class Clause extends AbstractClause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_USES = Constants.USES_DIRECTIVE;
 		
-		private static final String DIRECTIVE = '(' + Grammar.EXTENDED + ")(:=)(" + Grammar.ARGUMENT + ')';
-		private static final String TYPED_ATTR = '(' + Grammar.EXTENDED + ")(?:(\\:)(" + Grammar.TYPE + "))?=(" + Grammar.ARGUMENT + ')';
-		private static final Pattern PATTERN_NAMESPACE = Pattern.compile('(' + Grammar.NAMESPACE + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile("(?:(?:" + DIRECTIVE + ")|(?:" + TYPED_ATTR + "))(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(DIRECTIVE_EFFECTIVE);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_EFFECTIVE, EffectiveDirective.DEFAULT);
-		}
-		
 		private static String removeQuotes(String value) {
 			if (value == null)
 				return null;
@@ -51,91 +34,33 @@ public class ProvideCapabilityHeader imp
 			return value;
 		}
 		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
-		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_NAMESPACE.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing namespace path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				if (":=".equals(matcher.group(2))) {
-					// This is a directive.
-					parameters.put(matcher.group(1), DirectiveFactory.createDirective(matcher.group(1), removeQuotes(matcher.group(3))));
-				}
-				else if (":".equals(matcher.group(5)))
-					// This is a typed attribute with a declared version.
-					parameters.put(matcher.group(4), new TypedAttribute(matcher.group(4), removeQuotes(matcher.group(7)), matcher.group(6)));
-				else
-					// This is a typed attribute without a declared version.
-					parameters.put(matcher.group(4), new TypedAttribute(matcher.group(4), removeQuotes(matcher.group(7)), TypedAttribute.Type.String));
-			}
-			fillInDefaults(parameters);
-		}
-		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
+            super(
+            		parsePath(clause, Patterns.NAMESPACE, false),
+            		new HashMap<String, Parameter>(),
+            		generateDefaultParameters(
+            				EffectiveDirective.DEFAULT));
+            Matcher matcher = Patterns.TYPED_PARAMETER.matcher(clause);
+            while (matcher.find()) {
+            	if (":=".equals(matcher.group(2))) {
+            		// This is a directive.
+            		parameters.put(matcher.group(1), DirectiveFactory.createDirective(matcher.group(1), removeQuotes(matcher.group(3))));
+            	}
+            	else if (":".equals(matcher.group(5))) {
+            		// This is a typed attribute with a declared version.
+            		parameters.put(matcher.group(4), new TypedAttribute(matcher.group(4), removeQuotes(matcher.group(7)), matcher.group(6)));
+            	}
+            	else {
+            		// This is a typed attribute without a declared version.
+            		parameters.put(matcher.group(4), new TypedAttribute(matcher.group(4), removeQuotes(matcher.group(7)), TypedAttribute.Type.String));
+            	}
+            }
+		}
+
+        public String getNamespace() {
+            return path;
+        }
 
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((TypedAttribute)parameter);
-				}
-			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
-		}
-		
-		public String getNamespace() {
-			return path;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-		
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
 		public ProvideCapabilityCapability toCapability(Resource resource) {
 			return new ProvideCapabilityCapability(this, resource);
 		}
@@ -153,24 +78,18 @@ public class ProvideCapabilityHeader imp
 	
 	public static final String NAME = Constants.PROVIDE_CAPABILITY;
 	
-	private static final Pattern PATTERN = Pattern.compile('(' + Grammar.CAPABILITY + ")(?=,|\\z)");
-	
-	private final Set<Clause> clauses = new HashSet<Clause>();
-	
 	public ProvideCapabilityHeader(String value) {
-		Matcher matcher = PATTERN.matcher(value);
-		while (matcher.find())
-			clauses.add(new Clause(matcher.group()));
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	@Override
-	public Collection<ProvideCapabilityHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
-
-	@Override
 	public String getName() {
 		return NAME;
 	}
@@ -188,14 +107,4 @@ public class ProvideCapabilityHeader imp
 		return result;
 	}
 	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionResourceHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionResourceHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionResourceHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionResourceHeader.java Thu Sep 17 14:12:21 2015
@@ -15,14 +15,7 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.apache.aries.subsystem.core.internal.ResourceHelper;
 import org.apache.aries.subsystem.core.internal.Utils;
@@ -31,35 +24,18 @@ import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class ProvisionResourceHeader implements RequirementHeader<ProvisionResourceHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class ProvisionResourceHeader extends AbstractClauseBasedHeader<ProvisionResourceHeader.Clause> implements RequirementHeader<ProvisionResourceHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String ATTRIBUTE_DEPLOYEDVERSION = DeployedVersionAttribute.NAME;
 		public static final String ATTRIBUTE_RESOURCEID = "resourceId";
 		public static final String ATTRIBUTE_TYPE = TypeAttribute.NAME;
 		
-		private static final Pattern PATTERN_SYMBOLICNAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(ATTRIBUTE_TYPE);
-			if (parameter == null)
-				parameters.put(ATTRIBUTE_TYPE, TypeAttribute.DEFAULT);
-		}
-		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
-		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_SYMBOLICNAME.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing symbolic name path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
+			super(
+            		parsePath(clause, Patterns.SYMBOLIC_NAME, false), 
+            		parseParameters(clause, false), 
+            		generateDefaultParameters(
+            				TypeAttribute.DEFAULT));
 		}
 		
 		public Clause(Resource resource) {
@@ -75,65 +51,13 @@ public class ProvisionResourceHeader imp
 							ResourceHelper.getTypeAttribute(resource));
 		}
 		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute)
-				return (Attribute)result;
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values())
-				if (parameter instanceof Attribute)
-					attributes.add((Attribute)parameter);
-			attributes.trimToSize();
-			return attributes;
-		}
-		
 		public Version getDeployedVersion() {
 			return ((DeployedVersionAttribute)getAttribute(ATTRIBUTE_DEPLOYEDVERSION)).getVersion();
 		}
 
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive)
-				return (Directive)result;
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values())
-				if (parameter instanceof Directive)
-					directives.add((Directive)parameter);
-			directives.trimToSize();
-			return directives;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
 		public String getSymbolicName() {
 			return path;
 		}
-
 		
 		public String getType() {
 			return ((TypeAttribute)getAttribute(ATTRIBUTE_TYPE)).getType();
@@ -142,16 +66,6 @@ public class ProvisionResourceHeader imp
 		public ProvisionResourceRequirement toRequirement(Resource resource) {
 			return new ProvisionResourceRequirement(this, resource);
 		}
-		
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
 	}
 	
 	public static final String NAME = SubsystemConstants.PROVISION_RESOURCE;
@@ -187,25 +101,20 @@ public class ProvisionResourceHeader imp
 			.append(Utils.getId(resource));
 		return builder;
 	}
-	
-	private static Collection<Clause> processHeader(String value) {
-		Collection<String> clauseStrs = new ClauseTokenizer(value).getClauses();
-		Set<Clause> clauses = new HashSet<Clause>(clauseStrs.size());
-		for (String clause : new ClauseTokenizer(value).getClauses())
-			clauses.add(new Clause(clause));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
-	
+		
 	public ProvisionResourceHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
+		super(clauses);
 	}
 	
 	public ProvisionResourceHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	public boolean contains(Resource resource) {
@@ -229,11 +138,6 @@ public class ProvisionResourceHeader imp
 	}
 
 	@Override
-	public Collection<ProvisionResourceHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
-
-	@Override
 	public String getName() {
 		return NAME;
 	}
@@ -250,15 +154,4 @@ public class ProvisionResourceHeader imp
 			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ReferenceDirective.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ReferenceDirective.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ReferenceDirective.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ReferenceDirective.java Thu Sep 17 14:12:21 2015
@@ -31,8 +31,7 @@ public class ReferenceDirective extends
 			return TRUE;
 		if (VALUE_FALSE.equals(value))
 			return FALSE;
-		else
-			throw new IllegalArgumentException("Invalid " + NAME + " directive: " + value);
+        throw new IllegalArgumentException("Invalid " + NAME + " directive: " + value);
 	}
 	
 	private ReferenceDirective(String value) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java Thu Sep 17 14:12:21 2015
@@ -15,76 +15,62 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.aries.subsystem.core.capabilityset.SimpleFilter;
 import org.osgi.framework.Constants;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 
-public class RequireBundleHeader implements RequirementHeader<RequireBundleHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class RequireBundleHeader extends AbstractClauseBasedHeader<RequireBundleHeader.Clause>implements RequirementHeader<RequireBundleHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String ATTRIBUTE_BUNDLEVERSION = Constants.BUNDLE_VERSION_ATTRIBUTE;
 		public static final String DIRECTIVE_RESOLUTION = Constants.RESOLUTION_DIRECTIVE;
 		public static final String DIRECTIVE_VISIBILITY = Constants.VISIBILITY_DIRECTIVE;
 		
-		private static final Pattern PATTERN_SYMBOLICNAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(DIRECTIVE_VISIBILITY);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_VISIBILITY, VisibilityDirective.PRIVATE);
-			parameter = parameters.get(DIRECTIVE_RESOLUTION);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_RESOLUTION, ResolutionDirective.MANDATORY);
-		}
-		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+		private static final Collection<Parameter> defaultParameters = generateDefaultParameters(
+				VersionRangeAttribute.DEFAULT_BUNDLEVERSION,
+				VisibilityDirective.PRIVATE,
+				ResolutionDirective.MANDATORY);
 		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_SYMBOLICNAME.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing bundle description path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
-		}
-		
-		private static final String REGEX = "\\((" + RequireBundleRequirement.NAMESPACE + ")(=)([^\\)]+)\\)";
-		private static final Pattern PATTERN = Pattern.compile(REGEX);
-		
-		public Clause(Requirement requirement) {
-			if (!RequireBundleRequirement.NAMESPACE.equals(requirement.getNamespace()))
-				throw new IllegalArgumentException("Requirement must be in the '" + RequireBundleRequirement.NAMESPACE + "' namespace");
-			String filter = requirement.getDirectives().get(RequireBundleRequirement.DIRECTIVE_FILTER);
-			String path = null;
-			Matcher matcher = PATTERN.matcher(filter);
-			while (matcher.find()) {
-				String name = matcher.group(1);
-				String operator = matcher.group(2);
-				String value = matcher.group(3);
-				if (RequireBundleRequirement.NAMESPACE.equals(name)) {
-					path = value;
+			super(
+            		parsePath(clause, Patterns.SYMBOLIC_NAME, false),
+            		parseParameters(clause, true), 
+            		defaultParameters);
+		}
+		
+		public Clause(String path, Map<String, Parameter> parameters, Collection<Parameter> defaultParameters) {
+			super(path, parameters, defaultParameters);
+		}
+		
+		public static Clause valueOf(Requirement requirement) {
+			String namespace = requirement.getNamespace();
+			if (!RequireBundleRequirement.NAMESPACE.equals(namespace)) {
+				throw new IllegalArgumentException("Invalid namespace:" + namespace);
+			}
+			Map<String, String> directives = requirement.getDirectives();
+			String filter = directives.get(RequireBundleRequirement.DIRECTIVE_FILTER);
+			Map<String, Object> attributes = SimpleFilter.attributes(filter);
+			Map<String, Parameter> parameters = new HashMap<String, Parameter>(directives.size() + attributes.size());
+			for (Map.Entry<String, String> entry : directives.entrySet()) {
+				String key = entry.getKey();
+				if (RequireBundleRequirement.DIRECTIVE_FILTER.equals(key)) {
+					continue;
 				}
-				else if (ATTRIBUTE_BUNDLEVERSION.equals(name)) {
-					// TODO Parse the version range from the filter.
+				parameters.put(key, DirectiveFactory.createDirective(key, entry.getValue()));
+			}
+			for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+				String key = entry.getKey();
+				if (RequireBundleRequirement.NAMESPACE.equals(key)) {
+					continue;
 				}
+				parameters.put(key, AttributeFactory.createAttribute(key, String.valueOf(entry.getValue())));
 			}
-			if (path == null)
-				throw new IllegalArgumentException("Missing filter key: " + RequireBundleRequirement.NAMESPACE);
-			this.path = path;
+			String path = String.valueOf(attributes.get(RequireBundleRequirement.NAMESPACE));
+			return new Clause(path, parameters, defaultParameters);
 		}
 		
 		@Override
@@ -129,21 +115,6 @@ public class RequireBundleHeader impleme
 			return directives;
 		}
 
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
 		public String getSymbolicName() {
 			return path;
 		}
@@ -165,31 +136,22 @@ public class RequireBundleHeader impleme
 	
 	public static final String NAME = Constants.REQUIRE_BUNDLE;
 	
-	private static Collection<Clause> processHeader(String header) {
-		Set<Clause> clauses = new HashSet<Clause>();
-		for (String clause : new ClauseTokenizer(header).getClauses())
-			clauses.add(new Clause(clause));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
-	
 	public RequireBundleHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
+		super(clauses);
 	}
 	
 	public RequireBundleHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	@Override
-	public Collection<RequireBundleHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
-
-	@Override
 	public String getName() {
 		return NAME;
 	}
@@ -206,15 +168,4 @@ public class RequireBundleHeader impleme
 			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java Thu Sep 17 14:12:21 2015
@@ -15,119 +15,58 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.osgi.framework.Constants;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 
-public class RequireCapabilityHeader implements RequirementHeader<RequireCapabilityHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class RequireCapabilityHeader extends AbstractClauseBasedHeader<RequireCapabilityHeader.Clause> implements RequirementHeader<RequireCapabilityHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
 		public static final String DIRECTIVE_RESOLUTION = Constants.RESOLUTION_DIRECTIVE;
 		
-		private static final Pattern PATTERN_NAMESPACE = Pattern.compile('(' + Grammar.NAMESPACE + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(DIRECTIVE_EFFECTIVE);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_EFFECTIVE, EffectiveDirective.RESOLVE);
-			parameter = parameters.get(DIRECTIVE_RESOLUTION);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_RESOLUTION, ResolutionDirective.MANDATORY);
-		}
-		
-		private final String namespace;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+		private static final Collection<Parameter> defaultParameters = generateDefaultParameters(
+				EffectiveDirective.RESOLVE,
+				ResolutionDirective.MANDATORY);
 		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_NAMESPACE.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing namespace path: " + clause);
-			namespace = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
-		}
-		
-		public Clause(Requirement requirement) {
-			namespace = requirement.getNamespace();
-			for (Entry<String, String> directive : requirement.getDirectives().entrySet())
-				parameters.put(directive.getKey(), DirectiveFactory.createDirective(directive.getKey(), directive.getValue()));
-		}
-		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
-				}
-			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
+			super(
+            		parsePath(clause, Patterns.NAMESPACE, false), 
+            		parseParameters(clause, false), 
+            		defaultParameters);
+		}
+		
+		public Clause(String path, Map<String, Parameter> parameters, Collection<Parameter> defaultParameters) {
+			super(path, parameters, defaultParameters);
+		}
+		
+		public static Clause valueOf(Requirement requirement) {
+			if (!(requirement instanceof RequireCapabilityRequirement 
+					|| requirement instanceof OsgiExecutionEnvironmentRequirement)) {
+				throw new IllegalArgumentException();
+			}
+			String namespace = requirement.getNamespace();
+			Map<String, Object> attributes = requirement.getAttributes();
+			Map<String, String> directives = requirement.getDirectives();
+			Map<String, Parameter> parameters = new HashMap<String, Parameter>(attributes.size() + directives.size());
+			for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+				String key = entry.getKey();
+				parameters.put(key, AttributeFactory.createAttribute(key, String.valueOf(entry.getValue())));
+			}
+			for (Map.Entry<String, String> entry : directives.entrySet()) {
+				String key = entry.getKey();
+				parameters.put(key, DirectiveFactory.createDirective(key, entry.getValue()));
 			}
-			return null;
+			String path = namespace;
+			return new Clause(path, parameters, defaultParameters);
 		}
 
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
-		}
-		
 		public String getNamespace() {
-			return namespace;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return getNamespace();
+			return path;
 		}
 		
 		public RequireCapabilityRequirement toRequirement(Resource resource) {
@@ -147,31 +86,19 @@ public class RequireCapabilityHeader imp
 	
 	public static final String NAME = Constants.REQUIRE_CAPABILITY;
 	
-	private static final Pattern PATTERN = Pattern.compile('(' + Grammar.REQUIREMENT + ")(?=,|\\z)");
-	
-	private static Collection<Clause> processHeader(String header) {
-		Matcher matcher = PATTERN.matcher(header);
-		Set<Clause> clauses = new HashSet<Clause>();
-		while (matcher.find())
-			clauses.add(new Clause(matcher.group()));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
-	
 	public RequireCapabilityHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	public RequireCapabilityHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
-	}
-
-	@Override
-	public Collection<RequireCapabilityHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
+		super(clauses);
 	}
 
 	@Override
@@ -192,14 +119,4 @@ public class RequireCapabilityHeader imp
 		return requirements;
 	}
 	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ResolutionDirective.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ResolutionDirective.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ResolutionDirective.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ResolutionDirective.java Thu Sep 17 14:12:21 2015
@@ -32,8 +32,7 @@ public class ResolutionDirective extends
 			return MANDATORY;
 		if (VALUE_OPTIONAL.equals(value))
 			return OPTIONAL;
-		else
-			throw new IllegalArgumentException("Invalid " + Constants.RESOLUTION_DIRECTIVE + " directive: " + value);
+        throw new IllegalArgumentException("Invalid " + Constants.RESOLUTION_DIRECTIVE + " directive: " + value);
 	}
 	
 	private ResolutionDirective(String value) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java Thu Sep 17 14:12:21 2015
@@ -15,14 +15,7 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.apache.aries.subsystem.core.internal.ResourceHelper;
 import org.osgi.framework.Version;
@@ -31,49 +24,24 @@ import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemContentHeader implements RequirementHeader<SubsystemContentHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
-		public static final String ATTRIBUTE_VERSION = VersionRangeAttribute.NAME;
+public class SubsystemContentHeader extends AbstractClauseBasedHeader<SubsystemContentHeader.Clause> implements RequirementHeader<SubsystemContentHeader.Clause> {
+    public static class Clause extends AbstractClause {
+		public static final String ATTRIBUTE_VERSION = VersionRangeAttribute.NAME_VERSION;
 		public static final String ATTRIBUTE_TYPE = TypeAttribute.NAME;
 		public static final String DIRECTIVE_RESOLUTION = ResolutionDirective.NAME;
 		public static final String DIRECTIVE_STARTORDER = StartOrderDirective.NAME;
 		
-		private static final Pattern PATTERN_SYMBOLICNAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(ATTRIBUTE_TYPE);
-			if (parameter == null)
-				parameters.put(ATTRIBUTE_TYPE, TypeAttribute.DEFAULT);
-			parameter = parameters.get(ATTRIBUTE_VERSION);
-			if (parameter == null)
-				parameters.put(ATTRIBUTE_VERSION, VersionRangeAttribute.DEFAULT);
-			parameter = parameters.get(DIRECTIVE_RESOLUTION);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_RESOLUTION, ResolutionDirective.MANDATORY);
-			parameter = parameters.get(DIRECTIVE_STARTORDER);
-			if (parameter == null)
-				// This is an implementation specific start-order directive
-				// value. The specification states there is no default value.
-				parameters.put(DIRECTIVE_STARTORDER, new StartOrderDirective("0"));
-		}
-		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
-		
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_SYMBOLICNAME.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing symbolic name path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				if (parameter instanceof VersionAttribute)
-					parameter = new VersionRangeAttribute(new VersionRange(String.valueOf(parameter.getValue())));
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
+			super(
+					parsePath(clause, Patterns.SYMBOLIC_NAME, false), 
+					parseParameters(clause, true),
+					generateDefaultParameters(
+							TypeAttribute.DEFAULT,
+							VersionRangeAttribute.DEFAULT_VERSION,
+							ResolutionDirective.MANDATORY,
+							// This is an implementation specific start-order directive
+							// value. The specification states there is no default value.
+							new StartOrderDirective("0")));
 		}
 		
 		public Clause(Resource resource) {
@@ -89,57 +57,6 @@ public class SubsystemContentHeader impl
 							ResourceHelper.getTypeAttribute(resource));
 		}
 		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute)
-				return (Attribute)result;
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values())
-				if (parameter instanceof Attribute)
-					attributes.add((Attribute)parameter);
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive)
-				return (Directive)result;
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values())
-				if (parameter instanceof Directive)
-					directives.add((Directive)parameter);
-			directives.trimToSize();
-			return directives;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
 		public String getSymbolicName() {
 			return path;
 		}
@@ -163,16 +80,6 @@ public class SubsystemContentHeader impl
 		public SubsystemContentRequirement toRequirement(Resource resource) {
 			return new SubsystemContentRequirement(this, resource);
 		}
-		
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
 	}
 	
 	public static final String NAME = SubsystemConstants.SUBSYSTEM_CONTENT;
@@ -205,24 +112,19 @@ public class SubsystemContentHeader impl
 		return builder;
 	}
 	
-	private static Collection<Clause> processHeader(String value) {
-		Collection<String> clauseStrs = new ClauseTokenizer(value).getClauses();
-		Set<Clause> clauses = new HashSet<Clause>(clauseStrs.size());
-		for (String clause : clauseStrs)
-			clauses.add(new Clause(clause));
-		return clauses;
-	}
-	
-	private final Set<Clause> clauses;
-	
 	public SubsystemContentHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
+		super(clauses);
 	}
 	
 	public SubsystemContentHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 	
 	public boolean contains(Resource resource) {
@@ -242,11 +144,6 @@ public class SubsystemContentHeader impl
 		return null;
 	}
 	
-	@Override
-	public Collection<SubsystemContentHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
-	}
-	
 	public boolean isMandatory(Resource resource) {
 		Clause clause = getClause(resource);
 		if (clause == null)
@@ -271,15 +168,4 @@ public class SubsystemContentHeader impl
 			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java Thu Sep 17 14:12:21 2015
@@ -14,15 +14,7 @@
 package org.apache.aries.subsystem.core.archive;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
@@ -33,94 +25,21 @@ import org.osgi.resource.Capability;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemExportServiceHeader implements Header<SubsystemExportServiceHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class SubsystemExportServiceHeader extends AbstractClauseBasedHeader<SubsystemExportServiceHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
 
-		private static final Pattern PATTERN_OBJECTCLASS_OR_STAR = Pattern.compile("((" + Grammar.OBJECTCLASS + ")|[*])(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			// No defaults.
-		}
-
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
-
 		public Clause(String clause) {
-			Matcher main = PATTERN_OBJECTCLASS_OR_STAR.matcher(clause);
-			if (!main.find())
-				throw new IllegalArgumentException("Missing objectClass path: " + clause);
-			path = main.group();
-			main.usePattern(PATTERN_PARAMETER);
-			while (main.find()) {
-				Parameter parameter = ParameterFactory.create(main.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
-		}
-
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
-				}
-			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
+			super(
+	        		parsePath(clause, Patterns.OBJECTCLASS_OR_STAR, false), 
+	        		parseParameters(clause, false), 
+	        		generateDefaultParameters());
 		}
 
 		public String getObjectClass() {
 			return path;
 		}
 
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-
 		public List<Capability> toCapabilities(Resource resource) throws InvalidSyntaxException {
 			List<Capability> capabilities = resource.getCapabilities(ServiceNamespace.SERVICE_NAMESPACE);
 			if (capabilities.isEmpty())
@@ -134,16 +53,6 @@ public class SubsystemExportServiceHeade
 			return result;
 		}
 
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
-
 		private Filter computeFilter() throws InvalidSyntaxException {
 			return FrameworkUtil.createFilter(computeFilterString());
 		}
@@ -164,21 +73,15 @@ public class SubsystemExportServiceHeade
 
 	public static final String NAME = SubsystemConstants.SUBSYSTEM_EXPORTSERVICE;
 
-    private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SERVICE_OR_WILDCARD + ")(?=,|\\z)");
-
-	private final Set<Clause> clauses = new HashSet<Clause>();
-
 	public SubsystemExportServiceHeader(String value) {
-		Matcher matcher = PATTERN.matcher(value);
-		while (matcher.find())
-			clauses.add(new Clause(matcher.group()));
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-	}
-
-	@Override
-	public Collection<SubsystemExportServiceHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 
 	@Override
@@ -197,15 +100,4 @@ public class SubsystemExportServiceHeade
 			result.addAll(clause.toCapabilities(resource));
 		return result;
 	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java Thu Sep 17 14:12:21 2015
@@ -15,160 +15,84 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.aries.subsystem.core.capabilityset.SimpleFilter;
 import org.osgi.framework.Constants;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemImportServiceHeader implements RequirementHeader<SubsystemImportServiceHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+public class SubsystemImportServiceHeader extends AbstractClauseBasedHeader<SubsystemImportServiceHeader.Clause> implements RequirementHeader<SubsystemImportServiceHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
 		public static final String DIRECTIVE_RESOLUTION = Constants.RESOLUTION_DIRECTIVE;
 
-		private static final Pattern PATTERN_OBJECTCLASS_OR_STAR = Pattern.compile("((" + Grammar.OBJECTCLASS + ")|[*])(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(DIRECTIVE_EFFECTIVE);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_EFFECTIVE, EffectiveDirective.ACTIVE);
-			parameter = parameters.get(DIRECTIVE_RESOLUTION);
-			if (parameter == null)
-				parameters.put(DIRECTIVE_RESOLUTION, ResolutionDirective.MANDATORY);
-		}
-
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+		private static final Collection<Parameter> defaultParameters = generateDefaultParameters(
+				EffectiveDirective.ACTIVE,
+				ResolutionDirective.MANDATORY);
 
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_OBJECTCLASS_OR_STAR.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Missing namespace path: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
-		}
-
-		public Clause(Requirement requirement) {
-			path = requirement.getNamespace();
-			for (Entry<String, String> directive : requirement.getDirectives().entrySet())
-				parameters.put(directive.getKey(), DirectiveFactory.createDirective(directive.getKey(), directive.getValue()));
-		}
-
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
+			super(
+            		parsePath(clause, Patterns.OBJECTCLASS_OR_STAR, false), 
+            		parseParameters(clause, false), 
+            		defaultParameters);
+		}
+		
+		public Clause(String path, Map<String, Parameter> parameters, Collection<Parameter> defaultParameters) {
+			super(path, parameters, defaultParameters);
+		}
+
+		public static Clause valueOf(Requirement requirement) {
+			String namespace = requirement.getNamespace();
+			if (!SubsystemImportServiceRequirement.NAMESPACE.equals(namespace)) {
+				throw new IllegalArgumentException("Invalid namespace:" + namespace);
+			}
+			Map<String, String> directives = requirement.getDirectives();
+			Map<String, Parameter> parameters = new HashMap<String, Parameter>(directives.size());
+			for (Map.Entry<String, String> entry : directives.entrySet()) {
+				String key = entry.getKey();
+				if (SubsystemImportServiceRequirement.DIRECTIVE_FILTER.equals(key)) {
+					continue;
 				}
+				parameters.put(key, DirectiveFactory.createDirective(key, entry.getValue()));
 			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
+			String filter = directives.get(SubsystemImportServiceRequirement.DIRECTIVE_FILTER);
+			Map<String, Object> attributes = SimpleFilter.attributes(filter);
+			String path = String.valueOf(attributes.remove(Constants.OBJECTCLASS));
+			if (!attributes.isEmpty()) {
+				parameters.put(
+						SubsystemImportServiceRequirement.DIRECTIVE_FILTER, 
+						DirectiveFactory.createDirective(
+								SubsystemImportServiceRequirement.DIRECTIVE_FILTER,
+								SimpleFilter.convert(attributes).toString()));
 			}
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
-		}
-
-		@Override
-		public String getPath() {
-			return path;
+			return new Clause(path, parameters, defaultParameters);
 		}
 
 		public SubsystemImportServiceRequirement toRequirement(Resource resource) {
 			return new SubsystemImportServiceRequirement(this, resource);
 		}
-
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
 	}
 
 	public static final String NAME = SubsystemConstants.SUBSYSTEM_IMPORTSERVICE;
 
-    private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SERVICE_OR_WILDCARD + ")(?=,|\\z)");
-
-	private static Collection<Clause> processHeader(String header) {
-		Matcher matcher = PATTERN.matcher(header);
-		Set<Clause> clauses = new HashSet<Clause>();
-		while (matcher.find())
-			clauses.add(new Clause(matcher.group()));
-		return clauses;
-	}
-
-	private final Set<Clause> clauses;
-
 	public SubsystemImportServiceHeader(String value) {
-		this(processHeader(value));
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
 
 	public SubsystemImportServiceHeader(Collection<Clause> clauses) {
-		if (clauses.isEmpty())
-			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
-		this.clauses = new HashSet<Clause>(clauses);
-	}
-
-	@Override
-	public Collection<SubsystemImportServiceHeader.Clause> getClauses() {
-		return Collections.unmodifiableSet(clauses);
+		super(clauses);
 	}
 
 	@Override
@@ -188,15 +112,4 @@ public class SubsystemImportServiceHeade
 			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java Thu Sep 17 14:12:21 2015
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -272,6 +273,21 @@ public class SubsystemManifest {
 		return requirements;
 	}
 	
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder("[Subsystem Manifest: ");
+		Iterator<Header<?>> iterator = headers.values().iterator();
+		if (iterator.hasNext()) {
+			Header<?> header = iterator.next();
+			builder.append(header.getName()).append('=').append(header.getValue());
+			while (iterator.hasNext()) {
+				header = iterator.next();
+				builder.append(", ").append(header.getName()).append('=').append(header.getValue());
+			}
+		}
+		return builder.append(']').toString();
+	}
+	
 	public void write(OutputStream out) throws IOException {
 		Manifest manifest = new Manifest();
 		Attributes attributes = manifest.getMainAttributes();
@@ -282,4 +298,21 @@ public class SubsystemManifest {
 		}
 		manifest.write(out);
 	}
+
+    @Override
+    public int hashCode() {
+        return 31 * 17 + headers.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+    	if (o == this) {
+    		return true;
+    	}
+    	if (!(o instanceof SubsystemManifest)) {
+    		return false;
+    	}
+    	SubsystemManifest that = (SubsystemManifest)o;
+    	return that.headers.equals(this.headers);
+    }
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java?rev=1703631&r1=1703630&r2=1703631&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java Thu Sep 17 14:12:21 2015
@@ -13,105 +13,20 @@
  */
 package org.apache.aries.subsystem.core.archive;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemTypeHeader implements Header<SubsystemTypeHeader.Clause> {
-	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
-		private static final Pattern PATTERN_TYPE = Pattern.compile('(' + TYPE_APPLICATION + '|' + TYPE_COMPOSITE + '|' + TYPE_FEATURE + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
-		private static final Pattern PATTERN_PROVISION_POLICY = Pattern.compile(PROVISION_POLICY_ACCEPT_DEPENDENCIES + '|' + PROVISION_POLICY_REJECT_DEPENDENCIES);
-		
-		private static void fillInDefaults(Map<String, Parameter> parameters) {
-			Parameter parameter = parameters.get(DIRECTIVE_PROVISION_POLICY);
-			if (parameter == null)
-				parameter = ProvisionPolicyDirective.REJECT_DEPENDENCIES;
-			String value = ((Directive)parameter).getValue();
-			if (!PATTERN_PROVISION_POLICY.matcher(value).matches())
-				throw new IllegalArgumentException("Invalid " + DIRECTIVE_PROVISION_POLICY + " directive: " + value);
-			parameters.put(DIRECTIVE_PROVISION_POLICY, parameter);
-		}
-		
-		private final String path;
-		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
-		
+public class SubsystemTypeHeader extends AbstractClauseBasedHeader<SubsystemTypeHeader.Clause> {
+    public static class Clause extends AbstractClause {
 		public Clause(String clause) {
-			Matcher matcher = PATTERN_TYPE.matcher(clause);
-			if (!matcher.find())
-				throw new IllegalArgumentException("Invalid subsystem type: " + clause);
-			path = matcher.group();
-			matcher.usePattern(PATTERN_PARAMETER);
-			while (matcher.find()) {
-				Parameter parameter = ParameterFactory.create(matcher.group());
-				parameters.put(parameter.getName(), parameter);
-			}
-			fillInDefaults(parameters);
-		}
-		
-		@Override
-		public Attribute getAttribute(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Attribute) {
-				return (Attribute)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Attribute> getAttributes() {
-			ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Attribute) {
-					attributes.add((Attribute)parameter);
-				}
-			}
-			attributes.trimToSize();
-			return attributes;
-		}
-
-		@Override
-		public Directive getDirective(String name) {
-			Parameter result = parameters.get(name);
-			if (result instanceof Directive) {
-				return (Directive)result;
-			}
-			return null;
-		}
-
-		@Override
-		public Collection<Directive> getDirectives() {
-			ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
-			for (Parameter parameter : parameters.values()) {
-				if (parameter instanceof Directive) {
-					directives.add((Directive)parameter);
-				}
-			}
-			directives.trimToSize();
-			return directives;
-		}
-
-		@Override
-		public Parameter getParameter(String name) {
-			return parameters.get(name);
-		}
-
-		@Override
-		public Collection<Parameter> getParameters() {
-			return Collections.unmodifiableCollection(parameters.values());
+			super(
+            		parsePath(clause, Patterns.SUBSYSTEM_TYPE, false), 
+            		parseParameters(clause, false), 
+            		generateDefaultParameters(
+            				ProvisionPolicyDirective.REJECT_DEPENDENCIES));
 		}
-
-		@Override
-		public String getPath() {
-			return path;
-		}
-		
+				
 		public ProvisionPolicyDirective getProvisionPolicyDirective() {
 			return (ProvisionPolicyDirective)getDirective(DIRECTIVE_PROVISION_POLICY);
 		}
@@ -119,16 +34,6 @@ public class SubsystemTypeHeader impleme
 		public String getType() {
 			return path;
 		}
-		
-		@Override
-		public String toString() {
-			StringBuilder builder = new StringBuilder()
-					.append(getPath());
-			for (Parameter parameter : getParameters()) {
-				builder.append(';').append(parameter);
-			}
-			return builder.toString();
-		}
 	}
 	
 	public static final String DIRECTIVE_PROVISION_POLICY = SubsystemConstants.PROVISION_POLICY_DIRECTIVE;
@@ -141,25 +46,23 @@ public class SubsystemTypeHeader impleme
 	
 	public static final SubsystemTypeHeader DEFAULT = new SubsystemTypeHeader(TYPE_APPLICATION);
 	
-	private final Clause clause;
-	
 	public SubsystemTypeHeader(Clause clause) {
-		if (clause == null)
-			throw new NullPointerException("Missing required parameter: clause");
-		this.clause = clause;
+		super(Collections.singleton(clause));
 	}
 	
 	public SubsystemTypeHeader(String value) {
-		this(new Clause(value));
-	}
-	
-	public Clause getClause() {
-		return clause;
+		super(
+				value, 
+				new ClauseFactory<Clause>() {
+					@Override
+					public Clause newInstance(String clause) {
+						return new Clause(clause);
+					}
+				});
 	}
-	
-	@Override
-	public Collection<SubsystemTypeHeader.Clause> getClauses() {
-		return Collections.singleton(clause);
+
+    public Clause getClause() {
+		return clauses.iterator().next();
 	}
 
 	@Override
@@ -168,11 +71,11 @@ public class SubsystemTypeHeader impleme
 	}
 	
 	public ProvisionPolicyDirective getProvisionPolicyDirective() {
-		return clause.getProvisionPolicyDirective();
+		return clauses.iterator().next().getProvisionPolicyDirective();
 	}
 	
 	public String getType() {
-		return clause.getType();
+		return clauses.iterator().next().getType();
 	}
 
 	@Override
@@ -191,15 +94,4 @@ public class SubsystemTypeHeader impleme
 	public boolean isFeature() {
 		return TYPE_FEATURE.equals(getType());
 	}
-	
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Clause clause : getClauses()) {
-			builder.append(clause).append(',');
-		}
-		// Remove the trailing comma. Note at least one clause is guaranteed to exist.
-		builder.deleteCharAt(builder.length() - 1);
-		return builder.toString();
-	}
 }



Mime
View raw message