You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by nb...@apache.org on 2018/03/08 14:57:58 UTC
svn commit: r1826244 [3/3] - in /felix/trunk: ./ fileinstall-plugins/
fileinstall-plugins/installer.test/ fileinstall-plugins/installer.test/src/
fileinstall-plugins/installer.test/src/test/
fileinstall-plugins/installer.test/src/test/java/ fileinstall...
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/Path.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/Path.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/Path.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/Path.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+final class Path {
+
+ public static final String SLASH = "/";
+ public static final String GO_UP = "..";
+
+ private final List<String> parts;
+
+ private Path(List<String> parts) {
+ this.parts = Collections.unmodifiableList(parts);
+ }
+
+ public static Path parse(String string) {
+ String[] splits = string.split(SLASH);
+ List<String> parts = new ArrayList<String>(splits.length);
+ for (String split : splits) {
+ if (split.length() > 0) {
+ parts.add(split);
+ }
+ }
+ return new Path(parts);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ boolean first = true;
+ for (String part : this.parts) {
+ if (!first) {
+ builder.append(SLASH);
+ }
+ builder.append(part);
+ first = false;
+ }
+ return builder.toString();
+ }
+
+ public Path append(String pathString) {
+ return append(parse(pathString));
+ }
+
+ public Path append(Path path) {
+ List<String> newParts = new ArrayList<String>(this.parts.size() + path.parts.size());
+ newParts.addAll(this.parts);
+
+ boolean atRoot = newParts.isEmpty();
+ for (String part : path.parts) {
+ if (GO_UP.equals(part)) {
+ if (atRoot) {
+ newParts.add(GO_UP);
+ } else {
+ newParts.remove(newParts.size() - 1);
+ atRoot = newParts.isEmpty();
+ }
+ } else {
+ newParts.add(part);
+ }
+ }
+
+ return new Path(newParts);
+ }
+
+ public boolean isEmpty() {
+ return this.parts.isEmpty();
+ }
+
+ public int count() {
+ return this.parts.size();
+ }
+
+ public Path parent() {
+ ArrayList<String> newParts = new ArrayList<String>(this.parts);
+ if (newParts.isEmpty()) {
+ newParts.add(GO_UP);
+ } else {
+ newParts.remove(newParts.size() - 1);
+ }
+ return new Path(newParts);
+ }
+
+ public String head() {
+ if (this.parts.isEmpty()) {
+ throw new IllegalArgumentException("Cannot get head of empty path");
+ }
+ return this.parts.get(0);
+ }
+
+ public Path tail() {
+ if (this.parts.isEmpty()) {
+ throw new IllegalArgumentException("Cannot get tail of empty path");
+ }
+
+ ArrayList<String> newParts = new ArrayList<String>(this.parts);
+ newParts.remove(0);
+ return new Path(newParts);
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContext.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContext.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContext.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.felix.fileinstall.plugins.resolver.ResolveRequest;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wiring;
+import org.osgi.service.log.LogService;
+import org.osgi.service.repository.ContentNamespace;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolveContext;
+
+import aQute.bnd.deployer.repository.FixedIndexedRepo;
+import aQute.bnd.service.url.URLConnector;
+
+class PluginResolveContext extends ResolveContext {
+
+ private static final String INITIAL_RESOURCE_CAPABILITY_NAMESPACE = "__initial";
+ private static final String MIME_BUNDLE = "application/vnd.osgi.bundle";
+
+ private final BundleContext bundleContext;
+
+ // The repositories that will be queries for providers
+ private final Map<URI, Repository> repositories = new HashMap<>();
+ // A cache of resource->location (URL), generated during resolve and queried
+ // after resolve in order to fetch the resource.
+ private final Map<Resource, String> resourceLocationMap = new IdentityHashMap<>();
+ // A cache of resources to the repositories which own them; used from
+ // insertHostedCapability method.
+ private final Map<Resource, Repository> resourceRepositoryMap = new IdentityHashMap<>();
+
+ private final ResourceImpl initialResource;
+ private final LogService log;
+
+ PluginResolveContext(BundleContext bundleContext, ResolveRequest request, LogService log) throws IOException {
+ this.bundleContext = bundleContext;
+ this.log = log;
+
+ this.initialResource = new ResourceImpl();
+ for (Requirement requirement : request.getRequirements()) {
+ this.initialResource.addRequirement(requirement);
+ }
+ this.initialResource.addCapability(createIdentityCap(this.initialResource, request.getName()));
+ this.initialResource.addCapability(createInitialMarkerCapability(this.initialResource));
+
+ BasicRegistry registry = new BasicRegistry().put(URLConnector.class, new JarURLConnector());
+
+ for (URI indexUri : request.getIndexes()) {
+ // URI cachedIndexUri = getCacheIndexURI(indexUri);
+ Map<String, String> repoProps = new HashMap<>();
+ repoProps.put("locations", indexUri.toString());
+ FixedIndexedRepo repo = new FixedIndexedRepo();
+ repo.setRegistry(registry);
+ repo.setProperties(repoProps);
+
+ this.repositories.put(indexUri, repo);
+ }
+ }
+
+ @Override
+ public Collection<Resource> getMandatoryResources() {
+ return Collections.<Resource>singleton(this.initialResource);
+ }
+
+ @Override
+ public List<Capability> findProviders(Requirement requirement) {
+ List<Capability> resultCaps = new LinkedList<>();
+
+ // Find from installed bundles
+ Bundle[] bundles = this.bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ if (bundle.getState() == Bundle.UNINSTALLED) {
+ continue; // Skip UNINSTALLED bundles
+ }
+
+ BundleRevision revision = bundle.adapt(BundleRevision.class);
+ List<Capability> bundleCaps = revision.getCapabilities(requirement.getNamespace());
+ if (bundleCaps != null) {
+ for (Capability bundleCap : bundleCaps) {
+ if (match(requirement, bundleCap, this.log)) {
+ resultCaps.add(bundleCap);
+ }
+ }
+ }
+ }
+
+ // Find from repositories
+ for (Entry<URI, Repository> repoEntry : this.repositories.entrySet()) {
+ Repository repository = repoEntry.getValue();
+ Map<Requirement, Collection<Capability>> providers = repository
+ .findProviders(Collections.singleton(requirement));
+ if (providers != null) {
+ Collection<Capability> repoCaps = providers.get(requirement);
+ if (repoCaps != null) {
+ resultCaps.addAll(repoCaps);
+
+ for (Capability repoCap : repoCaps) {
+ // Get the list of physical URIs for this resource.
+ Resource resource = repoCap.getResource();
+ // Keep track of which repositories own which resources.
+ this.resourceRepositoryMap.put(resource, repository);
+
+ // Resolve the Resource's URI relative to the Repository
+ // Index URI and save for later.
+ URI repoIndexUri = repoEntry.getKey();
+ URI resolvedUri = resolveResourceLocation(resource, repoIndexUri);
+ if (resolvedUri != null) {
+ // Cache the resolved URI into the resource URI map,
+ // which will be used after resolve.
+ this.resourceLocationMap.put(resource, resolvedUri.toString());
+ }
+ }
+ }
+ }
+ }
+ return resultCaps;
+ }
+
+ static boolean match(Requirement requirement, Capability capability) {
+ return match(requirement, capability, null);
+ }
+
+ static boolean match(Requirement requirement, Capability capability, LogService log) {
+ // Namespace MUST match
+ if (!requirement.getNamespace().equals(capability.getNamespace())) {
+ return false;
+ }
+
+ // If capability effective!=resolve then it matches only requirements
+ // with same effective
+ String capabilityEffective = capability.getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE);
+ if (capabilityEffective != null) {
+ String requirementEffective = requirement.getDirectives().get(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE);
+ if (!capabilityEffective.equals(Namespace.EFFECTIVE_RESOLVE)
+ && !capabilityEffective.equals(requirementEffective)) {
+ return false;
+ }
+ }
+
+ String filterStr = requirement.getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
+ if (filterStr == null) {
+ return true; // no filter, the requirement always matches
+ }
+
+ try {
+ Filter filter = FrameworkUtil.createFilter(filterStr);
+ return filter.matches(capability.getAttributes());
+ } catch (InvalidSyntaxException e) {
+ if (log != null) {
+ Resource resource = requirement.getResource();
+ String id = resource != null ? getIdentity(resource) : "<unknown>";
+ log.log(LogService.LOG_ERROR,
+ String.format("Invalid filter syntax in requirement from resource %s: %s", id, filterStr), e);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Get the repository index for the specified resource, where 0 indicates an
+ * existing OSGi bundle in the framework and -1 indicates not found. This
+ * method is used by
+ * {@link #insertHostedCapability(List, HostedCapability)}.
+ */
+ private int findResourceRepositoryIndex(Resource resource) {
+ if (resource instanceof BundleRevision) {
+ return 0;
+ }
+
+ int index = 1;
+ Repository repo = this.resourceRepositoryMap.get(resource);
+ if (repo == null) {
+ return -1;
+ }
+ for (Repository match : this.repositories.values()) {
+ if (repo == match) {
+ return index;
+ }
+ index++;
+ }
+ // Still not found
+ return -1;
+ }
+
+ @Override
+ public int insertHostedCapability(List<Capability> capabilities, HostedCapability hc) {
+ int hostIndex = findResourceRepositoryIndex(hc.getResource());
+ if (hostIndex == -1) {
+ throw new IllegalArgumentException(
+ "Hosted capability has host resource not found in any known repository.");
+ }
+
+ for (int pos = 0; pos < capabilities.size(); pos++) {
+ int resourceIndex = findResourceRepositoryIndex(capabilities.get(pos).getResource());
+ if (resourceIndex > hostIndex) {
+ capabilities.add(pos, hc);
+ return pos;
+ }
+ }
+
+ // The list passed by (some versions of) Felix does not support the
+ // single-arg add() method... this throws UnsupportedOperationException.
+ // So we have to call the two-arg add() with an explicit index.
+ int lastPos = capabilities.size();
+ capabilities.add(lastPos, hc);
+ return lastPos;
+ }
+
+ @Override
+ public boolean isEffective(Requirement requirement) {
+ return true;
+ }
+
+ @Override
+ public Map<Resource, Wiring> getWirings() {
+ Map<Resource, Wiring> wiringMap = new HashMap<>();
+ Bundle[] bundles = this.bundleContext.getBundles();
+ for (Bundle bundle : bundles) {
+ // BundleRevision extends Resource
+ BundleRevision revision = bundle.adapt(BundleRevision.class);
+ // BundleWiring extends Wiring
+ BundleWiring wiring = revision.getWiring();
+ if (wiring != null) {
+ wiringMap.put(revision, wiring);
+ }
+ }
+ return wiringMap;
+ }
+
+ boolean isInitialResource(Resource resource) {
+ List<Capability> markerCaps = resource.getCapabilities(INITIAL_RESOURCE_CAPABILITY_NAMESPACE);
+ return markerCaps != null && !markerCaps.isEmpty();
+ }
+
+ String getLocation(Resource resource) {
+ String location;
+ if (resource instanceof BundleRevision) {
+ location = ((BundleRevision) resource).getBundle().getLocation();
+ } else {
+ location = this.resourceLocationMap.get(resource);
+ }
+ return location;
+ }
+
+ private static CapabilityImpl createInitialMarkerCapability(Resource resource) {
+ return new CapabilityImpl(INITIAL_RESOURCE_CAPABILITY_NAMESPACE, Collections.<String,String>emptyMap(), Collections.<String,Object>emptyMap(),
+ resource);
+ }
+
+ private static CapabilityImpl createIdentityCap(Resource resource, String identity) {
+ Map<String, Object> idCapAttrs = new HashMap<>();
+ idCapAttrs.put(IdentityNamespace.IDENTITY_NAMESPACE, identity);
+ CapabilityImpl idCap = new CapabilityImpl(IdentityNamespace.IDENTITY_NAMESPACE, Collections.<String,String>emptyMap(),
+ idCapAttrs, resource);
+ return idCap;
+ }
+
+ private static URI resolveResourceLocation(Resource resource, URI indexUri) {
+ List<Capability> contentCaps = resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
+ if (contentCaps != null) {
+ for (Capability contentCap : contentCaps) {
+ // Ensure this content entry has the correct MIME type for a
+ // bundle
+ if (MIME_BUNDLE.equals(contentCap.getAttributes().get(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE))) {
+ // Get the URI attribute in the index, which is either an
+ // asbolute URI, or a relative URI to be resolved against
+ // the index URI.
+ URI rawUri = null;
+ Object uriObj = contentCap.getAttributes().get(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
+ if (uriObj instanceof URI) {
+ rawUri = (URI) uriObj;
+ } else if (uriObj instanceof String) {
+ rawUri = URI.create((String) uriObj);
+ }
+ if (rawUri != null) {
+ URI resolvedUri = URIUtils.resolve(indexUri, rawUri);
+ return resolvedUri;
+ }
+ }
+ }
+ }
+
+ // No content capability was found in the appropriate form
+ return null;
+ }
+
+ private static String getIdentity(Resource resource) {
+ List<Capability> caps = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (caps == null || caps.isEmpty()) {
+ return "<unknown>";
+ }
+
+ Object idObj = caps.get(0).getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (!(idObj instanceof String)) {
+ return "<unknown>";
+ }
+
+ return (String) idObj;
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolverComponent.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolverComponent.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolverComponent.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolverComponent.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.felix.fileinstall.plugins.resolver.PluginResolver;
+import org.apache.felix.fileinstall.plugins.resolver.ResolveRequest;
+import org.apache.felix.fileinstall.plugins.resolver.ResolveResult;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.osgi.service.log.LogService;
+import org.osgi.service.resolver.Resolver;
+
+@Component(name = "org.apache.felix.fileinstall.plugins.resolver")
+public class PluginResolverComponent implements PluginResolver {
+
+ private BundleContext bundleContext;
+
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
+ LogService log;
+
+ @Reference(target = "(!(" + Constants.SERVICE_BUNDLEID + "=0))")
+ Resolver frameworkResolver;
+
+ @Activate
+ void activate(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public ResolveResult resolve(ResolveRequest request) throws Exception {
+ PluginResolveContext context = new PluginResolveContext(bundleContext, request, log);
+ Map<Resource, List<Wire>> resolved = frameworkResolver.resolve(context);
+
+ ResolveResultImpl result = new ResolveResultImpl(request);
+ for (Entry<Resource, List<Wire>> entry : resolved.entrySet()) {
+ Resource resource = entry.getKey();
+ // Skip the synthetic "<<INITIAL>>" resource
+ if (!context.isInitialResource(resource)) {
+ result.addResource(resource, context.getLocation(resource));
+ }
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/RequirementImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/RequirementImpl.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/RequirementImpl.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/RequirementImpl.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class RequirementImpl extends CapReqBase implements Requirement {
+
+ public static RequirementImpl copy(Requirement req, Resource resource) {
+ return new RequirementImpl(req.getNamespace(), req.getDirectives(), req.getAttributes(), resource);
+ }
+
+ public RequirementImpl(String namespace, Map<String, String> directives, Map<String, Object> attribs, Resource resource) {
+ super(namespace, directives, attribs, resource);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(this.namespace);
+
+ String filterStr = this.directives.get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
+ if (filterStr != null) {
+ sb.append(":").append(filterStr);
+ }
+
+ for (Entry<String,String> directive : this.directives.entrySet()) {
+ if (!Namespace.REQUIREMENT_FILTER_DIRECTIVE.equals(directive.getKey())) {
+ sb.append(", ").append(directive.getKey()).append(":=").append(directive.getValue());
+ }
+ }
+
+ for (Entry<String,Object> attrib : this.attribs.entrySet()) {
+ sb.append(", ").append(attrib.getKey()).append("=").append(attrib.getValue());
+ }
+
+ return sb.toString();
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResolveResultImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResolveResultImpl.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResolveResultImpl.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResolveResultImpl.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.felix.fileinstall.plugins.resolver.ResolveRequest;
+import org.apache.felix.fileinstall.plugins.resolver.ResolveResult;
+import org.osgi.resource.Resource;
+
+public class ResolveResultImpl implements ResolveResult {
+
+ private final ResolveRequest request;
+ private final Map<Resource, String> resourceMap = new IdentityHashMap<>();
+
+ public ResolveResultImpl(ResolveRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public ResolveRequest getRequest() {
+ return request;
+ }
+
+ @Override
+ public Map<Resource, String> getResources() {
+ return Collections.unmodifiableMap(resourceMap);
+ }
+
+ void addResource(Resource resource, String location) {
+ resourceMap.put(resource, location);
+ }
+
+
+}
\ No newline at end of file
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResourceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResourceImpl.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResourceImpl.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/ResourceImpl.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class ResourceImpl implements Resource {
+
+ private final Map<String, List<Requirement>> requirements = new HashMap<>();
+ private final Map<String, List<Capability>> capabilities = new HashMap<>();
+
+ void addRequirement(Requirement req) {
+ if (req.getResource() != this) {
+ req = RequirementImpl.copy(req, this);
+ }
+
+ List<Requirement> list = this.requirements.get(req.getNamespace());
+ if (list == null) {
+ list = new LinkedList<>();
+ this.requirements.put(req.getNamespace(), list);
+ }
+ list.add(req);
+ }
+
+ void addCapability(Capability cap) {
+ if (cap.getResource() != this) {
+ cap = CapabilityImpl.copy(cap, this);
+ }
+
+ List<Capability> list = this.capabilities.get(cap.getNamespace());
+ if (list == null) {
+ list = new LinkedList<>();
+ this.capabilities.put(cap.getNamespace(), list);
+ }
+ list.add(cap);
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ List<Capability> result;
+ if (namespace == null) {
+ result = new LinkedList<>();
+ for (List<Capability> list : this.capabilities.values()) {
+ result.addAll(list);
+ }
+ } else {
+ result = this.capabilities.get(namespace);
+ }
+ return result != null ? result : Collections.<Capability>emptyList();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ List<Requirement> result;
+ if (namespace == null) {
+ result = new LinkedList<>();
+ for (List<Requirement> list : this.requirements.values()) {
+ result.addAll(list);
+ }
+ } else {
+ result = this.requirements.get(namespace);
+ }
+ return result != null ? result : Collections.<Requirement>emptyList();
+ }
+
+ @Override
+ public String toString() {
+ String name = "<unknown>";
+ List<Capability> idCaps = getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (idCaps != null && !idCaps.isEmpty()) {
+ Object nameObj = idCaps.get(0).getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
+ if (nameObj instanceof String) {
+ name = (String) nameObj;
+ }
+ }
+ return name;
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtils.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtils.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtils.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.net.URI;
+
+public final class URIUtils {
+
+ private static final String JAR_URI_SCHEME = "jar";
+
+ private URIUtils() {}
+
+ /**
+ * Resolve a URI relative to a base URI.
+ *
+ * @param baseUri
+ * The base URI which must be absolute.
+ * @param uri
+ * The relative URI to resolve against the specified base. Note
+ * that if this URI is absolute, it will be simply returned
+ * unchanged.
+ * @return An absolute, resolved URI.
+ * @throws {@link IllegalArgumentException} If the {@code baseUri} parameter
+ * is null/relative/opaque or if the URI otherwise cannot be
+ * resolved.
+ */
+ public static URI resolve(URI baseUri, URI uri) throws IllegalArgumentException {
+ URI resolved;
+ if (uri.isAbsolute()) {
+ resolved = uri;
+ } else {
+ URI relative;
+ String innerPath;
+
+ // Work out if the relative URI contains a bang (!), meaning to navigate into a JAR
+ String uriPath = uri.getPath();
+ int bangIndex = uriPath.indexOf('!');
+ if (bangIndex >= 0) {
+ relative = URI.create(uriPath.substring(0, bangIndex));
+ innerPath = uriPath.substring(bangIndex + 1);
+ } else {
+ relative = uri;
+ innerPath = null;
+ }
+
+ // Do the normal resolution
+ if (baseUri == null) {
+ throw new IllegalArgumentException(String.format("Cannot resolve relative URI (%s): base URI is null/unavailable.", uri));
+ }
+ if (!baseUri.isAbsolute()) {
+ throw new IllegalArgumentException(String.format("Cannot resolve relative URI (%s): base URI is also relative (%s).", uri, baseUri));
+ }
+ if (baseUri.isOpaque()) {
+ // Handle "jar:" URIs as a special case
+ if (JAR_URI_SCHEME.equals(baseUri.getScheme())) {
+ resolved = resolveJarUri(baseUri, relative);
+ } else {
+ throw new IllegalArgumentException(String.format("Cannot resolve relative URI (%s): base URI is opaque (%s).", uri, baseUri));
+ }
+ } else {
+ resolved = baseUri.resolve(relative);
+ }
+
+ // If an inner path was indicated, create a jar: URI
+ if (innerPath != null) {
+ resolved = URI.create("jar:" + resolved.toString() + "!" + innerPath);
+ }
+ }
+ return resolved;
+ }
+
+ private static URI resolveJarUri(URI baseUri, URI uri) throws IllegalArgumentException {
+ assert JAR_URI_SCHEME.equals(baseUri.getScheme()) : "not a jar: URI";
+
+ String ssp = baseUri.getSchemeSpecificPart();
+ int bangIndex = ssp.lastIndexOf('!');
+ if (bangIndex == -1) {
+ throw new IllegalArgumentException("Invalid URI in the jar: scheme (missing ! separator): " + baseUri);
+ }
+ URI jarUri = URI.create(ssp.substring(0, bangIndex));
+ String pathStr = ssp.substring(bangIndex + 1);
+
+ String query = baseUri.getQuery();
+ if (query == null) {
+ int qmIndex = pathStr.lastIndexOf('?');
+ if (qmIndex >= 0) {
+ query = pathStr.substring(qmIndex + 1);
+ pathStr = pathStr.substring(0, qmIndex);
+ } else {
+ query = "";
+ }
+ }
+ boolean nonavigate = query.indexOf("navigate=false") >= 0;
+
+ Path basePath = Path.parse(pathStr);
+ Path baseDir = basePath.parent();
+ Path resolvedPath = baseDir.append(uri.getPath());
+
+ URI result;
+ if (resolvedPath.isEmpty()) {
+ result = jarUri;
+ } else if (Path.GO_UP.equals(resolvedPath.head())) {
+ if (nonavigate) {
+ throw new IllegalArgumentException("Cannot navigate outside JAR contents.");
+ }
+ result = jarUri.resolve(resolvedPath.tail().toString());
+ } else {
+ result = URI.create(JAR_URI_SCHEME + ":" + jarUri + "!/" + resolvedPath);
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the file name of the resource references by the URI. Works with jar: URIs, which normally return
+ * {@code null} if the {@link URI#getPath()} call is used.
+ * @param uri
+ * @return The filename, if it can be calculated.
+ * @throws IllegalArgumentException if the filename cannot be calculated (e.g. if the scheme is not understood).
+ */
+ public static String getFileName(URI uri) throws IllegalArgumentException {
+ String filename;
+ if (JAR_URI_SCHEME.equals(uri.getScheme())) {
+ String ssp = uri.getRawSchemeSpecificPart();
+ String innerPath;
+ int bang = ssp.indexOf('!');
+ if (bang < 0) {
+ throw new IllegalArgumentException("Invalid jar content URI; missing '!/' path separator: " + uri);
+ } else {
+ innerPath = ssp.substring(bang + 1);
+ }
+ filename = getPathLastSegment(innerPath);
+ } else {
+ String path = uri.getPath();
+ if (path == null) {
+ throw new IllegalArgumentException("Cannot calculate filename for unknown opaque URI scheme: " + uri);
+ }
+ filename = getPathLastSegment(path);
+ }
+ return filename;
+ }
+
+ private static String getPathLastSegment(String path) {
+ int slash = path.lastIndexOf('/');
+ if (slash < 0) {
+ return path;
+ }
+
+ return path.substring(slash + 1);
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/package-info.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/package-info.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/package-info.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/main/java/org/apache/felix/fileinstall/plugins/resolver/package-info.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.
+ *******************************************************************************/
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.felix.fileinstall.plugins.resolver;
+
Added: felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContextTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContextTest.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContextTest.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/PluginResolveContextTest.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+@SuppressWarnings("serial")
+public class PluginResolveContextTest {
+
+ @Test
+ public void testMatchRequirementsEffectiveResolve() throws Exception {
+ assertTrue("effective should match: req=default, cap=default",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", null),
+ createCapability("foo", null, new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertTrue("effective should match: req=default, cap=resolve",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", null),
+ createCapability("foo", "resolve", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertTrue("effective should match: req=resolve, cap=default",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "resolve"),
+ createCapability("foo", null, new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertTrue("effective should match: req=resolve, cap=resolve",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "resolve"),
+ createCapability("foo", "resolve", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ }
+
+ @Test
+ public void testEffectiveResolveCapsMatchAnyRequirement() throws Exception {
+ // Caps with effective=resolve (or default) match requirements with any
+ // effective=...
+ assertTrue("effective should match: req=blah, cap=default",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "blah"),
+ createCapability("foo", null, new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertTrue("effective should match: req=blah, cap=resolve",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "blah"),
+ createCapability("foo", "resolve", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ }
+
+ @Test
+ public void testEffectiveNonResolveCapsMatchRequirementWithSame() throws Exception {
+ // Caps with effective=!resolve ONLY match reqs with the same effective
+ assertTrue("effective should match: req=blah, cap=blah",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "blah"),
+ createCapability("foo", "blah", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertFalse("effective should NOT match: req=default, cap=blah",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", null),
+ createCapability("foo", "blah", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertFalse("effective should NOT match: req=default, cap=blah",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "resolve"),
+ createCapability("foo", "blah", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ assertFalse("effective should NOT match: req=wibble, cap=blah",
+ PluginResolveContext.match(createRequirement("foo", "(foo=bar)", "wibble"),
+ createCapability("foo", "blah", new HashMap<String, Object>() {
+ {
+ put("foo", "bar");
+ }
+ })));
+ }
+
+ static RequirementImpl createRequirement(String ns, String filter, String effective) {
+ Map<String, String> directives = new HashMap<>();
+ if (filter != null) {
+ directives.put("filter", "(foo=bar)");
+ }
+ if (effective != null) {
+ directives.put("effective", effective);
+ }
+
+ return new RequirementImpl(ns, directives, Collections.<String, Object>emptyMap(), null);
+ }
+
+ static CapabilityImpl createCapability(String ns, String effective, Map<String, Object> attrs) {
+ Map<String, String> directives = new HashMap<>();
+ if (effective != null) {
+ directives.put("effective", effective);
+ }
+
+ return new CapabilityImpl(ns, directives, attrs, null);
+ }
+
+}
Added: felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtilsTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtilsTest.java?rev=1826244&view=auto
==============================================================================
--- felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtilsTest.java (added)
+++ felix/trunk/fileinstall-plugins/resolver/src/test/java/org/apache/felix/fileinstall/plugins/resolver/impl/URIUtilsTest.java Thu Mar 8 14:57:57 2018
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) Intel Corporation
+ * Copyright (c) 2017
+ *
+ * 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
+ *
+ * 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.felix.fileinstall.plugins.resolver.impl;
+
+import java.net.URI;
+
+import junit.framework.TestCase;
+
+public class URIUtilsTest extends TestCase {
+ public void testResolveRelativeHttpUri() {
+ URI resolved = URIUtils.resolve(URI.create("http://example.org/repository/index.xml"), URI.create("bundle/bundle.jar"));
+ assertEquals("http://example.org/repository/bundle/bundle.jar", resolved.toString());
+ }
+
+ public void testResolveAbsoluteFileBaseUri() {
+ URI resolved = URIUtils.resolve(URI.create("file:/Users/bob/repository/index.xml"), URI.create("bundle/bundle.jar"));
+ assertEquals("file:/Users/bob/repository/bundle/bundle.jar", resolved.toString());
+ }
+
+ public void testResolveJarUri() throws Exception {
+ URI base = new URI("jar:http://example.com/systems/example.jar!/sys/system.xml");
+
+ // Sibling resource within the JAR
+ assertEquals("jar:http://example.com/systems/example.jar!/sys/repo/index-nim.xml", URIUtils.resolve(base, new URI("repo/index-nim.xml")).toString());
+
+ // Move up a path within the JAR
+ assertEquals("jar:http://example.com/systems/example.jar!/repo/index-nim.xml", URIUtils.resolve(base, new URI("../repo/index-nim.xml")).toString());
+
+ // Here's the tricky bit... move up a path *outside* the JAR
+ assertEquals("http://example.com/systems/index.xml", URIUtils.resolve(base, new URI("../../index.xml")).toString());
+ assertEquals("http://example.com/repos/index.xml", URIUtils.resolve(base, new URI("../../../repos/index.xml")).toString());
+
+ // Even trickier... move up a path to another JAR, and then into it
+ assertEquals("jar:http://example.com/systems/other.jar!/index.xml", URIUtils.resolve(base, new URI("../../other.jar!/index.xml")).toString());
+ }
+
+ public void testResolveJarUriNoNavigateUp() throws Exception {
+ URI base = new URI("jar:http://example.com/systems/example.jar!/sys/system.xml?navigate=false");
+
+ // Sibling resource within the JAR
+ assertEquals("jar:http://example.com/systems/example.jar!/sys/repo/index-nim.xml", URIUtils.resolve(base, new URI("repo/index-nim.xml")).toString());
+
+ // Move up a path within the JAR
+ assertEquals("jar:http://example.com/systems/example.jar!/repo/index-nim.xml", URIUtils.resolve(base, new URI("../repo/index-nim.xml")).toString());
+
+ // Moving outside the JAR is not allowed
+ try {
+ URIUtils.resolve(base, new URI("../../index.xml"));
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testGetFileName() {
+ assertEquals("system.xml", URIUtils.getFileName(URI.create("http://www.example.com/foo/bar/system.xml")));
+ assertEquals("system.xml", URIUtils.getFileName(URI.create("jar:http://www.example.com/foo/bar/system.jar!/bar/foo/system.xml")));
+
+ try {
+ URIUtils.getFileName(URI.create("blah:this/could/be/anything.xml"));
+ fail("Should throw IllArgExc");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ URIUtils.getFileName(URI.create("jar:http://www.example.com/foo/bar/system.jar"));
+ fail("Should throw IllArgExc");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
Modified: felix/trunk/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/pom.xml?rev=1826244&r1=1826243&r2=1826244&view=diff
==============================================================================
--- felix/trunk/pom.xml (original)
+++ felix/trunk/pom.xml Thu Mar 8 14:57:57 2018
@@ -95,5 +95,8 @@
<module>webconsole-plugins/upnp</module>
<module>webconsole-plugins/useradmin</module>
<module>wireadmin</module>
+ <module>fileinstall-plugins/resolver</module>
+ <module>fileinstall-plugins/installer</module>
+ <module>fileinstall-plugins/installer.test</module>
</modules>
</project>