You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2018/04/26 10:00:59 UTC
[sling-whiteboard] branch master updated: Use felix utils
ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil.
As with that the feature-support module is empty, remove it.
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new 6ff9e42 Use felix utils ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil. As with that the feature-support module is empty, remove it.
6ff9e42 is described below
commit 6ff9e42b61ba919ca2824c44f53917a0baf7211a
Author: Karl Pauls <kp...@adobe.com>
AuthorDate: Thu Apr 26 12:00:25 2018 +0200
Use felix utils ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil. As with that the feature-support module is empty, remove it.
---
featuremodel/feature-analyser/pom.xml | 8 +-
.../task/impl/CheckBundleExportsImports.java | 2 +-
.../task/impl/CheckRequirementsCapabilities.java | 35 +-
.../sling/feature/scanner/BundleDescriptor.java | 1 -
.../apache/sling/feature/scanner/Descriptor.java | 1 -
.../apache/sling/feature/scanner}/PackageInfo.java | 2 +-
.../feature/scanner/impl/BundleDescriptorImpl.java | 77 +-
.../scanner/impl/FelixFrameworkScanner.java | 76 +-
.../scanner/impl/BundleDescriptorImplTest.java | 73 ++
.../scanner/impl/FelixFrameworkScannerTest.java | 21 +
featuremodel/feature-applicationbuilder/pom.xml | 6 -
featuremodel/feature-karaf/pom.xml | 6 -
featuremodel/feature-launcher/pom.xml | 7 +-
featuremodel/feature-modelconverter/pom.xml | 6 -
featuremodel/feature-resolver/pom.xml | 6 -
.../feature/resolver/impl/BundleResourceImpl.java | 33 +-
.../sling/feature/resolver/AnalyserTest.java | 1 +
.../feature/resolver/TestBundleResourceImpl.java | 2 +-
.../resolver/impl/BundleResourceImplTest.java | 46 +-
featuremodel/feature-support/pom.xml | 132 ---
.../feature/support/util/CapabilityMatcher.java | 34 -
.../sling/feature/support/util/ManifestParser.java | 1025 --------------------
.../sling/feature/support/util/ManifestUtil.java | 175 ----
.../sling/feature/support/util/SimpleFilter.java | 650 -------------
.../feature/support/util/ManifestUtilTest.java | 43 -
featuremodel/osgifeature-maven-plugin/pom.xml | 5 -
featuremodel/pom.xml | 1 -
27 files changed, 259 insertions(+), 2215 deletions(-)
diff --git a/featuremodel/feature-analyser/pom.xml b/featuremodel/feature-analyser/pom.xml
index a2bca4b..0241695 100644
--- a/featuremodel/feature-analyser/pom.xml
+++ b/featuremodel/feature-analyser/pom.xml
@@ -56,7 +56,7 @@
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
- <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.sling.commons.osgi,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
+ <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.commons.johnzon,org.apache.sling.commons.osgi,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
</configuration>
</execution>
</executions>
@@ -126,12 +126,6 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.osgi</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
index 0fc5a00..6a44c97 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
@@ -29,7 +29,7 @@ import java.util.TreeMap;
import org.apache.sling.feature.analyser.task.AnalyserTask;
import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
import org.osgi.framework.Version;
public class CheckBundleExportsImports implements AnalyserTask {
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
index daa0a91..bd1732f 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
@@ -22,6 +22,7 @@ import org.apache.sling.feature.analyser.task.AnalyserTask;
import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
import org.apache.sling.feature.scanner.ArtifactDescriptor;
import org.apache.sling.feature.scanner.BundleDescriptor;
+import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.Requirement;
import java.util.ArrayList;
@@ -69,22 +70,30 @@ public class CheckRequirementsCapabilities implements AnalyserTask {
if (info.getRequirements() != null)
{
for (Requirement requirement : info.getRequirements()) {
- List<ArtifactDescriptor> candidates = getCandidates(artifacts, requirement);
+ if (!BundleRevision.PACKAGE_NAMESPACE.equals(requirement.getNamespace()))
+ {
+ List<ArtifactDescriptor> candidates = getCandidates(artifacts, requirement);
- if (candidates.isEmpty()) {
- if ( "osgi.service".equals(requirement.getNamespace()) ){
- // osgi.service is special - we don't provide errors or warnings in this case
- continue;
+ if (candidates.isEmpty())
+ {
+ if ("osgi.service".equals(requirement.getNamespace()))
+ {
+ // osgi.service is special - we don't provide errors or warnings in this case
+ continue;
+ }
+ if (!RequirementImpl.isOptional(requirement))
+ {
+ ctx.reportError(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "no artifact is providing a matching capability in this start level."));
+ }
+ else
+ {
+ ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "while the requirement is optional no artifact is providing a matching capability in this start level."));
+ }
}
- if (!RequirementImpl.isOptional(requirement)) {
- ctx.reportError(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "no artifact is providing a matching capability in this start level."));
+ else if (candidates.size() > 1)
+ {
+ ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "there is more than one matching capability in this start level."));
}
- else {
- ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "while the requirement is optional no artifact is providing a matching capability in this start level."));
- }
- }
- else if ( candidates.size() > 1 ) {
- ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "there is more than one matching capability in this start level."));
}
}
}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
index 748bec9..52f3a71 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
@@ -19,7 +19,6 @@ package org.apache.sling.feature.scanner;
import java.util.jar.Manifest;
import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.util.PackageInfo;
/**
* Information about a bundle
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
index a97cda0..2b5fc1b 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
@@ -20,7 +20,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-import org.apache.sling.feature.support.util.PackageInfo;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
similarity index 98%
rename from featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java
rename to featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
index 725906d..bb7081b 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sling.feature.support.util;
+package org.apache.sling.feature.scanner;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
index 2f2c54b..d93b89c 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
@@ -18,14 +18,21 @@ package org.apache.sling.feature.scanner.impl;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Set;
+import java.util.jar.JarFile;
import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.resource.ResourceBuilder;
+import org.apache.felix.utils.resource.ResourceImpl;
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.ManifestParser;
-import org.apache.sling.feature.support.util.ManifestUtil;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
import org.osgi.framework.Constants;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
@@ -60,8 +67,9 @@ public class BundleDescriptorImpl
this.artifact = a;
this.artifactFile = file;
this.startLevel = startLevel;
-
- this.manifest = ManifestUtil.getManifest(file);
+ try (final JarFile jarFile = new JarFile(this.artifactFile) ) {
+ this.manifest = jarFile.getManifest();
+ }
if ( this.manifest == null ) {
throw new IOException("File has no manifest");
}
@@ -142,13 +150,14 @@ public class BundleDescriptorImpl
this.symbolicName = newBundleName;
}
- this.getExportedPackages().addAll(ManifestUtil.extractExportedPackages(this.manifest));
- this.getImportedPackages().addAll(ManifestUtil.extractImportedPackages(this.manifest));
- this.getDynamicImportedPackages().addAll(ManifestUtil.extractDynamicImportedPackages(this.manifest));
+ this.getExportedPackages().addAll(extractExportedPackages(this.manifest));
+ this.getImportedPackages().addAll(extractImportedPackages(this.manifest));
+ this.getDynamicImportedPackages().addAll(extractDynamicImportedPackages(this.manifest));
try {
- ManifestParser parser = new ManifestParser(this.manifest);
- this.getCapabilities().addAll(ManifestUtil.extractCapabilities(parser));
- this.getRequirements().addAll(ManifestUtil.extractRequirements(parser));
+ ResourceImpl resource = ResourceBuilder.build(null, this.manifest.getMainAttributes().entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey().toString(), entry -> entry.getValue().toString())));
+ this.getCapabilities().addAll(resource.getCapabilities(null));
+ this.getRequirements().addAll(resource.getRequirements(null));
} catch (Exception ex) {
throw new IOException(ex);
}
@@ -156,4 +165,50 @@ public class BundleDescriptorImpl
throw new IOException("Unable to get bundle symbolic name from artifact " + getArtifact().getId().toMvnId());
}
}
+
+ public static List<PackageInfo> extractPackages(final Manifest m,
+ final String headerName,
+ final String defaultVersion,
+ final boolean checkOptional) {
+ final String pckInfo = m.getMainAttributes().getValue(headerName);
+ if (pckInfo != null) {
+ final Clause[] clauses = Parser.parseHeader(pckInfo);
+
+ final List<PackageInfo> pcks = new ArrayList<>();
+ for(final Clause entry : clauses) {
+ Object versionObj = entry.getAttribute("version");
+ final String version;
+ if ( versionObj == null ) {
+ version = defaultVersion;
+ } else {
+ version = versionObj.toString();
+ }
+
+ boolean optional = false;
+ if ( checkOptional ) {
+ final String resolution = entry.getDirective("resolution");
+ optional = "optional".equalsIgnoreCase(resolution);
+ }
+ final PackageInfo pck = new PackageInfo(entry.getName(),
+ version,
+ optional);
+ pcks.add(pck);
+ }
+
+ return pcks;
+ }
+ return Collections.emptyList();
+ }
+
+ public static List<PackageInfo> extractExportedPackages(final Manifest m) {
+ return extractPackages(m, Constants.EXPORT_PACKAGE, "0.0.0", false);
+ }
+
+ public static List<PackageInfo> extractImportedPackages(final Manifest m) {
+ return extractPackages(m, Constants.IMPORT_PACKAGE, null, true);
+ }
+
+ public static List<PackageInfo> extractDynamicImportedPackages(final Manifest m) {
+ return extractPackages(m, Constants.DYNAMICIMPORT_PACKAGE, null, false);
+ }
}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
index 14644d2..2bb2cde 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
@@ -16,15 +16,12 @@
*/
package org.apache.sling.feature.scanner.impl;
-import static org.apache.sling.feature.support.util.ManifestParser.convertProvideCapabilities;
-import static org.apache.sling.feature.support.util.ManifestParser.normalizeCapabilityClauses;
-import static org.apache.sling.feature.support.util.ManifestParser.parseStandardHeader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
@@ -37,14 +34,14 @@ import java.util.zip.ZipInputStream;
import org.apache.commons.lang.text.StrLookup;
import org.apache.commons.lang.text.StrSubstitutor;
-import org.apache.sling.commons.osgi.ManifestHeader;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.resource.ResourceBuilder;
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.KeyValueMap;
import org.apache.sling.feature.scanner.BundleDescriptor;
import org.apache.sling.feature.scanner.spi.FrameworkScanner;
-import org.apache.sling.feature.support.util.PackageInfo;
-import org.osgi.framework.BundleException;
+import org.apache.sling.feature.scanner.PackageInfo;
import org.osgi.framework.Constants;
import org.osgi.resource.Capability;
@@ -61,7 +58,7 @@ public class FelixFrameworkScanner implements FrameworkScanner {
return null;
}
final Set<PackageInfo> pcks = calculateSystemPackages(fwkProps);
- final Set<Capability> capabilities = calculateSystemCapabilities(fwkProps);
+ final List<Capability> capabilities = calculateSystemCapabilities(fwkProps);
final BundleDescriptor d = new BundleDescriptor() {
@@ -101,44 +98,45 @@ public class FelixFrameworkScanner implements FrameworkScanner {
return d;
}
- private Set<Capability> calculateSystemCapabilities(final KeyValueMap fwkProps) {
- return Stream.of(
+ private List<Capability> calculateSystemCapabilities(final KeyValueMap fwkProps) throws IOException
+ {
+ Map<String, String> mf = new HashMap<>();
+ mf.put(Constants.PROVIDE_CAPABILITY,
+ Stream.of(
fwkProps.get(Constants.FRAMEWORK_SYSTEMCAPABILITIES),
fwkProps.get(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA)
)
.filter(Objects::nonNull)
- .flatMap(header -> {
- try {
- return convertProvideCapabilities(normalizeCapabilityClauses(parseStandardHeader(header), "2"))
- .stream();
- } catch (BundleException ex) {
- throw new RuntimeException(ex);
- }
- })
- .collect(Collectors.toSet());
+ .collect(Collectors.joining(",")));
+ mf.put(Constants.EXPORT_PACKAGE, Stream.of(
+ fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES),
+ fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA)
+ ).filter(Objects::nonNull)
+ .collect(Collectors.joining(",")));
+ mf.put(Constants.BUNDLE_SYMBOLICNAME, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
+ mf.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ try
+ {
+ return ResourceBuilder.build(null, mf).getCapabilities(null);
+ }
+ catch (Exception ex) {
+ throw new IOException(ex);
+ }
}
private Set<PackageInfo> calculateSystemPackages(final KeyValueMap fwkProps) {
- final String system = fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES);
- final String extra = fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
- final Set<PackageInfo> packages = new HashSet<>();
- for(int i=0;i<2;i++) {
- final String value = (i == 0 ? system : extra);
- if ( value != null ) {
- final ManifestHeader header = ManifestHeader.parse(value);
- for(final ManifestHeader.Entry entry : header.getEntries()) {
- String version = entry.getAttributeValue("version");
- if ( version == null ) {
- version = "0.0.0";
- }
-
- final PackageInfo exportedPackageInfo = new PackageInfo(entry.getValue(),
- version, false);
- packages.add(exportedPackageInfo);
- }
- }
- }
- return packages;
+ return
+ Stream.of(
+ Parser.parseHeader(
+ Stream.of(
+ fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES),
+ fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA)
+ ).filter(Objects::nonNull)
+ .collect(Collectors.joining(","))
+ )
+ ).map(
+ clause -> new PackageInfo(clause.getName(), clause.getAttribute("version") != null ? clause.getAttribute("version") : "0.0.0", false))
+ .collect(Collectors.toSet());
}
private static final String DEFAULT_PROPERTIES = "default.properties";
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
new file mode 100644
index 0000000..a8d289c
--- /dev/null
+++ b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.sling.feature.scanner.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.scanner.PackageInfo;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+public class BundleDescriptorImplTest
+{
+
+ private void assertPackageInfo(Set<PackageInfo> infos, final String name, final Version version) {
+ for (PackageInfo info : infos)
+ {
+ if (name.equals(info.getName()) && version.equals(info.getPackageVersion()))
+ {
+ return;
+ }
+ }
+ fail();
+ }
+
+ @Test public void testExportPackage() throws Exception {
+ String bmf = "Bundle-SymbolicName: pkg.bundle\n"
+ + "Bundle-Version: 1\n"
+ + "Bundle-ManifestVersion: 2\n"
+ + "Export-Package: org.apache.sling;version=1.0,org.apache.felix;version=2.0\n";
+ File f = createBundle(bmf);
+ BundleDescriptorImpl bdf = new BundleDescriptorImpl(new Artifact(new ArtifactId("foo", "bar", "1.0", "bla", "bundle")), f, 1);
+ final Set<PackageInfo> infos = bdf.getExportedPackages();
+ assertEquals(2, infos.size());
+ assertPackageInfo(infos ,"org.apache.sling", Version.parseVersion("1.0"));
+ assertPackageInfo(infos,"org.apache.felix", Version.parseVersion("2.0"));
+ }
+
+ private File createBundle(String manifest) throws IOException
+ {
+ File f = File.createTempFile("bundle", ".jar");
+ f.deleteOnExit();
+ Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("UTF-8")));
+ mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+ JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+ os.close();
+ return f;
+ }
+}
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
index 7e0d02f..d5edc80 100644
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
+++ b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
@@ -16,13 +16,18 @@
*/
package org.apache.sling.feature.scanner.impl;
+import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.KeyValueMap;
+import org.apache.sling.feature.scanner.BundleDescriptor;
import org.junit.Test;
import java.io.File;
import java.net.URL;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
public class FelixFrameworkScannerTest {
@Test
@@ -46,4 +51,20 @@ public class FelixFrameworkScannerTest {
+ "osgi.ee; osgi.ee=\"JavaSE/compact2\"; version:List<Version>=\"1.8\", "
+ "osgi.ee; osgi.ee=\"JavaSE/compact3\"; version:List<Version>=\"1.8\" ", props.get("org.osgi.framework.system.capabilities"));
}
+
+ @Test
+ public void testGetFrameworkExports() throws Exception {
+ URL url = getClass().getResource("/test-framework.jar");
+ File fwFile = new File(url.toURI());
+
+ FelixFrameworkScanner ffs = new FelixFrameworkScanner();
+
+ KeyValueMap kvmap = new KeyValueMap();
+ BundleDescriptor bundleDescriptor = ffs.scan(new ArtifactId("org.apache.felix",
+ "org.apache.felix.framework",
+ "5.6.10", null, null), fwFile, kvmap);
+
+ assertFalse(bundleDescriptor.getExportedPackages().isEmpty());
+ assertFalse(bundleDescriptor.getCapabilities().isEmpty());
+ }
}
diff --git a/featuremodel/feature-applicationbuilder/pom.xml b/featuremodel/feature-applicationbuilder/pom.xml
index 3cb9e08..cc16c11 100644
--- a/featuremodel/feature-applicationbuilder/pom.xml
+++ b/featuremodel/feature-applicationbuilder/pom.xml
@@ -122,12 +122,6 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.johnzon</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
diff --git a/featuremodel/feature-karaf/pom.xml b/featuremodel/feature-karaf/pom.xml
index 315afec..6204869 100644
--- a/featuremodel/feature-karaf/pom.xml
+++ b/featuremodel/feature-karaf/pom.xml
@@ -74,11 +74,5 @@
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
</dependencies>
</project>
diff --git a/featuremodel/feature-launcher/pom.xml b/featuremodel/feature-launcher/pom.xml
index a71522d..fdcd201 100644
--- a/featuremodel/feature-launcher/pom.xml
+++ b/featuremodel/feature-launcher/pom.xml
@@ -55,7 +55,7 @@
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
- <includeArtifactIds>org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple,osgi.core</includeArtifactIds>
+ <includeArtifactIds>org.apache.sling.feature,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple,osgi.core</includeArtifactIds>
</configuration>
</execution>
</executions>
@@ -111,11 +111,6 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.converter</artifactId>
<version>0.1.0-SNAPSHOT</version>
diff --git a/featuremodel/feature-modelconverter/pom.xml b/featuremodel/feature-modelconverter/pom.xml
index 8386c38..62547a1 100644
--- a/featuremodel/feature-modelconverter/pom.xml
+++ b/featuremodel/feature-modelconverter/pom.xml
@@ -143,12 +143,6 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.provisioning.model</artifactId>
<version>1.8.2</version>
<scope>provided</scope>
diff --git a/featuremodel/feature-resolver/pom.xml b/featuremodel/feature-resolver/pom.xml
index c52badb..d320ce2 100644
--- a/featuremodel/feature-resolver/pom.xml
+++ b/featuremodel/feature-resolver/pom.xml
@@ -80,12 +80,6 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.osgi</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
diff --git a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
index 901b141..e196145 100644
--- a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
@@ -22,7 +22,7 @@ import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.resolver.FeatureResource;
import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.osgi.framework.namespace.BundleNamespace;
@@ -69,18 +69,6 @@ public class BundleResourceImpl extends AbstractResourceImpl implements FeatureR
l.add(new CapabilityImpl(this, c));
}
- // Add the package capabilities (export package)
- List<Capability> pkgCaps = new ArrayList<>();
- for(PackageInfo exported : bd.getExportedPackages()) {
- Map<String, Object> attrs = new HashMap<>();
- attrs.put(PackageNamespace.PACKAGE_NAMESPACE, exported.getName());
- attrs.put(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, exported.getPackageVersion());
- attrs.put(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
- attrs.put(PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, version);
- pkgCaps.add(new CapabilityImpl(this, PackageNamespace.PACKAGE_NAMESPACE, null, attrs));
- }
- caps.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgCaps));
-
// Add the identity capability
Map<String, Object> idattrs = new HashMap<>();
idattrs.put(IdentityNamespace.IDENTITY_NAMESPACE, bsn);
@@ -111,25 +99,6 @@ public class BundleResourceImpl extends AbstractResourceImpl implements FeatureR
// TODO What do we do with the execution environment?
reqs.remove(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
- // Add the package requirements (import package)
- List<Requirement> pkgReqs = new ArrayList<>();
- for(PackageInfo imported : bd.getImportedPackages()) {
- Map<String, String> dirs = new HashMap<>();
- VersionRange range = imported.getPackageVersionRange();
- String rangeFilter;
- if (range != null) {
- rangeFilter = range.toFilterString(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- } else {
- rangeFilter = "";
- }
- dirs.put(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE,
- "(&(" + PackageNamespace.PACKAGE_NAMESPACE + "=" + imported.getName() + ")" + rangeFilter + ")");
- if (imported.isOptional())
- dirs.put(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE,
- PackageNamespace.RESOLUTION_OPTIONAL);
- pkgReqs.add(new RequirementImpl(this, PackageNamespace.PACKAGE_NAMESPACE, dirs, null));
- }
- reqs.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgReqs));
requirements = Collections.unmodifiableMap(reqs);
}
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
index c4b8110..527eec5 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
@@ -27,6 +27,7 @@ import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
import org.apache.sling.feature.scanner.BundleDescriptor;
import org.apache.sling.feature.scanner.Scanner;
import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
+import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
index 86beec4..265aa21 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
@@ -21,7 +21,7 @@ import org.apache.felix.utils.resource.RequirementImpl;
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.osgi.framework.namespace.BundleNamespace;
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
index eb307d2..c829958 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
@@ -25,9 +25,11 @@ import org.apache.sling.feature.resolver.FeatureResource;
import org.apache.sling.feature.scanner.BundleDescriptor;
import org.apache.sling.feature.scanner.Descriptor;
import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
+import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
+import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.PackageNamespace;
@@ -35,6 +37,10 @@ import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
@@ -43,6 +49,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -95,17 +103,17 @@ public class BundleResourceImplTest {
ArtifactId id = new ArtifactId("grp", "art", "1.2.3", null, null);
Artifact artifact = new Artifact(id);
- PackageInfo ex1 = new PackageInfo("org.foo.a", "0.0.1.SNAPSHOT", false);
- Set<PackageInfo> pkgs = Collections.singleton(ex1);
- Set<Requirement> reqs = Collections.emptySet();
- Set<Capability> caps = Collections.emptySet();
- BundleDescriptor bd = new BundleDescriptorImpl(artifact, pkgs, reqs, caps);
+ String bmf = "Bundle-SymbolicName: " + Constants.SYSTEM_BUNDLE_SYMBOLICNAME + "\n"
+ + "Bundle-Version: 1.2.3\n"
+ + "Bundle-ManifestVersion: 2\n"
+ + "Export-Package: org.foo.a;version=0.0.1.SNAPSHOT\n"
+ + "Import-Package: org.bar;version=\"[1,2)\",org.tar;resolution:=\"optional\"\n";
+
+ File f = createBundle(bmf);
+
+
+ BundleDescriptor bd = new BundleDescriptorImpl(artifact, f, 1);
- setField(Descriptor.class, "locked", bd, false); // Unlock the Bundle Descriptor for the test
- PackageInfo im1 = new PackageInfo("org.bar", "[1,2)", false);
- PackageInfo im2 = new PackageInfo("org.tar", null, true);
- bd.getImportedPackages().add(im1);
- bd.getImportedPackages().add(im2);
Resource res = new BundleResourceImpl(bd, null);
assertNotNull(
@@ -137,11 +145,11 @@ public class BundleResourceImplTest {
}
assertEquals(1, reqBar.getDirectives().size());
- assertEquals("(&(osgi.wiring.package=org.bar)(&(version>=1.0.0)(!(version>=2.0.0))))",
+ assertEquals("(&(osgi.wiring.package=org.bar)(version>=1.0.0)(!(version>=2.0.0)))",
reqBar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE));
assertEquals(2, reqTar.getDirectives().size());
- assertEquals("(&(osgi.wiring.package=org.tar))",
+ assertEquals("(osgi.wiring.package=org.tar)",
reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE));
assertEquals(PackageNamespace.RESOLUTION_OPTIONAL,
reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
@@ -185,6 +193,18 @@ public class BundleResourceImplTest {
new HashSet<>(res.getRequirements(null)));
}
+
+ private File createBundle(String manifest) throws IOException
+ {
+ File f = File.createTempFile("bundle", ".jar");
+ f.deleteOnExit();
+ Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("UTF-8")));
+ mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+ JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+ os.close();
+ return f;
+ }
+
private Object getCapAttribute(Resource res, String ns, String attr) {
List<Capability> caps = res.getCapabilities(ns);
if (caps.size() == 0)
diff --git a/featuremodel/feature-support/pom.xml b/featuremodel/feature-support/pom.xml
deleted file mode 100644
index 97b9729..0000000
--- a/featuremodel/feature-support/pom.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
- <!--
- 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>33</version>
- <relativePath />
- </parent>
-
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <name>Apache Sling Feature Support</name>
- <description>
- Support classes for the feature tools
- </description>
-
- <properties>
- <sling.java.version>8</sling.java.version>
- </properties>
-
- <scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-support</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-support</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-support</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Conditional-Package>
- org.apache.felix.configurator.impl.json,
- org.apache.felix.configurator.impl.model
- </Conditional-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.annotation.versioning</artifactId>
- <version>1.0.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>osgi.core</artifactId>
- <version>6.0.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.io</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.converter</artifactId>
- <version>0.1.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.configurator</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <version>1.11.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-json_1.0_spec</artifactId>
- <version>1.0-alpha-1</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- Testing -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>2.8.9</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.johnzon</groupId>
- <artifactId>johnzon-core</artifactId>
- <version>1.0.0</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java
deleted file mode 100644
index 3c574a2..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.sling.feature.support.util;
-
-import org.apache.felix.utils.resource.CapabilitySet;
-import org.osgi.resource.Capability;
-
-
-public class CapabilityMatcher
-{
- static boolean matches(Capability cap, SimpleFilter sf)
- {
- // Translate the SimpleFilter into the one from Felix Utils.
- // Once the SimpleFilter has moved to Felix Utils, this class can be removed.
- org.apache.felix.utils.resource.SimpleFilter sf2 =
- org.apache.felix.utils.resource.SimpleFilter.parse(sf.toString());
-
- return CapabilitySet.matches(cap, sf2);
- }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java
deleted file mode 100644
index 1da64ab..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * 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.sling.feature.support.util;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-import org.osgi.framework.namespace.BundleNamespace;
-import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.jar.Manifest;
-
-public class ManifestParser {
-
- private final Manifest m_headerMap;
- private volatile String m_bundleSymbolicName;
- private volatile Version m_bundleVersion;
- private volatile List<Capability> m_capabilities;
- private volatile List<Requirement> m_requirements;
-
- public ManifestParser(Manifest m)
- throws BundleException
- {
- m_headerMap = m;
-
- // Verify that only manifest version 2 is specified.
- String manifestVersion = getManifestVersion(m_headerMap);
- if ((manifestVersion != null) && !manifestVersion.equals("2"))
- {
- throw new BundleException(
- "Unknown 'Bundle-ManifestVersion' value: " + manifestVersion);
- }
-
- List<Capability> capList = new ArrayList<>();
-
- //
- // Parse bundle version.
- //
-
- m_bundleVersion = Version.emptyVersion;
- if (m_headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION) != null)
- {
- try
- {
- m_bundleVersion = Version.parseVersion(m_headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
- }
- catch (RuntimeException ex)
- {
- // R4 bundle versions must parse, R3 bundle version may not.
- if (getManifestVersion().equals("2"))
- {
- throw ex;
- }
- m_bundleVersion = Version.emptyVersion;
- }
- }
-
- //
- // Parse bundle symbolic name.
- //
-
- Capability bundleCap = parseBundleSymbolicName(m_headerMap);
- if (bundleCap != null)
- {
- m_bundleSymbolicName = (String)
- bundleCap.getAttributes().get(BundleRevision.BUNDLE_NAMESPACE);
-
- // Add a bundle capability and a host capability to all
- // non-fragment bundles. A host capability is the same
- // as a require capability, but with a different capability
- // namespace. Bundle capabilities resolve required-bundle
- // dependencies, while host capabilities resolve fragment-host
- // dependencies.
- if (m_headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) == null)
- {
- // All non-fragment bundles have host capabilities.
- capList.add(bundleCap);
- // A non-fragment bundle can choose to not have a host capability.
- String attachment =
- bundleCap.getDirectives().get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
- attachment = (attachment == null)
- ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME
- : attachment;
- if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER))
- {
- Map<String, Object> hostAttrs =
- new HashMap<>(bundleCap.getAttributes());
- Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
- hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
- Capability cap = new CapabilityImpl(null, BundleRevision.HOST_NAMESPACE, bundleCap.getDirectives(), hostAttrs);
- capList.add(cap);
- }
- }
-
- //
- // Add the osgi.identity capability.
- //
- capList.add(addIdentityCapability(m_headerMap, bundleCap));
- }
-
- // Verify that bundle symbolic name is specified.
- if (getManifestVersion().equals("2") && (m_bundleSymbolicName == null))
- {
- throw new BundleException(
- "R4 bundle manifests must include bundle symbolic name.");
- }
-
- //
- // Parse Fragment-Host.
- //
-
- List<Requirement> hostReqs = parseFragmentHost(m_headerMap);
-
- //
- // Parse Require-Bundle
- //
-
- List<ParsedHeaderClause> rbClauses =
- parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.REQUIRE_BUNDLE));
- rbClauses = normalizeRequireClauses(rbClauses, getManifestVersion());
- List<Requirement> rbReqs = convertRequires(rbClauses);
-
-
- //
- // Parse Require-Capability.
- //
-
- List<ParsedHeaderClause> requireClauses =
- parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.REQUIRE_CAPABILITY));
- List<Requirement> requireReqs = convertRequireCapabilities(normalizeCapabilityClauses( requireClauses, getManifestVersion()));
-
- //
- // Parse Provide-Capability.
- //
-
- List<ParsedHeaderClause> provideClauses =
- parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.PROVIDE_CAPABILITY));
-
- List<Capability> provideCaps = convertProvideCapabilities(normalizeCapabilityClauses(provideClauses, getManifestVersion()));
-
- // Combine all requirements.
- m_requirements = new ArrayList<>();
- m_requirements.addAll(hostReqs);
- m_requirements.addAll(rbReqs);
- m_requirements.addAll(requireReqs);
-
- // Combine all capabilities.
- m_capabilities = new ArrayList<>();
- m_capabilities.addAll(capList);
- m_capabilities.addAll(provideCaps);
- }
-
-
- public static List<Requirement> convertRequireCapabilities(
- List<ParsedHeaderClause> clauses)
- throws BundleException
- {
- // Now convert generic header clauses into requirements.
- List<Requirement> reqList = new ArrayList<>();
- for (ParsedHeaderClause clause : clauses)
- {
- for (String path : clause.m_paths)
- {
- if (path.startsWith("osgi.wiring."))
- {
- throw new BundleException("Manifest cannot use Require-Capability for '"
- + path
- + "' namespace.");
- }
-
- Requirement req = new RequirementImpl(null, path, clause.m_dirs, clause.m_attrs);
- // Create requirement and add to requirement list.
- reqList.add(req);
- }
- }
-
- return reqList;
- }
-
- public static List<ParsedHeaderClause> normalizeCapabilityClauses(
- List<ParsedHeaderClause> clauses, String mv)
- throws BundleException
- {
-
- if (!mv.equals("2") && !clauses.isEmpty())
- {
- // Should we error here if we are not an R4 bundle?
- }
-
- // Convert attributes into specified types.
- for (ParsedHeaderClause clause : clauses)
- {
- for (Entry<String, String> entry : clause.m_types.entrySet())
- {
- String type = entry.getValue();
- if (!type.equals("String"))
- {
- if (type.equals("Double"))
- {
- clause.m_attrs.put(
- entry.getKey(),
- new Double(clause.m_attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Version"))
- {
- clause.m_attrs.put(
- entry.getKey(),
- new Version(clause.m_attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.equals("Long"))
- {
- clause.m_attrs.put(
- entry.getKey(),
- new Long(clause.m_attrs.get(entry.getKey()).toString().trim()));
- }
- else if (type.startsWith("List"))
- {
- int startIdx = type.indexOf('<');
- int endIdx = type.indexOf('>');
- if (((startIdx > 0) && (endIdx <= startIdx))
- || ((startIdx < 0) && (endIdx > 0)))
- {
- throw new BundleException(
- "Invalid Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
-
- String listType = "String";
- if (endIdx > startIdx)
- {
- listType = type.substring(startIdx + 1, endIdx).trim();
- }
-
- List<String> tokens = parseDelimitedString(
- clause.m_attrs.get(entry.getKey()).toString(), ",", false);
- List<Object> values = new ArrayList<>(tokens.size());
- for (String token : tokens)
- {
- if (listType.equals("String"))
- {
- values.add(token);
- }
- else if (listType.equals("Double"))
- {
- values.add(new Double(token.trim()));
- }
- else if (listType.equals("Version"))
- {
- values.add(new Version(token.trim()));
- }
- else if (listType.equals("Long"))
- {
- values.add(new Long(token.trim()));
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute list type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- clause.m_attrs.put(
- entry.getKey(),
- values);
- }
- else
- {
- throw new BundleException(
- "Unknown Provide-Capability attribute type for '"
- + entry.getKey()
- + "' : "
- + type);
- }
- }
- }
- }
-
- return clauses;
- }
-
- public static List<Capability> convertProvideCapabilities(
- List<ParsedHeaderClause> clauses)
- throws BundleException
- {
- List<Capability> capList = new ArrayList<>();
- for (ParsedHeaderClause clause : clauses)
- {
- for (String path : clause.m_paths)
- {
- if (path.startsWith("osgi.wiring."))
- {
- throw new BundleException("Manifest cannot use Provide-Capability for '"
- + path
- + "' namespace.");
- }
-
- Capability capability = new CapabilityImpl(null, path, clause.m_dirs, clause.m_attrs);
- // Create package capability and add to capability list.
- capList.add(capability);
- }
- }
-
- return capList;
- }
-
-
- public String getManifestVersion()
- {
- String manifestVersion = getManifestVersion(m_headerMap);
- return (manifestVersion == null) ? "1" : manifestVersion;
- }
-
- private static String getManifestVersion(Manifest headerMap)
- {
- String manifestVersion = headerMap.getMainAttributes().getValue(Constants.BUNDLE_MANIFESTVERSION);
- return (manifestVersion == null) ? null : manifestVersion.trim();
- }
-
- public String getSymbolicName()
- {
- return m_bundleSymbolicName;
- }
-
- public Version getBundleVersion()
- {
- return m_bundleVersion;
- }
-
- public List<Capability> getCapabilities()
- {
- return m_capabilities;
- }
-
- public List<Requirement> getRequirements()
- {
- return m_requirements;
- }
-
-
- static class ParsedHeaderClause
- {
- public final List<String> m_paths;
- public final Map<String, String> m_dirs;
- public final Map<String, Object> m_attrs;
- public final Map<String, String> m_types;
-
- public ParsedHeaderClause(
- List<String> paths, Map<String, String> dirs, Map<String, Object> attrs,
- Map<String, String> types)
- {
- m_paths = paths;
- m_dirs = dirs;
- m_attrs = attrs;
- m_types = types;
- }
- }
-
- private static Capability parseBundleSymbolicName(
- Manifest headerMap)
- throws BundleException
- {
- List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
- if (clauses.size() > 0)
- {
- if (clauses.size() > 1)
- {
- throw new BundleException(
- "Cannot have multiple symbolic names: "
- + headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
- }
- else if (clauses.get(0).m_paths.size() > 1)
- {
- throw new BundleException(
- "Cannot have multiple symbolic names: "
- + headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
- }
-
- // Get bundle version.
- Version bundleVersion = Version.emptyVersion;
- if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION) != null)
- {
- try
- {
- bundleVersion = Version.parseVersion(
- headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
- }
- catch (RuntimeException ex)
- {
- // R4 bundle versions must parse, R3 bundle version may not.
- String mv = getManifestVersion(headerMap);
- if (mv != null)
- {
- throw ex;
- }
- bundleVersion = Version.emptyVersion;
- }
- }
-
- // Create a require capability and return it.
- String symName = clauses.get(0).m_paths.get(0);
- clauses.get(0).m_attrs.put(BundleRevision.BUNDLE_NAMESPACE, symName);
- clauses.get(0).m_attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
- Capability cap = new CapabilityImpl(null, BundleRevision.BUNDLE_NAMESPACE, clauses.get(0).m_dirs, clauses.get(0).m_attrs);
-
- return cap;
- }
-
- return null;
- }
-
- private static Capability addIdentityCapability(Manifest headerMap, Capability bundleCap)
- {
- Map<String, Object> attrs = new HashMap<>();
-
- attrs.put(IdentityNamespace.IDENTITY_NAMESPACE,
- bundleCap.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE));
- attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
- headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) == null
- ? IdentityNamespace.TYPE_BUNDLE
- : IdentityNamespace.TYPE_FRAGMENT);
- attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE,
- bundleCap.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE));
-
- if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_COPYRIGHT) != null)
- {
- attrs.put(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE,
- headerMap.getMainAttributes().getValue(Constants.BUNDLE_COPYRIGHT));
- }
-
- if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION) != null)
- {
- attrs.put(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE,
- headerMap.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION));
- }
- if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_DOCURL) != null)
- {
- attrs.put(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE,
- headerMap.getMainAttributes().getValue(Constants.BUNDLE_DOCURL));
- }
- if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_LICENSE) != null)
- {
- attrs.put(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE,
- headerMap.getMainAttributes().getValue(Constants.BUNDLE_LICENSE));
- }
-
- Map<String, String> dirs;
- if (bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE) != null)
- {
- dirs = Collections.singletonMap(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE,
- bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE));
- }
- else
- {
- dirs = Collections.emptyMap();
- }
- Capability cap = new CapabilityImpl(null, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs);
- return cap;
- }
-
- private static List<Requirement> parseFragmentHost(
- Manifest headerMap)
- throws BundleException
- {
- List<Requirement> reqs = new ArrayList<>();
-
- String mv = getManifestVersion(headerMap);
- if ((mv != null) && mv.equals("2"))
- {
- List<ParsedHeaderClause> clauses = parseStandardHeader(
- headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
- if (clauses.size() > 0)
- {
- // Make sure that only one fragment host symbolic name is specified.
- if (clauses.size() > 1)
- {
- throw new BundleException(
- "Fragments cannot have multiple hosts: "
- + headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
- }
- else if (clauses.get(0).m_paths.size() > 1)
- {
- throw new BundleException(
- "Fragments cannot have multiple hosts: "
- + headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
- }
-
- // If the bundle-version attribute is specified, then convert
- // it to the proper type.
- Object value = clauses.get(0).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- value = (value == null) ? "0.0.0" : value;
- if (value != null)
- {
- clauses.get(0).m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.valueOf(value.toString()));
- }
-
- // Note that we use a linked hash map here to ensure the
- // host symbolic name is first, which will make indexing
- // more efficient.
-// TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the host symbolic name to the map of attributes.
- Map<String, Object> attrs = clauses.get(0).m_attrs;
- Map<String, Object> newAttrs = new LinkedHashMap<>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(
- BundleRevision.HOST_NAMESPACE,
- clauses.get(0).m_paths.get(0));
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(
- BundleRevision.HOST_NAMESPACE,
- clauses.get(0).m_paths.get(0));
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
-// TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clauses.get(0).m_dirs;
- Map<String, String> newDirs = new HashMap<>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(
- Constants.FILTER_DIRECTIVE,
- sf.toString());
-
- Requirement req = new RequirementImpl(null, BundleRevision.HOST_NAMESPACE, newDirs, newAttrs);
- reqs.add(req);
- }
- }
- else if (headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) != null)
- {
- String s = headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- s = (s == null) ? headerMap.getMainAttributes().getValue(Constants.BUNDLE_NAME) : s;
- s = (s == null) ? headerMap.toString() : s;
- }
-
- return reqs;
- }
-
-
- private static List<Requirement> parseBreeHeader(String header)
- {
- List<String> filters = new ArrayList<>();
- for (String entry : parseDelimitedString(header, ","))
- {
- List<String> names = parseDelimitedString(entry, "/");
- List<String> left = parseDelimitedString(names.get(0), "-");
-
- String lName = left.get(0);
- Version lVer;
- try
- {
- lVer = Version.parseVersion(left.get(1));
- }
- catch (Exception ex)
- {
- // Version doesn't parse. Make it part of the name.
- lName = names.get(0);
- lVer = null;
- }
-
- String rName = null;
- Version rVer = null;
- if (names.size() > 1)
- {
- List<String> right = parseDelimitedString(names.get(1), "-");
- rName = right.get(0);
- try
- {
- rVer = Version.parseVersion(right.get(1));
- }
- catch (Exception ex)
- {
- rName = names.get(1);
- rVer = null;
- }
- }
-
- String versionClause;
- if (lVer != null)
- {
- if ((rVer != null) && (!rVer.equals(lVer)))
- {
- // Both versions are defined, but different. Make each of them part of the name
- lName = names.get(0);
- rName = names.get(1);
- versionClause = null;
- }
- else
- {
- versionClause = getBreeVersionClause(lVer);
- }
- }
- else
- {
- versionClause = getBreeVersionClause(rVer);
- }
-
- if ("J2SE".equals(lName))
- {
- // J2SE is not used in the Capability variant of BREE, use JavaSE here
- // This can only happen with the lName part...
- lName = "JavaSE";
- }
-
- String nameClause;
- if (rName != null)
- nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + "/" + rName + ")";
- else
- nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + ")";
-
- String filter;
- if (versionClause != null)
- filter = "(&" + nameClause + versionClause + ")";
- else
- filter = nameClause;
-
- filters.add(filter);
- }
-
- if (filters.size() == 0)
- {
- return Collections.emptyList();
- }
- else
- {
- String reqFilter;
- if (filters.size() == 1)
- {
- reqFilter = filters.get(0);
- }
- else
- {
- // If there are more BREE filters, we need to or them together
- StringBuilder sb = new StringBuilder("(|");
- for (String f : filters)
- {
- sb.append(f);
- }
- sb.append(")");
- reqFilter = sb.toString();
- }
-
- SimpleFilter sf = SimpleFilter.parse(reqFilter);
- Requirement req = new RequirementImpl(null, ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE,
- Collections.singletonMap(ExecutionEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, reqFilter), null);
- return Collections.<Requirement>singletonList(req);
- }
- }
-
- private static String getBreeVersionClause(Version ver) {
- if (ver == null)
- return null;
-
- return "(" + ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE + "=" + ver + ")";
- }
-
- static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses, String mv)
- {
- // R3 bundles cannot require other bundles.
- if (!mv.equals("2"))
- {
- clauses.clear();
- }
- else
- {
- // Convert bundle version attribute to VersionRange type.
- for (ParsedHeaderClause clause : clauses)
- {
- Object value = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
- if (value != null)
- {
- clause.m_attrs.put(
- Constants.BUNDLE_VERSION_ATTRIBUTE,
- VersionRange.valueOf(value.toString()));
- }
- }
- }
-
- return clauses;
- }
-
- private static List<Requirement> convertRequires(
- List<ParsedHeaderClause> clauses)
- {
- List<Requirement> reqList = new ArrayList<>();
- for (ParsedHeaderClause clause : clauses)
- {
- for (String path : clause.m_paths)
- {
- // Prepend the bundle symbolic name to the array of attributes.
- Map<String, Object> attrs = clause.m_attrs;
- // Note that we use a linked hash map here to ensure the
- // symbolic name attribute is first, which will make indexing
- // more efficient.
-// TODO: OSGi R4.3 - This is ordering is kind of hacky.
- // Prepend the symbolic name to the array of attributes.
- Map<String, Object> newAttrs = new LinkedHashMap<>(attrs.size() + 1);
- // We want this first from an indexing perspective.
- newAttrs.put(
- BundleRevision.BUNDLE_NAMESPACE,
- path);
- newAttrs.putAll(attrs);
- // But we need to put it again to make sure it wasn't overwritten.
- newAttrs.put(
- BundleRevision.BUNDLE_NAMESPACE,
- path);
-
- // Create filter now so we can inject filter directive.
- SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
- // Inject filter directive.
-// TODO: OSGi R4.3 - Can we insert this on demand somehow?
- Map<String, String> dirs = clause.m_dirs;
- Map<String, String> newDirs = new HashMap<>(dirs.size() + 1);
- newDirs.putAll(dirs);
- newDirs.put(
- Constants.FILTER_DIRECTIVE,
- sf.toString());
-
- Requirement req = new RequirementImpl(null, BundleRevision.BUNDLE_NAMESPACE, newDirs, newAttrs);
- reqList.add(req);
- }
- }
-
- return reqList;
- }
-
- private static final char EOF = (char) -1;
-
- private static char charAt(int pos, String headers, int length)
- {
- if (pos >= length)
- {
- return EOF;
- }
- return headers.charAt(pos);
- }
-
- private static final int CLAUSE_START = 0;
- private static final int PARAMETER_START = 1;
- private static final int KEY = 2;
- private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
- private static final int ARGUMENT = 8;
- private static final int VALUE = 16;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static List<ParsedHeaderClause> parseStandardHeader(String header)
- {
- List<ParsedHeaderClause> clauses = new ArrayList<>();
- if (header == null)
- {
- return clauses;
- }
- ParsedHeaderClause clause = null;
- String key = null;
- Map targetMap = null;
- int state = CLAUSE_START;
- int currentPosition = 0;
- int startPosition = 0;
- int length = header.length();
- boolean quoted = false;
- boolean escaped = false;
-
- char currentChar = EOF;
- do
- {
- currentChar = charAt(currentPosition, header, length);
- switch (state)
- {
- case CLAUSE_START:
- clause = new ParsedHeaderClause(
- new ArrayList<>(),
- new HashMap<>(),
- new HashMap<>(),
- new HashMap<>());
- clauses.add(clause);
- state = PARAMETER_START;
- case PARAMETER_START:
- startPosition = currentPosition;
- state = KEY;
- case KEY:
- switch (currentChar)
- {
- case ':':
- case '=':
- key = header.substring(startPosition, currentPosition).trim();
- startPosition = currentPosition + 1;
- targetMap = clause.m_attrs;
- state = currentChar == ':' ? DIRECTIVE_OR_TYPEDATTRIBUTE : ARGUMENT;
- break;
- case EOF:
- case ',':
- case ';':
- clause.m_paths.add(header.substring(startPosition, currentPosition).trim());
- state = currentChar == ',' ? CLAUSE_START : PARAMETER_START;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case DIRECTIVE_OR_TYPEDATTRIBUTE:
- switch(currentChar)
- {
- case '=':
- if (startPosition != currentPosition)
- {
- clause.m_types.put(key, header.substring(startPosition, currentPosition).trim());
- }
- else
- {
- targetMap = clause.m_dirs;
- }
- state = ARGUMENT;
- startPosition = currentPosition + 1;
- break;
- default:
- break;
- }
- currentPosition++;
- break;
- case ARGUMENT:
- if (currentChar == '\"')
- {
- quoted = true;
- currentPosition++;
- }
- else
- {
- quoted = false;
- }
- if (!Character.isWhitespace(currentChar)) {
- state = VALUE;
- }
- else {
- currentPosition++;
- }
- break;
- case VALUE:
- if (escaped)
- {
- escaped = false;
- }
- else
- {
- if (currentChar == '\\' )
- {
- escaped = true;
- }
- else if (quoted && currentChar == '\"')
- {
- quoted = false;
- }
- else if (!quoted)
- {
- String value = null;
- switch(currentChar)
- {
- case EOF:
- case ';':
- case ',':
- value = header.substring(startPosition, currentPosition).trim();
- if (value.startsWith("\"") && value.endsWith("\""))
- {
- value = value.substring(1, value.length() - 1);
- }
- if (targetMap.put(key, value) != null)
- {
- throw new IllegalArgumentException(
- "Duplicate '" + key + "' in: " + header);
- }
- state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
- break;
- default:
- break;
- }
- }
- }
- currentPosition++;
- break;
- default:
- break;
- }
- } while ( currentChar != EOF);
-
- if (state > PARAMETER_START)
- {
- throw new IllegalArgumentException("Unable to parse header: " + header);
- }
- return clauses;
- }
-
- public static List<String> parseDelimitedString(String value, String delim)
- {
- return parseDelimitedString(value, delim, true);
- }
-
- /**
- * Parses delimited string and returns an array containing the tokens. This
- * parser obeys quotes, so the delimiter character will be ignored if it is
- * inside of a quote. This method assumes that the quote character is not
- * included in the set of delimiter characters.
- * @param value the delimited string to parse.
- * @param delim the characters delimiting the tokens.
- * @return a list of string or an empty list if there are none.
- **/
- public static List<String> parseDelimitedString(String value, String delim, boolean trim)
- {
- if (value == null)
- {
- value = "";
- }
-
- List<String> list = new ArrayList<>();
-
- int CHAR = 1;
- int DELIMITER = 2;
- int STARTQUOTE = 4;
- int ENDQUOTE = 8;
-
- StringBuffer sb = new StringBuffer();
-
- int expecting = (CHAR | DELIMITER | STARTQUOTE);
-
- boolean isEscaped = false;
- for (int i = 0; i < value.length(); i++)
- {
- char c = value.charAt(i);
-
- boolean isDelimiter = (delim.indexOf(c) >= 0);
-
- if (!isEscaped && (c == '\\'))
- {
- isEscaped = true;
- continue;
- }
-
- if (isEscaped)
- {
- sb.append(c);
- }
- else if (isDelimiter && ((expecting & DELIMITER) > 0))
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- sb.delete(0, sb.length());
- expecting = (CHAR | DELIMITER | STARTQUOTE);
- }
- else if ((c == '"') && ((expecting & STARTQUOTE) > 0))
- {
- sb.append(c);
- expecting = CHAR | ENDQUOTE;
- }
- else if ((c == '"') && ((expecting & ENDQUOTE) > 0))
- {
- sb.append(c);
- expecting = (CHAR | STARTQUOTE | DELIMITER);
- }
- else if ((expecting & CHAR) > 0)
- {
- sb.append(c);
- }
- else
- {
- throw new IllegalArgumentException("Invalid delimited string: " + value);
- }
-
- isEscaped = false;
- }
-
- if (sb.length() > 0)
- {
- if (trim)
- {
- list.add(sb.toString().trim());
- }
- else
- {
- list.add(sb.toString());
- }
- }
-
- return list;
- }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java
deleted file mode 100644
index 2b3772d..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.sling.feature.support.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.stream.Collectors;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-public class ManifestUtil {
-
- /**
- * Get the manifest from the artifact.
- * @param artifact The file
- * @throws IOException If the manifest can't be read
- */
- public static Manifest getManifest(final File artifact) throws IOException {
- try (final JarFile file = new JarFile(artifact) ) {
- return file.getManifest();
- }
- }
-
- public static List<PackageInfo> extractPackages(final Manifest m,
- final String headerName,
- final String defaultVersion,
- final boolean checkOptional) {
- final String pckInfo = m.getMainAttributes().getValue(headerName);
- if (pckInfo != null) {
- final List<ManifestParser.ParsedHeaderClause> clauses = ManifestParser.parseStandardHeader(pckInfo);
-
- final List<PackageInfo> pcks = new ArrayList<>();
- for(final ManifestParser.ParsedHeaderClause entry : clauses) {
- Object versionObj = entry.m_attrs.get("version");
- final String version;
- if ( versionObj == null ) {
- version = defaultVersion;
- } else {
- version = versionObj.toString();
- }
-
- boolean optional = false;
- if ( checkOptional ) {
- final String resolution = entry.m_dirs.get("resolution");
- optional = "optional".equalsIgnoreCase(resolution);
- }
- for(final String path : entry.m_paths) {
- final PackageInfo pck = new PackageInfo(path,
- version,
- optional);
- pcks.add(pck);
- }
- }
-
- return pcks;
- }
- return Collections.emptyList();
- }
-
- public static List<PackageInfo> extractExportedPackages(final Manifest m) {
- return extractPackages(m, Constants.EXPORT_PACKAGE, "0.0.0", false);
- }
-
- public static List<PackageInfo> extractImportedPackages(final Manifest m) {
- return extractPackages(m, Constants.IMPORT_PACKAGE, null, true);
- }
-
- public static List<PackageInfo> extractDynamicImportedPackages(final Manifest m) {
- return extractPackages(m, Constants.DYNAMICIMPORT_PACKAGE, null, false);
- }
-
- public static List<Capability> extractCapabilities(ManifestParser parser) {
- return parser.getCapabilities();
- }
-
- public static List<Requirement> extractRequirements(ManifestParser parser) {
- return parser.getRequirements();
- }
-
- public static void unmarshalAttribute(String key, Object value, BiConsumer<String, Object> sink) throws IOException {
- unmarshal(key + "=" + value, Capability::getAttributes, sink);
- }
-
- public static void unmarshalDirective(String key, Object value, BiConsumer<String, String> sink) throws IOException {
- unmarshal(key + ":=" + value, Capability::getDirectives, sink);
- }
-
- private static <T> void unmarshal(String header, Function<Capability, Map<String, T>> lookup, BiConsumer<String, T> sink) throws IOException {
- try {
- ManifestParser.convertProvideCapabilities(
- ManifestParser.normalizeCapabilityClauses(ManifestParser.parseStandardHeader("foo;" + header), "2"))
- .forEach(capability -> lookup.apply(capability).forEach(sink));
- } catch (Exception e) {
- throw new IOException(e);
- }
- }
-
- public static void marshalAttribute(String key, Object value, BiConsumer<String, String> sink) {
- marshal(key, value, sink);
- }
-
- public static void marshalDirective(String key, Object value, BiConsumer<String, String> sink) {
- marshal(key, value, sink);
- }
-
- private static void marshal(String key, Object value, BiConsumer<String, String> sink) {
- StringBuilder keyBuilder = new StringBuilder(key);
- if (value instanceof List) {
- List list = (List) value;
- keyBuilder.append(":List");
- if (!list.isEmpty()) {
- String type = type(list.get(0));
- if (!type.equals("String")) {
- keyBuilder.append('<').append(type).append('>');
- }
- value = list.stream().map(
- v -> v.toString().replace(",", "\\,")
- ).collect(Collectors.joining(","));
- }
- else {
- value = "";
- }
- }
- else {
- String type = type(value);
- if (!type.equals("String")) {
- keyBuilder.append(':').append(type);
- }
- }
- sink.accept(keyBuilder.toString(), value.toString());
- }
-
- private static String type(Object value) {
- if (value instanceof Long) {
- return "Long";
- }
- else if (value instanceof Double)
- {
- return "Double";
- }
- else if (value instanceof Version)
- {
- return "Version";
- }
- else
- {
- return "String";
- }
- }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java
deleted file mode 100644
index f9dc1cc..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * 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.sling.feature.support.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.osgi.framework.VersionRange;
-
-class SimpleFilter
-{
- public static final int MATCH_ALL = 0;
- public static final int AND = 1;
- public static final int OR = 2;
- public static final int NOT = 3;
- public static final int EQ = 4;
- public static final int LTE = 5;
- public static final int GTE = 6;
- public static final int SUBSTRING = 7;
- public static final int PRESENT = 8;
- public static final int APPROX = 9;
-
- private final String m_name;
- private final Object m_value;
- private final int m_op;
-
- SimpleFilter(String attr, Object value, int op)
- {
- m_name = attr;
- m_value = value;
- m_op = op;
- }
-
- public String getName()
- {
- return m_name;
- }
-
- public Object getValue()
- {
- return m_value;
- }
-
- public int getOperation()
- {
- return m_op;
- }
-
- @Override
- public String toString()
- {
- String s = null;
- switch (m_op)
- {
- case AND:
- s = "(&" + toString((List) m_value) + ")";
- break;
- case OR:
- s = "(|" + toString((List) m_value) + ")";
- break;
- case NOT:
- s = "(!" + toString((List) m_value) + ")";
- break;
- case EQ:
- s = "(" + m_name + "=" + toEncodedString(m_value) + ")";
- break;
- case LTE:
- s = "(" + m_name + "<=" + toEncodedString(m_value) + ")";
- break;
- case GTE:
- s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
- break;
- case SUBSTRING:
- s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
- break;
- case PRESENT:
- s = "(" + m_name + "=*)";
- break;
- case APPROX:
- s = "(" + m_name + "~=" + toEncodedString(m_value) + ")";
- break;
- case MATCH_ALL:
- s = "(*)";
- break;
- }
- return s;
- }
-
- private static String toString(List list)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < list.size(); i++)
- {
- sb.append(list.get(i).toString());
- }
- return sb.toString();
- }
-
- private static String toDecodedString(String s, int startIdx, int endIdx)
- {
- StringBuffer sb = new StringBuffer(endIdx - startIdx);
- boolean escaped = false;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = s.charAt(startIdx + i);
- if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- private static String toEncodedString(Object o)
- {
- if (o instanceof String)
- {
- String s = (String) o;
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
- {
- sb.append('\\');
- }
- sb.append(c);
- }
-
- o = sb.toString();
- }
-
- return o.toString();
- }
-
- public static SimpleFilter parse(String filter)
- {
- int idx = skipWhitespace(filter, 0);
-
- if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
- {
- throw new IllegalArgumentException("Null or empty filter.");
- }
- else if (filter.charAt(idx) != '(')
- {
- throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
- }
-
- SimpleFilter sf = null;
- List stack = new ArrayList();
- boolean isEscaped = false;
- while (idx < filter.length())
- {
- if (sf != null)
- {
- throw new IllegalArgumentException(
- "Only one top-level operation allowed: " + filter);
- }
-
- if (!isEscaped && (filter.charAt(idx) == '('))
- {
- // Skip paren and following whitespace.
- idx = skipWhitespace(filter, idx + 1);
-
- if (filter.charAt(idx) == '&')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '|')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (filter.charAt(idx) == '!')
- {
- int peek = skipWhitespace(filter, idx + 1);
- if (filter.charAt(peek) == '(')
- {
- idx = peek - 1;
- stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else
- {
- stack.add(0, new Integer(idx));
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == ')'))
- {
- Object top = stack.remove(0);
- if (top instanceof SimpleFilter)
- {
- if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
- }
- else
- {
- sf = (SimpleFilter) top;
- }
- }
- else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
- {
- ((List) ((SimpleFilter) stack.get(0)).m_value).add(
- SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx));
- }
- else
- {
- sf = SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx);
- }
- }
- else if (!isEscaped && (filter.charAt(idx) == '\\'))
- {
- isEscaped = true;
- }
- else
- {
- isEscaped = false;
- }
-
- idx = skipWhitespace(filter, idx + 1);
- }
-
- if (sf == null)
- {
- throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
- }
-
- return sf;
- }
-
- private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
- {
- final String opChars = "=<>~";
-
- // Determine the ending index of the attribute name.
- int attrEndIdx = startIdx;
- for (int i = 0; i < (endIdx - startIdx); i++)
- {
- char c = filter.charAt(startIdx + i);
- if (opChars.indexOf(c) >= 0)
- {
- break;
- }
- else if (!Character.isWhitespace(c))
- {
- attrEndIdx = startIdx + i + 1;
- }
- }
- if (attrEndIdx == startIdx)
- {
- throw new IllegalArgumentException(
- "Missing attribute name: " + filter.substring(startIdx, endIdx));
- }
- String attr = filter.substring(startIdx, attrEndIdx);
-
- // Skip the attribute name and any following whitespace.
- startIdx = skipWhitespace(filter, attrEndIdx);
-
- // Determine the operator type.
- int op = -1;
- switch (filter.charAt(startIdx))
- {
- case '=':
- op = EQ;
- startIdx++;
- break;
- case '<':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = LTE;
- startIdx += 2;
- break;
- case '>':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = GTE;
- startIdx += 2;
- break;
- case '~':
- if (filter.charAt(startIdx + 1) != '=')
- {
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
- op = APPROX;
- startIdx += 2;
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown operator: " + filter.substring(startIdx, endIdx));
- }
-
- // Parse value.
- Object value = toDecodedString(filter, startIdx, endIdx);
-
- // Check if the equality comparison is actually a substring
- // or present operation.
- if (op == EQ)
- {
- String valueStr = filter.substring(startIdx, endIdx);
- List<String> values = parseSubstring(valueStr);
- if ((values.size() == 2)
- && (values.get(0).length() == 0)
- && (values.get(1).length() == 0))
- {
- op = PRESENT;
- }
- else if (values.size() > 1)
- {
- op = SUBSTRING;
- value = values;
- }
- }
-
- return new SimpleFilter(attr, value, op);
- }
-
- public static List<String> parseSubstring(String value)
- {
- List<String> pieces = new ArrayList();
- StringBuffer ss = new StringBuffer();
- // int kind = SIMPLE; // assume until proven otherwise
- boolean wasStar = false; // indicates last piece was a star
- boolean leftstar = false; // track if the initial piece is a star
- boolean rightstar = false; // track if the final piece is a star
-
- int idx = 0;
-
- // We assume (sub)strings can contain leading and trailing blanks
- boolean escaped = false;
- loop: for (;;)
- {
- if (idx >= value.length())
- {
- if (wasStar)
- {
- // insert last piece as "" to handle trailing star
- rightstar = true;
- }
- else
- {
- pieces.add(ss.toString());
- // accumulate the last piece
- // note that in the case of
- // (cn=); this might be
- // the string "" (!=null)
- }
- ss.setLength(0);
- break loop;
- }
-
- // Read the next character and account for escapes.
- char c = value.charAt(idx++);
- if (!escaped && (c == '*'))
- {
- // If we have successive '*' characters, then we can
- // effectively collapse them by ignoring succeeding ones.
- if (!wasStar)
- {
- if (ss.length() > 0)
- {
- pieces.add(ss.toString()); // accumulate the pieces
- // between '*' occurrences
- }
- ss.setLength(0);
- // if this is a leading star, then track it
- if (pieces.isEmpty())
- {
- leftstar = true;
- }
- wasStar = true;
- }
- }
- else if (!escaped && (c == '\\'))
- {
- escaped = true;
- }
- else
- {
- escaped = false;
- wasStar = false;
- ss.append(c);
- }
- }
- if (leftstar || rightstar || pieces.size() > 1)
- {
- // insert leading and/or trailing "" to anchor ends
- if (rightstar)
- {
- pieces.add("");
- }
- if (leftstar)
- {
- pieces.add(0, "");
- }
- }
- return pieces;
- }
-
- public static String unparseSubstring(List<String> pieces)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < pieces.size(); i++)
- {
- if (i > 0)
- {
- sb.append("*");
- }
- sb.append(toEncodedString(pieces.get(i)));
- }
- return sb.toString();
- }
-
- public static boolean compareSubstring(List<String> pieces, String s)
- {
- // Walk the pieces to match the string
- // There are implicit stars between each piece,
- // and the first and last pieces might be "" to anchor the match.
- // assert (pieces.length > 1)
- // minimal case is <string>*<string>
-
- boolean result = true;
- int len = pieces.size();
-
- // Special case, if there is only one piece, then
- // we must perform an equality test.
- if (len == 1)
- {
- return s.equals(pieces.get(0));
- }
-
- // Otherwise, check whether the pieces match
- // the specified string.
-
- int index = 0;
-
- loop: for (int i = 0; i < len; i++)
- {
- String piece = pieces.get(i);
-
- // If this is the first piece, then make sure the
- // string starts with it.
- if (i == 0)
- {
- if (!s.startsWith(piece))
- {
- result = false;
- break loop;
- }
- }
-
- // If this is the last piece, then make sure the
- // string ends with it.
- if (i == (len - 1))
- {
- if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
- {
- result = true;
- }
- else
- {
- result = false;
- }
- break loop;
- }
-
- // If this is neither the first or last piece, then
- // make sure the string contains it.
- if ((i > 0) && (i < (len - 1)))
- {
- index = s.indexOf(piece, index);
- if (index < 0)
- {
- result = false;
- break loop;
- }
- }
-
- // Move string index beyond the matching piece.
- index += piece.length();
- }
-
- return result;
- }
-
- private static int skipWhitespace(String s, int startIdx)
- {
- int len = s.length();
- while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
- {
- startIdx++;
- }
- return startIdx;
- }
-
- /**
- * Converts a attribute map to a filter. The filter is created by iterating
- * over the map's entry set. If ordering of attributes is important (e.g.,
- * for hitting attribute indices), then the map's entry set should iterate
- * in the desired order. Equality testing is assumed for all attribute types
- * other than version ranges, which are handled appropriated. If the attribute
- * map is empty, then a filter that matches anything is returned.
- * @param attrs Map of attributes to convert to a filter.
- * @return A filter corresponding to the attributes.
- */
- public static SimpleFilter convert(Map<String, Object> attrs)
- {
- // Rather than building a filter string to be parsed into a SimpleFilter,
- // we will just create the parsed SimpleFilter directly.
-
- List<SimpleFilter> filters = new ArrayList<>();
-
- for (Entry<String, Object> entry : attrs.entrySet())
- {
- if (entry.getValue() instanceof VersionRange)
- {
- VersionRange vr = (VersionRange) entry.getValue();
- if (vr.getLeftType() == VersionRange.LEFT_CLOSED)
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getLeft().toString(),
- SimpleFilter.GTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getLeft().toString(),
- SimpleFilter.LTE));
- filters.add(not);
- }
-
- if (vr.getRight() != null)
- {
- if (vr.getRightType() == VersionRange.RIGHT_CLOSED)
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- vr.getRight().toString(),
- SimpleFilter.LTE));
- }
- else
- {
- SimpleFilter not =
- new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
- ((List) not.getValue()).add(
- new SimpleFilter(
- entry.getKey(),
- vr.getRight().toString(),
- SimpleFilter.GTE));
- filters.add(not);
- }
- }
- }
- else
- {
- List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
- if (values.size() > 1)
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values,
- SimpleFilter.SUBSTRING));
- }
- else
- {
- filters.add(
- new SimpleFilter(
- entry.getKey(),
- values.get(0),
- SimpleFilter.EQ));
- }
- }
- }
-
- SimpleFilter sf = null;
-
- if (filters.size() == 1)
- {
- sf = filters.get(0);
- }
- else if (attrs.size() > 1)
- {
- sf = new SimpleFilter(null, filters, SimpleFilter.AND);
- }
- else if (filters.isEmpty())
- {
- sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
- }
-
- return sf;
- }
-}
diff --git a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java b/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java
deleted file mode 100644
index ea62869..0000000
--- a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.sling.feature.support.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-import java.util.jar.Manifest;
-
-import org.junit.Test;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-public class ManifestUtilTest {
-
- private void assertPackageInfo(final String name, final Version version, final PackageInfo info) {
- assertEquals(name, info.getName());
- assertEquals(version, info.getPackageVersion());
- }
-
- @Test public void testExportPackage() throws Exception {
- final Manifest mf = new Manifest();
- mf.getMainAttributes().putValue(Constants.EXPORT_PACKAGE, "org.apache.sling;version=1.0,org.apache.felix;version=2.0");
- final List<PackageInfo> infos = ManifestUtil.extractExportedPackages(mf);
- assertEquals(2, infos.size());
- assertPackageInfo("org.apache.sling", Version.parseVersion("1.0"), infos.get(0));
- assertPackageInfo("org.apache.felix", Version.parseVersion("2.0"), infos.get(1));
- }
-}
diff --git a/featuremodel/osgifeature-maven-plugin/pom.xml b/featuremodel/osgifeature-maven-plugin/pom.xml
index ec05534..0d099b6 100644
--- a/featuremodel/osgifeature-maven-plugin/pom.xml
+++ b/featuremodel/osgifeature-maven-plugin/pom.xml
@@ -119,11 +119,6 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.support</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
diff --git a/featuremodel/pom.xml b/featuremodel/pom.xml
index 1864df6..3293b7d 100644
--- a/featuremodel/pom.xml
+++ b/featuremodel/pom.xml
@@ -64,7 +64,6 @@
<module>feature-launcher</module>
<module>feature-modelconverter</module>
<module>feature-resolver</module>
- <module>feature-support</module>
<module>osgifeature-maven-plugin</module>
</modules>
--
To stop receiving notification emails like this one, please contact
pauls@apache.org.