You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2015/08/12 15:22:03 UTC

svn commit: r1695506 - in /aries/trunk/subsystem: subsystem-core/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ subsystem-core/src/test/java/org/apache/aries...

Author: jwross
Date: Wed Aug 12 13:22:02 2015
New Revision: 1695506

URL: http://svn.apache.org/r1695506
Log:
(1) Assign osgi.identity type of osgi.fragment instead of osgi.bundle to fragment resources.
(2) Add support for the computation of osgi.wiring.host capabilities and requirements for bundle and fragment resources.
(3) Add tests.
(4) Point subsystem-core to version 2.0.0-SNAPSHOT of aries-testsupport.
(5) Update licenses on already modified files.

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java   (with props)
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java   (with props)
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java   (with props)
    aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java   (with props)
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java   (with props)
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java   (with props)
Modified:
    aries/trunk/subsystem/subsystem-core/pom.xml
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRepositoryContent.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestResource.java

Modified: aries/trunk/subsystem/subsystem-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/pom.xml?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/pom.xml (original)
+++ aries/trunk/subsystem/subsystem-core/pom.xml Wed Aug 12 13:22:02 2015
@@ -104,7 +104,7 @@
         <dependency>
             <groupId>org.apache.aries.testsupport</groupId>
             <artifactId>org.apache.aries.testsupport.unit</artifactId>
-            <version>1.0.0</version>
+            <version>2.0.0-SNAPSHOT</version>
             <scope>test</scope>
             <exclusions>
                 <exclusion>

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.internal.AbstractCapability;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.resource.Resource;
+
+public class FragmentHostCapability extends AbstractCapability {
+	public static final String ATTRIBUTE_BUNDLE_VERSION = HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE;
+	public static final String NAMESPACE = HostNamespace.HOST_NAMESPACE;
+	
+	private static Map<String, Object> initializeAttributes(BundleSymbolicNameHeader bsn, BundleVersionHeader version) {
+		if (version == null) {
+			version = new BundleVersionHeader();
+		}
+		Clause clause = bsn.getClauses().get(0);
+		Collection<Attribute> attributes = clause.getAttributes();
+		Map<String, Object> result = new HashMap<String, Object>(attributes.size() + 2);
+		result.put(NAMESPACE, clause.getPath());
+		result.put(ATTRIBUTE_BUNDLE_VERSION, version.getValue());
+		for (Attribute attribute : attributes) {
+			result.put(attribute.getName(), attribute.getValue());
+		}
+		return Collections.unmodifiableMap(result);
+	}
+	
+	private static Map<String, String> initializeDirectives(Collection<Directive> directives) {
+		if (directives.isEmpty())
+			return Collections.emptyMap();
+		Map<String, String> result = new HashMap<String, String>(directives.size());
+		for (Directive directive : directives) {
+			result.put(directive.getName(), directive.getValue());
+		}
+		return Collections.unmodifiableMap(result);
+	}
+	
+	private final Map<String, Object> attributes;
+	private final Map<String, String> directives;
+	private final Resource resource;
+	
+	public FragmentHostCapability(BundleSymbolicNameHeader bsn, BundleVersionHeader version, Resource resource) {
+		if (resource == null)
+			throw new NullPointerException("Missing required parameter: resource");
+		this.resource = resource;
+		attributes = initializeAttributes(bsn, version);
+		directives = initializeDirectives(bsn.getClauses().get(0).getDirectives());
+	}
+
+	@Override
+	public Map<String, Object> getAttributes() {
+		return attributes;
+	}
+
+	@Override
+	public Map<String, String> getDirectives() {
+		return directives;
+	}
+
+	@Override
+	public String getNamespace() {
+		return NAMESPACE;
+	}
+
+	@Override
+	public Resource getResource() {
+		return resource;
+	}
+}

