You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/04/27 10:08:06 UTC
[sling-whiteboard] branch master updated: Remove feature modules
that have been migrated to their own git repo
This is an automated email from the ASF dual-hosted git repository.
davidb 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 3269608 Remove feature modules that have been migrated to their own git repo
3269608 is described below
commit 32696080651ec9062853b28f222a0c0d72b70b5f
Author: David Bosschaert <bo...@adobe.com>
AuthorDate: Fri Apr 27 11:05:11 2018 +0100
Remove feature modules that have been migrated to their own git repo
The modules are:
* feature now in sling-org-apache-sling-feature
* feature-analyser now in sling-org-apache-sling-feature-analyser
* feature-applicationbuilder now in sling-org-apache-sling-feature-applicationbuilder
* feature-io now in sling-org-apache-sling-feature-io
* feature-karaf now in sling-org-apache-sling-feature-karaf
* feature-launcher now in sling-org-apache-sling-feature-launcher
* feature-modelconverter now in sling-org-apache-sling-feature-modelconverter
* feature-resolver now in sling-org-apache-sling-feature-resolver
* osgifeature-maven-plugin now in sling-slingfeature-maven-plugin
---
featuremodel/feature-analyser/pom.xml | 159 ------
.../apache/sling/feature/analyser/Analyser.java | 125 -----
.../apache/sling/feature/analyser/main/Main.java | 74 ---
.../sling/feature/analyser/package-info.java | 23 -
.../sling/feature/analyser/task/AnalyserTask.java | 41 --
.../feature/analyser/task/AnalyserTaskContext.java | 51 --
.../task/impl/CheckBundleExportsImports.java | 218 --------
.../task/impl/CheckBundlesForInitialContent.java | 85 ----
.../task/impl/CheckBundlesForResources.java | 82 ---
.../task/impl/CheckRequirementsCapabilities.java | 110 ----
.../sling/feature/analyser/task/package-info.java | 23 -
.../feature/scanner/ApplicationDescriptor.java | 39 --
.../sling/feature/scanner/ArtifactDescriptor.java | 39 --
.../sling/feature/scanner/BundleDescriptor.java | 94 ----
.../sling/feature/scanner/ContainerDescriptor.java | 70 ---
.../apache/sling/feature/scanner/Descriptor.java | 92 ----
.../sling/feature/scanner/FeatureDescriptor.java | 28 -
.../apache/sling/feature/scanner/PackageInfo.java | 110 ----
.../org/apache/sling/feature/scanner/Scanner.java | 223 --------
.../scanner/impl/ApplicationDescriptorImpl.java | 52 --
.../feature/scanner/impl/BundleDescriptorImpl.java | 194 -------
.../scanner/impl/ContentPackageDescriptor.java | 142 ------
.../scanner/impl/ContentPackageScanner.java | 357 -------------
.../impl/ContentPackagesExtensionScanner.java | 74 ---
.../scanner/impl/FeatureDescriptorImpl.java | 39 --
.../scanner/impl/FelixFrameworkScanner.java | 201 --------
.../feature/scanner/impl/RepoInitScanner.java | 65 ---
.../apache/sling/feature/scanner/package-info.java | 23 -
.../feature/scanner/spi/ExtensionScanner.java | 48 --
.../feature/scanner/spi/FrameworkScanner.java | 44 --
.../sling/feature/scanner/spi/package-info.java | 23 -
...apache.sling.feature.analyser.task.AnalyserTask | 5 -
...ache.sling.feature.scanner.spi.ExtensionScanner | 3 -
...ache.sling.feature.scanner.spi.FrameworkScanner | 2 -
.../scanner/impl/BundleDescriptorImplTest.java | 73 ---
.../scanner/impl/FelixFrameworkScannerTest.java | 70 ---
.../src/test/resources/test-framework.jar | Bin 19945 -> 0 bytes
featuremodel/feature-applicationbuilder/pom.xml | 167 ------
.../feature/applicationbuilder/impl/Main.java | 203 --------
.../impl/ApplicationBuilderTest.java | 177 -------
.../src/test/resources/featureA.json | 5 -
.../src/test/resources/featureB.json | 14 -
.../src/test/resources/featureC.json | 18 -
.../src/test/resources/featureD.json | 5 -
featuremodel/feature-io/pom.xml | 120 -----
.../apache/sling/feature/io/ArtifactHandler.java | 42 --
.../apache/sling/feature/io/ArtifactManager.java | 366 -------------
.../sling/feature/io/ArtifactManagerConfig.java | 142 ------
.../java/org/apache/sling/feature/io/IOUtils.java | 243 ---------
.../feature/io/json/ApplicationJSONReader.java | 92 ----
.../feature/io/json/ApplicationJSONWriter.java | 97 ----
.../feature/io/json/ConfigurationJSONReader.java | 78 ---
.../feature/io/json/ConfigurationJSONWriter.java | 64 ---
.../sling/feature/io/json/FeatureJSONReader.java | 431 ----------------
.../sling/feature/io/json/FeatureJSONWriter.java | 207 --------
.../sling/feature/io/json/JSONConstants.java | 88 ----
.../sling/feature/io/json/JSONReaderBase.java | 479 -----------------
.../sling/feature/io/json/JSONWriterBase.java | 259 ----------
.../sling/feature/io/json/ManifestUtils.java | 515 -------------------
.../apache/sling/feature/io/json/package-info.java | 23 -
.../org/apache/sling/feature/io/package-info.java | 23 -
.../sling/feature/io/spi/ArtifactProvider.java | 55 --
.../feature/io/spi/ArtifactProviderContext.java | 46 --
.../apache/sling/feature/io/spi/package-info.java | 23 -
.../sling/feature/io/ArtifactManagerTest.java | 102 ----
.../org/apache/sling/feature/io/IOUtilsTest.java | 50 --
.../feature/io/json/FeatureJSONReaderTest.java | 222 --------
.../feature/io/json/FeatureJSONWriterTest.java | 50 --
.../java/org/apache/sling/feature/io/json/U.java | 89 ----
.../src/test/resources/features/repoinit.json | 4 -
.../src/test/resources/features/repoinit2.json | 7 -
.../src/test/resources/features/test.json | 92 ----
.../src/test/resources/features/test2.json | 107 ----
.../src/test/resources/features/test3.json | 116 -----
featuremodel/feature-karaf/pom.xml | 78 ---
.../sling/feature/karaf/ConfigurationUtil.java | 87 ----
.../sling/feature/karaf/KarafFeatureWriter.java | 197 -------
.../apache/sling/feature/karaf/package-info.java | 23 -
featuremodel/feature-launcher/pom.xml | 140 -----
.../feature/launcher/impl/FeatureProcessor.java | 147 ------
.../sling/feature/launcher/impl/Installation.java | 137 -----
.../feature/launcher/impl/LauncherConfig.java | 122 -----
.../apache/sling/feature/launcher/impl/Main.java | 313 ------------
.../launcher/impl/launchers/AbstractRunner.java | 278 ----------
.../launcher/impl/launchers/FrameworkLauncher.java | 102 ----
.../launcher/impl/launchers/FrameworkRunner.java | 70 ---
.../sling/feature/launcher/spi/Launcher.java | 26 -
.../launcher/spi/LauncherPrepareContext.java | 32 --
.../feature/launcher/spi/LauncherRunContext.java | 58 ---
featuremodel/feature-modelconverter/pom.xml | 176 -------
.../modelconverter/impl/FeatureToProvisioning.java | 281 ----------
.../sling/feature/modelconverter/impl/Main.java | 208 --------
.../modelconverter/impl/ProvisioningToFeature.java | 524 -------------------
.../modelconverter/impl/ModelConverterTest.java | 564 ---------------------
.../src/test/resources/boot.json | 100 ----
.../src/test/resources/boot.txt | 60 ---
.../src/test/resources/boot_gav.json | 100 ----
.../src/test/resources/launchpad.json | 28 -
.../src/test/resources/launchpad.txt | 20 -
.../src/test/resources/oak.json | 97 ----
.../src/test/resources/oak.txt | 91 ----
.../src/test/resources/repoinit.json | 74 ---
.../src/test/resources/repoinit.txt | 78 ---
.../src/test/resources/simple.json | 9 -
.../src/test/resources/simple.txt | 24 -
featuremodel/feature-resolver/pom.xml | 118 -----
.../resolver/ApplicationResolverAssembler.java | 128 -----
.../sling/feature/resolver/FeatureResolver.java | 38 --
.../sling/feature/resolver/FeatureResource.java | 52 --
.../sling/feature/resolver/FrameworkResolver.java | 310 -----------
.../apache/sling/feature/resolver/Resolver.java | 32 --
.../sling/feature/resolver/ResolverContext.java | 46 --
.../resolver/impl/AbstractResourceImpl.java | 50 --
.../feature/resolver/impl/BundleResourceImpl.java | 228 ---------
.../feature/resolver/impl/FeatureResourceImpl.java | 174 -------
.../feature/resolver/impl/ResolveContextImpl.java | 96 ----
.../sling/feature/resolver/AnalyserTest.java | 115 -----
.../feature/resolver/FrameworkResolverTest.java | 149 ------
.../feature/resolver/TestBundleResourceImpl.java | 231 ---------
.../resolver/impl/BundleResourceImplTest.java | 208 --------
.../resolver/impl/ResolveContextImplTest.java | 126 -----
.../src/test/resources/feature1.json | 5 -
.../src/test/resources/feature2.json | 5 -
.../src/test/resources/feature3.json | 15 -
.../src/test/resources/feature4.json | 5 -
.../src/test/resources/feature5.json | 13 -
.../src/test/resources/feature6.json | 12 -
.../src/test/resources/feature_complete.json | 82 ---
.../src/test/resources/feature_incomplete.json | 82 ---
featuremodel/feature/pom.xml | 101 ----
.../java/org/apache/sling/feature/Application.java | 128 -----
.../java/org/apache/sling/feature/Artifact.java | 133 -----
.../java/org/apache/sling/feature/ArtifactId.java | 414 ---------------
.../java/org/apache/sling/feature/Bundles.java | 181 -------
.../org/apache/sling/feature/Configuration.java | 154 ------
.../org/apache/sling/feature/Configurations.java | 58 ---
.../java/org/apache/sling/feature/Extension.java | 184 -------
.../org/apache/sling/feature/ExtensionType.java | 27 -
.../java/org/apache/sling/feature/Extensions.java | 41 --
.../java/org/apache/sling/feature/Feature.java | 390 --------------
.../org/apache/sling/feature/FeatureConstants.java | 25 -
.../java/org/apache/sling/feature/Include.java | 115 -----
.../java/org/apache/sling/feature/KeyValueMap.java | 140 -----
.../sling/feature/builder/ApplicationBuilder.java | 153 ------
.../sling/feature/builder/BuilderContext.java | 81 ---
.../apache/sling/feature/builder/BuilderUtil.java | 267 ----------
.../sling/feature/builder/FeatureBuilder.java | 182 -------
.../feature/builder/FeatureExtensionHandler.java | 59 ---
.../sling/feature/builder/FeatureProvider.java | 36 --
.../apache/sling/feature/builder/package-info.java | 23 -
.../org/apache/sling/feature/package-info.java | 23 -
.../org/apache/sling/feature/ArtifactIdTest.java | 149 ------
.../java/org/apache/sling/feature/BundlesTest.java | 55 --
.../sling/feature/builder/BuilderUtilTest.java | 160 ------
.../sling/feature/builder/FeatureBuilderTest.java | 303 -----------
featuremodel/osgifeature-maven-plugin/pom.xml | 192 -------
.../feature/maven/ApplicationProjectConfig.java | 116 -----
.../feature/maven/ApplicationProjectInfo.java | 31 --
.../apache/sling/feature/maven/Environment.java | 35 --
.../sling/feature/maven/FeatureConstants.java | 32 --
.../sling/feature/maven/FeatureProjectConfig.java | 138 -----
.../sling/feature/maven/FeatureProjectInfo.java | 32 --
.../apache/sling/feature/maven/Preprocessor.java | 515 -------------------
.../apache/sling/feature/maven/ProjectHelper.java | 320 ------------
.../apache/sling/feature/maven/ProjectInfo.java | 27 -
.../feature/maven/mojos/AbstractFeatureMojo.java | 116 -----
.../sling/feature/maven/mojos/AttachFeature.java | 77 ---
.../mojos/DependencyLifecycleParticipant.java | 89 ----
.../META-INF/m2e/lifecycle-mapping-metadata.xml | 32 --
.../main/resources/META-INF/plexus/components.xml | 103 ----
.../src/site/markdown/index.md | 6 -
.../osgifeature-maven-plugin/src/site/site.xml | 35 --
featuremodel/pom.xml | 70 ---
173 files changed, 20034 deletions(-)
diff --git a/featuremodel/feature-analyser/pom.xml b/featuremodel/feature-analyser/pom.xml
deleted file mode 100644
index add7b59..0000000
--- a/featuremodel/feature-analyser/pom.xml
+++ /dev/null
@@ -1,159 +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.analyser</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-
- <name>Apache Sling Feature Analyser</name>
- <description>
- A feature describes an OSGi system
- </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-analyser</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-analyser</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-analyser</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>unpack-dependencies</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>unpack-dependencies</goal>
- </goals>
- <configuration>
- <excludes>META-INF/**</excludes>
- <outputDirectory>${project.build.directory}/classes</outputDirectory>
- <overWriteReleases>false</overWriteReleases>
- <overWriteSnapshots>true</overWriteSnapshots>
- <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.commons.johnzon,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.apache.sling.feature.analyser.main.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask</exclude>
- <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner</exclude>
- <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- </dependency>
- <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.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <scope>provided</scope>
- </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.sling</groupId>
- <artifactId>org.apache.sling.commons.johnzon</artifactId>
- <version>1.0.0</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>
-
- <!-- Testing -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java
deleted file mode 100644
index 8124c9b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java
+++ /dev/null
@@ -1,125 +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.analyser;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.apache.sling.feature.scanner.Scanner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Analyser {
-
- private final AnalyserTask[] tasks;
-
- private final Scanner scanner;
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- public Analyser(final Scanner scanner,
- final AnalyserTask...tasks)
- throws IOException {
- this.tasks = tasks;
- this.scanner = scanner;
- }
-
- public Analyser(final Scanner scanner,
- final String... taskIds)
- throws IOException {
- this(scanner, getTasks(taskIds));
- if ( this.tasks.length != taskIds.length ) {
- throw new IOException("Couldn't find all tasks " + taskIds);
- }
- }
-
- public Analyser(final Scanner scanner)
- throws IOException {
- this(scanner, getTasks((String[])null));
- }
-
- private static AnalyserTask[] getTasks(final String... taskIds) {
- final Set<String> ids = taskIds == null ? null : new HashSet<>(Arrays.asList(taskIds));
- final ServiceLoader<AnalyserTask> loader = ServiceLoader.load(AnalyserTask.class);
- final List<AnalyserTask> list = new ArrayList<>();
- for(final AnalyserTask task : loader) {
- if ( ids == null || ids.contains(task.getId()) ) {
- list.add(task);
- }
- }
- return list.toArray(new AnalyserTask[list.size()]);
- }
-
- public void analyse(final Application app)
- throws Exception {
- logger.info("Starting application analyzer...");
-
- final ApplicationDescriptor appDesc = scanner.scan(app);
-
- final List<String> warnings = new ArrayList<>();
- final List<String> errors = new ArrayList<>();
-
- // execute analyser tasks
- for(final AnalyserTask task : tasks) {
- logger.info("- Executing {}...", task.getName());
- task.execute(new AnalyserTaskContext() {
-
- @Override
- public Application getApplication() {
- return app;
- }
-
- @Override
- public ApplicationDescriptor getDescriptor() {
- return appDesc;
- }
-
- @Override
- public void reportWarning(final String message) {
- warnings.add(message);
- }
-
- @Override
- public void reportError(final String message) {
- errors.add(message);
- }
- });
- }
-
- for(final String msg : warnings) {
- logger.warn(msg);
- }
- for(final String msg : errors) {
- logger.error(msg);
- }
-
- if ( !errors.isEmpty() ) {
- throw new Exception("Analyser detected errors. See log output for error messages.");
- }
-
- logger.info("Provisioning model analyzer finished");
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
deleted file mode 100644
index 79cc35b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
+++ /dev/null
@@ -1,74 +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.analyser.main;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.analyser.Analyser;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.IOUtils;
-import org.apache.sling.feature.io.json.ApplicationJSONReader;
-import org.apache.sling.feature.scanner.Scanner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-public class Main {
-
- public static void main(final String[] args) {
- // setup logging
- System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
- System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
- System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
- System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
-
- final Logger logger = LoggerFactory.getLogger("analyser");
- logger.info("Apache Sling Application Analyser");
- logger.info("");
-
- if ( args.length == 0 ) {
- logger.error("Required argument missing: application file");
- System.exit(1);
- }
- if ( args.length > 1 ) {
- logger.error("Too many arguments. Only one (application file) is supported");
- System.exit(1);
- }
- final File f = new File(args[0]);
- Application app = null;
- try ( final FileReader r = new FileReader(f)) {
- app = ApplicationJSONReader.read(r);
- } catch ( final IOException ioe) {
- logger.error("Unable to read application: {}", f, ioe);
- System.exit(1);
- }
- if ( app.getFramework() == null ) {
- app.setFramework(IOUtils.getFelixFrameworkId(null));
- }
-
- try {
- final Scanner scanner = new Scanner(new ArtifactManagerConfig());
- final Analyser analyser = new Analyser(scanner);
- analyser.analyse(app);
- } catch ( final Exception e) {
- logger.error("Unable to analyse application: {}", f, e);
- System.exit(1);
- }
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java
deleted file mode 100644
index 3042a56..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.analyser;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java
deleted file mode 100644
index 97cd99a..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java
+++ /dev/null
@@ -1,41 +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.analyser.task;
-
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * A analyser task analyses a specific part of the assembled
- * application. It can report errors and warnings.
- */
-@ConsumerType
-public interface AnalyserTask {
-
- /** A unique (short) id. */
- default String getId() {
- return getClass().getName();
- };
-
- /** A human readable name to identify the task. */
- default String getName() {
- return getClass().getSimpleName();
- };
-
- /** Execute the task. */
- void execute(AnalyserTaskContext ctx) throws Exception;
-}
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java
deleted file mode 100644
index b33fd80..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java
+++ /dev/null
@@ -1,51 +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.analyser.task;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.osgi.annotation.versioning.ProviderType;
-
-@ProviderType
-public interface AnalyserTaskContext {
-
- /**
- * The assembled application.
- * @return The application.
- */
- Application getApplication();
-
- /**
- * The application descriptor
- */
- ApplicationDescriptor getDescriptor();
-
- /**
- * This method is invoked by a {@link AnalyserTask} to report
- * a warning.
- * @param message The message.
- */
- void reportWarning(String message);
-
- /**
- * This method is invoked by a {@link AnalyserTask} to report
- * an error.
- * @param message The message.
- */
- void reportError(String message);
-}
-
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
deleted file mode 100644
index 6a44c97..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
+++ /dev/null
@@ -1,218 +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.analyser.task.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-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.scanner.PackageInfo;
-import org.osgi.framework.Version;
-
-public class CheckBundleExportsImports implements AnalyserTask {
-
- @Override
- public String getName() {
- return "Bundle Import/Export Check";
- }
-
- @Override
- public String getId() {
- return "bundle-packages";
- }
-
- public static final class Report {
-
- public List<PackageInfo> exportWithoutVersion = new ArrayList<>();
-
- public List<PackageInfo> exportMatchingSeveral = new ArrayList<>();
-
- public List<PackageInfo> importWithoutVersion = new ArrayList<>();
-
- public List<PackageInfo> missingExports = new ArrayList<>();
-
- public List<PackageInfo> missingExportsWithVersion = new ArrayList<>();
-
- public List<PackageInfo> missingExportsForOptional = new ArrayList<>();
- }
-
- private Report getReport(final Map<BundleDescriptor, Report> reports, final BundleDescriptor info) {
- Report report = reports.get(info);
- if ( report == null ) {
- report = new Report();
- reports.put(info, report);
- }
- return report;
- }
-
- private void checkForVersionOnExportedPackages(final AnalyserTaskContext ctx, final Map<BundleDescriptor, Report> reports) {
- for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
- if ( info.getExportedPackages() != null ) {
- for(final PackageInfo i : info.getExportedPackages()) {
- if ( i.getPackageVersion().compareTo(Version.emptyVersion) == 0 ) {
- getReport(reports, info).exportWithoutVersion.add(i);
- }
- }
- }
- }
- }
-
- private void checkForVersionOnImportingPackages(final AnalyserTaskContext ctx, final Map<BundleDescriptor, Report> reports) {
- for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
- if ( info.getImportedPackages() != null ) {
- for(final PackageInfo i : info.getImportedPackages()) {
- if ( i.getVersion() == null ) {
- // don't report for javax and org.w3c. packages (TODO)
- if ( !i.getName().startsWith("javax.")
- && !i.getName().startsWith("org.w3c.")) {
- getReport(reports, info).importWithoutVersion.add(i);
- }
- }
- }
- }
- }
- }
-
-
- @Override
- public void execute(final AnalyserTaskContext ctx) throws IOException {
- // basic checks
- final Map<BundleDescriptor, Report> reports = new HashMap<>();
- checkForVersionOnExportedPackages(ctx, reports);
- checkForVersionOnImportingPackages(ctx, reports);
-
- final SortedMap<Integer, List<BundleDescriptor>> bundlesMap = new TreeMap<>();
- for(final BundleDescriptor bi : ctx.getDescriptor().getBundleDescriptors()) {
- List<BundleDescriptor> list = bundlesMap.get(bi.getBundleStartLevel());
- if ( list == null ) {
- list = new ArrayList<>();
- bundlesMap.put(bi.getBundleStartLevel(), list);
- }
- list.add(bi);
- }
-
- // add all system packages
- final List<BundleDescriptor> exportingBundles = new ArrayList<>();
- exportingBundles.add(ctx.getDescriptor().getFrameworkDescriptor());
-
- for(final Map.Entry<Integer, List<BundleDescriptor>> entry : bundlesMap.entrySet()) {
- // first add all exporting bundles
- for(final BundleDescriptor info : entry.getValue()) {
- if ( info.getExportedPackages() != null ) {
- exportingBundles.add(info);
- }
- }
- // check importing bundles
- for(final BundleDescriptor info : entry.getValue()) {
- if ( info.getImportedPackages() != null ) {
- for(final PackageInfo pck : info.getImportedPackages() ) {
- final List<BundleDescriptor> candidates = getCandidates(exportingBundles, pck);
- if ( candidates.isEmpty() ) {
- if ( pck.isOptional() ) {
- getReport(reports, info).missingExportsForOptional.add(pck);
- } else {
- getReport(reports, info).missingExports.add(pck);
- }
- } else {
- final List<BundleDescriptor> matchingCandidates = new ArrayList<>();
- for(final BundleDescriptor i : candidates) {
- if ( i.isExportingPackage(pck) ) {
- matchingCandidates.add(i);
- }
- }
- if ( matchingCandidates.isEmpty() ) {
- if ( pck.isOptional() ) {
- getReport(reports, info).missingExportsForOptional.add(pck);
- } else {
- getReport(reports, info).missingExportsWithVersion.add(pck);
- }
- } else if ( matchingCandidates.size() > 1 ) {
- getReport(reports, info).exportMatchingSeveral.add(pck);
- }
- }
- }
- }
- }
- }
-
- for(final Map.Entry<BundleDescriptor, Report> entry : reports.entrySet()) {
- final String key = "Bundle " + entry.getKey().getArtifact().getId().getArtifactId() + ":" + entry.getKey().getArtifact().getId().getVersion();
-
- if ( !entry.getValue().importWithoutVersion.isEmpty() ) {
- ctx.reportWarning(key + " is importing package(s) " + getPackageInfo(entry.getValue().importWithoutVersion, false) + " without specifying a version range.");
- }
- if ( !entry.getValue().exportWithoutVersion.isEmpty() ) {
- ctx.reportWarning(key + " is exporting package(s) " + getPackageInfo(entry.getValue().importWithoutVersion, false) + " without a version.");
- }
-
- if ( !entry.getValue().missingExports.isEmpty() ) {
- ctx.reportError(key + " is importing package(s) " + getPackageInfo(entry.getValue().missingExports, false) + " in start level " +
- String.valueOf(entry.getKey().getBundleStartLevel()) + " but no bundle is exporting these for that start level.");
- }
- if ( !entry.getValue().missingExportsWithVersion.isEmpty() ) {
- ctx.reportError(key + " is importing package(s) " + getPackageInfo(entry.getValue().missingExportsWithVersion, true) + " in start level " +
- String.valueOf(entry.getKey().getBundleStartLevel()) + " but no bundle is exporting these for that start level in the required version range.");
- }
- }
- }
-
- private String getPackageInfo(final List<PackageInfo> pcks, final boolean includeVersion) {
- if ( pcks.size() == 1 ) {
- if (includeVersion) {
- return pcks.get(0).toString();
- } else {
- return pcks.get(0).getName();
- }
- }
- final StringBuilder sb = new StringBuilder();
- boolean first = true;
- sb.append('[');
- for(final PackageInfo info : pcks) {
- if ( first ) {
- first = false;
- } else {
- sb.append(", ");
- }
- if (includeVersion) {
- sb.append(info.toString());
- } else {
- sb.append(info.getName());
- }
- }
- sb.append(']');
- return sb.toString();
- }
-
- private List<BundleDescriptor> getCandidates(final List<BundleDescriptor> exportingBundles, final PackageInfo pck) {
- final List<BundleDescriptor> candidates = new ArrayList<>();
- for(final BundleDescriptor info : exportingBundles) {
- if ( info.isExportingPackage(pck.getName()) ) {
- candidates.add(info);
- }
- }
- return candidates;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java
deleted file mode 100644
index d5e2360..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java
+++ /dev/null
@@ -1,85 +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.analyser.task.impl;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.Manifest;
-
-public class CheckBundlesForInitialContent implements AnalyserTask {
-
- /** The manifest header to specify initial content to be loaded. */
- private static final String CONTENT_HEADER = "Sling-Initial-Content";
-
- /**
- * The path directive specifying the target node where initial content will
- * be loaded.
- */
- private static final String PATH_DIRECTIVE = "path";
-
- @Override
- public String getName() {
- return "Bundle Initial Content Check";
- }
-
- @Override
- public String getId() {
- return "bundle-content";
- }
-
- @Override
- public void execute(final AnalyserTaskContext ctx) {
- // check for initial content
- for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
- final List<String> initialContent = extractInitialContent(info.getManifest());
-
- if ( !initialContent.isEmpty() ) {
- ctx.reportWarning("Found initial content in " + info.getArtifact() + " : " + initialContent);
- }
- }
- }
-
- private List<String> extractInitialContent(final Manifest m) {
- final List<String> initialContent = new ArrayList<>();
- if ( m != null ) {
- final String root = m.getMainAttributes().getValue(CONTENT_HEADER);
- if (root != null) {
- Clause[] clauses = Parser.parseHeader(root);
- for (final Clause entry :clauses) {
-
- String path = entry.getDirective(PATH_DIRECTIVE);
- if (path == null) {
- path = "/";
- } else if (!path.startsWith("/")) {
- // make relative path absolute
- path = "/" + path;
- }
- initialContent.add(path);
- }
- }
- }
- return initialContent;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java
deleted file mode 100644
index 545244e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java
+++ /dev/null
@@ -1,82 +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.analyser.task.impl;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.Manifest;
-
-public class CheckBundlesForResources implements AnalyserTask {
-
- /** The manifest header to specify bundle resources. */
- private static final String BUNDLE_RESOURCE_ROOTS = "Sling-Bundle-Resources";
-
- /**
- * The path directive specifying the target node where initial content will
- * be loaded.
- */
- private static final String PATH_DIRECTIVE = "path";
-
- @Override
- public String getName() {
- return "Bundle Resources Check";
- }
-
- @Override
- public String getId() {
- return "bundle-resources";
- }
-
- @Override
- public void execute(final AnalyserTaskContext ctx) {
- // check for initial content
- for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
- final List<String> bundleResources = extractBundleResources(info.getManifest());
- if ( !bundleResources.isEmpty() ) {
- ctx.reportWarning("Found bundle resources in " + info.getArtifact() + " : " + bundleResources);
- }
- }
- }
-
- private List<String> extractBundleResources(final Manifest m) {
- final List<String> bundleResources = new ArrayList<>();
- if ( m != null ) {
- final String root = m.getMainAttributes().getValue(BUNDLE_RESOURCE_ROOTS);
- if (root != null) {
- Clause[] clauses = Parser.parseHeader(root);
- for (final Clause entry : clauses) {
- final String resourceRoot = entry.getName();
- final String pathDirective = entry.getDirective(PATH_DIRECTIVE);
- if (pathDirective != null) {
- bundleResources.add(resourceRoot + "!" + pathDirective);
- } else {
- bundleResources.add(resourceRoot);
- }
- }
- }
- }
- return bundleResources;
- }
-}
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
deleted file mode 100644
index bd1732f..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
+++ /dev/null
@@ -1,110 +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.analyser.task.impl;
-
-import org.apache.felix.utils.resource.CapabilitySet;
-import org.apache.felix.utils.resource.RequirementImpl;
-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;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-
-public class CheckRequirementsCapabilities implements AnalyserTask {
- private final String format = "Artifact %s:%s requires %s in start level %d but %s";
-
- @Override
- public void execute(AnalyserTaskContext ctx) throws Exception {
- final SortedMap<Integer, List<ArtifactDescriptor>> artifactsMap = new TreeMap<>();
- for(final BundleDescriptor bi : ctx.getDescriptor().getBundleDescriptors()) {
- List<ArtifactDescriptor> list = artifactsMap.get(bi.getBundleStartLevel());
- if ( list == null ) {
- list = new ArrayList<>();
- artifactsMap.put(bi.getBundleStartLevel(), list);
- }
- list.add(bi);
- }
-
- if (!ctx.getDescriptor().getArtifactDescriptors().isEmpty()) {
- artifactsMap.put(
- (artifactsMap.isEmpty() ? 0 : artifactsMap.lastKey()) + 1,
- new ArrayList<>(ctx.getDescriptor().getArtifactDescriptors())
- );
- }
-
- // add system artifact
- final List<ArtifactDescriptor> artifacts = new ArrayList<>();
- artifacts.add(ctx.getDescriptor().getFrameworkDescriptor());
-
- for(final Map.Entry<Integer, List<ArtifactDescriptor>> entry : artifactsMap.entrySet()) {
- // first add all providing artifacts
- for (final ArtifactDescriptor info : entry.getValue()) {
- if (info.getCapabilities() != null) {
- artifacts.add(info);
- }
- }
- // check requiring artifacts
- for (final ArtifactDescriptor info : entry.getValue()) {
- if (info.getRequirements() != null)
- {
- for (Requirement requirement : info.getRequirements()) {
- 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 (!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."));
- }
- }
- 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."));
- }
- }
- }
- }
- }
- }
- }
-
- private List<ArtifactDescriptor> getCandidates(List<ArtifactDescriptor> artifactDescriptors, Requirement requirement) {
- return artifactDescriptors.stream()
- .filter(artifactDescriptor -> artifactDescriptor.getCapabilities() != null)
- .filter(artifactDescriptor -> artifactDescriptor.getCapabilities().stream().anyMatch(capability -> CapabilitySet.matches(capability, requirement)))
- .collect(Collectors.toList());
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java
deleted file mode 100644
index d265303..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.analyser.task;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java
deleted file mode 100644
index 5dabc64..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java
+++ /dev/null
@@ -1,39 +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.scanner;
-
-import org.apache.sling.feature.Application;
-
-/**
- * Information about an application.
- * This is the aggregated information.
- */
-public abstract class ApplicationDescriptor extends ContainerDescriptor {
-
- public abstract Application getApplication();
-
- public abstract BundleDescriptor getFrameworkDescriptor();
-
- @Override
- public void lock() {
- if ( this.isLocked() ) {
- return;
- }
- this.aggregate(this.getFrameworkDescriptor());
- super.lock();
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java
deleted file mode 100644
index 988b9d0..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java
+++ /dev/null
@@ -1,39 +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.scanner;
-
-import java.io.File;
-
-import org.apache.sling.feature.Artifact;
-
-/**
- * Information about an artifact
- */
-public abstract class ArtifactDescriptor extends Descriptor {
-
- /**
- * Get the artifact file
- * @return The artifact file
- */
- public abstract File getArtifactFile();
-
- /**
- * Get the artifact
- * @return The artifact
- */
- public abstract Artifact getArtifact();
-}
\ No newline at end of file
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
deleted file mode 100644
index 52f3a71..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
+++ /dev/null
@@ -1,94 +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.scanner;
-
-import java.util.jar.Manifest;
-
-import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-
-/**
- * Information about a bundle
- */
-public abstract class BundleDescriptor extends ArtifactDescriptor implements Comparable<BundleDescriptor> {
-
- /**
- * Get the bundle symbolic name.
- * @return The bundle symbolic name
- */
- public abstract String getBundleSymbolicName();
-
- /**
- * Get the bundle version
- * @return The bundle version
- */
- public abstract String getBundleVersion();
-
- /**
- * Get the start level
- * @return The start level.
- */
- public abstract int getBundleStartLevel();
-
- /**
- * If the artifact has a manifest, return it
- * @return The manifest
- */
- public abstract Manifest getManifest();
-
- public boolean isExportingPackage(final String packageName) {
- for(final PackageInfo i : getExportedPackages()) {
- if ( i.getName().equals(packageName) ) {
- return true;
- }
- }
- return false;
- }
-
- public boolean isExportingPackage(final PackageInfo info) {
- for(final PackageInfo i : getExportedPackages()) {
- if ( i.getName().equals(info.getName())
- && (info.getVersion() == null || info.getPackageVersionRange().includes(i.getPackageVersion()))) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean equals(Object obj) {
- if ( obj instanceof BundleDescriptorImpl ) {
- return this.getBundleSymbolicName().equals(((BundleDescriptorImpl)obj).getBundleSymbolicName()) && this.getBundleVersion().equals(((BundleDescriptorImpl)obj).getBundleVersion());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return (this.getBundleSymbolicName() + ':' + this.getBundleVersion()).hashCode();
-
- }
-
- @Override
- public String toString() {
- return "BundleInfo [symbolicName=" + getBundleSymbolicName() + ", version=" + this.getBundleVersion() + "]";
- }
-
- @Override
- public int compareTo(final BundleDescriptor o) {
- return (this.getBundleSymbolicName() + ':' + this.getBundleVersion()).compareTo((o.getBundleSymbolicName() + ':' + o.getBundleVersion()));
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java
deleted file mode 100644
index 0ae37f3..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java
+++ /dev/null
@@ -1,70 +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.scanner;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Information about a container (feature/application).
- * This is the aggregated information.
- */
-public abstract class ContainerDescriptor extends Descriptor {
-
- private final Set<BundleDescriptor> bundles = new HashSet<>();
-
- private final Set<ArtifactDescriptor> artifacts = new HashSet<>();
-
- /**
- * Return a set of bundle descriptors.
- *
- * The requirements and capabilities of the returned bundles are
- * available as an aggregate from {@link Descriptor#getCapabilities()},
- * {@link Descriptor#getRequirements()}, {@link Descriptor#getDynamicImportedPackages()}
- * {@link Descriptor#getExportedPackages()} and {@link Descriptor#getImportedPackages()}
- * @return The set of bundle descriptors (might be empty)
- */
- public final Set<BundleDescriptor> getBundleDescriptors() {
- return this.isLocked() ? Collections.unmodifiableSet(bundles) : bundles;
- }
-
- /**
- * Return a set of artifact descriptors
- * The requirements and capabilities of the returned artifacts are
- * available as an aggregate from {@link Descriptor#getCapabilities()},
- * {@link Descriptor#getRequirements()}.
- * @return The set of artifact descriptors (might be empty)
- */
- public final Set<ArtifactDescriptor> getArtifactDescriptors() {
- return this.isLocked() ? Collections.unmodifiableSet(artifacts) : artifacts;
- }
-
- @Override
- public void lock() {
- if ( this.isLocked() ) {
- return;
- }
- for(final BundleDescriptor bd : this.bundles) {
- this.aggregate(bd);
- }
- for(final ArtifactDescriptor d : this.artifacts) {
- this.aggregate(d);
- }
- super.lock();
- }
-}
\ No newline at end of file
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
deleted file mode 100644
index 2b5fc1b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
+++ /dev/null
@@ -1,92 +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.scanner;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-/**
- * A descriptor holds information about requirements and capabilities
- */
-public abstract class Descriptor {
-
- private boolean locked;
-
- private final Set<PackageInfo> exports = new HashSet<>();
-
- private final Set<PackageInfo> imports = new HashSet<>();
-
- private final Set<PackageInfo> dynImports = new HashSet<>();
-
- private final Set<Requirement> reqs = new HashSet<>();
-
- private final Set<Capability> caps = new HashSet<>();
-
- public void lock() {
- this.locked = true;
- }
-
- public final boolean isLocked() {
- return this.locked;
- }
-
- protected void checkLocked() {
- if (this.locked) {
- throw new IllegalStateException("Descriptor is locked.");
- }
- }
-
- protected void aggregate(final Descriptor d) {
- reqs.addAll(d.getRequirements());
- caps.addAll(d.getCapabilities());
- dynImports.addAll(d.getDynamicImportedPackages());
- imports.addAll(d.getImportedPackages());
- exports.addAll(d.getExportedPackages());
- }
-
- public final Set<PackageInfo> getExportedPackages() {
- return locked ? Collections.unmodifiableSet(exports) : exports;
- }
-
- public final Set<PackageInfo> getImportedPackages() {
- return locked ? Collections.unmodifiableSet(imports) : imports;
- }
-
- public final Set<PackageInfo> getDynamicImportedPackages() {
- return locked ? Collections.unmodifiableSet(dynImports) : dynImports;
- }
-
- /**
- * Return the list of requirements.
- * @return The list of requirements. The list might be empty.
- */
- public final Set<Requirement> getRequirements() {
- return locked ? Collections.unmodifiableSet(reqs) : reqs;
- }
-
- /**
- * Return the list of capabilities.
- * @return The list of capabilities. The list might be empty.
- */
- public final Set<Capability> getCapabilities() {
- return locked ? Collections.unmodifiableSet(caps) : caps;
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java
deleted file mode 100644
index d82b6f1..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java
+++ /dev/null
@@ -1,28 +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.scanner;
-
-import org.apache.sling.feature.Feature;
-
-/**
- * Information about a feature.
- * This is the aggregated information.
- */
-public abstract class FeatureDescriptor extends ContainerDescriptor {
-
- public abstract Feature getFeature();
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
deleted file mode 100644
index bb7081b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
+++ /dev/null
@@ -1,110 +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.scanner;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-
-public class PackageInfo implements Comparable<PackageInfo> {
-
- private final boolean optional;
- private final String name;
- private final String version;
-
- public PackageInfo(final String name, final String version, final boolean optional) {
- this.name = name;
- this.version = version;
- this.optional = optional;
- }
-
- public String getName() {
- return name;
- }
-
- public String getVersion() {
- return version;
- }
-
- public boolean isOptional() {
- return optional;
- }
-
- public Version getPackageVersion() {
- if (this.version == null)
- return null;
-
- return new Version(this.version);
- }
-
- public VersionRange getPackageVersionRange() {
- if (this.version == null)
- return null;
-
- return new VersionRange(this.version);
- }
-
- @Override
- public String toString() {
- return "Package " + name
- + ";version=" + version
- + (this.optional ? " (optional)" : "");
- }
-
- @Override
- public int compareTo(final PackageInfo o) {
- int result = this.name.compareTo(o.name);
- if ( result == 0 ) {
- result = this.version.compareTo(o.version);
- }
- return result;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + (optional ? 1231 : 1237);
- result = prime * result + ((version == null) ? 0 : version.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- PackageInfo other = (PackageInfo) obj;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- if (optional != other.optional)
- return false;
- if (version == null) {
- if (other.version != null)
- return false;
- } else if (!version.equals(other.version))
- return false;
- return true;
- }
-
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java
deleted file mode 100644
index b0c29a9..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java
+++ /dev/null
@@ -1,223 +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.scanner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.scanner.impl.ApplicationDescriptorImpl;
-import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.scanner.impl.FeatureDescriptorImpl;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-import org.apache.sling.feature.scanner.spi.FrameworkScanner;
-
-/**
- * The scanner is a service that scans items and provides descriptions for these.
- * The following items can be scanned individually
- * <ul>
- * <li>A bundle artifact
- * <li>An extension (requires {@link ExtensionScanner}s)
- * <li>A feature (requires {@link ExtensionScanner}s)
- * <li>A framework (requires {@link FrameworkScanner}s)
- * <li>An application (requires all scanner types)
- * </ul>
- */
-public class Scanner {
-
- private final ArtifactManager artifactManager;
-
- private final List<ExtensionScanner> extensionScanners;
-
- private final List<FrameworkScanner> frameworkScanners;
-
- /**
- * Create a new scanner
- *
- * @param amConfig The artifact manager configuration
- * @param artifactScanners A list of artifact scanners
- * @param extensionScanners A list of extension scanners
- * @param frameworkScanners A list of framework scanners
- * @throws IOException If something goes wrong
- */
- public Scanner(final ArtifactManagerConfig amConfig,
- final List<ExtensionScanner> extensionScanners,
- final List<FrameworkScanner> frameworkScanners)
- throws IOException {
- this.artifactManager = ArtifactManager.getArtifactManager(amConfig);
- this.extensionScanners = extensionScanners == null ? getServices(ExtensionScanner.class) : extensionScanners;
- this.frameworkScanners = frameworkScanners == null ? getServices(FrameworkScanner.class) : frameworkScanners;
- }
-
- /**
- * Create a new scanner and use the service loader to find the scanners
- *
- * @param amConfig The artifact manager configuration
- * @throws IOException If something goes wrong
- */
- public Scanner(final ArtifactManagerConfig amConfig)
- throws IOException {
- this(amConfig, null, null);
- }
-
- /**
- * Get services from the service loader
- *
- * @param clazz The service class
- * @return The list of services might be empty.
- */
- private static <T> List<T> getServices(final Class<T> clazz) {
- final ServiceLoader<T> loader = ServiceLoader.load(clazz);
- final List<T> list = new ArrayList<>();
- for(final T task : loader) {
- list.add(task);
- }
- return list;
- }
-
- /**
- * Scan a bundle
- *
- * @param bundle The bundle artifact
- * @param startLevel The start level of the bundle
- * @return The bundle descriptor
- * @throws IOException If something goes wrong or the provided artifact is not a bundle.
- */
- public BundleDescriptor scan(final Artifact bundle, final int startLevel) throws IOException {
- final File file = artifactManager.getArtifactHandler(bundle.getId().toMvnUrl()).getFile();
- if ( file == null ) {
- throw new IOException("Unable to find file for " + bundle.getId());
- }
-
- return new BundleDescriptorImpl(bundle, file, startLevel);
- }
-
- /**
- * Get all bundle descriptors for a feature / application
- * @param bundles The bundles
- * @param desc The descriptor
- * @throws IOException If something goes wrong or no suitable scanner is found.
- */
- private void getBundleInfos(final Bundles bundles, final ContainerDescriptor desc)
- throws IOException {
- for(final Map.Entry<Integer, List<Artifact>> entry : bundles.getBundlesByStartOrder().entrySet()) {
- for(final Artifact bundle : entry.getValue() ) {
- final BundleDescriptor bundleDesc = scan(bundle, entry.getKey());
- desc.getBundleDescriptors().add(bundleDesc);
- }
- }
- }
-
- private void scan(final Extensions extensions, final ContainerDescriptor desc)
- throws IOException {
- for(final Extension ext : extensions) {
- ContainerDescriptor extDesc = null;
- for(final ExtensionScanner scanner : this.extensionScanners) {
- extDesc = scanner.scan(ext, this.artifactManager);
- if ( extDesc != null ) {
- break;
- }
- }
- if ( extDesc == null ) {
- throw new IOException("No extension scanner found for extension named " + ext.getName() + " of type " + ext.getType().name());
- }
- desc.getRequirements().addAll(extDesc.getRequirements());
- desc.getCapabilities().addAll(extDesc.getCapabilities());
- desc.getExportedPackages().addAll(extDesc.getExportedPackages());
- desc.getImportedPackages().addAll(extDesc.getImportedPackages());
- desc.getDynamicImportedPackages().addAll(extDesc.getDynamicImportedPackages());
-
- desc.getArtifactDescriptors().addAll(extDesc.getArtifactDescriptors());
- desc.getBundleDescriptors().addAll(extDesc.getBundleDescriptors());
- }
- }
-
- private void compact(final ContainerDescriptor desc) {
- // TBD remove all import packages / dynamic import packages which are resolved by this bundle set
- // same with requirements
-
- }
-
- /**
- * Scan a feature
- *
- * @param feature The feature
- * @return The feature descriptor
- * @throws IOException If something goes wrong or a scanner is missing
- */
- public FeatureDescriptor scan(final Feature feature) throws IOException {
- final FeatureDescriptorImpl desc = new FeatureDescriptorImpl(feature);
-
- getBundleInfos(feature.getBundles(), desc);
- scan(feature.getExtensions(), desc);
-
- compact(desc);
-
- desc.lock();
-
- return desc;
- }
-
- /**
- * Scan an application
- *
- * @param app The application
- * @return The application descriptor
- * @throws IOException If something goes wrong or a scanner is missing
- */
- public ApplicationDescriptor scan(final Application app) throws IOException {
- final ApplicationDescriptorImpl desc = new ApplicationDescriptorImpl(app);
-
- getBundleInfos(app.getBundles(), desc);
- scan(app.getExtensions(), desc);
-
- compact(desc);
-
- // framework
- final File file = artifactManager.getArtifactHandler(app.getFramework().toMvnUrl()).getFile();
- if ( file == null ) {
- throw new IOException("Unable to find file for " + app.getFramework());
- }
-
- BundleDescriptor fwk = null;
- for(final FrameworkScanner scanner : this.frameworkScanners) {
- fwk = scanner.scan(app.getFramework(), file, app.getFrameworkProperties());
- if ( fwk != null ) {
- break;
- }
- }
- if ( fwk == null ) {
- throw new IOException("No scanner found for framework " + app.getFramework().toMvnId());
- }
-
- desc.setFrameworkDescriptor(fwk);
-
- desc.lock();
- return desc;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java
deleted file mode 100644
index cf9248e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java
+++ /dev/null
@@ -1,52 +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.scanner.impl;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-/**
- * Information about an application.
- * This is the aggregated information.
- */
-public class ApplicationDescriptorImpl
- extends ApplicationDescriptor {
-
- private BundleDescriptor frameworkDescriptor;
-
- private final Application app;
-
- public ApplicationDescriptorImpl(final Application app) {
- this.app = app;
- }
-
- @Override
- public Application getApplication() {
- return this.app;
- }
-
- @Override
- public BundleDescriptor getFrameworkDescriptor() {
- return frameworkDescriptor;
- }
-
- public void setFrameworkDescriptor(final BundleDescriptor frameworkDescriptor) {
- checkLocked();
- this.frameworkDescriptor = frameworkDescriptor;
- }
-}
\ No newline at end of file
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
deleted file mode 100644
index d933060..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ /dev/null
@@ -1,194 +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.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.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.scanner.PackageInfo;
-import org.osgi.framework.Constants;
-
-/**
- * Information about a bundle
- */
-public class BundleDescriptorImpl
- extends BundleDescriptor {
-
- /** The bundle symbolic name. */
- private String symbolicName;
-
- /** The bundle version. */
- private String bundleVersion;
-
- /** The start level of this artifact. */
- private final int startLevel;
-
- /** Manifest */
- private final Manifest manifest;
-
- /** The physical file for analyzing. */
- private final File artifactFile;
-
- /** The corresponding artifact from the feature. */
- private final Artifact artifact;
-
- public BundleDescriptorImpl(final Artifact a,
- final File file,
- final int startLevel) throws IOException {
- this.artifact = a;
- this.artifactFile = file;
- this.startLevel = startLevel;
- try (final JarFile jarFile = new JarFile(this.artifactFile) ) {
- this.manifest = jarFile.getManifest();
- }
- if ( this.manifest == null ) {
- throw new IOException("File has no manifest");
- }
- this.analyze();
- this.lock();
- }
-
- /**
- * Get the bundle symbolic name.
- * @return The bundle symbolic name
- */
- @Override
- public String getBundleSymbolicName() {
- return symbolicName;
- }
-
- /**
- * Get the bundle version
- * @return The bundle version
- */
- @Override
- public String getBundleVersion() {
- return bundleVersion;
- }
-
- /**
- * Get the start level
- * @return The start level or {@code 0} for the default.
- */
- @Override
- public int getBundleStartLevel() {
- return startLevel;
- }
-
- @Override
- public File getArtifactFile() {
- return artifactFile;
- }
-
- @Override
- public Artifact getArtifact() {
- return artifact;
- }
-
- @Override
- public Manifest getManifest() {
- return this.manifest;
- }
-
- protected void analyze() throws IOException {
- final String name = this.manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- if ( name != null ) {
- final String version = this.manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
- if ( version == null ) {
- throw new IOException("Unable to get bundle version from artifact " + getArtifact().getId().toMvnId());
- }
- this.symbolicName = name;
- this.bundleVersion = version;
- final String newBundleName = this.getArtifact().getMetadata().get("bundle:rename-bsn");
- if (newBundleName != null) {
- this.symbolicName = newBundleName;
- }
-
- this.getExportedPackages().addAll(extractExportedPackages(this.manifest));
- this.getImportedPackages().addAll(extractImportedPackages(this.manifest));
- this.getDynamicImportedPackages().addAll(extractDynamicImportedPackages(this.manifest));
- try {
- 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);
- }
- } else {
- 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);
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java
deleted file mode 100644
index 9d67b1e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java
+++ /dev/null
@@ -1,142 +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.scanner.impl;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.scanner.ArtifactDescriptor;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-/**
- * Information about a content package.
- */
-public class ContentPackageDescriptor extends ArtifactDescriptor {
-
- /** The content package name. */
- private String name;
-
- /** Bundles in the content package. */
- public final List<BundleDescriptor> bundles = new ArrayList<>();
-
- /** Configurations in the content package. */
- public final List<Configuration> configs = new ArrayList<>();
-
- private File artifactFile;
-
- private Artifact artifact;
-
- /**
- * Get the artifact file
- * @return The artifact file
- */
- @Override
- public File getArtifactFile() {
- return artifactFile;
- }
-
- /**
- * Get the artifact
- * @return The artifact
- */
- @Override
- public Artifact getArtifact() {
- return artifact;
- }
-
- /**
- * Set the artifact
- * @param artifact The artifact
- */
- public void setArtifact(Artifact artifact) {
- checkLocked();
- this.artifact = artifact;
- }
-
- /**
- * Set the artifact file
- * @param artifactFile The artifact file
- */
- public void setArtifactFile(File artifactFile) {
- checkLocked();
- this.artifactFile = artifactFile;
- }
-
- /** Optional: the artifact of the content package. */
- private Artifact contentPackage;
-
- /** Optional: the path inside of the content package. */
- private String contentPath;
-
- /**
- * Get the content package
- * @return The content package or {@code null}
- */
- public Artifact getContentPackage() {
- return contentPackage;
- }
-
- /**
- * Get the content path
- * @return The content path or {@code null}
- */
- public String getContentPath() {
- return this.contentPath;
- }
-
- /**
- * Whether this artifact is embedded in a content package
- * @return {@code true} if embedded.
- */
- public boolean isEmbeddedInContentPackage() {
- return this.contentPath != null;
- }
-
- /**
- * Set the information about the content package containing this artifact
- * @param artifact The package
- * @param path The path inside the package
- */
- public void setContentPackageInfo(final Artifact artifact, final String path) {
- checkLocked();
- this.contentPackage = artifact;
- this.contentPath = path;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(final String value) {
- checkLocked();
- this.name = value;
- }
-
-
- public boolean hasEmbeddedArtifacts() {
- return !this.bundles.isEmpty() || !this.configs.isEmpty();
- }
-
- @Override
- public String toString() {
- return "ContentPackage [" + name + "]";
- }
-}
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java
deleted file mode 100644
index 5720166..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java
+++ /dev/null
@@ -1,357 +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.scanner.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ContentPackageScanner {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- private final byte[] buffer = new byte[65536];
-
- private enum FileType {
- BUNDLE,
- CONFIG,
- PACKAGE
- }
-
- public Set<ContentPackageDescriptor> scan(final Artifact desc, final File file) throws IOException {
- if (!file.getName().endsWith(".zip") ) {
- throw new IOException("Artifact seems to be no content package (not a zip file): " + desc.getId().toMvnId());
- }
-
- final Set<ContentPackageDescriptor> contentPackages = new HashSet<>();
- final ContentPackageDescriptor cp = new ContentPackageDescriptor();
- final int lastDot = file.getName().lastIndexOf(".");
- cp.setName(file.getName().substring(0, lastDot));
- cp.setArtifact(desc);
- cp.setArtifactFile(file);
-
- extractContentPackage(cp, contentPackages, file);
-
- contentPackages.add(cp);
- cp.lock();
-
- return contentPackages;
- }
-
- private void extractContentPackage(final ContentPackageDescriptor cp,
- final Set<ContentPackageDescriptor> infos,
- final File archive)
- throws IOException {
- logger.debug("Analyzing Content Package {}", archive.getName());
-
- final File tempDir = Files.createTempDirectory(null).toFile();
- try {
- final File toDir = new File(tempDir, archive.getName());
- toDir.mkdirs();
-
- final List<File> toProcess = new ArrayList<>();
-
- try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(archive)) ) {
- boolean done = false;
- while ( !done ) {
- final ZipEntry entry = zis.getNextEntry();
- if ( entry == null ) {
- done = true;
- } else {
- final String entryName = entry.getName();
- if ( !entryName.endsWith("/") && entryName.startsWith("jcr_root/") ) {
- final String contentPath = entryName.substring(8);
-
- FileType fileType = null;
-
- if ( entryName.endsWith(".zip") ) {
- // embedded content package
- fileType = FileType.PACKAGE;
-
- // check for libs or apps
- } else if ( entryName.startsWith("jcr_root/libs/") || entryName.startsWith("jcr_root/apps/") ) {
-
- // check if this is an install folder (I)
- // install folders are either named:
- // "install" or
- // "install.{runmode}"
- boolean isInstall = entryName.indexOf("/install/") != -1;
- if ( !isInstall ) {
- final int pos = entryName.indexOf("/install.");
- if ( pos != -1 ) {
- final int endSlashPos = entryName.indexOf('/', pos + 1);
- if ( endSlashPos != -1 ) {
- isInstall = true;
- }
- }
- }
- if ( !isInstall ) {
- // check if this is an install folder (II)
- // config folders are either named:
- // "config" or
- // "config.{runmode}"
- isInstall = entryName.indexOf("/config/") != -1;
- if ( !isInstall ) {
- final int pos = entryName.indexOf("/config.");
- if ( pos != -1 ) {
- final int endSlashPos = entryName.indexOf('/', pos + 1);
- if ( endSlashPos != -1 ) {
- isInstall = true;
- }
- }
- }
- }
-
- if (isInstall ) {
-
- if ( entryName.endsWith(".jar") ) {
- fileType = FileType.BUNDLE;
- } else if ( entryName.endsWith(".xml") || entryName.endsWith(".config") ) {
- fileType = FileType.CONFIG;
- }
- }
- }
-
- if ( fileType != null ) {
- logger.debug("- extracting : {}", entryName);
- final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
- newFile.getParentFile().mkdirs();
-
- try (final FileOutputStream fos = new FileOutputStream(newFile)) {
- int len;
- while ((len = zis.read(buffer)) > -1) {
- fos.write(buffer, 0, len);
- }
- }
-
- if ( fileType == FileType.BUNDLE ) {
- int startLevel = 20;
- final int lastSlash = contentPath.lastIndexOf('/');
- final int nextSlash = contentPath.lastIndexOf('/', lastSlash - 1);
- final String part = contentPath.substring(nextSlash + 1, lastSlash);
- try {
- startLevel = Integer.valueOf(part);
- } catch ( final NumberFormatException ignore ) {
- // ignore
- }
-
- final Artifact bundle = new Artifact(extractArtifactId(tempDir, newFile));
- final BundleDescriptor info = new BundleDescriptorImpl(bundle, newFile, startLevel);
- bundle.getMetadata().put("content-package", cp.getArtifact().getId().toMvnId());
- bundle.getMetadata().put("content-path", contentPath);
-
- cp.bundles.add(info);
-
- } else if ( fileType == FileType.CONFIG ) {
-
- final Configuration configEntry = this.process(newFile, cp.getArtifact(), contentPath);
- if ( configEntry != null ) {
-
- cp.configs.add(configEntry);
- }
-
- } else if ( fileType == FileType.PACKAGE ) {
- toProcess.add(newFile);
- }
-
- }
-
- }
- zis.closeEntry();
- }
- }
-
- }
-
- for(final File f : toProcess) {
- extractContentPackage(cp, infos, f);
- final ContentPackageDescriptor i = new ContentPackageDescriptor();
- final int lastDot = f.getName().lastIndexOf(".");
- i.setName(f.getName().substring(0, lastDot));
- i.setArtifactFile(f);
- i.setContentPackageInfo(cp.getArtifact(), f.getName());
- infos.add(i);
-
- i.lock();
- }
- } finally {
- if ( tempDir.exists() ) {
- tempDir.delete();
- }
- }
- }
-
- private ArtifactId extractArtifactId(final File tempDir, final File bundleFile)
- throws IOException {
- logger.debug("Extracting Bundle {}", bundleFile.getName());
-
- final File toDir = new File(tempDir, bundleFile.getName());
- toDir.mkdirs();
-
- try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(bundleFile)) ) {
- boolean done = false;
- while ( !done ) {
- final ZipEntry entry = zis.getNextEntry();
- if ( entry == null ) {
- done = true;
- } else {
- final String entryName = entry.getName();
- if ( !entryName.endsWith("/") && entryName.startsWith("META-INF/maven/") && entryName.endsWith("/pom.properties")) {
- logger.debug("- extracting : {}", entryName);
- final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
- newFile.getParentFile().mkdirs();
-
- try (final FileOutputStream fos = new FileOutputStream(newFile)) {
- int len;
- while ((len = zis.read(buffer)) > -1) {
- fos.write(buffer, 0, len);
- }
- }
-
- }
- zis.closeEntry();
- }
- }
-
- }
-
- // check for maven
-
- final File metaInfDir = new File(toDir, "META-INF");
- if ( metaInfDir.exists() ) {
- final File mavenDir = new File(metaInfDir, "maven");
- if ( mavenDir.exists() ) {
- File groupDir = null;
- for(final File d : mavenDir.listFiles()) {
- if ( d.isDirectory() && !d.getName().startsWith(".") ) {
- groupDir = d;
- break;
- }
- }
- if ( groupDir != null ) {
- File artifactDir = null;
- for(final File d : groupDir.listFiles()) {
- if ( d.isDirectory() && !d.getName().startsWith(".") ) {
- artifactDir = d;
- break;
- }
- }
- if ( artifactDir != null ) {
- final File propsFile = new File(artifactDir, "pom.properties");
- if ( propsFile.exists() ) {
- final Properties props = new Properties();
- try ( final Reader r = new FileReader(propsFile) ) {
- props.load(r);
- }
- String groupId = props.getProperty("groupId");
- String artifactId = props.getProperty("artifactId");
- String version = props.getProperty("version");
- String classifier = null;
-
- // Capture classifier
- final int pos = bundleFile.getName().indexOf(version) + version.length();
- if ( bundleFile.getName().charAt(pos) == '-') {
- classifier = bundleFile.getName().substring(pos + 1, bundleFile.getName().lastIndexOf('.'));
- }
-
- final String parts[] = version.split("\\.");
- if ( parts.length == 4 ) {
- final int lastDot = version.lastIndexOf('.');
- version = version.substring(0, lastDot) + '-' + version.substring(lastDot + 1);
- }
-
- if ( groupId != null && artifactId != null && version != null ) {
- return new ArtifactId(groupId,
- artifactId,
- version, classifier, null);
- }
- }
- }
- }
- }
- }
-
- throw new IOException(bundleFile.getName() + " has no maven coordinates!");
- }
-
- private Configuration process(final File configFile,
- final Artifact packageArtifact,
- final String contentPath)
- throws IOException {
-
- boolean isConfig = true;
- if ( configFile.getName().endsWith(".xml") ) {
- final String contents = Files.readAllLines(configFile.toPath()).toString();
- if ( contents.indexOf("jcr:primaryType=\"sling:OsgiConfig\"") == -1 ) {
- isConfig = false;
- }
- }
-
- if ( isConfig ) {
- final String id;
- if ( ".content.xml".equals(configFile.getName()) ) {
- final int lastSlash = contentPath.lastIndexOf('/');
- final int previousSlash = contentPath.lastIndexOf('/', lastSlash - 1);
- id = contentPath.substring(previousSlash + 1, lastSlash);
- } else {
- final int lastDot = configFile.getName().lastIndexOf('.');
- id = configFile.getName().substring(0, lastDot);
- }
-
- final String pid, factoryPid;
- final int slashPos = id.indexOf('-');
- if ( slashPos == -1 ) {
- pid = id;
- factoryPid = null;
- } else {
- pid = id.substring(slashPos + 1);
- factoryPid = id.substring(0, slashPos);
- }
-
- final Configuration cfg;
- if ( factoryPid != null ) {
- cfg = new Configuration(factoryPid, pid);
- } else {
- cfg = new Configuration(pid);
- }
- cfg.getProperties().put("content-path", contentPath);
- cfg.getProperties().put("content-package", packageArtifact.getId().toMvnId());
-
- return cfg;
- }
-
- return null;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java
deleted file mode 100644
index e125ce0..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java
+++ /dev/null
@@ -1,74 +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.scanner.impl;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class ContentPackagesExtensionScanner implements ExtensionScanner {
-
- @Override
- public String getId() {
- return "content-packages";
- }
-
- @Override
- public String getName() {
- return "Content Packages Scanner";
- }
-
- @Override
- public ContainerDescriptor scan(final Extension extension,
- final ArtifactManager artifactManager)
- throws IOException {
- if (!FeatureConstants.EXTENSION_NAME_CONTENT_PACKAGES.equals(extension.getName()) ) {
- return null;
- }
- if ( extension.getType() != ExtensionType.ARTIFACTS ) {
- return null;
- }
-
- final ContentPackageScanner scanner = new ContentPackageScanner();
- final ContainerDescriptor cd = new ContainerDescriptor() {};
-
- for(final Artifact a : extension.getArtifacts()) {
- final File file = artifactManager.getArtifactHandler(a.getId().toMvnUrl()).getFile();
- if ( file == null ) {
- throw new IOException("Unable to find file for " + a.getId());
- }
-
- final Set<ContentPackageDescriptor> pcks = scanner.scan(a, file);
- for(final ContentPackageDescriptor desc : pcks) {
- cd.getArtifactDescriptors().add(desc);
- cd.getBundleDescriptors().addAll(desc.bundles);
- }
- }
-
- cd.lock();
-
- return cd;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java
deleted file mode 100644
index 63b2c1d..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java
+++ /dev/null
@@ -1,39 +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.scanner.impl;
-
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.scanner.FeatureDescriptor;
-
-/**
- * Information about a feature.
- * This is the aggregated information.
- */
-public class FeatureDescriptorImpl
- extends FeatureDescriptor {
-
- private final Feature feature;
-
- public FeatureDescriptorImpl(final Feature feature) {
- this.feature = feature;
- }
-
- @Override
- public Feature getFeature() {
- return this.feature;
- }
-}
\ 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
deleted file mode 100644
index 2bb2cde..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
+++ /dev/null
@@ -1,201 +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.scanner.impl;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.Manifest;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.apache.commons.lang.text.StrLookup;
-import org.apache.commons.lang.text.StrSubstitutor;
-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.scanner.PackageInfo;
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-
-public class FelixFrameworkScanner implements FrameworkScanner {
-
-
- @Override
- public BundleDescriptor scan(final ArtifactId framework,
- final File platformFile,
- final KeyValueMap frameworkProps)
- throws IOException {
- final KeyValueMap fwkProps = getFrameworkProperties(frameworkProps, platformFile);
- if ( fwkProps == null ) {
- return null;
- }
- final Set<PackageInfo> pcks = calculateSystemPackages(fwkProps);
- final List<Capability> capabilities = calculateSystemCapabilities(fwkProps);
-
- final BundleDescriptor d = new BundleDescriptor() {
-
- @Override
- public String getBundleSymbolicName() {
- return Constants.SYSTEM_BUNDLE_SYMBOLICNAME;
- }
-
- @Override
- public String getBundleVersion() {
- return framework.getOSGiVersion().toString();
- }
-
- @Override
- public int getBundleStartLevel() {
- return 0;
- }
-
- @Override
- public File getArtifactFile() {
- return platformFile;
- }
-
- @Override
- public Artifact getArtifact() {
- return new Artifact(framework);
- }
-
- @Override
- public Manifest getManifest() {
- return new Manifest();
- }
- };
- d.getCapabilities().addAll(capabilities);
- d.getExportedPackages().addAll(pcks);
- d.lock();
- return d;
- }
-
- 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)
- .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) {
- 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";
-
- KeyValueMap getFrameworkProperties(final KeyValueMap appProps, final File framework)
- throws IOException {
- final Map<String, Properties> propsMap = new HashMap<>();
- try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(framework)) ) {
- boolean done = false;
- while ( !done ) {
- final ZipEntry entry = zis.getNextEntry();
- if ( entry == null ) {
- done = true;
- } else {
- final String entryName = entry.getName();
- if ( entryName.endsWith(".properties") ) {
- final Properties props = new Properties();
- props.load(zis);
-
- propsMap.put(entryName, props);
- }
- zis.closeEntry();
- }
- }
- }
-
- final Properties defaultMap = propsMap.get(DEFAULT_PROPERTIES);
- if ( defaultMap == null ) {
- return null;
- }
-
- final KeyValueMap frameworkProps = new KeyValueMap();
- frameworkProps.putAll(appProps);
-
- // replace variables
- defaultMap.put("java.specification.version",
- System.getProperty("java.specification.version", "1.8"));
-
- StrSubstitutor ss = new StrSubstitutor(new StrLookup() {
- @Override
- public String lookup(String key) {
- // Normally if a variable cannot be found, StrSubstitutor will
- // leave the raw variable in place. We need to replace it with
- // nothing in that case.
-
- String val = defaultMap.getProperty(key);
- return val != null ? val : "";
- }
- });
- ss.setEnableSubstitutionInVariables(true);
-
- for(final Object name : defaultMap.keySet()) {
- if ( frameworkProps.get(name.toString()) == null ) {
- final String value = (String)defaultMap.get(name);
- final String substValue = ss.replace(value);
- frameworkProps.put(name.toString(), substValue);
- }
- }
-
- return frameworkProps;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java
deleted file mode 100644
index 97fa3b7..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java
+++ /dev/null
@@ -1,65 +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.scanner.impl;
-
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.util.Collections;
-
-public class RepoInitScanner implements ExtensionScanner {
- private static final Requirement REQUIREMENT_REPOINIT = new RequirementImpl(null, "osgi.implementation",
- Collections.singletonMap("filter", "(&(osgi.implementation=org.apache.sling.jcr.repoinit)(version>=1.0)(!(version>=2.0)))"),
- null);
-
- @Override
- public String getId() {
- return "repoinit";
- }
-
- @Override
- public String getName() {
- return "Apache Sling Repoinit Scanner";
- }
-
- @Override
- public ContainerDescriptor scan(final Extension extension,
- final ArtifactManager artifactManager)
- throws IOException {
- if (!FeatureConstants.EXTENSION_NAME_REPOINIT.equals(extension.getName()) ) {
- return null;
- }
- if ( extension.getType() != ExtensionType.TEXT ) {
- return null;
- }
-
- final ContainerDescriptor cd = new ContainerDescriptor() {};
-
- cd.getRequirements().add(REQUIREMENT_REPOINIT);
-
- cd.lock();
-
- return cd;
- }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java
deleted file mode 100644
index 4c65dc3..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.scanner;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java
deleted file mode 100644
index 773f210..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java
+++ /dev/null
@@ -1,48 +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.scanner.spi;
-
-import java.io.IOException;
-
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * The extension scanner scans an extension.
- */
-@ConsumerType
-public interface ExtensionScanner {
-
- /** A unique (short) id. */
- String getId();
-
- /** A human readable name to identify the scanner. */
- String getName();
-
- /**
- * Try to scan the extension and return a descriptor
- *
- * @param extension The extension
- * @param manager Artifact manager
- * @return The descriptor or {@code null} if the scanner does not know the extension
- * @throws IOException If an error occurs while scanning the extension or the extension is invalid
- */
- ContainerDescriptor scan(Extension extension,
- ArtifactManager manager) throws IOException;
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java
deleted file mode 100644
index fcfc0ef..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java
+++ /dev/null
@@ -1,44 +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.scanner.spi;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.KeyValueMap;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * The framework scanner scans the framework
- */
-@ConsumerType
-public interface FrameworkScanner {
-
- /**
- * Try to scan the artifact
- * @param framework The framework artifact id
- * @param file The framework artifact
- * @param frameworkProps framework properties to launch the framework
- * @return A descriptor or {@code null}
- * @throws IOException If an error occurs while scanning the platform or the artifact is invalid
- */
- BundleDescriptor scan(ArtifactId framework,
- File platformFile,
- KeyValueMap frameworkProps) throws IOException;
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java
deleted file mode 100644
index 3ecb9cb..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.scanner.spi;
-
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask
deleted file mode 100644
index dabd8fb..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask
+++ /dev/null
@@ -1,5 +0,0 @@
-org.apache.sling.feature.analyser.task.impl.CheckBundleExportsImports
-org.apache.sling.feature.analyser.task.impl.CheckBundlesForInitialContent
-org.apache.sling.feature.analyser.task.impl.CheckBundlesForResources
-org.apache.sling.feature.analyser.task.impl.CheckRequirementsCapabilities
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner
deleted file mode 100644
index 643c7cf..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner
+++ /dev/null
@@ -1,3 +0,0 @@
-org.apache.sling.feature.scanner.impl.ContentPackagesExtensionScanner
-org.apache.sling.feature.scanner.impl.RepoInitScanner
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner
deleted file mode 100644
index ad10c99..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.sling.feature.scanner.impl.FelixFrameworkScanner
-
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
deleted file mode 100644
index a8d289c..0000000
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
+++ /dev/null
@@ -1,73 +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.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
deleted file mode 100644
index d5edc80..0000000
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
+++ /dev/null
@@ -1,70 +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.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
- public void testGetFrameworkProperties() throws Exception {
- URL url = getClass().getResource("/test-framework.jar");
- File fwFile = new File(url.toURI());
-
- FelixFrameworkScanner ffs = new FelixFrameworkScanner();
-
- KeyValueMap kvmap = new KeyValueMap();
- KeyValueMap props = ffs.getFrameworkProperties(kvmap, fwFile);
- assertEquals("osgi.service; objectClass:List<String>=org.osgi.service.resolver.Resolver; "
- + "uses:=org.osgi.service.resolver, "
- + "osgi.service; objectClass:List<String>=org.osgi.service.startlevel.StartLevel; "
- + "uses:=org.osgi.service.startlevel, "
- + "osgi.service; objectClass:List<String>=org.osgi.service.packageadmin.PackageAdmin; "
- + "uses:=org.osgi.service.packageadmin , "
- + "osgi.ee; osgi.ee=\"OSGi/Minimum\"; version:List<Version>=\"1.0,1.1,1.2\", "
- + "osgi.ee; osgi.ee=\"JavaSE\"; version:List<Version>=\"1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8\", "
- + "osgi.ee; osgi.ee=\"JavaSE/compact1\"; version:List<Version>=\"1.8\", "
- + "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-analyser/src/test/resources/test-framework.jar b/featuremodel/feature-analyser/src/test/resources/test-framework.jar
deleted file mode 100644
index 51fe8a1..0000000
Binary files a/featuremodel/feature-analyser/src/test/resources/test-framework.jar and /dev/null differ
diff --git a/featuremodel/feature-applicationbuilder/pom.xml b/featuremodel/feature-applicationbuilder/pom.xml
deleted file mode 100644
index fed4c08..0000000
--- a/featuremodel/feature-applicationbuilder/pom.xml
+++ /dev/null
@@ -1,167 +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.applicationbuilder</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-
- <name>Apache Sling Feature Application Builder</name>
- <description>
- A feature describes an OSGi system
- </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-applicationbuilder</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-applicationbuilder</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-applicationbuilder</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>unpack-dependencies</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>unpack-dependencies</goal>
- </goals>
- <configuration>
- <excludes>META-INF/**</excludes>
- <outputDirectory>${project.build.directory}/classes</outputDirectory>
- <overWriteReleases>false</overWriteReleases>
- <overWriteSnapshots>true</overWriteSnapshots>
- <includeArtifactIds>commons-cli,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,slf4j-api,slf4j-simple,osgi.core,org.apache.felix.converter,org.osgi.service.resolver,org.apache.sling.feature.resolver,org.apache.sling.feature.analyser</includeArtifactIds>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.apache.sling.feature.applicationbuilder.impl.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <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.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-cli</groupId>
- <artifactId>commons-cli</artifactId>
- <version>1.3.1</version>
- </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.analyser</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.sling</groupId>
- <artifactId>org.apache.sling.feature.resolver</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>
- </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.framework</artifactId>
- <version>5.6.10</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.osgi</groupId>
- <artifactId>org.osgi.service.resolver</artifactId>
- <version>1.0.1</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- Testing -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java b/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
deleted file mode 100644
index d07be10..0000000
--- a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
+++ /dev/null
@@ -1,203 +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.applicationbuilder.impl;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.IOUtils;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.stream.Stream;
-
-public class Main {
-
- private static Logger LOGGER;
-
- private static String output;
-
- private static String filesInput;
-
- private static String dirsInput;
-
- private static String repoUrls;
-
- private static String propsFile;
-
- /**
- * Parse the command line parameters and update a configuration object.
- * @param args Command line parameters
- * @return Configuration object.
- */
- private static void parseArgs(final String[] args) {
- final Option repoOption = Option.builder("u").hasArg().argName("Set repository url")
- .desc("repository url").build();
-
- final Option filesOption = new Option("f", true, "Set feature files (comma separated)");
- final Option dirsOption = new Option("d", true, "Set feature file dirs (comma separated)");
- final Option propsOption = new Option("p", true, "sling.properties file");
-
-
- final Option outputOption = Option.builder("o").hasArg().argName("Set output file")
- .desc("output file").build();
-
- final Options options = new Options();
- options.addOption(repoOption);
- options.addOption(filesOption);
- options.addOption(dirsOption);
- options.addOption(outputOption);
- options.addOption(propsOption);
-
- final CommandLineParser parser = new DefaultParser();
- try {
- final CommandLine cl = parser.parse(options, args);
-
- if ( cl.hasOption(repoOption.getOpt()) ) {
- repoUrls = cl.getOptionValue(repoOption.getOpt());
- }
- if ( cl.hasOption(filesOption.getOpt()) ) {
- filesInput = cl.getOptionValue(filesOption.getOpt());
- }
- if ( cl.hasOption(dirsOption.getOpt()) ) {
- dirsInput = cl.getOptionValue(dirsOption.getOpt());
- }
- if ( cl.hasOption(outputOption.getOpt()) ) {
- output = cl.getOptionValue(outputOption.getOpt());
- }
- if ( cl.hasOption(propsOption.getOpt()) ) {
- propsFile = cl.getOptionValue(propsOption.getOpt());
- }
- } catch ( final ParseException pe) {
- LOGGER.error("Unable to parse command line: {}", pe.getMessage(), pe);
- System.exit(1);
- }
- if ( filesInput == null && dirsInput == null) {
- LOGGER.error("Required argument missing: model files or directory");
- System.exit(1);
- }
- }
-
- private static ArtifactManager getArtifactManager() {
- final ArtifactManagerConfig amConfig = new ArtifactManagerConfig();
- if ( repoUrls != null ) {
- amConfig.setRepositoryUrls(repoUrls.split(","));
- }
- try {
- return ArtifactManager.getArtifactManager(amConfig);
- } catch ( IOException ioe) {
- LOGGER.error("Unable to create artifact manager " + ioe.getMessage(), ioe);
- System.exit(1);
- }
- // we never reach this, but have to keep the compiler happy
- return null;
- }
-
- private static FeatureResolver getFeatureResolver(ArtifactManager am) {
- return new FrameworkResolver(am, Collections.emptyMap());
- }
-
- public static void main(final String[] args) {
- // setup logging
- System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
- System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
- System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
- System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
-
- LOGGER = LoggerFactory.getLogger("applicationbuilder");
-
- LOGGER.info("Apache Sling Feature Application Builder");
- LOGGER.info("");
-
- parseArgs(args);
-
- final ArtifactManager am = getArtifactManager();
-
-
- final String[] files =
- Stream.concat(
- Stream.of(filesInput != null ? filesInput.split(",") : new String[0])
- .map(path -> new File(path))
- .filter(File::isFile),
- Stream.of(dirsInput != null ? dirsInput.split(",") : new String[0])
- .map(path -> new File(path))
- .filter(File::isDirectory)
- .flatMap(dir ->
- Stream.of(dir.listFiles())))
- .filter(file -> !file.getName().startsWith("."))
- .sorted()
- .map(File::getAbsolutePath)
- .toArray(String[]::new);
-
- if (files.length == 0) {
- LOGGER.error("No feature files found.");
- System.exit(1);
- }
-
- try (FeatureResolver fr = getFeatureResolver(am)) {
- writeApplication(buildApplication(ApplicationResolverAssembler.assembleApplication(null, am, fr, files)), output == null ? "application.json" : output);
-
- } catch ( final IOException ioe) {
- LOGGER.error("Unable to read feature/application files " + ioe.getMessage(), ioe);
- System.exit(1);
- } catch ( final Exception e) {
- LOGGER.error("Problem generating application", e);
- System.exit(1);
- }
- }
-
- private static Application buildApplication(final Application app) {
- final org.apache.sling.feature.Artifact a = new org.apache.sling.feature.Artifact(ArtifactId.parse("org.apache.sling/org.apache.sling.launchpad.api/1.2.0"));
- a.getMetadata().put(org.apache.sling.feature.Artifact.KEY_START_ORDER, "1");
- app.getBundles().add(a);
- // sling.properties (TODO)
- if ( propsFile == null ) {
- app.getFrameworkProperties().put("org.osgi.framework.bootdelegation", "sun.*,com.sun.*");
- } else {
-
- }
- // felix framework hard coded for now
- app.setFramework(IOUtils.getFelixFrameworkId(null));
- return app;
- }
-
- private static void writeApplication(final Application app, final String out) {
- LOGGER.info("Writing application: " + out);
- final File file = new File(out);
- try ( final FileWriter writer = new FileWriter(file)) {
- ApplicationJSONWriter.write(writer, app);
- } catch ( final IOException ioe) {
- LOGGER.error("Unable to write application to {} : {}", out, ioe.getMessage(), ioe);
- System.exit(1);
- }
- }
-}
diff --git a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java b/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
deleted file mode 100644
index c80f485..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
+++ /dev/null
@@ -1,177 +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.applicationbuilder.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonStructure;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.builder.ApplicationBuilder;
-import org.apache.sling.feature.builder.BuilderContext;
-import org.apache.sling.feature.builder.FeatureProvider;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.Constants;
-
-public class ApplicationBuilderTest {
- private Path tempDir;
-
- @Before
- public void setup() throws Exception {
- tempDir = Files.createTempDirectory(getClass().getSimpleName());
- }
-
- @After
- public void tearDown() throws Exception {
- // Delete the temp dir again
- Files.walk(tempDir)
- .sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- }
-
- private Map<String, String> getFrameworkProps() {
- return Collections.singletonMap(Constants.FRAMEWORK_STORAGE, tempDir.toFile().getAbsolutePath());
- }
-
- @Test
- public void testBundleOrdering() throws Exception {
- FeatureProvider fp = new TestFeatureProvider();
- BuilderContext bc = new BuilderContext(fp);
- ArtifactManager am = ArtifactManager.getArtifactManager(new ArtifactManagerConfig());
-
- Feature fa = readFeature("/featureA.json", am);
- Feature fb = readFeature("/featureB.json", am);
- Feature[] features = {fa, fb};
-
- try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
- Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
- String actualJSON = writeApplication(app);
-
- String expectedJSON = "{\"features\":["
- + "\"org.apache.sling.test.features:featureB:1.0.0\","
- + "\"org.apache.sling.test.features:featureA:1.0.0\"],"
- + "\"bundles\":["
- + "{\"id\":\"commons-io:commons-io:2.6\",\"start-level\":\"10\",\"start-order\":\"10\"},"
- + "{\"id\":\"org.apache.felix:org.apache.felix.http.servlet-api:1.1.2\",\"start-level\":\"15\",\"start-order\":\"15\"},"
- + "{\"id\":\"commons-fileupload:commons-fileupload:1.3.3\",\"start-level\":\"16\",\"start-order\":\"16\"}]}";
-
- StringWriter expectedWriter = new StringWriter();
- StringWriter actualWriter = new StringWriter();
-
- canonicalize(expectedJSON, expectedWriter, actualJSON, actualWriter);
- assertEquals(expectedWriter.toString(), actualWriter.toString());
- }
- }
-
- @Test
- public void testFeatureDependency() throws Exception {
- FeatureProvider fp = new TestFeatureProvider();
- BuilderContext bc = new BuilderContext(fp);
- ArtifactManager am = ArtifactManager.getArtifactManager(new ArtifactManagerConfig());
-
- // Feature D has a bundle (slf4j-api) with a dependency on feature C,
- // which provides a package for slf4j
- Feature fc = readFeature("/featureC.json", am);
- Feature fd = readFeature("/featureD.json", am);
- Feature[] features = {fd, fc};
-
- try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
- Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
- String genApp = writeApplication(app);
-
- String expected = "{\"features\":["
- + "\"org.apache.sling.test.features:featureC:1.0.0\","
- + "\"org.apache.sling.test.features:featureD:1.0.0\"],"
- + "\"bundles\":[{\"id\":\"org.slf4j:slf4j-api:1.7.25\",\"start-level\":\"6\",\"start-order\":\"6\"}]}";
-
- StringWriter expectedWriter = new StringWriter();
- StringWriter actualWriter = new StringWriter();
- canonicalize(expected, expectedWriter, genApp, actualWriter);
-
- assertEquals(expectedWriter.toString(), actualWriter.toString());
- }
- }
-
- // Turn JSON into pretty-formatted canoncical JSON that should be comparable using String compare
- private void canonicalize(String expected, StringWriter expectedWriter, String actual, StringWriter actualWriter) {
- JsonStructure es = Json.createReader(new StringReader(expected)).read();
- JsonStructure ea = Json.createReader(new StringReader(actual)).read();
-
- JsonWriterFactory writerFactory = Json.createWriterFactory(
- Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
- JsonWriter w = writerFactory.createWriter(expectedWriter);
- w.write(es);
-
- JsonWriter w2 = writerFactory.createWriter(actualWriter);
- w2.write(ea);
- }
-
- private Feature readFeature(final String res,
- final ArtifactManager artifactManager) throws Exception {
- URL url = getClass().getResource(res);
- String file = new File(url.toURI()).getAbsolutePath();
- final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(file);
-
- try (final FileReader r = new FileReader(featureArtifact.getFile())) {
- final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), SubstituteVariables.RESOLVE);
- return f;
- }
- }
-
- private static String writeApplication(Application app) throws Exception {
- Writer writer = new StringWriter();
- ApplicationJSONWriter.write(writer, app);
- return writer.toString();
- }
-
- private static class TestFeatureProvider implements FeatureProvider {
- @Override
- public Feature provide(ArtifactId id) {
- return null;
- }
- }
-}
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json
deleted file mode 100644
index 1daed33..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "id": "org.apache.sling.test.features/featureA/1.0.0",
- "bundles":
- ["commons-fileupload/commons-fileupload/1.3.3"]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json
deleted file mode 100644
index 952c810..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": "org.apache.sling.test.features/featureB/1.0.0",
- "bundles":
- [
- {
- "id": "org.apache.felix/org.apache.felix.http.servlet-api/1.1.2",
- "start-order" : 10
- },
- {
- "id": "commons-io/commons-io/2.6",
- "start-order" : 5
- }
- ]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json
deleted file mode 100644
index 0aed875..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "id": "org.apache.sling.test.features/featureC/1.0.0",
- "capabilities": [
- {
- "namespace": "org.foo.bar",
- "attributes": {
- "org.foo.bar": "toast",
- "version:Version": "1.1"
- }
- }, {
- "namespace": "osgi.wiring.package",
- "attributes": {
- "osgi.wiring.package": "org.slf4j.impl",
- "version:Version": "1.7.1.test"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json
deleted file mode 100644
index e9aa806..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "id": "org.apache.sling.test.features/featureD/1.0.0",
- "bundles":
- ["org.slf4j/slf4j-api/1.7.25"]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/pom.xml b/featuremodel/feature-io/pom.xml
deleted file mode 100644
index 8053a89..0000000
--- a/featuremodel/feature-io/pom.xml
+++ /dev/null
@@ -1,120 +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.io</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <name>Apache Sling Feature IO Module</name>
- <description>
- IO functionality for the Feature Model
- </description>
-
- <properties>
- <sling.java.version>8</sling.java.version>
- </properties>
-
- <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.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>
- <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.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>
-
- <!-- 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-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java
deleted file mode 100644
index 45f27be..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java
+++ /dev/null
@@ -1,42 +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.io;
-
-import java.io.File;
-
-/**
- * A handler provides a file object for an artifact.
- */
-public class ArtifactHandler {
-
- private final String url;
-
- private final File file;
-
- public ArtifactHandler(final String url, final File file) {
- this.url = url;
- this.file = file;
- }
-
- public String getUrl() {
- return url;
- }
-
- public File getFile() {
- return file;
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
deleted file mode 100644
index 954ac1a..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
+++ /dev/null
@@ -1,366 +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.io;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.file.Files;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-/**
- * The artifact manager is the central service to get artifacts.
- * It uses {@link ArtifactProvider}s to get artifacts. The
- * providers are loaded using the service loader.
- */
-public class ArtifactManager {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- /** The map of providers. */
- private final Map<String, ArtifactProvider> providers;
-
- /** The configuration */
- private final ArtifactManagerConfig config;
-
- /**
- * Get an artifact manager based on the configuration
- * @param config The configuration
- * @return The artifact manager
- * @throws IOException If the manager can't be initialized
- */
- public static ArtifactManager getArtifactManager(final ArtifactManagerConfig config) throws IOException {
- final ServiceLoader<ArtifactProvider> loader = ServiceLoader.load(ArtifactProvider.class);
- final Map<String, ArtifactProvider> providers = new HashMap<>();
- for(final ArtifactProvider provider : loader) {
- providers.put(provider.getProtocol(), provider);
- }
-
- final String[] repositoryURLs = new String[config.getRepositoryUrls().length];
- int index = 0;
- for(final String urlString : config.getRepositoryUrls()) {
- repositoryURLs[index] = urlString;
- index++;
- }
- // default
- if ( !providers.containsKey("*") ) {
- providers.put("*", new DefaultArtifactHandler());
- }
-
- return new ArtifactManager(config, providers);
- }
-
- ArtifactManager(final ArtifactManagerConfig config, final Map<String, ArtifactProvider> providers)
- throws IOException {
- this.config = config;
- this.providers = providers;
- try {
- for(final ArtifactProvider provider : this.providers.values()) {
- provider.init(config);
- }
- } catch ( final IOException io) {
- shutdown();
- throw io;
- }
- }
-
- /**
- * Shutdown the artifact manager.
- */
- public void shutdown() {
- for(final ArtifactProvider provider : this.providers.values()) {
- provider.shutdown();
- }
- this.providers.clear();
- }
-
- private final File getArtifactFromProviders(final String url, final String relativeCachePath) throws IOException {
- final int pos = url.indexOf(":");
- final String scheme = url.substring(0, pos);
-
- ArtifactProvider provider = this.providers.get(scheme);
- if ( provider == null ) {
- provider = this.providers.get("*");
- }
- if ( provider == null ) {
- throw new IOException("No URL provider found for " + url);
- }
- return provider.getArtifact(url, relativeCachePath);
- }
-
- /**
- * Get the full artifact url and file for an artifact.
- * @param url Artifact url or relative path.
- * @return Absolute url and file in the form of a handler.
- * @throws IOException If something goes wrong.
- */
- public ArtifactHandler getArtifactHandler(final String url) throws IOException {
- logger.debug("Trying to get artifact for {}", url);
-
- final String path;
-
- if ( url.startsWith("mvn:") ) {
- // mvn url
- path = ArtifactId.fromMvnUrl(url).toMvnPath();
-
- } else if ( url.startsWith(":") ) {
- // repository path
- path = url.substring(1);
-
- } else if ( url.indexOf(":/") > 0 ) {
-
- // absolute URL
- int pos = url.indexOf(":/") + 2;
- while ( url.charAt(pos) == '/') {
- pos++;
- }
- final File file = this.getArtifactFromProviders(url, url.substring(pos));
- if ( file == null || !file.exists()) {
- throw new IOException("Artifact " + url + " not found.");
- }
- return new ArtifactHandler(url, file);
-
- } else {
- // file (either relative or absolute)
- final File f = new File(url);
- if ( !f.exists()) {
- throw new IOException("Artifact " + url + " not found.");
- }
- return new ArtifactHandler(f.toURI().toString(), f);
- }
- logger.debug("Querying repositories for {}", path);
-
- for(final String repoUrl : this.config.getRepositoryUrls()) {
- final StringBuilder builder = new StringBuilder();
- builder.append(repoUrl);
- builder.append('/');
- builder.append(path);
-
- final String artifactUrl = builder.toString();
- final int pos = artifactUrl.indexOf(":");
- final String scheme = artifactUrl.substring(0, pos);
-
- ArtifactProvider handler = this.providers.get(scheme);
- if ( handler == null ) {
- handler = this.providers.get("*");
- }
- if ( handler == null ) {
- throw new IOException("No URL handler found for " + artifactUrl);
- }
-
- logger.debug("Checking {} to get artifact from {}", handler, artifactUrl);
-
- final File file = handler.getArtifact(artifactUrl, path);
- if ( file != null ) {
- logger.debug("Found artifact {}", artifactUrl);
- return new ArtifactHandler(artifactUrl, file);
- }
-
- // check for SNAPSHOT
- final int lastSlash = artifactUrl.lastIndexOf('/');
- final int startSnapshot = artifactUrl.indexOf("-SNAPSHOT", lastSlash + 1);
-
- if ( startSnapshot > -1 ) {
- // special snapshot handling
- final String metadataUrl = artifactUrl.substring(0, lastSlash) + "/maven-metadata.xml";
- try {
- final ArtifactHandler metadataHandler = this.getArtifactHandler(metadataUrl);
-
- final String contents = getFileContents(metadataHandler);
-
- final String latestVersion = getLatestSnapshot(contents);
- if ( latestVersion != null ) {
- final String name = artifactUrl.substring(lastSlash); // includes slash
- final String fullURL = artifactUrl.substring(0, lastSlash) + name.replace("SNAPSHOT", latestVersion);
- int pos2 = fullURL.indexOf(":/") + 2;
- while ( fullURL.charAt(pos2) == '/') {
- pos2++;
- }
- final File file2 = this.getArtifactFromProviders(fullURL, path);
- if ( file2 == null || !file2.exists()) {
- throw new IOException("Artifact " + fullURL + " not found.");
- }
- return new ArtifactHandler(artifactUrl, file2);
- }
- } catch ( final IOException ignore ) {
- // we ignore this but report the original 404
- }
- }
- }
-
- throw new IOException("Artifact " + url + " not found in any repository.");
- }
-
- protected String getFileContents(final ArtifactHandler handler) throws IOException {
- final StringBuilder sb = new StringBuilder();
- for(final String line : Files.readAllLines(handler.getFile().toPath())) {
- sb.append(line).append('\n');
- }
-
- return sb.toString();
- }
-
- public static String getValue(final String xml, final String[] xpath) {
- String value = null;
- int pos = 0;
- for(final String name : xpath) {
- final String element = '<' + name + '>';
-
- pos = xml.indexOf(element, pos);
- if ( pos == -1 ) {
- final String elementWithAttributes = '<' + name + ' ';
- pos = xml.indexOf(elementWithAttributes, pos);
- if ( pos == -1 ) {
- break;
- }
- }
- pos = xml.indexOf('>', pos) + 1;
- }
- if ( pos != -1 ) {
- final int endPos = xml.indexOf("</", pos);
- if ( endPos != -1 ) {
- value = xml.substring(pos, endPos).trim();
- }
- }
- return value;
- }
- public static String getLatestSnapshot(final String mavenMetadata) {
- final String timestamp = getValue(mavenMetadata, new String[] {"metadata", "versioning", "snapshot", "timestamp"});
- final String buildNumber = getValue(mavenMetadata, new String[] {"metadata", "versioning", "snapshot", "buildNumber"});
-
- if ( timestamp != null && buildNumber != null ) {
- return timestamp + '-' + buildNumber;
- }
-
- return null;
- }
-
- private static final class DefaultArtifactHandler implements ArtifactProvider {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- private volatile File cacheDir;
-
- private volatile ArtifactProviderContext config;
-
- @Override
- public String getProtocol() {
- return "*";
- }
-
- @Override
- public void init(final ArtifactProviderContext config) throws IOException {
- this.cacheDir = config.getCacheDirectory();
- this.config = config;
- }
-
- @Override
- public void shutdown() {
- this.config = null;
- this.cacheDir = null;
- }
-
- @Override
- public File getArtifact(final String url, final String relativeCachePath) {
- logger.debug("Checking url to be local file {}", url);
- // check if this is already a local file
- try {
- final File f = new File(new URL(url).toURI());
- if ( f.exists() ) {
- this.config.incLocalArtifacts();
- return f;
- }
- return null;
- } catch ( final URISyntaxException ise) {
- // ignore
- } catch ( final IllegalArgumentException iae) {
- // ignore
- } catch ( final MalformedURLException mue) {
- // ignore
- }
- logger.debug("Checking remote url {}", url);
- try {
- // check for url
- if ( url.indexOf(":") == -1 ) {
- return null;
- }
-
- final String filePath = (this.cacheDir.getAbsolutePath() + File.separatorChar + relativeCachePath).replace('/', File.separatorChar);
- final File cacheFile = new File(filePath);
-
- if ( !cacheFile.exists() ) {
- cacheFile.getParentFile().mkdirs();
- final URL u = new URL(url);
- final URLConnection con = u.openConnection();
- con.connect();
-
- final InputStream readIS = con.getInputStream();
- final byte[] buffer = new byte[32768];
- int l;
- OutputStream os = null;
- try {
- os = new FileOutputStream(cacheFile);
- while ( (l = readIS.read(buffer)) >= 0 ) {
- os.write(buffer, 0, l);
- }
- } finally {
- try {
- readIS.close();
- } catch ( final IOException ignore) {
- // ignore
- }
- if ( os != null ) {
- try {
- os.close();
- } catch ( final IOException ignore ) {
- // ignore
-
- }
- }
- }
- this.config.incDownloadedArtifacts();
- } else {
- this.config.incCachedArtifacts();
- }
- return cacheFile;
- } catch ( final Exception e) {
- logger.info("Artifact not found in one repository", e);
- // ignore for now
- return null;
- }
- }
-
- @Override
- public String toString() {
- return "DefaultArtifactHandler";
- }
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
deleted file mode 100644
index 5df9ed8..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
+++ /dev/null
@@ -1,142 +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.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-
-/**
- * This class holds the configuration of artifact manager.
- */
-public class ArtifactManagerConfig implements ArtifactProviderContext {
-
- /** The repository urls. */
- private volatile String[] repositoryUrls;
-
- /** The cache directory. */
- private volatile File cacheDirectory;
-
- private volatile long cachedArtifacts;
-
- private volatile long downloadedArtifacts;
-
- private volatile long localArtifacts;
-
- /**
- * Create a new configuration object.
- * Set the default values
- */
- public ArtifactManagerConfig() {
- // set defaults
- this.repositoryUrls = new String[] {
- "file://" + System.getProperty("user.home") + "/.m2/repository",
- "https://repo.maven.apache.org/maven2",
- "https://repository.apache.org/content/groups/snapshots"
- };
- try {
- this.cacheDirectory = Files.createTempDirectory("slingfeature").toFile();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Set the repository urls
- * @param urls The repository urls
- */
- public void setRepositoryUrls(final String[] urls) {
- if ( urls == null || urls.length == 0 ) {
- this.repositoryUrls = null;
- } else {
- this.repositoryUrls = new String[urls.length];
- System.arraycopy(urls, 0, this.repositoryUrls, 0, urls.length);
- for(int i=0; i<this.repositoryUrls.length; i++) {
- if ( this.repositoryUrls[i].endsWith("/") ) {
- this.repositoryUrls[i] = this.repositoryUrls[i].substring(0, this.repositoryUrls[i].length() - 1);
- }
- }
- }
- }
-
- /**
- * Get the repository urls.
- * A repository url does not end with a slash.
- * @return The repository urls.
- */
- public String[] getRepositoryUrls() {
- return repositoryUrls;
- }
-
- /**
- * Get the cache directory
- * @return The cache directory.
- */
- @Override
- public File getCacheDirectory() {
- return cacheDirectory;
- }
-
- /**
- * Set the cache directory
- * @param dir The cache directory
- */
- public void setCacheDirectory(final File dir) {
- this.cacheDirectory = dir;
- }
-
- @Override
- public void incCachedArtifacts() {
- this.cachedArtifacts++;
- }
-
- @Override
- public void incDownloadedArtifacts() {
- this.downloadedArtifacts++;
- }
-
- @Override
- public void incLocalArtifacts() {
- this.localArtifacts++;
- }
-
- /**
- * Get the number of cached artifacts
- * @return The number of cached artifacts
- */
- public long getCachedArtifacts() {
- return this.cachedArtifacts;
- }
-
- /**
- * Get the number of downloaded artifacts
- * @return The number of downloaded artifacts
- */
- public long getDownloadedArtifacts() {
- return this.downloadedArtifacts;
- }
-
- /**
- * Get the number of local artifacts
- * @return The number of local artifacts
- */
- public long getLocalArtifacts() {
- return this.localArtifacts;
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
deleted file mode 100644
index 70af38c..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
+++ /dev/null
@@ -1,243 +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.io;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-public class IOUtils {
-
- /** The extension for a reference file. */
- public static final String EXTENSION_REF_FILE = ".ref";
-
- /** The extension for a feature file. */
- public static final String EXTENSION_FEATURE_FILE = ".json";
-
- /** The default directory to search for features. */
- public static final String DEFAULT_DIRECTORY = "features";
-
- /** The default name of the feature file. */
- public static final String DEFAULT_FEATURE_FILE = "feature" + EXTENSION_FEATURE_FILE;
-
- /**
- * Parse a feature reference file
- * @param file The file
- * @return The referenced features
- * @throws IOException If reading fails
- */
- public static List<String> parseFeatureRefFile(final File file)
- throws IOException {
- final List<String> result = new ArrayList<>();
- final List<String> lines = Files.readAllLines(file.toPath());
- for(String line : lines) {
- line = line.trim();
- if ( !line.isEmpty() && !line.startsWith("#") ) {
- if ( line.indexOf(':') == -1 ) {
- result.add(new File(line).getAbsolutePath());
- } else {
- result.add(line);
- }
- }
- }
- return result;
- }
-
- /**
- * Get the list of feature files.
- * If the provided list of files is {@code null} or an empty array, the default is used.
- * The default checks for the following places, the first one found is used. If none is
- * found an empty list is returned.
- * <ol>
- * <li>A directory named {@link #DEFAULT_DIRECTORY} in the current directory
- * <li>A file named {@link #DEFAULT_FEATURE_FILE} in the current directory
- * <li>A directory named {@link #DEFAULT_DIRECTORY} in the home directory
- * <li>A file named {@link #DEFAULT_FEATURE_FILE} in the home directory
- * </ol>
- *
- * The list of files is processed one after the other. If it is relative, it is
- * first tried to be resolved against the current directory and then against the
- * home directory.
- * If an entry denotes a directory, all children ending in {@link #EXTENSION_FEATURE_FILE} or
- * {@link #EXTENSION_REF_FILE} of that directory are read.
- * If a file ends in {@link #EXTENSION_REF_FILE} the contents is read and every line not
- * starting with the hash sign is considered a reference to a feature artifact.
- *
- * @param homeDirectory If relative files should be resolved, this is the directory to use
- * @param files Optional list of files. If none is provided, a default is used.
- * @return The list of files.
- * @throws IOException If an error occurs.
- */
- public static List<String> getFeatureFiles(final File homeDirectory, final String... files)
- throws IOException {
- String[] featureFiles = files;
- if ( featureFiles == null || featureFiles.length == 0 ) {
- // Default value - check feature directory otherwise features file
- final File[] candidates = new File[] {
- new File(homeDirectory, DEFAULT_DIRECTORY),
- new File(homeDirectory, DEFAULT_FEATURE_FILE),
- new File(DEFAULT_DIRECTORY),
- new File(DEFAULT_FEATURE_FILE)
- };
- File f = null;
- for(final File c : candidates) {
- if ( c.exists() ) {
- f = c;
- break;
- }
- }
- // nothing found, we default to the first candidate and fail later
- if ( f == null ) {
- f = candidates[0];
- }
-
- featureFiles = new String[] {f.getAbsolutePath()};
- }
-
- final List<String> paths = new ArrayList<>();
- for(final String name : featureFiles) {
- // check for absolute
- if ( name.indexOf(':') > 1 ) {
- paths.add(name);
- } else {
- // file or relative
- File f = null;
- final File test = new File(name);
- if ( test.isAbsolute() ) {
- f = test;
- } else {
- final File[] candidates = {
- new File(homeDirectory, name),
- new File(homeDirectory, DEFAULT_DIRECTORY + File.separatorChar + name),
- new File(name),
- new File(DEFAULT_DIRECTORY + File.separatorChar + name),
- };
- for(final File c : candidates) {
- if ( c.exists() && c.isFile() ) {
- f = c;
- break;
- }
- }
- }
-
- if ( f != null && f.exists() ) {
- if ( f.isFile() ) {
- processFile(paths, f);
- } else {
- processDir(paths, f);
- }
- } else {
- // we simply add the path and fail later on
- paths.add(new File(name).getAbsolutePath());
- }
- }
- }
-
- Collections.sort(paths, FEATURE_PATH_COMP);
- return paths;
- }
-
- /**
- * Read the feature
- *
- * @param url The feature url
- * @param artifactManager The artifact manager to read the feature
- * @param substituteVariables Variable substitution handling
- * @return The read feature
- * @throws IOException If reading fails
- */
- public static Feature getFeature(final String url,
- final ArtifactManager artifactManager,
- final SubstituteVariables substituteVariables)
- throws IOException {
- final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(url);
-
- try (final FileReader r = new FileReader(featureArtifact.getFile())) {
- final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), substituteVariables);
- return f;
- }
- }
-
- /**
- * Get an artifact id for the Apache Felix framework
- * @param version The version to use or {@code null} for the default version
- * @return The artifact id
- * @throws IllegalArgumentException If the provided version is invalid
- */
- public static ArtifactId getFelixFrameworkId(final String version) {
- return new ArtifactId("org.apache.felix",
- "org.apache.felix.framework",
- version != null ? version : "5.6.10", null, null);
- }
-
- static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
- @Override
- public int compare(final String o1, final String o2) {
- // windows path conversion
- final String key1 = o1.replace(File.separatorChar, '/');
- final String key2 = o2.replace(File.separatorChar, '/');
-
- final int lastSlash1 = key1.lastIndexOf('/');
- final int lastSlash2 = key2.lastIndexOf('/');
- if ( lastSlash1 == -1 || lastSlash2 == -1 ) {
- return o1.compareTo(o2);
- }
- final String path1 = key1.substring(0, lastSlash1 + 1);
- final String path2 = key2.substring(0, lastSlash2 + 1);
- if ( path1.equals(path2) ) {
- return o1.compareTo(o2);
- }
- if ( path1.startsWith(path2) ) {
- return 1;
- } else if ( path2.startsWith(path1) ) {
- return -1;
- }
- return o1.compareTo(o2);
- }
- };
-
- private static void processDir(final List<String> paths, final File dir)
- throws IOException {
- for(final File f : dir.listFiles()) {
- if ( f.isFile() && !f.getName().startsWith(".")) {
- // check if file is a reference
- if ( f.getName().endsWith(EXTENSION_REF_FILE) || f.getName().endsWith(EXTENSION_FEATURE_FILE) ) {
- processFile(paths, f);
- }
- }
- }
- }
-
- private static void processFile(final List<String> paths, final File f)
- throws IOException {
- if ( f.getName().endsWith(EXTENSION_REF_FILE) ) {
- paths.addAll(parseFeatureRefFile(f));
- } else {
- paths.add(f.getAbsolutePath());
- }
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java
deleted file mode 100644
index 88d3bc5..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java
+++ /dev/null
@@ -1,92 +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.io.json;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-
-/**
- * This class offers a method to read an {@code Application} using a {@code Reader} instance.
- */
-public class ApplicationJSONReader extends JSONReaderBase {
-
- /**
- * Read a new application from the reader
- * The reader is not closed. It is up to the caller to close the reader.
- *
- * @param reader The reader for the feature
- * @return The application
- * @throws IOException If an IO errors occurs or the JSON is invalid.
- */
- public static Application read(final Reader reader)
- throws IOException {
- try {
- final ApplicationJSONReader mr = new ApplicationJSONReader();
- mr.readApplication(reader);
- return mr.app;
- } catch (final IllegalStateException | IllegalArgumentException e) {
- throw new IOException(e);
- }
- }
-
- /** The read application. */
- private final Application app;
-
- /**
- * Private constructor
- */
- private ApplicationJSONReader() {
- super(null);
- this.app = new Application();
- }
-
- /**
- * Read a full application
- * @param reader The reader
- * @throws IOException If an IO error occurs or the JSON is not valid.
- */
- private void readApplication(final Reader reader)
- throws IOException {
- final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-
- @SuppressWarnings("unchecked")
- final Map<String, Object> map = (Map<String, Object>) JSONUtil.getValue(json);
-
- final String frameworkId = this.getProperty(map, JSONConstants.APP_FRAMEWORK);
- if ( frameworkId != null ) {
- app.setFramework(ArtifactId.parse(frameworkId));
- }
- this.readBundles(map, app.getBundles(), app.getConfigurations());
- this.readFrameworkProperties(map, app.getFrameworkProperties());
- this.readConfigurations(map, app.getConfigurations());
-
- this.readExtensions(map,
- JSONConstants.APP_KNOWN_PROPERTIES,
- this.app.getExtensions(), this.app.getConfigurations());
- }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java
deleted file mode 100644
index bdf4902..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java
+++ /dev/null
@@ -1,97 +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.io.json;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-/**
- * Simple JSON writer for an application
- */
-public class ApplicationJSONWriter extends JSONWriterBase {
-
- /**
- * Writes the application to the writer.
- * The writer is not closed.
- * @param writer Writer
- * @param app The application
- * @throws IOException If writing fails
- */
- public static void write(final Writer writer, final Application app)
- throws IOException {
- final ApplicationJSONWriter w = new ApplicationJSONWriter();
- w.writeApp(writer, app);
- }
-
- private void writeApp(final Writer writer, final Application app)
- throws IOException {
- JsonObjectBuilder ob = Json.createObjectBuilder();
-
- // framework
- if ( app.getFramework() != null ) {
- ob.add(JSONConstants.APP_FRAMEWORK, app.getFramework().toMvnId());
- }
-
- // features
- if ( !app.getFeatureIds().isEmpty() ) {
- JsonArrayBuilder featuresArr = Json.createArrayBuilder();
-
- for(final ArtifactId id : app.getFeatureIds()) {
- featuresArr.add(id.toMvnId());
- }
- ob.add(JSONConstants.APP_FEATURES, featuresArr.build());
- }
-
- // bundles
- writeBundles(ob, app.getBundles(), app.getConfigurations());
-
- // configurations
- final Configurations cfgs = new Configurations();
- for(final Configuration cfg : app.getConfigurations()) {
- final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
- if ( artifactProp == null ) {
- cfgs.add(cfg);
- }
- }
- writeConfigurations(ob, cfgs);
-
- // framework properties
- writeFrameworkProperties(ob, app.getFrameworkProperties());
-
- // extensions
- writeExtensions(ob, app.getExtensions(), app.getConfigurations());
-
- JsonWriterFactory writerFactory = Json.createWriterFactory(
- Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
- JsonWriter jw = writerFactory.createWriter(writer);
- jw.writeObject(ob.build());
- jw.close();
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
deleted file mode 100644
index 5fca482..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
+++ /dev/null
@@ -1,78 +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.io.json;
-
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.sling.feature.Configurations;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * JSON Reader for configurations.
- */
-public class ConfigurationJSONReader extends JSONReaderBase {
-
- /**
- * Read a map of configurations from the reader
- * The reader is not closed. It is up to the caller to close the reader.
- *
- * @param reader The reader for the configuration
- * @param location Optional location
- * @return The read configurations
- * @throws IOException If an IO errors occurs or the JSON is invalid.
- */
- public static Configurations read(final Reader reader, final String location)
- throws IOException {
- try {
- final ConfigurationJSONReader mr = new ConfigurationJSONReader(location);
- return mr.readConfigurations(reader);
- } catch (final IllegalStateException | IllegalArgumentException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Private constructor
- * @param location Optional location
- */
- ConfigurationJSONReader(final String location) {
- super(location);
- }
-
- Configurations readConfigurations(final Reader reader) throws IOException {
- final Configurations result = new Configurations();
-
- final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-
- @SuppressWarnings("unchecked")
- final Map<String, Object> map = (Map<String, Object>) JSONUtil.getValue(json);
-
- final Map<String, Object> objMap = Collections.singletonMap(JSONConstants.FEATURE_CONFIGURATIONS, (Object)map);
-
- readConfigurations(objMap, result);
-
- return result;
- }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
deleted file mode 100644
index 64e937d..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
+++ /dev/null
@@ -1,64 +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.io.json;
-
-import org.apache.sling.feature.Configurations;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-
-import javax.json.Json;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-
-/**
- * JSON writer for configurations
- */
-public class ConfigurationJSONWriter extends JSONWriterBase {
-
- /**
- * Writes the configurations to the writer.
- * The writer is not closed.
- * @param writer Writer
- * @param configs List of configurations
- * @throws IOException If writing fails
- */
- public static void write(final Writer writer, final Configurations configs)
- throws IOException {
- final ConfigurationJSONWriter w = new ConfigurationJSONWriter();
- w.writeConfigurations(writer, configs);
- }
-
- private void writeConfigurations(final Writer writer, final Configurations configs)
- throws IOException {
- JsonObjectBuilder ob = Json.createObjectBuilder();
-
- // TODO is this correct?
- ob.add(JSONConstants.FEATURE_CONFIGURATIONS,
- writeConfigurationsMap(configs));
-
- JsonWriterFactory writerFactory = Json.createWriterFactory(
- Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
- JsonWriter jw = writerFactory.createWriter(writer);
- jw.writeObject(ob.build());
- jw.close();
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
deleted file mode 100644
index 0d21598..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
+++ /dev/null
@@ -1,431 +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.io.json;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.apache.sling.feature.KeyValueMap;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-
-/**
- * This class offers a method to read a {@code Feature} using a {@code Reader} instance.
- */
-public class FeatureJSONReader extends JSONReaderBase {
- public enum SubstituteVariables { NONE, RESOLVE, LAUNCH }
-
- // The pattern that variables in Feature JSON follow
- private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\{[a-zA-Z0-9.-_]+\\}");
-
- /**
- * Read a new feature from the reader
- * The reader is not closed. It is up to the caller to close the reader.
- *
- * @param reader The reader for the feature
- * @param location Optional location
- * @return The read feature
- * @throws IOException If an IO errors occurs or the JSON is invalid.
- */
- public static Feature read(final Reader reader, final String location, final SubstituteVariables phase)
- throws IOException {
- return read(reader, null, location, phase);
- }
-
- /**
- * Read a new feature from the reader
- * The reader is not closed. It is up to the caller to close the reader.
- *
- * @param reader The reader for the feature
- * @param providedId Optional artifact id
- * @param location Optional location
- * @return The read feature
- * @throws IOException If an IO errors occurs or the JSON is invalid.
- */
- public static Feature read(final Reader reader,
- final ArtifactId providedId,
- final String location,
- final SubstituteVariables phase)
- throws IOException {
- try {
- final FeatureJSONReader mr = new FeatureJSONReader(providedId, location, phase);
- return mr.readFeature(reader);
- } catch (final IllegalStateException | IllegalArgumentException e) {
- throw new IOException(e);
- }
- }
-
- /** The read feature. */
- private Feature feature;
-
- /** The provided id. */
- private final ArtifactId providedId;
-
- /** The variables from the JSON. */
- private Map<String, String> variables;
-
- /** The current reading phase. */
- private final SubstituteVariables phase;
-
- /**
- * Private constructor
- * @param pId Optional id
- * @param location Optional location
- */
- FeatureJSONReader(final ArtifactId pId, final String location, final SubstituteVariables phase) {
- super(location);
- this.providedId = pId;
- this.phase = phase;
- }
-
- /**
- * Read a full feature
- * @param reader The reader
- * @return The feature object
- * @throws IOException If an IO error occurs or the JSON is not valid.
- */
- private Feature readFeature(final Reader reader)
- throws IOException {
- final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
- final Map<String, Object> map = getJsonMap(json);
-
- checkModelVersion(map);
-
- final ArtifactId fId;
- if ( !map.containsKey(JSONConstants.FEATURE_ID) ) {
- if ( this.providedId == null ) {
- throw new IOException(this.exceptionPrefix + "Feature id is missing");
- }
- fId = this.providedId;
- } else {
- final Object idObj = map.get(JSONConstants.FEATURE_ID);
- checkType(JSONConstants.FEATURE_ID, idObj, String.class);
- fId = ArtifactId.parse(idObj.toString());
- }
- this.feature = new Feature(fId);
- this.feature.setLocation(this.location);
-
- // title, description, vendor and license
- this.feature.setTitle(getProperty(map, JSONConstants.FEATURE_TITLE));
- this.feature.setDescription(getProperty(map, JSONConstants.FEATURE_DESCRIPTION));
- this.feature.setVendor(getProperty(map, JSONConstants.FEATURE_VENDOR));
- this.feature.setLicense(getProperty(map, JSONConstants.FEATURE_LICENSE));
-
- this.readVariables(map, feature.getVariables());
- this.readBundles(map, feature.getBundles(), feature.getConfigurations());
- this.readFrameworkProperties(map, feature.getFrameworkProperties());
- this.readConfigurations(map, feature.getConfigurations());
-
- this.readCapabilities(map);
- this.readRequirements(map);
- this.readIncludes(map);
-
- this.readExtensions(map,
- JSONConstants.FEATURE_KNOWN_PROPERTIES,
- this.feature.getExtensions(), this.feature.getConfigurations());
-
- return feature;
- }
-
- private void checkModelVersion(final Map<String, Object> map) throws IOException {
- String modelVersion = getProperty(map, JSONConstants.FEATURE_MODEL_VERSION);
- if (modelVersion == null) {
- modelVersion = "1";
- }
- if (!"1".equals(modelVersion)) {
- throw new IOException("Unsupported model version: " + modelVersion);
- }
- }
-
- @Override
- protected Object handleResolveVars(Object val) {
- if (phase == SubstituteVariables.RESOLVE) {
- return handleVars(val);
- } else {
- return val;
- }
- }
-
- @Override
- protected Object handleLaunchVars(Object val) {
- if (phase == SubstituteVariables.LAUNCH) {
- return handleVars(val);
- }
- return val;
- }
-
- private Object handleVars(Object value) {
- if (!(value instanceof String)) {
- return value;
- }
-
- String textWithVars = (String) value;
-
- Matcher m = VARIABLE_PATTERN.matcher(textWithVars.toString());
- StringBuffer sb = new StringBuffer();
- while (m.find()) {
- String var = m.group();
-
- int len = var.length();
- String name = var.substring(2, len - 1);
- String val = variables.get(name);
- if (val != null) {
- m.appendReplacement(sb, Matcher.quoteReplacement(val));
- } else {
- throw new IllegalStateException("Undefined variable: " + name);
- }
- }
- m.appendTail(sb);
-
- return sb.toString();
- }
-
- private void readVariables(Map<String, Object> map, KeyValueMap kvMap) throws IOException {
- variables = new HashMap<>();
-
- if (map.containsKey(JSONConstants.FEATURE_VARIABLES)) {
- final Object variablesObj = map.get(JSONConstants.FEATURE_VARIABLES);
- checkType(JSONConstants.FEATURE_VARIABLES, variablesObj, Map.class);
-
- @SuppressWarnings("unchecked")
- final Map<String, Object> vars = (Map<String, Object>) variablesObj;
- for (final Map.Entry<String, Object> entry : vars.entrySet()) {
- checkType("variable value", entry.getValue(), String.class, Boolean.class, Number.class);
-
- String key = entry.getKey();
- if (kvMap.get(key) != null) {
- throw new IOException(this.exceptionPrefix + "Duplicate variable " + key);
- }
- String value = "" + entry.getValue();
- kvMap.put(key, value);
- variables.put(key, value);
- }
- }
- }
-
- private void readIncludes(final Map<String, Object> map) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_INCLUDES)) {
- final Object includesObj = map.get(JSONConstants.FEATURE_INCLUDES);
- checkType(JSONConstants.FEATURE_INCLUDES, includesObj, List.class);
-
- @SuppressWarnings("unchecked")
- final List<Object> includes = (List<Object>)includesObj;
- for(final Object inc : includes) {
- checkType("Include", inc, Map.class, String.class);
- final Include include;
- if ( inc instanceof String ) {
- final ArtifactId id = ArtifactId.parse(inc.toString());
- include = new Include(id);
- } else {
- @SuppressWarnings("unchecked")
- final Map<String, Object> obj = (Map<String, Object>) inc;
- if ( !obj.containsKey(JSONConstants.ARTIFACT_ID) ) {
- throw new IOException(exceptionPrefix + " include is missing required artifact id");
- }
- checkType("Include " + JSONConstants.ARTIFACT_ID, obj.get(JSONConstants.ARTIFACT_ID), String.class);
- final ArtifactId id = ArtifactId.parse(handleResolveVars(obj.get(JSONConstants.ARTIFACT_ID)).toString());
- include = new Include(id);
-
- if ( obj.containsKey(JSONConstants.INCLUDE_REMOVALS) ) {
- checkType("Include removals", obj.get(JSONConstants.INCLUDE_REMOVALS), Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> removalObj = (Map<String, Object>) obj.get(JSONConstants.INCLUDE_REMOVALS);
- if ( removalObj.containsKey(JSONConstants.FEATURE_BUNDLES) ) {
- checkType("Include removal bundles", removalObj.get(JSONConstants.FEATURE_BUNDLES), List.class);
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_BUNDLES);
- for(final Object val : list) {
- checkType("Include removal bundles", val, String.class);
- include.getBundleRemovals().add(ArtifactId.parse(val.toString()));
- }
- }
- if ( removalObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
- checkType("Include removal configuration", removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS), List.class);
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS);
- for(final Object val : list) {
- checkType("Include removal bundles", val, String.class);
- include.getConfigurationRemovals().add(val.toString());
- }
- }
- if ( removalObj.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
- checkType("Include removal framework properties", removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES), List.class);
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
- for(final Object val : list) {
- checkType("Include removal bundles", val, String.class);
- include.getFrameworkPropertiesRemovals().add(val.toString());
- }
- }
- if ( removalObj.containsKey(JSONConstants.INCLUDE_EXTENSION_REMOVALS) ) {
- checkType("Include removal extensions", removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS), List.class);
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>)removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
- for(final Object val : list) {
- checkType("Include removal extension", val, String.class, Map.class);
- if ( val instanceof String ) {
- include.getExtensionRemovals().add(val.toString());
- } else {
- @SuppressWarnings("unchecked")
- final Map<String, Object> removalMap = (Map<String, Object>)val;
- final Object nameObj = removalMap.get("name");
- checkType("Include removal extension", nameObj, String.class);
- if ( removalMap.containsKey("artifacts") ) {
- checkType("Include removal extension artifacts", removalMap.get("artifacts"), List.class);
- @SuppressWarnings("unchecked")
- final List<Object> artifactList = (List<Object>)removalMap.get("artifacts");
- final List<ArtifactId> ids = new ArrayList<>();
- for(final Object aid : artifactList) {
- checkType("Include removal extension artifact", aid, String.class);
- ids.add(ArtifactId.parse(aid.toString()));
- }
- include.getArtifactExtensionRemovals().put(nameObj.toString(), ids);
- } else {
- include.getExtensionRemovals().add(nameObj.toString());
- }
- }
- }
- }
-
- }
- }
- for(final Include i : feature.getIncludes()) {
- if ( i.getId().equals(include.getId()) ) {
- throw new IOException(exceptionPrefix + "Duplicate include of " + include.getId());
- }
- }
- feature.getIncludes().add(include);
- }
- }
- }
-
- private void readRequirements(Map<String, Object> map) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_REQUIREMENTS)) {
- final Object reqObj = map.get(JSONConstants.FEATURE_REQUIREMENTS);
- checkType(JSONConstants.FEATURE_REQUIREMENTS, reqObj, List.class);
-
- @SuppressWarnings("unchecked")
- final List<Object> requirements = (List<Object>)reqObj;
- for(final Object req : requirements) {
- checkType("Requirement", req, Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> obj = (Map<String, Object>) req;
-
- if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
- throw new IOException(this.exceptionPrefix + "Namespace is missing for requirement");
- }
- checkType("Requirement namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
- Map<String, Object> attrMap = new HashMap<>();
- if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
- checkType("Requirement attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
- attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, handleResolveVars(value), attrMap::put)));
- }
-
- Map<String, String> dirMap = new HashMap<>();
- if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
- checkType("Requirement directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> dirs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_DIRECTIVES);
- dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, handleResolveVars(value), dirMap::put)));
- }
-
- final Requirement r = new RequirementImpl(null, handleResolveVars(obj.get(JSONConstants.REQCAP_NAMESPACE)).toString(), dirMap, attrMap);
- feature.getRequirements().add(r);
- }
- }
- }
-
- private void readCapabilities(Map<String, Object> map) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_CAPABILITIES)) {
- final Object capObj = map.get(JSONConstants.FEATURE_CAPABILITIES);
- checkType(JSONConstants.FEATURE_CAPABILITIES, capObj, List.class);
-
- @SuppressWarnings("unchecked")
- final List<Object> capabilities = (List<Object>)capObj;
- for(final Object cap : capabilities) {
- checkType("Capability", cap, Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> obj = (Map<String, Object>) cap;
-
- if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
- throw new IOException(this.exceptionPrefix + "Namespace is missing for capability");
- }
- checkType("Capability namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
- Map<String, Object> attrMap = new HashMap<>();
- if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
- checkType("Capability attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
- attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, handleResolveVars(value), attrMap::put)));
- }
-
- Map<String, String> dirMap = new HashMap<>();
- if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
- checkType("Capability directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
- @SuppressWarnings("unchecked")
- final Map<String, Object> dirs = (Map<String, Object>) obj.get(JSONConstants.REQCAP_DIRECTIVES);
- dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, handleResolveVars(value), dirMap::put)));
- }
-
- final Capability c = new CapabilityImpl(null, handleResolveVars(obj.get(JSONConstants.REQCAP_NAMESPACE)).toString(), dirMap, attrMap);
- feature.getCapabilities().add(c);
- }
- }
- }
-
- @FunctionalInterface
- private interface BiConsumer_WithExceptions<T, V, E extends Exception> {
- void accept(T t, V u) throws E;
- }
-
- private static <T, V, E extends Exception> BiConsumer<T, V> rethrowBiConsumer(BiConsumer_WithExceptions<T, V, E> biConsumer) {
- return (t, u) -> {
- try {
- biConsumer.accept(t, u);
- } catch (Exception exception) {
- throwAsUnchecked(exception);
- }
- };
- }
-
- @SuppressWarnings ("unchecked")
- private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
- throw (E) exception;
- }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
deleted file mode 100644
index 57428e1..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
+++ /dev/null
@@ -1,207 +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.io.json;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-/**
- * Simple JSON writer for a feature
- */
-public class FeatureJSONWriter extends JSONWriterBase {
- private FeatureJSONWriter() {}
-
- /**
- * Writes the feature to the writer.
- * The writer is not closed.
- * @param writer Writer
- * @param feature Feature
- * @throws IOException If writing fails
- */
- public static void write(final Writer writer, final Feature feature)
- throws IOException {
- final FeatureJSONWriter w = new FeatureJSONWriter();
- w.writeFeature(writer, feature);
- }
-
- private void writeProperty(final JsonObjectBuilder ob, final String key, final String value) {
- if ( value != null ) {
- ob.add(key, value);
- }
- }
-
- private void writeFeature(final Writer writer, final Feature feature)
- throws IOException {
- JsonObjectBuilder ob = Json.createObjectBuilder();
- ob.add(JSONConstants.FEATURE_ID, feature.getId().toMvnId());
-
- // title, description, vendor, license
- writeProperty(ob, JSONConstants.FEATURE_TITLE, feature.getTitle());
- writeProperty(ob, JSONConstants.FEATURE_DESCRIPTION, feature.getDescription());
- writeProperty(ob, JSONConstants.FEATURE_VENDOR, feature.getVendor());
- writeProperty(ob, JSONConstants.FEATURE_LICENSE, feature.getLicense());
-
- // variables
- writeVariables(ob, feature.getVariables());
-
- // includes
- if ( !feature.getIncludes().isEmpty() ) {
- JsonArrayBuilder incArray = Json.createArrayBuilder();
- for(final Include inc : feature.getIncludes()) {
- if ( inc.getArtifactExtensionRemovals().isEmpty()
- && inc.getBundleRemovals().isEmpty()
- && inc.getConfigurationRemovals().isEmpty()
- && inc.getFrameworkPropertiesRemovals().isEmpty() ) {
- incArray.add(inc.getId().toMvnId());
- } else {
- JsonObjectBuilder includeObj = Json.createObjectBuilder();
- includeObj.add(JSONConstants.ARTIFACT_ID, inc.getId().toMvnId());
-
- JsonObjectBuilder removalsObj = Json.createObjectBuilder();
- if ( !inc.getArtifactExtensionRemovals().isEmpty()
- || inc.getExtensionRemovals().isEmpty() ) {
- JsonArrayBuilder extRemovals = Json.createArrayBuilder();
- for(final String id : inc.getExtensionRemovals()) {
- extRemovals.add(id);
- }
- for(final Map.Entry<String, List<ArtifactId>> entry : inc.getArtifactExtensionRemovals().entrySet()) {
- JsonArrayBuilder ab = Json.createArrayBuilder();
- for(final ArtifactId id : entry.getValue()) {
- ab.add(id.toMvnId());
- }
- extRemovals.add(Json.createObjectBuilder().add(entry.getKey(),
- ab.build()).build());
- }
- removalsObj.add(JSONConstants.INCLUDE_EXTENSION_REMOVALS, extRemovals.build());
- }
- if ( !inc.getConfigurationRemovals().isEmpty() ) {
- JsonArrayBuilder cfgRemovals = Json.createArrayBuilder();
- for(final String val : inc.getConfigurationRemovals()) {
- cfgRemovals.add(val);
- }
- removalsObj.add(JSONConstants.FEATURE_CONFIGURATIONS, cfgRemovals.build());
- }
- if ( !inc.getBundleRemovals().isEmpty() ) {
- JsonArrayBuilder bundleRemovals = Json.createArrayBuilder();
- for(final ArtifactId val : inc.getBundleRemovals()) {
- bundleRemovals.add(val.toMvnId());
- }
- removalsObj.add(JSONConstants.FEATURE_BUNDLES, bundleRemovals.build());
- }
- if ( !inc.getFrameworkPropertiesRemovals().isEmpty() ) {
- JsonArrayBuilder propRemovals = Json.createArrayBuilder();
- for(final String val : inc.getFrameworkPropertiesRemovals()) {
- propRemovals.add(val);
- }
- removalsObj.add(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propRemovals.build());
- }
- includeObj.add(JSONConstants.INCLUDE_REMOVALS, removalsObj.build());
-
- incArray.add(includeObj.build());
- }
- }
- ob.add(JSONConstants.FEATURE_INCLUDES, incArray.build());
- }
-
- // requirements
- if ( !feature.getRequirements().isEmpty() ) {
- JsonArrayBuilder requirements = Json.createArrayBuilder();
-
- for(final Requirement req : feature.getRequirements()) {
- JsonObjectBuilder requirementObj = Json.createObjectBuilder();
- requirementObj.add(JSONConstants.REQCAP_NAMESPACE, req.getNamespace());
- if ( !req.getAttributes().isEmpty() ) {
- JsonObjectBuilder attrObj = Json.createObjectBuilder();
- req.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, attrObj::add));
- requirementObj.add(JSONConstants.REQCAP_ATTRIBUTES, attrObj.build());
- }
- if ( !req.getDirectives().isEmpty() ) {
- JsonObjectBuilder reqObj = Json.createObjectBuilder();
- req.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, reqObj::add));
- requirementObj.add(JSONConstants.REQCAP_DIRECTIVES, reqObj.build());
- }
- requirements.add(requirementObj.build());
- }
- ob.add(JSONConstants.FEATURE_REQUIREMENTS, requirements.build());
- }
-
- // capabilities
- if ( !feature.getCapabilities().isEmpty() ) {
- JsonArrayBuilder capabilities = Json.createArrayBuilder();
-
- for(final Capability cap : feature.getCapabilities()) {
- JsonObjectBuilder capabilityObj = Json.createObjectBuilder();
- capabilityObj.add(JSONConstants.REQCAP_NAMESPACE, cap.getNamespace());
- if ( !cap.getAttributes().isEmpty() ) {
- JsonObjectBuilder attrObj = Json.createObjectBuilder();
- cap.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, attrObj::add));
- capabilityObj.add(JSONConstants.REQCAP_ATTRIBUTES, attrObj.build());
- }
- if ( !cap.getDirectives().isEmpty() ) {
- JsonObjectBuilder reqObj = Json.createObjectBuilder();
- cap.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, reqObj::add));
- capabilityObj.add(JSONConstants.REQCAP_DIRECTIVES, reqObj.build());
- }
- capabilities.add(capabilityObj.build());
- }
- ob.add(JSONConstants.FEATURE_CAPABILITIES, capabilities.build());
- }
-
- // bundles
- writeBundles(ob, feature.getBundles(), feature.getConfigurations());
-
- // configurations
- final Configurations cfgs = new Configurations();
- for(final Configuration cfg : feature.getConfigurations()) {
- final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
- if ( artifactProp == null ) {
- cfgs.add(cfg);
- }
- }
- writeConfigurations(ob, cfgs);
-
- // framework properties
- writeFrameworkProperties(ob, feature.getFrameworkProperties());
-
- // extensions
- writeExtensions(ob, feature.getExtensions(), feature.getConfigurations());
-
- JsonWriterFactory writerFactory = Json.createWriterFactory(
- Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
- JsonWriter jw = writerFactory.createWriter(writer);
- jw.writeObject(ob.build());
- jw.close();
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java
deleted file mode 100644
index 3b6f707..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java
+++ /dev/null
@@ -1,88 +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.io.json;
-
-import org.apache.sling.feature.Configuration;
-
-import java.util.Arrays;
-import java.util.List;
-
-public abstract class JSONConstants {
-
- public static final String FEATURE_ID = "id";
-
- public static final String FEATURE_VARIABLES = "variables";
-
- public static final String FEATURE_BUNDLES = "bundles";
-
- public static final String FEATURE_FRAMEWORK_PROPERTIES = "framework-properties";
-
- public static final String FEATURE_CONFIGURATIONS = "configurations";
-
- public static final String FEATURE_INCLUDES = "includes";
-
- public static final String FEATURE_REQUIREMENTS = "requirements";
-
- public static final String FEATURE_CAPABILITIES = "capabilities";
-
- public static final String FEATURE_TITLE = "title";
-
- public static final String FEATURE_DESCRIPTION = "description";
-
- public static final String FEATURE_VENDOR = "vendor";
-
- public static final String FEATURE_LICENSE = "license";
-
- public static final String FEATURE_MODEL_VERSION = "model-version";
-
- public static final List<String> FEATURE_KNOWN_PROPERTIES = Arrays.asList(FEATURE_ID,
- FEATURE_MODEL_VERSION,
- FEATURE_VARIABLES,
- FEATURE_BUNDLES,
- FEATURE_FRAMEWORK_PROPERTIES,
- FEATURE_CONFIGURATIONS,
- FEATURE_INCLUDES,
- FEATURE_REQUIREMENTS,
- FEATURE_CAPABILITIES,
- FEATURE_TITLE,
- FEATURE_DESCRIPTION,
- FEATURE_VENDOR,
- FEATURE_LICENSE);
-
- public static final String ARTIFACT_ID = "id";
-
- public static final List<String> ARTIFACT_KNOWN_PROPERTIES = Arrays.asList(ARTIFACT_ID,
- Configuration.PROP_ARTIFACT,
- FEATURE_CONFIGURATIONS);
-
- public static final String INCLUDE_REMOVALS = "removals";
-
- public static final String INCLUDE_EXTENSION_REMOVALS = "extensions";
-
- public static final String REQCAP_NAMESPACE = "namespace";
- public static final String REQCAP_ATTRIBUTES = "attributes";
- public static final String REQCAP_DIRECTIVES = "directives";
-
- public static final String APP_FRAMEWORK = "frameworkId";
- public static final String APP_FEATURES = "features";
-
- public static final List<String> APP_KNOWN_PROPERTIES = Arrays.asList(APP_FRAMEWORK,
- FEATURE_BUNDLES,
- FEATURE_FRAMEWORK_PROPERTIES,
- FEATURE_CONFIGURATIONS,
- APP_FEATURES);
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
deleted file mode 100644
index fe3b89e..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
+++ /dev/null
@@ -1,479 +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.io.json;
-
-import org.apache.felix.configurator.impl.json.JSMin;
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.felix.configurator.impl.json.TypeConverter;
-import org.apache.felix.configurator.impl.model.Config;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.KeyValueMap;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-import javax.json.JsonWriter;
-
-/**
- * Common methods for JSON reading.
- */
-abstract class JSONReaderBase {
-
- /** The optional location. */
- protected final String location;
-
- /** Exception prefix containing the location (if set) */
- protected final String exceptionPrefix;
-
- /**
- * Private constructor
- * @param location Optional location
- */
- JSONReaderBase(final String location) {
- this.location = location;
- if ( location == null ) {
- exceptionPrefix = "";
- } else {
- exceptionPrefix = location + " : ";
- }
- }
-
- protected String minify(final Reader reader) throws IOException {
- // minify JSON (remove comments)
- final String contents;
- try ( final Writer out = new StringWriter()) {
- final JSMin min = new JSMin(reader, out);
- min.jsmin();
- contents = out.toString();
- }
- return contents;
- }
-
- /** Get the JSON object as a map, removing all comments that start with a '#' character
- */
- protected Map<String, Object> getJsonMap(JsonObject json) {
- @SuppressWarnings("unchecked")
- Map<String, Object> m = (Map<String, Object>) JSONUtil.getValue(json);
-
- removeComments(m);
- return m;
- }
-
- private void removeComments(Map<String, Object> m) {
- for(Iterator<Map.Entry<String, Object>> it = m.entrySet().iterator(); it.hasNext(); ) {
- Entry<String, ?> entry = it.next();
- if (entry.getKey().startsWith("#")) {
- it.remove();
- } else if (entry.getValue() instanceof Map) {
- @SuppressWarnings("unchecked")
- Map<String, Object> embedded = (Map<String, Object>) entry.getValue();
- removeComments(embedded);
- } else if (entry.getValue() instanceof Collection) {
- Collection<?> embedded = (Collection<?>) entry.getValue();
- removeComments(embedded);
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private void removeComments(Collection<?> embedded) {
- for (Object el : embedded) {
- if (el instanceof Collection) {
- removeComments((Collection<?>) el);
- } else if (el instanceof Map) {
- removeComments((Map<String, Object>) el);
- }
- }
- }
-
- protected String getProperty(final Map<String, Object> map, final String key) throws IOException {
- final Object val = map.get(key);
- if ( val != null ) {
- checkType(key, val, String.class);
- return val.toString();
- }
- return null;
- }
-
- /**
- * Read the bundles / start levels section
- * @param map The map describing the feature
- * @param container The bundles container
- * @param configContainer The configurations container
- * @throws IOException If the json is invalid.
- */
- protected void readBundles(
- final Map<String, Object> map,
- final Bundles container,
- final Configurations configContainer) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_BUNDLES)) {
- final Object bundlesObj = map.get(JSONConstants.FEATURE_BUNDLES);
- checkType(JSONConstants.FEATURE_BUNDLES, bundlesObj, List.class);
-
- final List<Artifact> list = new ArrayList<>();
- readArtifacts(JSONConstants.FEATURE_BUNDLES, "bundle", list, bundlesObj, configContainer);
-
- for(final Artifact a : list) {
- Artifact sameFound = container.getSame(a.getId());
- if ( sameFound != null) {
- String str1 = a.getMetadata().get("run-modes");
- String str2 = sameFound.getMetadata().get("run-modes");
-
- if (str1 == null ? str2 == null : str1.equals(str2)) {
- throw new IOException(exceptionPrefix + "Duplicate bundle " + a.getId().toMvnId());
- }
- }
- try {
- // check start order
- a.getStartOrder();
- } catch ( final IllegalArgumentException nfe) {
- throw new IOException(exceptionPrefix + "Illegal start order '" + a.getMetadata().get(Artifact.KEY_START_ORDER) + "'");
- }
- container.add(a);
- }
- }
- }
-
- protected void readArtifacts(final String section,
- final String artifactType,
- final List<Artifact> artifacts,
- final Object listObj,
- final Configurations container)
- throws IOException {
- checkType(section, listObj, List.class);
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>) listObj;
- for(final Object entry : list) {
- final Artifact artifact;
- checkType(artifactType, entry, Map.class, String.class);
- if ( entry instanceof String ) {
- artifact = new Artifact(ArtifactId.parse(handleResolveVars(entry).toString()));
- } else {
- @SuppressWarnings("unchecked")
- final Map<String, Object> bundleObj = (Map<String, Object>) entry;
- if ( !bundleObj.containsKey(JSONConstants.ARTIFACT_ID) ) {
- throw new IOException(exceptionPrefix + " " + artifactType + " is missing required artifact id");
- }
- checkType(artifactType + " " + JSONConstants.ARTIFACT_ID, bundleObj.get(JSONConstants.ARTIFACT_ID), String.class);
- final ArtifactId id = ArtifactId.parse(handleResolveVars(bundleObj.get(JSONConstants.ARTIFACT_ID)).toString());
-
- artifact = new Artifact(id);
- for(final Map.Entry<String, Object> metadataEntry : bundleObj.entrySet()) {
- final String key = metadataEntry.getKey();
- if ( JSONConstants.ARTIFACT_KNOWN_PROPERTIES.contains(key) ) {
- continue;
- }
- checkType(artifactType + " metadata " + key, metadataEntry.getValue(), String.class, Number.class, Boolean.class);
- artifact.getMetadata().put(key, metadataEntry.getValue().toString());
- }
- if ( bundleObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
- checkType(artifactType + " configurations", bundleObj.get(JSONConstants.FEATURE_CONFIGURATIONS), Map.class);
- List<Configuration> bundleConfigs = addConfigurations(bundleObj, artifact, container);
- artifact.getMetadata().put(JSONConstants.FEATURE_CONFIGURATIONS, bundleConfigs);
- }
- }
- artifacts.add(artifact);
- }
- }
-
- /** Substitutes variables that need to be specified before the resolver executes.
- * These are variables in features, artifacts (such as bundles), requirements
- * and capabilities.
- * @param val The value that may contain a variable.
- * @return The value with the variable substitiuted.
- */
- protected Object handleResolveVars(Object val) {
- // No variable substitution at this level, but subclasses can add this in
- return val;
- }
-
- /** Substitutes variables that need to be substituted at launch time.
- * These are all variables that are not needed by the resolver.
- * @param val The value that may contain a variable.
- * @return The value with the variable substitiuted.
- */
- protected Object handleLaunchVars(Object val) {
- // No variable substitution at this level, but subclasses can add this in
- return val;
- }
-
- protected List<Configuration> addConfigurations(final Map<String, Object> map,
- final Artifact artifact,
- final Configurations container) throws IOException {
- final JSONUtil.Report report = new JSONUtil.Report();
- @SuppressWarnings("unchecked")
- final List<Config> configs = JSONUtil.readConfigurationsJSON(new TypeConverter(null),
- 0, "", (Map<String, ?>)map.get(JSONConstants.FEATURE_CONFIGURATIONS), report);
- if ( !report.errors.isEmpty() || !report.warnings.isEmpty() ) {
- final StringBuilder builder = new StringBuilder(exceptionPrefix);
- builder.append("Errors in configurations:");
- for(final String w : report.warnings) {
- builder.append("\n");
- builder.append(w);
- }
- for(final String e : report.errors) {
- builder.append("\n");
- builder.append(e);
- }
- throw new IOException(builder.toString());
- }
-
- List<Configuration> newConfigs = new ArrayList<>();
- for(final Config c : configs) {
- final int pos = c.getPid().indexOf('~');
- final Configuration config;
- if ( pos != -1 ) {
- config = new Configuration(c.getPid().substring(0, pos), c.getPid().substring(pos + 1));
- } else {
- config = new Configuration(c.getPid());
- }
- final Enumeration<String> keyEnum = c.getProperties().keys();
- while ( keyEnum.hasMoreElements() ) {
- final String key = keyEnum.nextElement();
- if ( key.startsWith(":configurator:") ) {
- throw new IOException(exceptionPrefix + "Configuration must not define configurator property " + key);
- }
- final Object val = c.getProperties().get(key);
- config.getProperties().put(key, handleLaunchVars(val));
- }
- if ( config.getProperties().get(Configuration.PROP_ARTIFACT) != null ) {
- throw new IOException(exceptionPrefix + "Configuration must not define property " + Configuration.PROP_ARTIFACT);
- }
- if ( artifact != null ) {
- config.getProperties().put(Configuration.PROP_ARTIFACT, artifact.getId().toMvnId());
- }
- for(final Configuration current : container) {
- if ( current.equals(config) ) {
- throw new IOException(exceptionPrefix + "Duplicate configuration " + config);
- }
- }
- container.add(config);
- newConfigs.add(config);
- }
- return newConfigs;
- }
-
-
- protected void readConfigurations(final Map<String, Object> map,
- final Configurations container) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
- checkType(JSONConstants.FEATURE_CONFIGURATIONS, map.get(JSONConstants.FEATURE_CONFIGURATIONS), Map.class);
- addConfigurations(map, null, container);
- }
- }
-
- protected void readFrameworkProperties(final Map<String, Object> map,
- final KeyValueMap container) throws IOException {
- if ( map.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
- final Object propsObj= map.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
- checkType(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propsObj, Map.class);
-
- @SuppressWarnings("unchecked")
- final Map<String, Object> props = (Map<String, Object>) propsObj;
- for(final Map.Entry<String, Object> entry : props.entrySet()) {
- checkType("framework property value", entry.getValue(), String.class, Boolean.class, Number.class);
- if ( container.get(entry.getKey()) != null ) {
- throw new IOException(this.exceptionPrefix + "Duplicate framework property " + entry.getKey());
- }
- container.put(entry.getKey(), handleLaunchVars(entry.getValue()).toString());
- }
-
- }
- }
-
- protected void readExtensions(final Map<String, Object> map,
- final List<String> keywords,
- final Extensions container,
- final Configurations configContainer) throws IOException {
- final Set<String> keySet = new HashSet<>(map.keySet());
- keySet.removeAll(keywords);
- // the remaining keys are considered extensions!
- for(final String key : keySet) {
- final int pos = key.indexOf(':');
- final String postfix = pos == -1 ? null : key.substring(pos + 1);
- final int sep = (postfix == null ? key.indexOf('|') : postfix.indexOf('|'));
- final String name;
- final String type;
- final String optional;
- if ( pos == -1 ) {
- type = ExtensionType.ARTIFACTS.name();
- if ( sep == -1 ) {
- name = key;
- optional = Boolean.FALSE.toString();
- } else {
- name = key.substring(0, sep);
- optional = key.substring(sep + 1);
- }
- } else {
- name = key.substring(0, pos);
- if ( sep == -1 ) {
- type = postfix;
- optional = Boolean.FALSE.toString();
- } else {
- type = postfix.substring(0, sep);
- optional = postfix.substring(sep + 1);
- }
- }
- if ( JSONConstants.APP_KNOWN_PROPERTIES.contains(name) ) {
- throw new IOException(this.exceptionPrefix + "Extension is using reserved name : " + name);
- }
- if ( JSONConstants.FEATURE_KNOWN_PROPERTIES.contains(name) ) {
- throw new IOException(this.exceptionPrefix + "Extension is using reserved name : " + name);
- }
- if ( container.getByName(name) != null ) {
- throw new IOException(exceptionPrefix + "Duplicate extension with name " + name);
- }
-
- final ExtensionType extType = ExtensionType.valueOf(type);
- final boolean opt = Boolean.valueOf(optional).booleanValue();
-
- final Extension ext = new Extension(extType, name, opt);
- final Object value = map.get(key);
- switch ( extType ) {
- case ARTIFACTS : final List<Artifact> list = new ArrayList<>();
- readArtifacts("Extension " + name, "artifact", list, value, configContainer);
- for(final Artifact a : list) {
- if ( ext.getArtifacts().contains(a) ) {
- throw new IOException(exceptionPrefix + "Duplicate artifact in extension " + name + " : " + a.getId().toMvnId());
- }
- ext.getArtifacts().add(a);
- }
- break;
- case JSON : checkType("JSON Extension " + name, value, Map.class, List.class);
- final JsonStructure struct = build(value);
- try ( final StringWriter w = new StringWriter()) {
- final JsonWriter jw = Json.createWriter(w);
- jw.write(struct);
- w.flush();
- ext.setJSON(w.toString());
- }
- break;
- case TEXT : checkType("Text Extension " + name, value, String.class, List.class);
- if ( value instanceof String ) {
- // string
- ext.setText(value.toString());
- } else {
- // list (array of strings)
- @SuppressWarnings("unchecked")
- final List<Object> l = (List<Object>)value;
- final StringBuilder sb = new StringBuilder();
- for(final Object o : l) {
- checkType("Text Extension " + name + ", value " + o, o, String.class);
- sb.append(o.toString());
- sb.append('\n');
- }
- ext.setText(sb.toString());
- }
- break;
- }
-
- container.add(ext);
- }
- }
-
- private JsonStructure build(final Object value) {
- if ( value instanceof List ) {
- @SuppressWarnings("unchecked")
- final List<Object> list = (List<Object>)value;
- final JsonArrayBuilder builder = Json.createArrayBuilder();
- for(final Object obj : list) {
- if ( obj instanceof String ) {
- builder.add(obj.toString());
- } else if ( obj instanceof Long ) {
- builder.add((Long)obj);
- } else if ( obj instanceof Double ) {
- builder.add((Double)obj);
- } else if (obj instanceof Boolean ) {
- builder.add((Boolean)obj);
- } else if ( obj instanceof Map ) {
- builder.add(build(obj));
- } else if ( obj instanceof List ) {
- builder.add(build(obj));
- }
-
- }
- return builder.build();
- } else if ( value instanceof Map ) {
- @SuppressWarnings("unchecked")
- final Map<String, Object> map = (Map<String, Object>)value;
- final JsonObjectBuilder builder = Json.createObjectBuilder();
- for(final Map.Entry<String, Object> entry : map.entrySet()) {
- if ( entry.getValue() instanceof String ) {
- builder.add(entry.getKey(), entry.getValue().toString());
- } else if ( entry.getValue() instanceof Long ) {
- builder.add(entry.getKey(), (Long)entry.getValue());
- } else if ( entry.getValue() instanceof Double ) {
- builder.add(entry.getKey(), (Double)entry.getValue());
- } else if ( entry.getValue() instanceof Boolean ) {
- builder.add(entry.getKey(), (Boolean)entry.getValue());
- } else if ( entry.getValue() instanceof Map ) {
- builder.add(entry.getKey(), build(entry.getValue()));
- } else if ( entry.getValue() instanceof List ) {
- builder.add(entry.getKey(), build(entry.getValue()));
- }
- }
- return builder.build();
- }
- return null;
- }
-
- /**
- * Check if the value is one of the provided types
- * @param key A key for the error message
- * @param val The value to check
- * @param types The allowed types
- * @throws IOException If the val is not of the specified types
- */
- protected void checkType(final String key, final Object val, Class<?>...types) throws IOException {
- boolean valid = false;
- for(final Class<?> c : types) {
- if ( c.isInstance(val) ) {
- valid = true;
- break;
- }
- }
- if ( !valid ) {
- throw new IOException(this.exceptionPrefix + "Key " + key + " is not one of the allowed types " + Arrays.toString(types) + " : " + val.getClass());
- }
- }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
deleted file mode 100644
index ff502af..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
+++ /dev/null
@@ -1,259 +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.io.json;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.KeyValueMap;
-
-import java.io.StringReader;
-import java.lang.reflect.Array;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-
-/**
- * Common functionality for writing JSON
- */
-abstract class JSONWriterBase {
- protected void writeBundles(final JsonObjectBuilder ob,
- final Bundles bundles,
- final Configurations allConfigs) {
- // bundles
- if ( !bundles.isEmpty() ) {
- JsonArrayBuilder bundleArray = Json.createArrayBuilder();
-
- for(final Artifact artifact : bundles) {
- final Configurations cfgs = new Configurations();
- for(final Configuration cfg : allConfigs) {
- String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
- if (artifactProp != null) {
- if (artifactProp.startsWith("mvn:")) {
- // Change Maven URL to maven GAV syntax
- artifactProp = artifactProp.substring("mvn:".length());
- artifactProp = artifactProp.replace('/', ':');
- }
- if (artifact.getId().toMvnId().equals(artifactProp)) {
- cfgs.add(cfg);
- }
- }
- }
- KeyValueMap md = artifact.getMetadata();
- if ( md.isEmpty() && cfgs.isEmpty() ) {
- bundleArray.add(artifact.getId().toMvnId());
- } else {
- JsonObjectBuilder bundleObj = Json.createObjectBuilder();
- bundleObj.add(JSONConstants.ARTIFACT_ID, artifact.getId().toMvnId());
-
- if (md.get("start-level") == null) {
- String so = md.get("start-order");
- if (so != null) {
- md.put("start-level", so);
- }
- }
-
- Object runmodes = md.remove("runmodes");
- if (runmodes instanceof String) {
- md.put("run-modes", runmodes);
- }
-
- for(final Map.Entry<String, String> me : md) {
- bundleObj.add(me.getKey(), me.getValue());
- }
-
- writeConfigurations(bundleObj, cfgs);
-
- bundleArray.add(bundleObj.build());
- }
- }
- ob.add(JSONConstants.FEATURE_BUNDLES, bundleArray.build());
- }
- }
-
- /**
- * Write the list of configurations into a "configurations" element
- * @param ob The json generator
- * @param cfgs The list of configurations
- */
- protected void writeConfigurations(final JsonObjectBuilder ob, final Configurations cfgs) {
- if ( !cfgs.isEmpty() ) {
- ob.add(JSONConstants.FEATURE_CONFIGURATIONS,
- writeConfigurationsMap(cfgs));
- }
- }
-
- /**
- * Write the list of configurations into a "configurations" element
- * @param w The json generator
- * @param cfgs The list of configurations
- * @return
- */
- protected JsonObject writeConfigurationsMap(final Configurations cfgs) {
- JsonObjectBuilder configObj = Json.createObjectBuilder();
- for(final Configuration cfg : cfgs) {
- final String key;
- if ( cfg.isFactoryConfiguration() ) {
- key = cfg.getFactoryPid() + "~" + cfg.getName();
- } else {
- key = cfg.getPid();
- }
- JsonObjectBuilder cfgValObj = Json.createObjectBuilder();
-
- final Enumeration<String> e = cfg.getProperties().keys();
- while ( e.hasMoreElements() ) {
- final String name = e.nextElement();
- if ( Configuration.PROP_ARTIFACT.equals(name) ) {
- continue;
- }
-
- final Object val = cfg.getProperties().get(name);
-
- String typePostFix = null;
- final Object typeCheck;
- if ( val.getClass().isArray() ) {
- if ( Array.getLength(val) > 0 ) {
- typeCheck = Array.get(val, 0);
- } else {
- typeCheck = null;
- }
- } else {
- typeCheck = val;
- }
-
- if ( typeCheck instanceof Integer ) {
- typePostFix = ":Integer";
- } else if ( typeCheck instanceof Byte ) {
- typePostFix = ":Byte";
- } else if ( typeCheck instanceof Character ) {
- typePostFix = ":Character";
- } else if ( typeCheck instanceof Float ) {
- typePostFix = ":Float";
- }
-
- if ( val.getClass().isArray() ) {
- JsonArrayBuilder ab = Json.createArrayBuilder();
- for(int i=0; i<Array.getLength(val);i++ ) {
- final Object obj = Array.get(val, i);
- if ( typePostFix == null ) {
- if ( obj instanceof String ) {
- ab.add((String)obj);
- } else if ( obj instanceof Boolean ) {
- ab.add((Boolean)obj);
- } else if ( obj instanceof Long ) {
- ab.add((Long)obj);
- } else if ( obj instanceof Double ) {
- ab.add((Double)obj);
- }
- } else {
- ab.add(obj.toString());
- }
- }
- cfgValObj.add(name, ab.build());
- } else {
- if ( typePostFix == null ) {
- if ( val instanceof String ) {
- cfgValObj.add(name, (String)val);
- } else if ( val instanceof Boolean ) {
- cfgValObj.add(name, (Boolean)val);
- } else if ( val instanceof Long ) {
- cfgValObj.add(name, (Long)val);
- } else if ( val instanceof Double ) {
- cfgValObj.add(name, (Double)val);
- }
- } else {
- cfgValObj.add(name + typePostFix, val.toString());
- }
- }
- }
- configObj.add(key, cfgValObj.build());
- }
- return configObj.build();
- }
-
- protected void writeVariables(final JsonObjectBuilder ob, final KeyValueMap vars) {
- if ( !vars.isEmpty()) {
- JsonObjectBuilder varsObj = Json.createObjectBuilder();
- for (final Map.Entry<String, String> entry : vars) {
- varsObj.add(entry.getKey(), entry.getValue());
- }
- ob.add(JSONConstants.FEATURE_VARIABLES, varsObj.build());
- }
- }
-
- protected void writeFrameworkProperties(final JsonObjectBuilder ob, final KeyValueMap props) {
- // framework properties
- if ( !props.isEmpty() ) {
- JsonObjectBuilder propsObj = Json.createObjectBuilder();
- for(final Map.Entry<String, String> entry : props) {
- propsObj.add(entry.getKey(), entry.getValue());
- }
- ob.add(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propsObj.build());
- }
- }
-
- protected void writeExtensions(final JsonObjectBuilder ob,
- final List<Extension> extensions,
- final Configurations allConfigs) {
- for(final Extension ext : extensions) {
- final String key = ext.getName() + ":" + ext.getType().name() + "|" + ext.isOptional();
- if ( ext.getType() == ExtensionType.JSON ) {
- final JsonStructure struct;
- try ( final StringReader reader = new StringReader(ext.getJSON()) ) {
- struct = Json.createReader(reader).read();
- }
- ob.add(key, struct);
- } else if ( ext.getType() == ExtensionType.TEXT ) {
- ob.add(key, ext.getText());
- } else {
- JsonArrayBuilder extensionArr = Json.createArrayBuilder();
- for(final Artifact artifact : ext.getArtifacts()) {
- final Configurations artifactCfgs = new Configurations();
- for(final Configuration cfg : allConfigs) {
- final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
- if ( artifact.getId().toMvnId().equals(artifactProp) ) {
- artifactCfgs.add(cfg);
- }
- }
- if ( artifact.getMetadata().isEmpty() && artifactCfgs.isEmpty() ) {
- extensionArr.add(artifact.getId().toMvnId());
- } else {
- JsonObjectBuilder extObj = Json.createObjectBuilder();
- extObj.add(JSONConstants.ARTIFACT_ID, artifact.getId().toMvnId());
-
- for(final Map.Entry<String, String> me : artifact.getMetadata()) {
- extObj.add(me.getKey(), me.getValue());
- }
-
- writeConfigurations(ob, artifactCfgs);
- extensionArr.add(extObj.build());
- }
- }
- ob.add(key, extensionArr.build());
- }
- }
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
deleted file mode 100644
index ee6585f..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
+++ /dev/null
@@ -1,515 +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.io.json;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-// This class can be picked up from Felix Utils once it has been moved there. At that point
-// this class can be removed.
-class ManifestUtils {
- 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 {
- convertProvideCapabilities(
- normalizeCapabilityClauses(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);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- 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";
- }
- }
-
- 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 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;
- }
-
- 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;
- }
-
- /**
- * 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;
- }
-
- 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;
- }
- }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java
deleted file mode 100644
index 6b84931..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io.json;
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java
deleted file mode 100644
index 25e2f46..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io;
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java
deleted file mode 100644
index 5f250d7..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java
+++ /dev/null
@@ -1,55 +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.io.spi;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * The artifact provider is an extension point for providing artifacts
- * from different sources, like for example s3.
- */
-public interface ArtifactProvider {
-
- /**
- * The protocol name of the provider, e.g. "s3"
- * @return The protocol name.
- */
- String getProtocol();
-
- /**
- * Initialize the provider.
- * @param context The context
- * @throws IOException If the provider can't be initialized.
- */
- void init(ArtifactProviderContext context) throws IOException;
-
- /**
- * Shutdown the provider.
- */
- void shutdown();
-
- /**
- * Get a local file for the artifact URL.
- *
- * @param url Artifact url
- * @param relativeCachePath A relative path that can be used as a cache path
- * by the provider. The path does not start with a slash.
- * @return A file if the artifact exists or {@code null}
- */
- File getArtifact(String url, String relativeCachePath);
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java
deleted file mode 100644
index c837548..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java
+++ /dev/null
@@ -1,46 +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.io.spi;
-
-import java.io.File;
-
-/**
- * This is the context for the artifact providers
- */
-public interface ArtifactProviderContext {
-
- /**
- * Get the cache directory
- * @return The cache directory.
- */
- File getCacheDirectory();
-
- /**
- * Inform about an artifact found in the cache.
- */
- void incCachedArtifacts();
-
- /**
- * Inform about an artifact being downloaded
- */
- void incDownloadedArtifacts();
-
- /**
- * Inform about an artifact found locally.
- */
- void incLocalArtifacts();
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java
deleted file mode 100644
index b69692b..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io.spi;
-
-
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
deleted file mode 100644
index f89c40b..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
+++ /dev/null
@@ -1,102 +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.io;
-
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ArtifactManagerTest {
-
- private static final String METADATA = "<metadata modelVersion=\"1.1.0\">\n" +
- "<groupId>org.apache.sling.samples</groupId>\n" +
- "<artifactId>slingshot</artifactId>\n" +
- "<version>0-DEFAULT-SNAPSHOT</version>\n" +
- "<versioning>\n" +
- "<snapshot>\n" +
- "<timestamp>20160321.103951</timestamp>\n" +
- "<buildNumber>1</buildNumber>\n" +
- "</snapshot>\n" +
- "<lastUpdated>20160321103951</lastUpdated>\n" +
- "<snapshotVersions>\n" +
- "<snapshotVersion>\n" +
- "<extension>txt</extension>\n" +
- "<value>0-DEFAULT-20160321.103951-1</value>\n" +
- "<updated>20160321103951</updated>\n" +
- "</snapshotVersion>\n" +
- "<snapshotVersion>\n" +
- "<extension>pom</extension>\n" +
- "<value>0-DEFAULT-20160321.103951-1</value>\n" +
- "<updated>20160321103951</updated>\n" +
- "</snapshotVersion>\n" +
- "</snapshotVersions>\n" +
- "</versioning></metadata>";
-
- @Test public void testMetadataParsing() {
- final String version = ArtifactManager.getLatestSnapshot(METADATA);
- assertEquals("20160321.103951-1", version);
- }
-
- @Test public void testSnapshotHandling() throws IOException {
- final String REPO = "http://org.apache.sling";
- final ArtifactManagerConfig config = mock(ArtifactManagerConfig.class);
- when(config.getRepositoryUrls()).thenReturn(new String[] {REPO});
-
- final File metadataFile = mock(File.class);
- when(metadataFile.exists()).thenReturn(true);
- when(metadataFile.getPath()).thenReturn("/maven-metadata.xml");
-
- final File artifactFile = mock(File.class);
- when(artifactFile.exists()).thenReturn(true);
-
- final ArtifactProvider provider = mock(ArtifactProvider.class);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(null);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml", "org.apache.sling/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml")).thenReturn(metadataFile);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-20160321.103951-1.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(artifactFile);
-
- final Map<String, ArtifactProvider> providers = new HashMap<>();
- providers.put("*", provider);
-
- final ArtifactManager mgr = new ArtifactManager(config, providers) {
-
- @Override
- protected String getFileContents(final ArtifactHandler handler) throws IOException {
- final String path = handler.getFile().getPath();
- if ( "/maven-metadata.xml".equals(path) ) {
- return METADATA;
- }
- return super.getFileContents(handler);
- }
- };
-
- final ArtifactHandler handler = mgr.getArtifactHandler("mvn:group/artifact/1.0.0-SNAPSHOT/txt");
- assertNotNull(handler);
- assertEquals(artifactFile, handler.getFile());
- }
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
deleted file mode 100644
index 08ce172..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
+++ /dev/null
@@ -1,50 +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.io;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.sling.feature.io.IOUtils;
-import org.junit.Test;
-
-public class IOUtilsTest {
-
- @Test public void testFileSort() {
- final String[] files = new String[] {
- "/different/path/app.json",
- "/path/to/base.json",
- "/path/to/feature.json",
- "/path/to/amode/feature.json",
- "/path/to/later/feature.json",
- "http://sling.apache.org/features/one.json",
- "http://sling.apache.org/features/two.json",
- "http://sling.apache.org/features/amode/feature.json"
- };
-
- final List<String> l = new ArrayList<>(Arrays.asList(files));
- Collections.sort(l, IOUtils.FEATURE_PATH_COMP);
- for(int i=0; i<files.length; i++) {
- assertEquals(files[i], l.get(i));
- }
- }
-
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java
deleted file mode 100644
index 47ab83b..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java
+++ /dev/null
@@ -1,222 +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.io.json;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.apache.sling.feature.KeyValueMap;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.junit.Test;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class FeatureJSONReaderTest {
-
- @Test public void testRead() throws Exception {
- final Feature feature = U.readFeature("test");
- assertNotNull(feature);
- assertNotNull(feature.getId());
- assertEquals("org.apache.sling", feature.getId().getGroupId());
- assertEquals("test-feature", feature.getId().getArtifactId());
- assertEquals("1.1", feature.getId().getVersion());
- assertEquals("jar", feature.getId().getType());
- assertNull(feature.getId().getClassifier());
-
- assertEquals(2, feature.getConfigurations().size());
- final Configuration cfg1 = U.findConfiguration(feature.getConfigurations(), "my.pid");
- assertEquals(7, cfg1.getProperties().get("number"));
- final Configuration cfg2 = U.findFactoryConfiguration(feature.getConfigurations(), "my.factory.pid", "name");
- assertEquals("yeah", cfg2.getProperties().get("a.value"));
-
- assertEquals(3, feature.getCapabilities().size());
- Capability capability = U.findCapability(feature.getCapabilities(),"osgi.service");
- assertNotNull(capability.getAttributes().get("objectClass"));
-
- assertEquals(Arrays.asList("org.osgi.service.http.runtime.HttpServiceRuntime"), capability.getAttributes().get("objectClass"));
-
- }
-
- @Test public void testReadWithVariablesResolve() throws Exception {
- final Feature feature = U.readFeature("test2");
-
- List<Include> includes = feature.getIncludes();
- assertEquals(1, includes.size());
- Include include = includes.get(0);
- assertEquals("org.apache.sling:sling:9", include.getId().toMvnId());
-
- List<Requirement> reqs = feature.getRequirements();
- Requirement req = reqs.get(0);
- assertEquals("osgi.contract", req.getNamespace());
- assertEquals("(&(osgi.contract=JavaServlet)(&(version>=3.0)(!(version>=4.0))))",
- req.getDirectives().get("filter"));
-
- List<Capability> caps = feature.getCapabilities();
- Capability cap = null;
- for (Capability c : caps) {
- if ("osgi.service".equals(c.getNamespace())) {
- cap = c;
- break;
- }
- }
- assertEquals(Collections.singletonList("org.osgi.service.http.runtime.HttpServiceRuntime"),
- cap.getAttributes().get("objectClass"));
- assertEquals("org.osgi.service.http.runtime",
- cap.getDirectives().get("uses"));
- // TODO this seems quite broken: fix!
- // assertEquals("org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto",
- // cap.getDirectives().get("uses"));
-
- KeyValueMap fwProps = feature.getFrameworkProperties();
- assertEquals("Framework property substitution should not happen at resolve time",
- "${something}", fwProps.get("brave"));
-
- Bundles bundles = feature.getBundles();
- ArtifactId id = new ArtifactId("org.apache.sling", "foo-xyz", "1.2.3", null, null);
- assertTrue(bundles.containsExact(id));
- ArtifactId id2 = new ArtifactId("org.apache.sling", "bar-xyz", "1.2.3", null, null);
- assertTrue(bundles.containsExact(id2));
-
- Configurations configurations = feature.getConfigurations();
- Configuration config = configurations.getConfiguration("my.pid2");
- Dictionary<String, Object> props = config.getProperties();
- assertEquals("Configuration substitution should not happen at resolve time",
- "aa${ab_config}", props.get("a.value"));
- assertEquals("${ab_config}bb", props.get("b.value"));
- assertEquals("c${c_config}c", props.get("c.value"));
- }
-
- @Test public void testReadWithVariablesLaunch() throws Exception {
- final Feature feature = U.readFeature("test3", SubstituteVariables.LAUNCH);
-
- List<Include> includes = feature.getIncludes();
- assertEquals(1, includes.size());
- Include include = includes.get(0);
- assertEquals("Include substitution should not happen at launch time",
- "${sling.gid}:sling:10", include.getId().toMvnId());
-
- List<Requirement> reqs = feature.getRequirements();
- Requirement req = reqs.get(0);
- assertEquals("Requirement substitution should not happen at launch time",
- "osgi.${ns}", req.getNamespace());
- assertEquals("Requirement substitution should not happen at launch time",
- "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))",
- req.getDirectives().get("filter"));
- assertEquals("There should be 1 directive, comments should be ignored",
- 1, req.getDirectives().size());
-
- List<Capability> caps = feature.getCapabilities();
- Capability cap = null;
- for (Capability c : caps) {
- if ("osgi.${svc}".equals(c.getNamespace())) {
- cap = c;
- break;
- }
- }
- assertEquals("Capability substitution should not happen at launch time",
- Collections.singletonList("org.osgi.${svc}.http.runtime.HttpServiceRuntime"),
- cap.getAttributes().get("objectClass"));
- assertEquals("There should be 1 attribute, comments should be ignored",
- 1, cap.getAttributes().size());
-
- KeyValueMap fwProps = feature.getFrameworkProperties();
- assertEquals("something", fwProps.get("brave"));
- assertEquals("There should be 3 framework properties, comments not included",
- 3, fwProps.size());
-
- Configurations configurations = feature.getConfigurations();
- assertEquals("There should be 2 configurations, comments not included",
- 2, configurations.size());
-
- Configuration config1 = configurations.getConfiguration("my.pid2");
- for (Enumeration<?> en = config1.getProperties().elements(); en.hasMoreElements(); ) {
- assertFalse("The comment should not show up in the configuration",
- "comment".equals(en.nextElement()));
- }
-
- Configuration config2 = configurations.getConfiguration("my.pid2");
- Dictionary<String, Object> props = config2.getProperties();
- assertEquals("aaright!", props.get("a.value"));
- assertEquals("right!bb", props.get("b.value"));
- assertEquals("creally?c", props.get("c.value"));
- assertEquals("The variable definition looks like a variable definition, this escaping mechanism should work",
- "${refvar}", props.get("refvar"));
- }
-
- @Test public void testReadRepoInitExtension() throws Exception {
- Feature feature = U.readFeature("repoinit");
- Extensions extensions = feature.getExtensions();
- assertEquals(1, extensions.size());
- Extension ext = extensions.iterator().next();
- assertEquals("some repo init\ntext", ext.getText());
- }
-
- @Test public void testReadRepoInitExtensionArray() throws Exception {
- Feature feature = U.readFeature("repoinit2");
- Extensions extensions = feature.getExtensions();
- assertEquals(1, extensions.size());
- Extension ext = extensions.iterator().next();
- assertEquals("some repo init\ntext\n", ext.getText());
- }
-
- @Test public void testHandleVars() throws Exception {
- FeatureJSONReader reader = new FeatureJSONReader(null, null, SubstituteVariables.LAUNCH);
- Map<String, Object> vars = new HashMap<>();
- vars.put("var1", "bar");
- vars.put("varvariable", "${myvar}");
- vars.put("var.2", "2");
- setPrivateField(reader, "variables", vars);
-
- assertEquals("foobarfoo", reader.handleLaunchVars("foo${var1}foo"));
- assertEquals("barbarbar", reader.handleLaunchVars("${var1}${var1}${var1}"));
- assertEquals("${}test${myvar}2", reader.handleLaunchVars("${}test${varvariable}${var.2}"));
- try {
- reader.handleLaunchVars("${undefined}");
- fail("Should throw an exception on the undefined variable");
- } catch (IllegalStateException ise) {
- // good
- }
- }
-
- private void setPrivateField(Object obj, String name, Object value) throws Exception {
- Field field = obj.getClass().getDeclaredField(name);
- field.setAccessible(true);
- field.set(obj, value);
- }
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
deleted file mode 100644
index 81db5e6..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
+++ /dev/null
@@ -1,50 +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.io.json;
-
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.junit.Test;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-
-public class FeatureJSONWriterTest {
-
- @Test public void testRead() throws Exception {
- final Feature f = U.readFeature("test");
- final Feature rf;
- try ( final StringWriter writer = new StringWriter() ) {
- FeatureJSONWriter.write(writer, f);
- try ( final StringReader reader = new StringReader(writer.toString()) ) {
- rf = FeatureJSONReader.read(reader, null, SubstituteVariables.RESOLVE);
- }
- }
- assertEquals(f.getId(), rf.getId());
- assertEquals("org.apache.sling:test-feature:1.1", rf.getId().toMvnId());
- assertEquals("The feature description", rf.getDescription());
-
- assertEquals(Arrays.asList("org.osgi.service.http.runtime.HttpServiceRuntime"),
- U.findCapability(rf.getCapabilities(), "osgi.service").getAttributes().get("objectClass"));
- }
-
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java
deleted file mode 100644
index 904f158..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java
+++ /dev/null
@@ -1,89 +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.io.json;
-
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.List;
-
-import static org.junit.Assert.fail;
-
-/** Test utilities */
-public class U {
-
- /** Read the feature from the provided resource
- */
- public static Feature readFeature(final String name) throws Exception {
- return readFeature(name, SubstituteVariables.RESOLVE);
- }
-
- public static Feature readFeature(final String name, final SubstituteVariables phase) throws Exception {
- try ( final Reader reader = new InputStreamReader(U.class.getResourceAsStream("/features/" + name + ".json"),
- "UTF-8") ) {
- return FeatureJSONReader.read(reader, name, phase);
- }
- }
-
- public static Configuration findConfiguration(final List<Configuration> cfgs, final String pid) {
- for(final Configuration c : cfgs) {
- if ( !c.isFactoryConfiguration() && pid.equals(c.getPid()) ) {
- return c;
- }
- }
- fail("Configuration not found " + pid);
- return null;
- }
-
- public static Configuration findFactoryConfiguration(final List<Configuration> cfgs, final String factoryid, final String name) {
- for(final Configuration c : cfgs) {
- if ( c.isFactoryConfiguration() && factoryid.equals(c.getFactoryPid()) && name.equals(c.getName())) {
- return c;
- }
- }
- fail("Factory Configuration not found " + factoryid + "~" + name);
- return null;
- }
-
- public static Capability findCapability(List<Capability> capabilities, final String namespace) {
- for (Capability capability : capabilities) {
- if (capability.getNamespace().equals(namespace)) {
- return capability;
- }
- }
-
- fail(String.format("No Capability with namespace '%s' found", namespace));
- return null;
- }
-
- public static Requirement findRequirement(List<Requirement> requirements, final String namespace) {
- for (Requirement requirement : requirements) {
- if (requirement.getNamespace().equals(namespace)) {
- return requirement;
- }
- }
-
- fail(String.format("No Requirement with namespace '%s' found", namespace));
- return null;
- }
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/repoinit.json b/featuremodel/feature-io/src/test/resources/features/repoinit.json
deleted file mode 100644
index 2177702..0000000
--- a/featuremodel/feature-io/src/test/resources/features/repoinit.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "id": "test/repoinit/1.0.0",
- "repoinit:TEXT|false": "some repo init\ntext"
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/repoinit2.json b/featuremodel/feature-io/src/test/resources/features/repoinit2.json
deleted file mode 100644
index beef986..0000000
--- a/featuremodel/feature-io/src/test/resources/features/repoinit2.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "id": "test/repoinit2/1.0.0",
- "repoinit:TEXT|false": [
- "some repo init",
- "text"
- ]
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/test.json b/featuremodel/feature-io/src/test/resources/features/test.json
deleted file mode 100644
index 8ae346c..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "id" : "org.apache.sling/test-feature/1.1",
- "description": "The feature description",
-
- "includes" : [
- {
- "id" : "org.apache.sling/sling/9",
- "removals" : {
- "configurations" : [
- ],
- "bundles" : [
- ],
- "framework-properties" : [
- ]
- }
- }
- ],
- "requirements" : [
- {
- "namespace" : "osgi.contract",
- "directives" : {
- "filter" : "(&(osgi.contract=JavaServlet)(&(version>=3.0)(!(version>=4.0))))"
- }
- }
- ],
- "capabilities" : [
- {
- "namespace" : "osgi.implementation",
- "attributes" : {
- "osgi.implementation" : "osgi.http",
- "version:Version" : "1.1"
- },
- "directives" : {
- "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
- }
- },
- {
- "namespace" : "osgi.service",
- "attributes" : {
- "objectClass:List<String>" : "org.osgi.service.http.runtime.HttpServiceRuntime"
- },
- "directives" : {
- "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
- }
- },
- {
- "namespace" : "osgi.contract",
- "attributes" : {
- "osgi.contract" : "JavaServlet",
- "osgi.implementation" : "osgi.http",
- "version:Version" : "3.1"
- },
- "directives" : {
- "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
- }
- }
- ],
- "framework-properties" : {
- "foo" : 1,
- "brave" : "something",
- "org.apache.felix.scr.directory" : "launchpad/scr"
- },
- "bundles" :[
- {
- "id" : "org.apache.sling/oak-server/1.0.0",
- "hash" : "4632463464363646436",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/application-bundle/2.0.0",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/another-bundle/2.1.0",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/foo-xyz/1.2.3",
- "start-order" : 2
- }
- ],
- "configurations" : {
- "my.pid" : {
- "foo" : 5,
- "bar" : "test",
- "number:Integer" : 7
- },
- "my.factory.pid~name" : {
- "a.value" : "yeah"
- }
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/src/test/resources/features/test2.json b/featuremodel/feature-io/src/test/resources/features/test2.json
deleted file mode 100644
index 0e5c1c6..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test2.json
+++ /dev/null
@@ -1,107 +0,0 @@
-{
- "model-version": "1",
- "id" : "org.apache.sling/test2/1.1",
-
- "variables": {
- "common.version": "1.2.3",
- "contract.name": "JavaServlet",
- "ab_config": "right!",
- "c_config": "really?",
- "includever": "9",
- "ns": "contract",
- "sling.gid": "org.apache.sling",
- "something": "something",
- "svc": "service"
- },
-
- "includes" : [
- {
- "id" : "${sling.gid}/sling/${includever}",
- "removals" : {
- "configurations" : [
- ],
- "bundles" : [
- ],
- "framework-properties" : [
- ]
- }
- }
- ],
- "requirements" : [
- {
- "namespace" : "osgi.${ns}",
- "directives" : {
- "filter" : "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))"
- }
- }
- ],
- "capabilities" : [
- {
- "namespace" : "osgi.implementation",
- "attributes" : {
- "osgi.implementation" : "osgi.http",
- "version:Version" : "1.1"
- },
- "directives" : {
- "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
- }
- },
- {
- "namespace" : "osgi.${svc}",
- "attributes" : {
- "objectClass:List<String>" : "org.osgi.${svc}.http.runtime.HttpServiceRuntime"
- },
- "directives" : {
- "uses" : "org.osgi.${svc}.http.runtime,org.osgi.${svc}.http.runtime.dto"
- }
- },
- {
- "namespace" : "osgi.contract",
- "attributes" : {
- "osgi.contract" : "JavaServlet",
- "osgi.implementation" : "osgi.http",
- "version:Version" : "3.1"
- },
- "directives" : {
- "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
- }
- }
- ],
- "framework-properties" : {
- "foo" : 1,
- "brave" : "${something}",
- "org.apache.felix.scr.directory" : "launchpad/scr"
- },
- "bundles" :[
- {
- "id" : "org.apache.sling/oak-server/1.0.0",
- "hash" : "4632463464363646436",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/application-bundle/2.0.0",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/another-bundle/2.1.0",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/foo-xyz/${common.version}",
- "start-order" : 2
- },
- "org.apache.sling/bar-xyz/${common.version}"
- ],
- "configurations" : {
- "my.pid" : {
- "foo" : 5,
- "bar" : "test",
- "number:Integer" : 7
- },
- "my.pid2" : {
- "a.value" : "aa${ab_config}",
- "b.value" : "${ab_config}bb",
- "c.value" : "c${c_config}c"
- }
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/src/test/resources/features/test3.json b/featuremodel/feature-io/src/test/resources/features/test3.json
deleted file mode 100644
index 630239d..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test3.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "#": "A comment",
- "# array": ["array", "comment"],
- "id": "org.apache.sling/test2/1.1",
-
- "variables": {
- "common.version": "1.2.3",
- "contract.name": "JavaServlet",
- "ab_config": "right!",
- "c_config": "really?",
- "includever": "9",
- "ns": "contract",
- "sling.gid": "org.apache.sling",
- "something": "something",
- "svc": "service",
- "refvar": "${refvar}"
- },
-
- "includes" : [
- {
- "#": "comment",
- "id" : "${sling.gid}/sling/10",
- "removals" : {
- "configurations" : [
- ],
- "bundles" : [
- ],
- "#": "comment",
- "framework-properties" : [
- ]
- }
- }
- ],
- "requirements" : [
- {
- "namespace" : "osgi.${ns}",
- "#": "comment",
- "directives" : {
- "#": "comment",
- "filter" : "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))"
- }
- }
- ],
- "capabilities" : [
- {
- "#": "comment",
- "namespace" : "osgi.implementation",
- "attributes" : {
- "osgi.implementation" : "osgi.http",
- "version:Version" : "1.1"
- },
- "directives" : {
- "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
- }
- },
- {
- "namespace" : "osgi.${svc}",
- "attributes" : {
- "#": "comment",
- "objectClass:List<String>" : "org.osgi.${svc}.http.runtime.HttpServiceRuntime"
- },
- "directives" : {
- "uses" : "org.osgi.${svc}.http.runtime,org.osgi.${svc}.http.runtime.dto"
- }
- },
- {
- "namespace" : "osgi.contract",
- "attributes" : {
- "osgi.contract" : "JavaServlet",
- "osgi.implementation" : "osgi.http",
- "version:Version" : "3.1"
- },
- "directives" : {
- "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
- }
- }
- ],
- "framework-properties" : {
- "# one": "comment",
- "# two": "comment",
- "foo" : 1,
- "brave" : "${something}",
- "org.apache.felix.scr.directory" : "launchpad/scr"
- },
- "bundles" :[
- {
- "id" : "org.apache.sling/oak-server/1.0.0",
- "hash" : "4632463464363646436",
- "start-order" : 1,
- "#": "comment"
- },
- {
- "id" : "org.apache.sling/application-bundle/2.0.0",
- "start-order" : 1
- },
- {
- "id" : "org.apache.sling/another-bundle/2.1.0",
- "start-order" : 1
- }
- ],
- "configurations" : {
- "#": "comment",
- "my.pid" : {
- "#": "comment",
- "foo" : 5,
- "bar" : "test",
- "number:Integer" : 7
- },
- "my.pid2" : {
- "a.value" : "aa${ab_config}",
- "b.value" : "${ab_config}bb",
- "c.value" : "c${c_config}c",
- "refvar": "${refvar}"
- }
- }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-karaf/pom.xml b/featuremodel/feature-karaf/pom.xml
deleted file mode 100644
index 6204869..0000000
--- a/featuremodel/feature-karaf/pom.xml
+++ /dev/null
@@ -1,78 +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.karaf</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <name>Apache Sling Feature Karaf</name>
- <description>
- A feature describes an OSGi system
- </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-karaf</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-karaf</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-karaf</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- </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.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>
- </dependencies>
-</project>
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java
deleted file mode 100644
index e29e7a9..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java
+++ /dev/null
@@ -1,87 +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.karaf;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.Map;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.io.json.ConfigurationJSONWriter;
-import org.osgi.framework.Constants;
-
-
-public class ConfigurationUtil {
-
- public static final String REQUIRE_CONFIGURATOR_CAPABILITY =
- "osgi.extender;filter:=\"(&(osgi.extender=osgi.configurator)(version>=1.0)(!(version>=2.0)))\"";
-
- /**
- * Create a bundle containing the configurations to be processed the
- * OSGi configurator
- *
- * @param os The output stream. The stream is not closed
- * @param configurations The list of configurations
- * @param symbolicName The symbolic name for the generated bundle
- * @param version The version for the generated bundle
- * @param additionalAttributes Optional additional attributes for the Manifest.
- * @throws IOException If something goes wrong
- */
- public static void createConfiguratorBundle(final OutputStream os,
- final Configurations configurations,
- final String symbolicName,
- final String version,
- final Map<String, String> additionalAttributes)
- throws IOException {
-
- final Manifest mf = new Manifest();
- mf.getMainAttributes().putValue("Manifest-Version", "1.0");
- mf.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
- mf.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
- mf.getMainAttributes().putValue(Constants.BUNDLE_VERSION, version);
- mf.getMainAttributes().putValue(Constants.BUNDLE_VENDOR, "The Apache Software Foundation");
- mf.getMainAttributes().putValue(Constants.REQUIRE_CAPABILITY, REQUIRE_CONFIGURATOR_CAPABILITY);
-
- if ( additionalAttributes != null ) {
- for(final Map.Entry<String, String> entry : additionalAttributes.entrySet()) {
- if ( Constants.REQUIRE_CAPABILITY.equals(entry.getKey())
- && !entry.getValue().contains("osgi.extender=osgi.configurator")) {
- mf.getMainAttributes().putValue(entry.getKey(), entry.getValue() + "," + REQUIRE_CONFIGURATOR_CAPABILITY);
- } else {
- mf.getMainAttributes().putValue(entry.getKey(), entry.getValue());
- }
- }
- }
-
- final JarOutputStream jos = new JarOutputStream(os, mf);
-
- final ZipEntry ze = new ZipEntry("OSGI-INF/configurator/configurations.json");
- jos.putNextEntry(ze);
- final Writer w = new OutputStreamWriter(jos, "UTF-8");
- ConfigurationJSONWriter.write(w, configurations);
- w.flush();
- jos.closeEntry();
-
- jos.flush();
- jos.finish();
- }
-}
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java
deleted file mode 100644
index 6bea0f7..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java
+++ /dev/null
@@ -1,197 +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.karaf;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-
-/**
- * This writer writes out a Karaf feature XML.
- *
- */
-public class KarafFeatureWriter {
- private static final String REQUIRE_REPOINIT_CAPABILITY =
- "osgi.implementation;filter:=\"(&(osgi.implementation=org.apache.sling.jcr.repoinit)(version>=1.0)(!(version>=2.0)))\"";
-
-
- public static void writeKAR(final OutputStream os,
- final Feature feature,
- final ArtifactManager artifactManager)
- throws IOException {
- // check for repoinit extension
- final Extension repoinitExt = feature.getExtensions().getByName(FeatureConstants.EXTENSION_NAME_REPOINIT);
- File configurationBundleFile = null;
- Artifact configuratorBundle = null;
- try {
- final Configurations configs = new Configurations();
- configs.addAll(feature.getConfigurations());
- if ( repoinitExt != null ) {
- final Configuration cfg = new Configuration("org.apache.sling.jcr.repoinit.RepositoryInitializer",
- "feature-" + feature.getId().getArtifactId());
- cfg.getProperties().put("scripts", repoinitExt.getText());
- configs.add(cfg);
- }
- if ( !configs.isEmpty() ) {
- configurationBundleFile = Files.createTempFile(null, null).toFile();
-
- try ( final FileOutputStream fos = new FileOutputStream(configurationBundleFile)) {
- final Map<String, String> map;
- if ( repoinitExt == null ) {
- map = null;
- } else {
- map = Collections.singletonMap("Require-Capability", REQUIRE_REPOINIT_CAPABILITY);
- }
- ConfigurationUtil.createConfiguratorBundle(os,
- configs,
- feature.getId().getGroupId() + "." + feature.getId().getArtifactId(),
- feature.getId().getOSGiVersion().toString(),
- map);
- configuratorBundle = new Artifact(new ArtifactId(feature.getId().getGroupId(),
- feature.getId().getArtifactId(),
- feature.getId().getVersion(), "configurator", null));
- }
- }
-
- try ( final ZipOutputStream jos = new ZipOutputStream(os) ) {
- // repository/features.xml
- // repository/{maven-path-to-bundle}
- final ZipEntry xmlEntry = new ZipEntry("repository/features.xml");
- jos.putNextEntry(xmlEntry);
-
- final Writer writer = new OutputStreamWriter(jos);
- writeFeaturesXML(writer, feature, configuratorBundle);
- writer.flush();
-
- jos.closeEntry();
-
- for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
- for(final Artifact artifact : entry.getValue()) {
- final ArtifactHandler handler = artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());
-
- addEntry(jos, artifact, handler.getFile());
- }
- }
-
- if ( configuratorBundle != null ) {
- addEntry(jos, configuratorBundle, configurationBundleFile);
- }
- }
- } finally {
- if ( configurationBundleFile != null ) {
- configurationBundleFile.delete();
- }
- }
- }
-
- private static void addEntry(final ZipOutputStream jos, final Artifact artifact, final File file)
- throws IOException {
- final ZipEntry bundleEntry = new ZipEntry("repository/" + artifact.getId().toMvnPath());
- jos.putNextEntry(bundleEntry);
-
- final byte[] buffer = new byte[16384];
- try ( final FileInputStream fis = new FileInputStream(file)) {
- int l = 0;
- while ( (l = fis.read(buffer)) > 0 ) {
- jos.write(buffer, 0, l);
- }
- }
-
- jos.closeEntry();
- }
-
- /**
- * Writes the feature XML to the writer.
- * The writer is not closed.
- * @param writer Writer
- * @param model Model
- * @throws IOException
- */
- private static void writeFeaturesXML(final Writer writer,
- final Feature feature,
- final Artifact configuratorBundle)
- throws IOException {
- final PrintWriter w = new PrintWriter(writer);
-
- w.print("<features name=\"");
- w.print(feature.getId().getArtifactId());
- w.print("-repo-");
- w.print(feature.getId().getVersion());
- w.println("\" xmlns=\"http://karaf.apache.org/xmlns/features/v1.4.0\">");
-
- write(w, feature, configuratorBundle);
-
- w.println("</features>");
- w.flush();
- }
-
- private static void write(final PrintWriter w, final Feature feature, final Artifact configuratorBundle)
- throws IOException {
- w.print(" <feature name=\"");
- w.print(feature.getId().getGroupId());
- w.print('.');
- w.print(feature.getId().getArtifactId());
- if ( feature.getId().getClassifier() != null ) {
- w.print('.');
- w.print(feature.getId().getClassifier());
- }
- w.print("\" version=\"");
- w.print(feature.getId().getVersion());
- w.println("\">");
-
- if ( configuratorBundle != null ) {
- w.print(" <bundle start-level=\"1\">");
- w.print(configuratorBundle.getId().toMvnUrl());
- w.println("</bundle>");
- }
-
- // bundles
- for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
- for(final Artifact artifact : entry.getValue()) {
- w.print(" <bundle start-level=\"");
- w.print(entry.getKey().toString());
- w.print("\">");
- w.print(artifact.getId().toMvnUrl());
- w.println("</bundle>");
- }
- }
-
- w.println(" </feature>");
- }
-}
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java
deleted file mode 100644
index 76136a3..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.karaf;
-
-
diff --git a/featuremodel/feature-launcher/pom.xml b/featuremodel/feature-launcher/pom.xml
deleted file mode 100644
index fdcd201..0000000
--- a/featuremodel/feature-launcher/pom.xml
+++ /dev/null
@@ -1,140 +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.launcher</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-
- <name>Apache Sling Feature Launcher</name>
- <description>
- A application launcher using Apache Sling Features
- </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-launcher</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-launcher</developerConnection>
- <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-launcher</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>unpack-dependencies</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>unpack-dependencies</goal>
- </goals>
- <configuration>
- <excludes>META-INF/**</excludes>
- <outputDirectory>${project.build.directory}/classes</outputDirectory>
- <overWriteReleases>false</overWriteReleases>
- <overWriteSnapshots>true</overWriteSnapshots>
- <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>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.apache.sling.feature.launcher.impl.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- </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.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.io</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.resolver</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>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-cli</groupId>
- <artifactId>commons-cli</artifactId>
- <version>1.3.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.johnzon</artifactId>
- <version>1.0.0</version>
- </dependency>
- <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>
- </dependencies>
-</project>
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
deleted file mode 100644
index 557ec90..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
+++ /dev/null
@@ -1,147 +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.launcher.impl;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.json.ApplicationJSONReader;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class FeatureProcessor {
-
- /**
- * Initialize the launcher
- * Read the features and prepare the application
- * @param config The current configuration
- * @param artifactManager The artifact manager
- */
- public static Application createApplication(final LauncherConfig config,
- final ArtifactManager artifactManager)
- throws IOException {
- Application app = null;
- if ( config.getApplicationFile() != null ) {
- String absoluteArg = config.getApplicationFile();
- if ( absoluteArg.indexOf(":") < 2 ) {
- absoluteArg = new File(absoluteArg).getAbsolutePath();
- }
- final ArtifactHandler appArtifact = artifactManager.getArtifactHandler(absoluteArg);
-
- try (final FileReader r = new FileReader(appArtifact.getFile())) {
- app = ApplicationJSONReader.read(r);
- }
-
- } else {
- try (FeatureResolver resolver = new FrameworkResolver(artifactManager, Collections.emptyMap())) {
- app = ApplicationResolverAssembler.assembleApplication(null, artifactManager, resolver,
- org.apache.sling.feature.io.IOUtils.getFeatureFiles(config.getHomeDirectory(), config.getFeatureFiles()).toArray(new String[0]));
- } catch (Exception ex) {
- Main.LOG().error("Error while assembling application: {}", ex.getMessage(), ex);
- System.exit(1);
- }
- }
-
- // write application back
- final File file = new File(config.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "application.json");
- file.getParentFile().mkdirs();
-
- try (final FileWriter writer = new FileWriter(file)) {
- ApplicationJSONWriter.write(writer, app);
- } catch ( final IOException ioe) {
- Main.LOG().error("Error while writing application file: {}", ioe.getMessage(), ioe);
- System.exit(1);
- }
-
- return app;
- }
-
- /**
- * Prepare the launcher
- * - add all bundles to the bundle map of the installation object
- * - add all other artifacts to the install directory (only if startup mode is INSTALL)
- * - process configurations
- */
- public static void prepareLauncher(final LauncherConfig config,
- final ArtifactManager artifactManager,
- final Application app) throws Exception {
- for(final Map.Entry<Integer, List<Artifact>> entry : app.getBundles().getBundlesByStartOrder().entrySet()) {
- for(final Artifact a : entry.getValue()) {
- final ArtifactHandler handler = artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
- final File artifactFile = handler.getFile();
-
- config.getInstallation().addBundle(entry.getKey(), artifactFile);
- }
- }
- int index = 1;
- for(final Extension ext : app.getExtensions()) {
- if ( ext.getType() == ExtensionType.ARTIFACTS ) {
- for(final Artifact a : ext.getArtifacts() ) {
- if ( config.getStartupMode() == StartupMode.PURE ) {
- throw new Exception("Artifacts other than bundle are not supported by framework launcher.");
- }
- final ArtifactHandler handler = artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
- config.getInstallation().addInstallableArtifact(handler.getFile());
- }
- } else {
- if ( ext.getName().equals(FeatureConstants.EXTENSION_NAME_REPOINIT) ) {
- if ( ext.getType() != ExtensionType.TEXT ) {
- throw new Exception(FeatureConstants.EXTENSION_NAME_REPOINIT + " extension must be of type text and not json");
- }
- final Configuration cfg = new Configuration("org.apache.sling.jcr.repoinit.RepositoryInitializer", "repoinit" + String.valueOf(index));
- index++;
- cfg.getProperties().put("scripts", ext.getText());
- config.getInstallation().addConfiguration(cfg.getName(), cfg.getFactoryPid(), cfg.getProperties());
- } else {
- if ( ext.isRequired() ) {
- throw new Exception("Unknown required extension " + ext.getName());
- }
- }
- }
- }
-
- for(final Configuration cfg : app.getConfigurations()) {
- if ( cfg.isFactoryConfiguration() ) {
- config.getInstallation().addConfiguration(cfg.getName(), cfg.getFactoryPid(), cfg.getProperties());
- } else {
- config.getInstallation().addConfiguration(cfg.getPid(), null, cfg.getProperties());
- }
- }
-
- for(final Map.Entry<String, String> prop : app.getFrameworkProperties()) {
- if ( !config.getInstallation().getFrameworkProperties().containsKey(prop.getKey()) ) {
- config.getInstallation().getFrameworkProperties().put(prop.getKey(), prop.getValue());
- }
- }
- }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
deleted file mode 100644
index 2dff508..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
+++ /dev/null
@@ -1,137 +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.launcher.impl;
-
-import org.apache.sling.feature.launcher.spi.LauncherRunContext;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class holds the configuration of the launcher.
- */
-public class Installation implements LauncherRunContext {
-
- /** The map with the framework properties. */
- private final Map<String, String> fwkProperties = new HashMap<>();
-
- /** Bundle map */
- private final Map<Integer, List<File>> bundleMap = new HashMap<>();
-
- /** Artifacts to be installed */
- private final List<File> installables = new ArrayList<>();
-
- /** Configurations, they are installed on first start. */
- private final List<Object[]> configurations = new ArrayList<>();
-
- /** The list of app jars. */
- private final List<File> appJars = new ArrayList<>();
-
- /**
- * Add an application jar.
- * @param jar The application jar
- */
- public void addAppJar(final File jar) {
- this.appJars.add(jar);
- }
-
- /**
- * Get the list of application jars.
- * @return The list of app jars
- */
- public List<File> getAppJars() {
- return this.appJars;
- }
-
- /**
- * Add a bundle with the given start level
- * @param startLevel The start level
- * @param file The bundle file
- */
- public void addBundle(final Integer startLevel, final File file) {
- List<File> files = bundleMap.get(startLevel);
- if ( files == null ) {
- files = new ArrayList<>();
- bundleMap.put(startLevel, files);
- }
- files.add(file);
- }
-
- /**
- * Add an artifact to be installed by the installer
- * @param file The file
- */
- public void addInstallableArtifact(final File file) {
- this.installables.add(file);
- }
-
- /**
- * Add a configuration
- * @param pid The pid
- * @param factoryPid The factory pid
- * @param properties The propertis
- */
- public void addConfiguration(final String pid, final String factoryPid, final Dictionary<String, Object> properties) {
- this.configurations.add(new Object[] {pid, factoryPid, properties});
- }
-
- /**
- * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getFrameworkProperties()
- */
- @Override
- public Map<String, String> getFrameworkProperties() {
- return this.fwkProperties;
- }
-
- /**
- * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getBundleMap()
- */
- @Override
- public Map<Integer, List<File>> getBundleMap() {
- return this.bundleMap;
- }
-
- /**
- * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getConfigurations()
- */
- @Override
- public List<Object[]> getConfigurations() {
- return this.configurations;
- }
-
- /**
- * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getInstallableArtifacts()
- */
- @Override
- public List<File> getInstallableArtifacts() {
- return this.installables;
- }
-
- /**
- * Clear all in-memory objects
- */
- public void clear() {
- this.configurations.clear();
- this.fwkProperties.clear();
- this.bundleMap.clear();
- this.installables.clear();
- }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
deleted file mode 100644
index 1feb931..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
+++ /dev/null
@@ -1,122 +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.launcher.impl;
-
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * This class holds the configuration of the launcher.
- */
-public class LauncherConfig
- extends ArtifactManagerConfig
- implements ArtifactProviderContext {
-
- public enum StartupMode {
- INSTALLER,
- PURE
- };
-
- private static final String HOME = "launcher";
-
- private static final String CACHE_DIR = "cache";
-
- /** The feature files or directories. */
- private volatile String[] featureFiles;
-
- /** The application file. */
- private volatile String appFile;
-
- private volatile StartupMode startupMode = StartupMode.PURE;
-
- private final Installation installation = new Installation();
-
- /**
- * Create a new configuration object.
- * Set the default values
- */
- public LauncherConfig() {
- this.setCacheDirectory(new File(getHomeDirectory(), CACHE_DIR));
- }
-
- public void setApplicationFile(final String value) {
- appFile = value;
- }
-
- public String getApplicationFile() {
- return this.appFile;
- }
-
- /**
- * Set the list of feature files or directories.
- * @param value The array with the feature file names.
- */
- public void setFeatureFiles(final String[] value) {
- this.featureFiles = value;
- if ( value != null && value.length == 0 ) {
- this.featureFiles = null;
- }
- }
-
- /**
- * Get the list of feature files.
- * @return The array of names.
- * @throws IOException
- */
- public String[] getFeatureFiles() {
- return this.featureFiles;
- }
-
-
- /**
- * Get the home directory.
- * @return The home directory.
- */
- public File getHomeDirectory() {
- return new File(HOME);
- }
-
- /**
- * Get the startup mode.
- *
- * @return The current startup mode.
- */
- public StartupMode getStartupMode() {
- return this.startupMode;
- }
-
- /**
- * Sets the startup mode to {@link StartupMode#INSTALLER}.
- */
- public void setUseInstaller() {
- this.startupMode = StartupMode.INSTALLER;
- }
-
- public Installation getInstallation() {
- return this.installation;
- }
-
- /**
- * Clear all in-memory objects
- */
- public void clear() {
- this.installation.clear();
- }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
deleted file mode 100644
index 6593319..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
+++ /dev/null
@@ -1,313 +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.launcher.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.launcher.impl.launchers.FrameworkLauncher;
-import org.apache.sling.feature.launcher.spi.Launcher;
-import org.apache.sling.feature.launcher.spi.LauncherPrepareContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is the launcher main class.
- * It parses command line parameters and prepares the launcher.
- */
-public class Main {
-
- private static Logger LOGGER;
-
- public static Logger LOG() {
- if ( LOGGER == null ) {
- LOGGER = LoggerFactory.getLogger("launcher");
- }
- return LOGGER;
- }
-
- /** Split a string into key and value */
- private static String[] split(final String val) {
- final int pos = val.indexOf('=');
- if ( pos == -1 ) {
- return new String[] {val, "true"};
- }
- return new String[] {val.substring(0, pos), val.substring(pos + 1)};
- }
-
- /**
- * Parse the command line parameters and update a configuration object.
- * @param args Command line parameters
- * @return Configuration object.
- */
- private static void parseArgs(final LauncherConfig config, final String[] args) {
- Main.LOG().info("Assembling configuration...");
- final Options options = new Options();
-
- final Option repoOption = new Option("u", true, "Set repository url");
- final Option modelOption = new Option("f", true, "Set feature files/directories");
- final Option appOption = new Option("a", true, "Set application file");
- final Option fwkProperties = new Option("D", true, "Set framework properties");
- fwkProperties.setArgs(20);
- final Option debugOption = new Option("v", true, "Verbose");
- debugOption.setArgs(0);
- final Option installerOption = new Option("I", true, "Use OSGi installer for additional artifacts.");
- installerOption.setArgs(0);
- options.addOption(repoOption);
- options.addOption(appOption);
- options.addOption(modelOption);
- options.addOption(fwkProperties);
- options.addOption(debugOption);
- options.addOption(installerOption);
-
- final CommandLineParser clp = new BasicParser();
- try {
- final CommandLine cl = clp.parse(options, args);
-
- if ( cl.hasOption(repoOption.getOpt()) ) {
- final String value = cl.getOptionValue(repoOption.getOpt());
- config.setRepositoryUrls(value.split(","));
- }
- if ( cl.hasOption(modelOption.getOpt()) ) {
- final String value = cl.getOptionValue(modelOption.getOpt());
- config.setFeatureFiles(value.split(","));
- }
- if ( cl.hasOption(fwkProperties.getOpt()) ) {
- for(final String value : cl.getOptionValues(fwkProperties.getOpt())) {
- final String[] keyVal = split(value);
-
- config.getInstallation().getFrameworkProperties().put(keyVal[0], keyVal[1]);
- }
- }
- if ( cl.hasOption(debugOption.getOpt()) ) {
- System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
- LOGGER = null;
- }
- if ( cl.hasOption(installerOption.getOpt()) ) {
- config.setUseInstaller();
- }
- if ( cl.hasOption(appOption.getOpt()) ) {
- config.setApplicationFile(cl.getOptionValue(appOption.getOpt()));
- }
- } catch ( final ParseException pe) {
- Main.LOG().error("Unable to parse command line: {}", pe.getMessage(), pe);
- System.exit(1);
- }
- }
-
- public static void main(final String[] args) {
- // setup logging
- System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
- System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
- System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
- System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
- Main.LOG().info("");
- Main.LOG().info("Apache Sling Application Launcher");
- Main.LOG().info("---------------------------------");
-
- // check if launcher has already been created
- final LauncherConfig launcherConfig = new LauncherConfig();
- parseArgs(launcherConfig, args);
-
- ArtifactManager artifactManager = null;
- try {
-
- Main.LOG().info("Initializing...");
- try {
- artifactManager = ArtifactManager.getArtifactManager(launcherConfig);
- } catch ( final IOException ioe) {
- Main.LOG().error("Unable to setup artifact manager: {}", ioe.getMessage(), ioe);
- System.exit(1);
- }
- Main.LOG().info("Artifact Repositories: {}", Arrays.toString(launcherConfig.getRepositoryUrls()));
- Main.LOG().info("Assembling provisioning model...");
-
- try {
- final Launcher launcher = new FrameworkLauncher();
- final Application app = FeatureProcessor.createApplication(launcherConfig, artifactManager);
-
- Main.LOG().info("");
- Main.LOG().info("Assembling launcher...");
- final ArtifactManager aMgr = artifactManager;
- final LauncherPrepareContext ctx = new LauncherPrepareContext() {
-
- @Override
- public File getArtifactFile(final ArtifactId artifact) throws IOException {
- final ArtifactHandler handler = aMgr.getArtifactHandler(":" + artifact.toMvnPath());
- return handler.getFile();
- }
-
- @Override
- public void addAppJar(final File jar) {
- launcherConfig.getInstallation().addAppJar(jar);
- }
- };
- launcher.prepare(ctx, app);
-
- FeatureProcessor.prepareLauncher(launcherConfig, artifactManager, app);
-
- } catch ( final Exception iae) {
- Main.LOG().error("Error while assembling launcher: {}", iae.getMessage(), iae);
- System.exit(1);
- }
-
- Main.LOG().info("Using {} local artifacts, {} cached artifacts, and {} downloaded artifacts",
- launcherConfig.getLocalArtifacts(), launcherConfig.getCachedArtifacts(), launcherConfig.getDownloadedArtifacts());
- } finally {
- if ( artifactManager != null ) {
- artifactManager.shutdown();
- }
- }
-
- try {
- run(launcherConfig);
- } catch ( final Exception iae) {
- Main.LOG().error("Error while running launcher: {}", iae.getMessage(), iae);
- System.exit(1);
- }
- }
-
- private static final String STORAGE_PROPERTY = "org.osgi.framework.storage";
-
- private static final String START_LEVEL_PROP = "org.osgi.framework.startlevel.beginning";
-
- /**
- * Run launcher.
- * @param config The configuration
- * @throws Exception If anything goes wrong
- */
- private static void run(final LauncherConfig config) throws Exception {
- Main.LOG().info("");
- Main.LOG().info("Starting launcher...");
- Main.LOG().info("Launcher Home: {}", config.getHomeDirectory().getAbsolutePath());
- Main.LOG().info("Cache Directory: {}", config.getCacheDirectory().getAbsolutePath());
- Main.LOG().info("Startup Mode: {}", config.getStartupMode());
- Main.LOG().info("");
-
- final Installation installation = config.getInstallation();
-
- // set sling home, and use separate locations for launchpad and properties
- installation.getFrameworkProperties().put("sling.home", config.getHomeDirectory().getAbsolutePath());
- installation.getFrameworkProperties().put("sling.launchpad", config.getHomeDirectory().getAbsolutePath() + "/launchpad");
- installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
-
-
- // additional OSGi properties
- // move storage inside launcher
- if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
- installation.getFrameworkProperties().put(STORAGE_PROPERTY, config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
- }
- // set start level to 30
- if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
- installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
- }
-
- final Launcher launcher = new FrameworkLauncher();
- launcher.run(installation, createClassLoader(installation));
-
- config.clear();
- }
-
- /**
- * Create the class loader.
- * @param installation The launcher configuration
- * @throws Exception If anything goes wrong
- */
- public static ClassLoader createClassLoader(final Installation installation) throws Exception {
- final List<URL> list = new ArrayList<>();
- for(final File f : installation.getAppJars()) {
- try {
- list.add(f.toURI().toURL());
- } catch (IOException e) {
- // ignore
- }
- }
- list.add(Main.class.getProtectionDomain().getCodeSource().getLocation());
-
- final URL[] urls = list.toArray(new URL[list.size()]);
-
- if ( Main.LOG().isDebugEnabled() ) {
- Main.LOG().debug("App classpath: ");
- for (int i = 0; i < urls.length; i++) {
- Main.LOG().debug(" - {}", urls[i]);
- }
- }
-
- // create a paranoid class loader, loading from parent last
- final ClassLoader cl = new URLClassLoader(urls) {
- @Override
- public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- // First check if it's already loaded
- Class<?> clazz = findLoadedClass(name);
-
- if (clazz == null) {
-
- try {
- clazz = findClass(name);
- } catch (ClassNotFoundException cnfe) {
- ClassLoader parent = getParent();
- if (parent != null) {
- // Ask to parent ClassLoader (can also throw a CNFE).
- clazz = parent.loadClass(name);
- } else {
- // Propagate exception
- throw cnfe;
- }
- }
- }
-
- if (resolve) {
- resolveClass(clazz);
- }
-
- return clazz;
- }
-
- @Override
- public final URL getResource(final String name) {
-
- URL resource = findResource(name);
- ClassLoader parent = this.getParent();
- if (resource == null && parent != null) {
- resource = parent.getResource(name);
- }
-
- return resource;
- }
- };
-
- Thread.currentThread().setContextClassLoader(cl);
-
- return cl;
- }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
deleted file mode 100644
index 0be1804..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ /dev/null
@@ -1,278 +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.launcher.impl.launchers;
-
-import org.apache.sling.feature.launcher.impl.Main;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.launch.Framework;
-import org.osgi.framework.startlevel.BundleStartLevel;
-import org.osgi.framework.wiring.FrameworkWiring;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Common functionality for the framework start.
- */
-public class AbstractRunner {
-
- private volatile ServiceTracker<Object, Object> configAdminTracker;
-
- private volatile ServiceTracker<Object, Object> installerTracker;
-
- private final List<Object[]> configurations;
-
- private final List<File> installables;
-
- public AbstractRunner(final List<Object[]> configurations, final List<File> installables) {
- this.configurations = new ArrayList<>(configurations);
- this.installables = installables;
- }
-
- protected void setupFramework(final Framework framework, final Map<Integer, List<File>> bundlesMap)
- throws BundleException {
- if ( !configurations.isEmpty() ) {
- this.configAdminTracker = new ServiceTracker<>(framework.getBundleContext(),
- "org.osgi.service.cm.ConfigurationAdmin",
- new ServiceTrackerCustomizer<Object, Object>() {
-
- @Override
- public Object addingService(final ServiceReference<Object> reference) {
- // get config admin
- final Object cm = framework.getBundleContext().getService(reference);
- if ( cm != null ) {
- try {
- configure(cm);
- } finally {
- framework.getBundleContext().ungetService(reference);
- }
- }
- return null;
- }
-
- @Override
- public void modifiedService(ServiceReference<Object> reference, Object service) {
- // nothing to do
- }
-
- @Override
- public void removedService(ServiceReference<Object> reference, Object service) {
- // nothing to do
- }
- });
- this.configAdminTracker.open();
- }
- if ( installables != null && !installables.isEmpty() ) {
- this.installerTracker = new ServiceTracker<>(framework.getBundleContext(),
- "org.apache.sling.installer.api.OsgiInstaller",
- new ServiceTrackerCustomizer<Object, Object>() {
-
- @Override
- public Object addingService(final ServiceReference<Object> reference) {
- // get installer
- final Object installer = framework.getBundleContext().getService(reference);
- if ( installer != null ) {
- try {
- install(installer);
- } finally {
- framework.getBundleContext().ungetService(reference);
- }
- }
- return null;
- }
-
- @Override
- public void modifiedService(ServiceReference<Object> reference, Object service) {
- // nothing to do
- }
... 11290 lines suppressed ...
--
To stop receiving notification emails like this one, please contact
davidb@apache.org.