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-org-apache-sling-feature-extension-content.git
commit 7c4028d06395ad2a401b3bd3c43c99c5e9b77bbc Author: Dominik Suess <[email protected]> AuthorDate: Thu Sep 6 11:56:21 2018 +0200 SLING-7870 - Proposal for FSRegistry based Content Handler Extension --- pom.xml | 159 +++++++++++++++++++++ .../feature/extension/content/ContentHandler.java | 146 +++++++++++++++++++ ...eature.launcher.spi.extensions.ExtensionHandler | 1 + 3 files changed, 306 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9c5b284 --- /dev/null +++ b/pom.xml @@ -0,0 +1,159 @@ +<?xml version="1.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. --> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>34</version> + <relativePath /> + </parent> + + <artifactId>org.apache.sling.feature.extension.content</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>Sling Featuremodel - Content Deployment Exension</name> + + <licenses> + <!-- This is also in the Apache parent POM, but adding it here includes + it in dependency-reduced-pom.xml so that it passes the rat check. --> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + </licenses> + + <properties> + <jdk.version>8</jdk.version> + </properties> + + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <minimizeJar>true</minimizeJar> + <filters> + <filter> + <includes> + <include>org.apache.commons:collections:*</include> + </includes> + </filter> + </filters> + </configuration> + </execution> + </executions> + + </plugin> + <plugin> + <groupId>org.apache.rat</groupId> + <artifactId>apache-rat-plugin</artifactId> + <configuration> + <excludes> + <exclude>src/main/resources/META-INF/services/**</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.apache.jackrabbit.vault</groupId> + <artifactId>org.apache.jackrabbit.vault</artifactId> + <version>3.2.1-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.feature.launcher</artifactId> + <version>0.1.0-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.feature.io</artifactId> + <version>0.1.3-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.feature</artifactId> + <version>0.1.3-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-nop</artifactId> + <version>1.7.25</version> + <scope>compile</scope> + </dependency> <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.johnzon</artifactId> + <version>1.0.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.converter</artifactId> + <version>1.0.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.jcr.jcr-wrapper</artifactId> + <version>2.0.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <artifactId>jackrabbit-spi-commons</artifactId> + <version>2.17.3</version> + <groupId>org.apache.jackrabbit</groupId> + <scope>compile</scope> + </dependency> + <dependency> + <artifactId>commons-io</artifactId> + <version>2.6</version> + <groupId>commons-io</groupId> + <scope>compile</scope> + </dependency> + <dependency> + <artifactId>jackrabbit-jcr-commons</artifactId> + <version>2.17.3</version> + <groupId>org.apache.jackrabbit</groupId> + <scope>compile</scope> + </dependency> + <dependency> + <artifactId>jackrabbit-spi</artifactId> + <version>2.17.3</version> + <groupId>org.apache.jackrabbit</groupId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.3.1</version> + <scope>compile</scope> + </dependency> + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java b/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java new file mode 100644 index 0000000..e19ba12 --- /dev/null +++ b/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java @@ -0,0 +1,146 @@ +/* + * 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.extension.content; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections.map.MultiValueMap; +import org.apache.jackrabbit.vault.packaging.PackageId; +import org.apache.jackrabbit.vault.packaging.SubPackageHandling; +import org.apache.jackrabbit.vault.packaging.registry.ExecutionPlanBuilder; +import org.apache.jackrabbit.vault.packaging.registry.PackageTask.Type; +import org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry; +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.launcher.spi.LauncherPrepareContext; +import org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler; +import org.apache.sling.feature.launcher.spi.extensions.ExtensionInstallationContext; + +public class ContentHandler implements ExtensionHandler { + + public static final String PACKAGEREGISTRY_HOME = "packageregistry.home"; + + private static final String REPOSITORY_HOME = "repository.home"; + + private static final String REGISTRY_FOLDER = "packageregistry"; + + private static ExecutionPlanBuilder buildExecutionPlan(Collection<Artifact> artifacts, LauncherPrepareContext prepareContext, File registryHome) throws Exception { + + List<File> packageReferences = new ArrayList<File>(); + + for (final Artifact a : artifacts) { + final File file = prepareContext.getArtifactFile(a.getId()); + if (file.exists()) { + packageReferences.add(file); + } + + } + + if(!registryHome.exists()) { + registryHome.mkdirs(); + } + + FSPackageRegistry registry = new FSPackageRegistry(registryHome); + + ExecutionPlanBuilder builder = registry.createExecutionPlan(); + + for (File pkgFile : packageReferences) { + PackageId pid = registry.registerExternal(pkgFile, true); + Map<PackageId, SubPackageHandling.Option> subPkgs = registry.getInstallState(pid).getSubPackages(); + if (!subPkgs.isEmpty()) { + for (PackageId subId : subPkgs.keySet()) { + SubPackageHandling.Option opt = subPkgs.get(subId); + if (opt != SubPackageHandling.Option.IGNORE) { + builder.addTask().with(subId).with(Type.EXTRACT); + } + } + } + + builder.addTask().with(pid).with(Type.EXTRACT); + } + builder.validate(); + return builder; + + } + + @Override + public boolean handle(Extension extension, LauncherPrepareContext prepareContext, + ExtensionInstallationContext installationContext) throws Exception { + File registryHome = getRegistryHomeDir(installationContext); + if (extension.getType() == ExtensionType.ARTIFACTS + && extension.getName().equals(FeatureConstants.EXTENSION_NAME_CONTENT_PACKAGES)) { + MultiValueMap orderedArtifacts = MultiValueMap.decorate(new LinkedHashMap<Integer, Collection<Artifact>>()); + for (final Artifact a : extension.getArtifacts()) { + orderedArtifacts.put(Integer.valueOf(a.getStartOrder()), a); + } + List<String> executionPlans = new ArrayList<String>(); + for (Object key : orderedArtifacts.keySet()) { + @SuppressWarnings("unchecked") + Collection<Artifact> artifacts = orderedArtifacts.getCollection(key); + ExecutionPlanBuilder builder = buildExecutionPlan(artifacts, prepareContext, registryHome); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + builder.save(baos); + executionPlans.add(baos.toString("UTF-8")); + } + final Configuration initcfg = new Configuration("org.apache.sling.jcr.packageinit.impl.ExecutionPlanRepoInitializer"); + initcfg.getProperties().put("executionplans", executionPlans.toArray(new String[executionPlans.size()])); + installationContext.addConfiguration(initcfg.getPid(), initcfg.getFactoryPid(), initcfg.getProperties()); + + final Configuration registrycfg = new Configuration("org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry"); + registrycfg.getProperties().put("homePath", REGISTRY_FOLDER); + installationContext.addConfiguration(registrycfg.getPid(), registrycfg.getFactoryPid(), registrycfg.getProperties());; + + return true; + } + else { + return false; + } + } + + private File getRegistryHomeDir(ExtensionInstallationContext installationContext) { + //read repository- home from framework properties (throw exception if repo.home not set) + String registryPath = System.getProperty(PACKAGEREGISTRY_HOME); + File registryHome; + if (registryPath != null) { + registryHome = Paths.get(registryPath).toFile(); + + } else { + String repoHome = installationContext.getFrameworkProperties().get(REPOSITORY_HOME); + if (repoHome == null) { + throw new IllegalStateException("Neither registry.home set nor repository.home configured."); + } + registryHome = Paths.get(repoHome, REGISTRY_FOLDER).toFile(); + } + if (!registryHome.exists()) { + registryHome.mkdirs(); + } + if (!registryHome.isDirectory()) { + throw new IllegalStateException("Registry but points to file - must be directory"); + } + return registryHome; + } +} diff --git a/src/main/resources/META-INF/services/org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler b/src/main/resources/META-INF/services/org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler new file mode 100644 index 0000000..b89c4aa --- /dev/null +++ b/src/main/resources/META-INF/services/org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler @@ -0,0 +1 @@ +org.apache.sling.feature.extension.content.ContentHandler