Propchange: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostCapability.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+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.Version;
+import org.osgi.framework.VersionRange;
+import org.osgi.resource.Resource;
+
+public class FragmentHostHeader implements RequirementHeader<FragmentHostHeader.Clause> {
+	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+		public static final String ATTRIBUTE_BUNDLEVERSION = Constants.BUNDLE_VERSION_ATTRIBUTE;
+		
+		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_BUNDLEVERSION);
+            if (parameter == null) {
+                parameters.put(ATTRIBUTE_BUNDLEVERSION, 
+                        new BundleVersionAttribute(
+                                new VersionRange(
+                                        VersionRange.LEFT_CLOSED, 
+                                        new Version("0"), 
+                                        null, 
+                                        VersionRange.RIGHT_OPEN)));
+            }
+		}
+		
+		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: " + 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());
+		}
+
+		@Override
+		public String getPath() {
+			return path;
+		}
+		
+		public String getSymbolicName() {
+			return path;
+		}
+		
+		public FragmentHostRequirement toRequirement(Resource resource) {
+			return new FragmentHostRequirement(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 = Constants.FRAGMENT_HOST;
+	
+	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 FragmentHostHeader(Collection<Clause> clauses) {
+		if (clauses.size() != 1) {
+		    throw new IllegalArgumentException("A " + NAME + " header must have one and only one clause");
+		}
+		this.clauses = new HashSet<Clause>(clauses);
+	}
+	
+	public FragmentHostHeader(String value) {
+		this(processHeader(value));
+	}
+	
+	@Override
+	public Collection<FragmentHostHeader.Clause> getClauses() {
+		return Collections.unmodifiableSet(clauses);
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	public String getValue() {
+		return toString();
+	}
+	
+	@Override
+	public List<FragmentHostRequirement> toRequirements(Resource resource) {
+		List<FragmentHostRequirement> requirements = new ArrayList<FragmentHostRequirement>(clauses.size());
+		for (Clause clause : clauses)
+			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();
+	}
+}

Propchange: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostHeader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.internal.AbstractRequirement;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.resource.Resource;
+
+public class FragmentHostRequirement extends AbstractRequirement {
+    public static final String DIRECTIVE_EXTENSION = HostNamespace.REQUIREMENT_EXTENSION_DIRECTIVE;
+	public static final String DIRECTIVE_FILTER = HostNamespace.REQUIREMENT_FILTER_DIRECTIVE;
+	public static final String NAMESPACE = HostNamespace.HOST_NAMESPACE;
+	
+	private final Map<String, String> directives;
+	private final Resource resource;
+	
+	public FragmentHostRequirement(
+			FragmentHostHeader.Clause clause, Resource resource) {
+		directives = new HashMap<String, String>(clause.getDirectives().size() + 1);
+		for (Directive directive : clause.getDirectives())
+			directives.put(directive.getName(), directive.getValue());
+		StringBuilder builder = new StringBuilder("(&(")
+				.append(NAMESPACE).append('=')
+				.append(clause.getSymbolicName()).append(')');
+		for (Attribute attribute : clause.getAttributes())
+			attribute.appendToFilter(builder);
+		directives.put(DIRECTIVE_FILTER, builder.append(')').toString());
+		this.resource = resource;
+	}
+
+	@Override
+	public Map<String, Object> getAttributes() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Map<String, String> getDirectives() {
+		return Collections.unmodifiableMap(directives);
+	}
+
+	@Override
+	public String getNamespace() {
+		return NAMESPACE;
+	}
+
+	@Override
+	public Resource getResource() {
+		return resource;
+	}
+}

Propchange: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/FragmentHostRequirement.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.core.archive;
 
@@ -117,6 +122,8 @@ public class HeaderFactory {
 			return new BundleRequiredExecutionEnvironmentHeader(value);
 		if (SubsystemLocalizationHeader.NAME.equals(name))
 			return new SubsystemLocalizationHeader(value);
+		if (FragmentHostHeader.NAME.equals(name))
+		    return new FragmentHostHeader(value);
 		return new GenericHeader(name, value);
 			
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResource.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResource.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.core.internal;
 
@@ -29,6 +34,9 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.BundleSymbolicNameHeader;
 import org.apache.aries.subsystem.core.archive.BundleVersionHeader;
 import org.apache.aries.subsystem.core.archive.ExportPackageHeader;
+import org.apache.aries.subsystem.core.archive.FragmentHostCapability;
+import org.apache.aries.subsystem.core.archive.FragmentHostHeader;
+import org.apache.aries.subsystem.core.archive.FragmentHostRequirement;
 import org.apache.aries.subsystem.core.archive.ImportPackageHeader;
 import org.apache.aries.subsystem.core.archive.ProvideBundleCapability;
 import org.apache.aries.subsystem.core.archive.ProvideCapabilityCapability;
@@ -157,7 +165,10 @@ public class BundleResource implements R
 	}
 	
 	private void computeOsgiWiringBundleCapability() {
-		// TODO The osgi.wiring.bundle capability should not be provided for fragments. Nor should the host capability.
+		if (manifest.getHeader(org.osgi.framework.Constants.FRAGMENT_HOST) != null) {
+	        // The osgi.wiring.bundle capability is not provided by fragments.
+	        return;
+	    }
 		BundleSymbolicNameHeader bsnh = (BundleSymbolicNameHeader)manifest.getHeader(BundleSymbolicNameHeader.NAME);
 		BundleVersionHeader bvh = (BundleVersionHeader)manifest.getHeader(BundleVersionHeader.NAME);
 		capabilities.add(new ProvideBundleCapability(bsnh, bvh, this));
@@ -170,6 +181,23 @@ public class BundleResource implements R
 				requirements.add(new RequireBundleRequirement(clause, this));
 	}
 	
+	private void computeOsgiWiringHostCapability() {
+	    if (manifest.getHeader(org.osgi.framework.Constants.FRAGMENT_HOST) != null) {
+            // The osgi.wiring.host capability is not provided by fragments.
+            return;
+        }
+        BundleSymbolicNameHeader bsnh = (BundleSymbolicNameHeader)manifest.getHeader(BundleSymbolicNameHeader.NAME);
+        BundleVersionHeader bvh = (BundleVersionHeader)manifest.getHeader(BundleVersionHeader.NAME);
+        capabilities.add(new FragmentHostCapability(bsnh, bvh, this));
+    }
+	
+	private void computeOsgiWiringHostRequirement() {
+        FragmentHostHeader fhh = (FragmentHostHeader)manifest.getHeader(FragmentHostHeader.NAME);
+        if (fhh != null) {
+            requirements.add(new FragmentHostRequirement(fhh.getClauses().iterator().next(), this));
+        }
+    }
+	
 	private void computeOsgiWiringPackageCapabilities() {
 		ExportPackageHeader eph = (ExportPackageHeader)manifest.getHeader(ExportPackageHeader.NAME);
 		if (eph != null)
@@ -213,6 +241,8 @@ public class BundleResource implements R
 		computeGenericRequirements();
 		computeOsgiWiringBundleRequirements();
 		computeOsgiExecutionEnvironmentRequirement();
+		computeOsgiWiringHostRequirement();
+		computeOsgiWiringHostCapability();
 	}
 	
 	private String getFileName(IFile file) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.core.internal;
 
@@ -70,7 +75,7 @@ public class OsgiIdentityCapability exte
 				resource,
 				((SymbolicNameHeader)manifest.getHeader(Constants.BUNDLE_SYMBOLICNAME)).getSymbolicName(),
 				((VersionHeader)manifest.getHeader(Constants.BUNDLE_VERSION)).getVersion(),
-				IdentityNamespace.TYPE_BUNDLE);
+				manifest.getHeader(Constants.FRAGMENT_HOST) == null ? IdentityNamespace.TYPE_BUNDLE : IdentityNamespace.TYPE_FRAGMENT);
 	}
 
 	public Map<String, Object> getAttributes() {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.core.internal;
 
@@ -41,17 +46,13 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.SubsystemManifest;
 import org.apache.aries.util.filesystem.FileSystem;
 import org.apache.aries.util.filesystem.IDirectory;
-import org.apache.aries.util.manifest.ManifestHeaderProcessor;
 import org.eclipse.equinox.region.Region;
 import org.eclipse.equinox.region.RegionDigraph;
 import org.eclipse.equinox.region.RegionFilter;
 import org.eclipse.equinox.region.RegionFilterBuilder;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.hooks.weaving.WeavingHook;
 import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.namespace.NativeNamespace;

Added: aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.core.archive;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+public class FragmentHostHeaderTest {
+	@Test
+	public void testNullClause() {
+		String headerStr = null;
+		try {
+		    new FragmentHostHeader(headerStr);
+		    fail("Null clause not allowed");
+		}
+		catch (NullPointerException e) {}
+		catch (Exception e) {
+		    fail("Null clause should result in NPE");
+		}
+	}
+	
+	@Test
+    public void testEmptyClause() {
+        String headerStr = "";
+        try {
+            new FragmentHostHeader(headerStr);
+            fail("Empty clause not allowed");
+        }
+        catch (IllegalArgumentException e) {}
+        catch (Exception e) {
+            fail("Empty clause should result in IAE");
+        }
+    }
+	
+	@Test
+    public void testMultipleClauses() {
+        String headerStr = "foo;bundle-version=1.0,bar";
+        try {
+            new FragmentHostHeader(headerStr);
+            fail("Multiple clauses not allowed");
+        }
+        catch (IllegalArgumentException e) {}
+        catch (Exception e) {
+            fail("Multiple cluases should result in IAE");
+        }
+    }
+	
+	@Test
+    public void testSymbolicName() {
+        String headerStr = "org.foo";
+        FragmentHostHeader header = new FragmentHostHeader(headerStr);
+        assertClauses(header, 1);
+        assertSymbolicName(header.getClauses().iterator().next(), headerStr);
+        assertBundleVersionAttribute(
+                header.getClauses().iterator().next(), 
+                new VersionRange(VersionRange.LEFT_CLOSED, new Version("0"), null, VersionRange.RIGHT_OPEN));
+    }
+	
+	@Test
+	public void testBundleVersionSingle() {
+		String headerStr = "com.bar.foo;bundle-version=1.0";
+		FragmentHostHeader header = new FragmentHostHeader(headerStr);
+		assertClauses(header, 1);
+		assertSymbolicName(header.getClauses().iterator().next(), "com.bar.foo");
+		assertBundleVersionAttribute(
+                header.getClauses().iterator().next(), 
+                new VersionRange("1.0"));
+	}
+	
+	@Test
+    public void testBundleVersionRange() {
+        String headerStr = "com.acme.support;bundle-version=\"[2.0,3.0)\"";
+        FragmentHostHeader header = new FragmentHostHeader(headerStr);
+        assertClauses(header, 1);
+        assertSymbolicName(header.getClauses().iterator().next(), "com.acme.support");
+        assertBundleVersionAttribute(
+                header.getClauses().iterator().next(), 
+                new VersionRange(VersionRange.LEFT_CLOSED, new Version("2.0"), new Version("3.0"), VersionRange.RIGHT_OPEN));
+    }
+	
+	private void assertBundleVersionAttribute(FragmentHostHeader.Clause clause, VersionRange value) {
+	    assertEquals("Wrong bundle version", value, ((BundleVersionAttribute)clause.getAttribute(BundleVersionAttribute.NAME)).getVersionRange());
+	}
+	
+	private void assertClauses(FragmentHostHeader header, int expectedClauses) {
+		assertEquals("Wrong number of clauses", expectedClauses, header.getClauses().size());
+	}
+	
+	private void assertSymbolicName(FragmentHostHeader.Clause clause, String value) {
+	    assertEquals("Wrong symbolic name", value, clause.getSymbolicName());
+	}
+}

Propchange: aries/trunk/subsystem/subsystem-core/src/test/java/org/apache/aries/subsystem/core/archive/FragmentHostHeaderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.itests.defect;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.aries.subsystem.itests.Header;
+import org.apache.aries.subsystem.itests.SubsystemTest;
+import org.apache.aries.subsystem.itests.util.TestCapability;
+import org.apache.aries.subsystem.itests.util.TestRepository;
+import org.apache.aries.subsystem.itests.util.TestRepositoryContent;
+import org.apache.aries.subsystem.itests.util.TestRequirement;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+/*
+ * https://issues.apache.org/jira/browse/ARIES-1368
+ */
+public class Aries1368Test extends SubsystemTest {
+    /*
+     * Subsystem-SymbolicName: application.a.esa
+     * Subsystem-Content: bundle.a.jar;type=osgi.bundle, fragment.a.jar;type=osgi.fragment
+     * 
+     * Included in archive:
+     *      bundle.a.jar
+     *      fragment.a.jar
+     */
+    private static final String APPLICATION_A = "application.a.esa";
+    /*
+     * Subsystem-SymbolicName: application.b.esa
+     * Subsystem-Content: bundle.a.jar;type=osgi.bundle, fragment.a.jar;type=osgi.fragment
+     * 
+     * Included in archive:
+     *      bundle.a.jar
+     * 
+     * Included in remote repository:
+     *      fragment.a.jar
+     */
+    private static final String APPLICATION_B = "application.b.esa";
+	/*
+	 * Bundle-SymbolicName: bundle.a.jar
+	 */
+	private static final String BUNDLE_A = "bundle.a.jar";
+	/*
+	 * Bundle-SymbolicName: fragment.a.jar
+	 * Fragment-Host: bundle.a.jar
+	 */
+	private static final String FRAGMENT_A = "fragment.a.jar";
+	
+	private static boolean createdTestFiles;
+	
+	@Before
+	public void createTestFiles() throws Exception {
+		if (createdTestFiles)
+			return;
+		createBundleA();
+		createFragmentA();
+		createApplicationA();
+		createApplicationB();
+		createdTestFiles = true;
+	}
+	
+	private void createBundleA() throws IOException {
+		createBundle(name(BUNDLE_A));
+	}
+	
+	private void createFragmentA() throws IOException {
+		createBundle(name(FRAGMENT_A), new Header(Constants.FRAGMENT_HOST, BUNDLE_A));
+	}
+	
+	private void createApplicationA() throws IOException {
+        createApplicationAManifest();
+        createSubsystem(APPLICATION_A, BUNDLE_A, FRAGMENT_A);
+    }
+    
+    private void createApplicationAManifest() throws IOException {
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_A);
+        attributes.put(SubsystemConstants.SUBSYSTEM_CONTENT, BUNDLE_A + ";type=osgi.bundle," + FRAGMENT_A + ";type=osgi.fragment");
+        createManifest(APPLICATION_A + ".mf", attributes);
+    }
+    
+    private void createApplicationB() throws IOException {
+        createApplicationBManifest();
+        createSubsystem(APPLICATION_B, BUNDLE_A);
+    }
+    
+    private void createApplicationBManifest() throws IOException {
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_B);
+        attributes.put(SubsystemConstants.SUBSYSTEM_CONTENT, BUNDLE_A + ";type=osgi.bundle," + FRAGMENT_A + ";type=osgi.fragment");
+        createManifest(APPLICATION_B + ".mf", attributes);
+    }
+    
+    @Test
+    public void testApplicationWithFragmentInArchiveWithSubsystemContentHeaderWithType() throws Exception {
+        Subsystem applicationA = installSubsystemFromFile(APPLICATION_A);
+        try {
+            assertConstituents(3, applicationA);
+            startSubsystem(applicationA);
+            assertBundleState(Bundle.ACTIVE, BUNDLE_A, applicationA);
+            assertBundleState(Bundle.RESOLVED, FRAGMENT_A, applicationA);
+            Bundle bundle = context(applicationA).getBundleByName(FRAGMENT_A);
+            assertNotNull("Bundle not found: " + FRAGMENT_A, bundle);
+            Resource resource = bundle.adapt(BundleRevision.class);
+            Capability capability = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
+            assertEquals(
+                    "Wrong type", 
+                    IdentityNamespace.TYPE_FRAGMENT, 
+                    capability.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+        }
+        finally {
+            stopAndUninstallSubsystemSilently(applicationA);
+        }
+    }
+    
+    @Test
+    public void testApplicationWithFragmentInRepositoryWithSubsystemContentHeaderWithType() throws Exception {
+        Subsystem applicationB = installSubsystemFromFile(APPLICATION_B);
+        try {
+            assertConstituents(3, applicationB);
+            startSubsystem(applicationB);
+            assertBundleState(Bundle.ACTIVE, BUNDLE_A, applicationB);
+            assertBundleState(Bundle.RESOLVED, FRAGMENT_A, applicationB);
+            Bundle bundle = context(applicationB).getBundleByName(FRAGMENT_A);
+            assertNotNull("Bundle not found: " + FRAGMENT_A, bundle);
+            Resource resource = bundle.adapt(BundleRevision.class);
+            Capability capability = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
+            String type = String.valueOf(capability.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+            assertEquals("Wrong type", IdentityNamespace.TYPE_FRAGMENT, type);
+        }
+        finally {
+            stopAndUninstallSubsystemSilently(applicationB);
+        }
+    }
+    
+    private Repository createTestRepository() throws IOException {
+        return new TestRepository.Builder()
+        .resource(createTestBundleFragmentResource())
+        .build();
+    }
+    
+    private byte[] createTestBundleFragmentContent() throws IOException {
+        Manifest manifest = new Manifest();
+        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        manifest.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME, FRAGMENT_A);
+        manifest.getMainAttributes().putValue(Constants.FRAGMENT_HOST, BUNDLE_A);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        JarOutputStream jos = new JarOutputStream(baos, manifest);
+        jos.close();
+        return baos.toByteArray();
+    }
+    
+    private Resource createTestBundleFragmentResource() throws IOException {
+        return new TestRepositoryContent.Builder()
+        .capability(
+                new TestCapability.Builder()
+                    .namespace(IdentityNamespace.IDENTITY_NAMESPACE)
+                    .attribute(IdentityNamespace.IDENTITY_NAMESPACE, FRAGMENT_A)
+                    .attribute(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, IdentityNamespace.TYPE_FRAGMENT)
+                    .attribute(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, Version.emptyVersion))
+        .requirement(
+                new TestRequirement.Builder()
+                    .namespace(HostNamespace.HOST_NAMESPACE)
+                    .attribute(HostNamespace.HOST_NAMESPACE, BUNDLE_A))
+        .content(createTestBundleFragmentContent())
+        .build();
+    }
+    
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        try {
+            serviceRegistrations.add(
+                    bundleContext.registerService(
+                            Repository.class, 
+                            createTestRepository(), 
+                            null));
+        }
+        catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

Propchange: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1368Test.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRepositoryContent.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRepositoryContent.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRepositoryContent.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRepositoryContent.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.itests.util;
 
@@ -18,13 +23,12 @@ import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.osgi.resource.Requirement;
 import org.osgi.service.repository.RepositoryContent;
 
 public class TestRepositoryContent extends TestResource implements RepositoryContent {
 	public static class Builder {
 		private final List<TestCapability.Builder> capabilities = new ArrayList<TestCapability.Builder>();
-		private final List<Requirement> requirements = new ArrayList<Requirement>();
+		private final List<TestRequirement.Builder> requirements = new ArrayList<TestRequirement.Builder>();
 		
 		private byte[] content;
 		
@@ -42,7 +46,7 @@ public class TestRepositoryContent exten
 			return this;
 		}
 		
-		public Builder requirement(Requirement value) {
+		public Builder requirement(TestRequirement.Builder value) {
 			requirements.add(value);
 			return this;
 		}
@@ -52,7 +56,7 @@ public class TestRepositoryContent exten
 	
 	public TestRepositoryContent(
 			List<TestCapability.Builder> capabilities, 
-			List<Requirement> requirements,
+			List<TestRequirement.Builder> requirements,
 			byte[] content) {
 		super(capabilities, requirements);
 		this.content = content;

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java?rev=1695506&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java Wed Aug 12 13:22:02 2015
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.subsystem.itests.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class TestRequirement implements Requirement {
+	public static class Builder {
+		private final Map<String, Object> attributes = new HashMap<String, Object>();
+		private final Map<String, String> directives = new HashMap<String, String>();
+		
+		private String namespace;
+		private Resource resource;
+		
+		public Builder attribute(String name, Object value) {
+			attributes.put(name,  value);
+			return this;
+		}
+		
+		public TestRequirement build() {
+			return new TestRequirement(namespace, attributes, directives, resource);
+		}
+		
+		public Builder directive(String name, String value) {
+			directives.put(name, value);
+			return this;
+		}
+		
+		public Builder namespace(String value) {
+			namespace = value;
+			return this;
+		}
+		
+		public Builder resource(Resource value) {
+			resource = value;
+			return this;
+		}
+	}
+	
+	private final Map<String, Object> attributes;
+	private final Map<String, String> directives;
+	private final String namespace;
+	private final Resource resource;
+	
+	public TestRequirement(
+			String namespace,
+			Map<String, Object> attributes,
+			Map<String, String> directives,
+			Resource resource) {
+		this.namespace = namespace;
+		this.attributes = new HashMap<String, Object>(attributes);
+		this.directives = new HashMap<String, String>(directives);
+		this.resource = resource;
+	}
+
+	@Override
+	public Map<String, Object> getAttributes() {
+		return Collections.unmodifiableMap(attributes);
+	}
+
+	@Override
+	public Map<String, String> getDirectives() {
+		return Collections.unmodifiableMap(directives);
+	}
+
+	@Override
+	public String getNamespace() {
+		return namespace;
+	}
+
+	@Override
+	public Resource getResource() {
+		return resource;
+	}
+}

Propchange: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestRequirement.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestResource.java?rev=1695506&r1=1695505&r2=1695506&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestResource.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/TestResource.java Wed Aug 12 13:22:02 2015
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.aries.subsystem.itests.util;
 
@@ -24,7 +29,7 @@ import org.osgi.resource.Resource;
 public class TestResource implements Resource {
 	public static class Builder {
 		private final List<TestCapability.Builder> capabilities = new ArrayList<TestCapability.Builder>();
-		private final List<Requirement> requirements = new ArrayList<Requirement>();
+		private final List<TestRequirement.Builder> requirements = new ArrayList<TestRequirement.Builder>();
 		
 		public TestResource build() {
 			return new TestResource(capabilities, requirements);
@@ -35,7 +40,7 @@ public class TestResource implements Res
 			return this;
 		}
 		
-		public Builder requirement(Requirement value) {
+		public Builder requirement(TestRequirement.Builder value) {
 			requirements.add(value);
 			return this;
 		}
@@ -44,11 +49,13 @@ public class TestResource implements Res
 	private final List<Capability> capabilities;
 	private final List<Requirement> requirements;
 	
-	public TestResource(List<TestCapability.Builder> capabilities, List<Requirement> requirements) {
+	public TestResource(List<TestCapability.Builder> capabilities, List<TestRequirement.Builder> requirements) {
 		this.capabilities = new ArrayList<Capability>(capabilities.size());
 		for (TestCapability.Builder builder : capabilities)
 			this.capabilities.add(builder.resource(this).build());
-		this.requirements = requirements;
+		this.requirements = new ArrayList<Requirement>(requirements.size());
+		for (TestRequirement.Builder builder : requirements)
+            this.requirements.add(builder.resource(this).build());
 	}
 
 	@Override