You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2021/02/07 13:14:55 UTC
[jackrabbit-filevault] 01/01: JCRVLT-503 introduce composite
package registry
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/composite-package-registry
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git
commit 99db81b686f3c6988f6298817b3df20e5de9cced
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sun Feb 7 14:14:35 2021 +0100
JCRVLT-503 introduce composite package registry
---
.../jackrabbit/vault/packaging/Packaging.java | 18 +++
.../vault/packaging/impl/PackagingImpl.java | 42 ++++++-
.../registry/impl/CompositePackageRegistry.java | 140 +++++++++++++++++++++
3 files changed, 194 insertions(+), 6 deletions(-)
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/Packaging.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/Packaging.java
index 76cc618..f89c28f 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/Packaging.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/Packaging.java
@@ -21,6 +21,8 @@ import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.apache.jackrabbit.vault.packaging.registry.PackageRegistry;
+import org.apache.jackrabbit.vault.packaging.registry.impl.JcrPackageRegistry;
import org.osgi.annotation.versioning.ProviderType;
/**
@@ -68,4 +70,20 @@ public interface Packaging {
* @since 2.3.0
*/
JcrPackage open(Node node, boolean allowInvalid) throws RepositoryException;
+
+ /**
+ * Returns a new composite package registry which acts on all currently registered package registries and
+ * a JCR-based registry for the current configuration and the given session.
+ * All operations creating new packages will act on the primary registry which is determined by argument
+ * {@code useJcrRegistryAsPrimaryRegistry}.
+ * Due to the dynamic nature of package registries the return value should not be persisted.
+ *
+ * @param session the JCR session to use for the JCR-based registry
+ * @param useJcrRegistryAsPrimaryRegistry if {@code true} the JCR-based registry will be used as primary
+ * registry, otherwise the first registered package registry is used and the JCR-based registry will be inserted as last registry.
+ * @return the composite package registry
+ */
+ PackageRegistry getCompositePackageRegistry(Session session, boolean useJcrRegistryAsPrimaryRegistry);
+
+ JcrPackageRegistry getJcrPackageRegistry(Session session);
}
\ No newline at end of file
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
index 9cb04ac..96ea176 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagingImpl.java
@@ -16,6 +16,9 @@
*/
package org.apache.jackrabbit.vault.packaging.impl;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -27,11 +30,15 @@ import org.apache.jackrabbit.vault.packaging.PackageManager;
import org.apache.jackrabbit.vault.packaging.Packaging;
import org.apache.jackrabbit.vault.packaging.events.impl.PackageEventDispatcher;
import org.apache.jackrabbit.vault.packaging.registry.PackageRegistry;
+import org.apache.jackrabbit.vault.packaging.registry.impl.AbstractPackageRegistry;
+import org.apache.jackrabbit.vault.packaging.registry.impl.CompositePackageRegistry;
+import org.apache.jackrabbit.vault.packaging.registry.impl.JcrPackageRegistry;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -57,12 +64,12 @@ public class PackagingImpl implements Packaging {
@Reference
private PackageEventDispatcher eventDispatcher;
- // In case a PackageRegistry is exposed as OSGi Service this will be considered
+ // In case a PackageRegistry is exposed as OSGi Service the first one will be considered
// as base registry to fall back for dependency checks - currently only FSPackageRegistry is exposed as such
- // currently no support for multiple registered PackageRegistries (OSGi Framework will will pick first found)
- @Reference (cardinality = ReferenceCardinality.OPTIONAL,
- policy = ReferencePolicy.DYNAMIC)
- private volatile PackageRegistry baseRegistry;
+ @Reference (cardinality = ReferenceCardinality.MULTIPLE,
+ policy = ReferencePolicy.DYNAMIC,
+ policyOption = ReferencePolicyOption.GREEDY)
+ private List<PackageRegistry> registries;
/**
* package manager is a singleton
@@ -112,7 +119,10 @@ public class PackagingImpl implements Packaging {
public JcrPackageManager getPackageManager(Session session) {
JcrPackageManagerImpl mgr = new JcrPackageManagerImpl(session, config.packageRoots(), config.authIdsForHookExecution(), config.authIdsForRootInstallation());
mgr.setDispatcher(eventDispatcher);
- mgr.getInternalRegistry().setBaseRegistry(baseRegistry);
+ List<PackageRegistry> allRegistries = registries;
+ if (!allRegistries.isEmpty()) {
+ mgr.getInternalRegistry().setBaseRegistry(allRegistries.get(0));
+ }
return mgr;
}
@@ -130,4 +140,24 @@ public class PackagingImpl implements Packaging {
JcrPackageManager pMgr = getPackageManager(node.getSession());
return pMgr.open(node, allowInvalid);
}
+
+ @Override
+ public PackageRegistry getCompositePackageRegistry(Session session, boolean useJcrRegistryAsPrimaryRegistry) {
+ List<PackageRegistry> allRegistries = new ArrayList<>(registries);
+ JcrPackageRegistry jcrPackageRegistry = getJcrPackageRegistry(session);
+ if (useJcrRegistryAsPrimaryRegistry) {
+ allRegistries.add(0, jcrPackageRegistry);
+ } else {
+ allRegistries.add(jcrPackageRegistry);
+ }
+ return new CompositePackageRegistry(allRegistries);
+ }
+
+ @Override
+ public JcrPackageRegistry getJcrPackageRegistry(Session session) {
+ JcrPackageRegistry registry = new JcrPackageRegistry(session, new AbstractPackageRegistry.SecurityConfig(config.authIdsForHookExecution(), config.authIdsForRootInstallation()), config.packageRoots());
+ registry.setDispatcher(eventDispatcher);
+ // TODO: baseRegistry?
+ return registry;
+ }
}
\ No newline at end of file
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/CompositePackageRegistry.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/CompositePackageRegistry.java
new file mode 100644
index 0000000..7e70a3a
--- /dev/null
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/CompositePackageRegistry.java
@@ -0,0 +1,140 @@
+/*
+ * 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.jackrabbit.vault.packaging.registry.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.jackrabbit.vault.packaging.Dependency;
+import org.apache.jackrabbit.vault.packaging.NoSuchPackageException;
+import org.apache.jackrabbit.vault.packaging.PackageExistsException;
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.registry.DependencyReport;
+import org.apache.jackrabbit.vault.packaging.registry.ExecutionPlanBuilder;
+import org.apache.jackrabbit.vault.packaging.registry.PackageRegistry;
+import org.apache.jackrabbit.vault.packaging.registry.RegisteredPackage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class CompositePackageRegistry implements PackageRegistry {
+
+ private final List<PackageRegistry> registries;
+ private final PackageRegistry primaryRegistry;
+
+ public CompositePackageRegistry(List<PackageRegistry> registries) {
+ this.registries = registries;
+ this.primaryRegistry = registries.get(0);
+ }
+
+ @Override
+ public boolean contains(@NotNull PackageId id) throws IOException {
+ for (PackageRegistry registry : registries) {
+ if (registry.contains(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public @NotNull Set<PackageId> packages() throws IOException {
+ Set<PackageId> allPackages = new HashSet<>();
+ for (PackageRegistry registry : registries) {
+ allPackages.addAll(registry.packages());
+ }
+ return allPackages;
+ }
+
+ @Override
+ public @Nullable RegisteredPackage open(@NotNull PackageId id) throws IOException {
+ for (PackageRegistry registry : registries) {
+ if (registry.contains(id)) {
+ return registry.open(id);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public @NotNull PackageId register(@NotNull InputStream in, boolean replace) throws IOException, PackageExistsException {
+ return primaryRegistry.register(in, replace);
+ }
+
+ @Override
+ public @NotNull PackageId register(@NotNull File file, boolean replace) throws IOException, PackageExistsException {
+ return primaryRegistry.register(file, replace);
+ }
+
+ @Override
+ public @NotNull PackageId registerExternal(@NotNull File file, boolean replace) throws IOException, PackageExistsException {
+ return primaryRegistry.registerExternal(file, replace);
+ }
+
+ @Override
+ public void remove(@NotNull PackageId id) throws IOException, NoSuchPackageException {
+ for (PackageRegistry registry : registries) {
+ if (registry.contains(id)) {
+ registry.remove(id);
+ return;
+ }
+ }
+ throw new NoSuchPackageException("No registry contains the given package id " + id);
+ }
+
+ @Override
+ public @NotNull DependencyReport analyzeDependencies(@NotNull PackageId id, boolean onlyInstalled)
+ throws IOException, NoSuchPackageException {
+ for (PackageRegistry registry : registries) {
+ if (registry.contains(id)) {
+ return registry.analyzeDependencies(id, onlyInstalled);
+ }
+ }
+ throw new NoSuchPackageException("No registry contains the given package id " + id);
+ }
+
+ @Override
+ public @Nullable PackageId resolve(@NotNull Dependency dependency, boolean onlyInstalled) throws IOException {
+ PackageId packageId = null;
+ for (PackageRegistry registry : registries) {
+ packageId = registry.resolve(dependency, onlyInstalled);
+ if (packageId != null) {
+ return packageId;
+ }
+ }
+ return packageId;
+ }
+
+ @Override
+ public @NotNull PackageId[] usage(@NotNull PackageId id) throws IOException {
+ for (PackageRegistry registry : registries) {
+ if (registry.contains(id)) {
+ return registry.usage(id);
+ }
+ }
+ return new PackageId[] {};
+ }
+
+ @Override
+ public @NotNull ExecutionPlanBuilder createExecutionPlan() {
+ return new ExecutionPlanBuilderImpl(this);
+ }
+
+}