You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2013/10/17 21:49:49 UTC
svn commit: r1533228 - in
/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault:
fs/io/ packaging/ packaging/impl/
Author: tripod
Date: Thu Oct 17 19:49:48 2013
New Revision: 1533228
URL: http://svn.apache.org/r1533228
Log:
JCRVLT-17 Provide better abstraction for install hook handling
Added:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessor.java
- copied, changed from r1526256, jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessorFactory.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessorImpl.java
- copied, changed from r1526256, jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java
Removed:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java
Modified:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallContextImpl.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java?rev=1533228&r1=1533227&r2=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/ImportOptions.java Thu Oct 17 19:49:48 2013
@@ -25,19 +25,12 @@ import java.util.regex.PatternSyntaxExce
import org.apache.jackrabbit.vault.fs.api.ImportMode;
import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Option that control the package import.
*/
public class ImportOptions {
- /**
- * default logger
- */
- private static final Logger log = LoggerFactory.getLogger(ImportOptions.class);
-
private boolean strict;
private ProgressTrackerListener listener;
@@ -68,6 +61,11 @@ public class ImportOptions {
// default constructor.
}
+ /**
+ * @deprecated use {@link #copy()} instead.
+ * @param base base options
+ */
+ @Deprecated
public ImportOptions(ImportOptions base) {
if (base != null) {
strict = base.strict;
@@ -86,6 +84,24 @@ public class ImportOptions {
}
}
+ public ImportOptions copy() {
+ ImportOptions ret = new ImportOptions();
+ ret.strict = strict;
+ ret.listener = listener;
+ ret.patchParentPath = patchParentPath;
+ ret.patchDirectory = patchDirectory;
+ ret.patchKeepInRepo = patchKeepInRepo;
+ ret.nonRecursive = nonRecursive;
+ ret.dryRun = dryRun;
+ ret.autoSave = autoSave;
+ ret.acHandling = acHandling;
+ ret.importMode = importMode;
+ ret.cndPattern = cndPattern;
+ ret.filter = filter;
+ ret.hookClassLoader = hookClassLoader;
+ return ret;
+ }
+
public boolean isStrict() {
return strict;
}
Copied: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessor.java (from r1526256, jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java)
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessor.java?p2=jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessor.java&p1=jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java&r1=1526256&r2=1533228&rev=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessor.java Thu Oct 17 19:49:48 2013
@@ -14,242 +14,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.jackrabbit.vault.packaging;
-package org.apache.jackrabbit.vault.packaging.impl;
-
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.TreeMap;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.vault.fs.api.VaultInputSource;
import org.apache.jackrabbit.vault.fs.io.Archive;
-import org.apache.jackrabbit.vault.packaging.InstallContext;
-import org.apache.jackrabbit.vault.packaging.InstallHook;
-import org.apache.jackrabbit.vault.packaging.PackageException;
-import org.apache.jackrabbit.vault.packaging.VaultPackage;
-import org.apache.jackrabbit.vault.util.Constants;
-import org.apache.jackrabbit.vault.util.Text;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
- * processor for install hooks
+ * The install hook processor is used for handle the install hooks, from registration to execution.
*/
-public class InstallHookProcessor {
+public interface InstallHookProcessor {
+
+ /**
+ * Register all hooks found in the given archive.
+ * @param archive the archive.
+ * @param classLoader the class loader
+ * @throws PackageException if an error occurs.
+ */
+ void registerHooks(Archive archive, ClassLoader classLoader) throws PackageException;
/**
- * default logger
+ * Register the hook provided by the given input source.
+ * @param input a vault input source containing the jar file of the install hook
+ * @param classLoader the class loader
+ * @throws IOException if an I/O error occurs
+ * @throws PackageException if an error occurs.
*/
- private static final Logger log = LoggerFactory.getLogger(InstallHookProcessor.class);
+ void registerHook(VaultInputSource input, ClassLoader classLoader) throws IOException, PackageException;
- private final TreeMap<String, Hook> hooks = new TreeMap<String, Hook>();
+ /**
+ * Checks if this process has any hooks registered.
+ * @return <code>true</code> if there are hooks registered.
+ */
+ boolean hasHooks();
- public void registerHooks(Archive archive, ClassLoader classLoader) throws PackageException {
- try {
- Archive.Entry root = archive.getRoot();
- root = root.getChild(Constants.META_INF);
- if (root == null) {
- log.warn("Archive {} does not have a {} directory.", archive, Constants.META_INF);
- return;
- }
- root = root.getChild(Constants.VAULT_DIR);
- if (root == null) {
- log.warn("Archive {} does not have a {} directory.", archive, Constants.VAULT_DIR);
- return;
- }
- root = root.getChild(Constants.HOOKS_DIR);
- if (root == null) {
- log.debug("Archive {} does not have a {} directory.", archive, Constants.HOOKS_DIR);
- } else {
- for (Archive.Entry entry : root.getChildren()) {
- // only respect .jar files
- if (entry.getName().endsWith(".jar")) {
- registerHook(archive.getInputSource(entry), classLoader);
- }
- }
- }
-
- // also look for external hooks in properties
- // currently only the format: "installhook.{name}.class" is supported
- Properties props = archive.getMetaInf().getProperties();
- if (props != null) {
- Enumeration names = props.propertyNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement().toString();
- if (name.startsWith(VaultPackage.PREFIX_INSTALL_HOOK)) {
- String[] segs = Text.explode(name.substring(VaultPackage.PREFIX_INSTALL_HOOK.length()), '.');
- if (segs.length == 0 || segs.length > 2 || !segs[1].equals("class")) {
- throw new PackageException("Invalid installhook property: " + name);
- }
- Hook hook = new Hook(segs[0], props.getProperty(name), classLoader);
- initHook(hook);
- }
- }
- }
- } catch (IOException e) {
- throw new PackageException("I/O Error while registering hooks", e);
- }
- }
-
- public void registerHook(VaultInputSource input, ClassLoader classLoader) throws IOException, PackageException {
- // first we need to spool the jar file to disk.
- File jarFile = File.createTempFile("vaulthook", ".jar");
- Hook hook = new Hook(input.getSystemId(), jarFile, classLoader);
-
- OutputStream out = null;
- InputStream in = input.getByteStream();
- try {
- out = FileUtils.openOutputStream(jarFile);
- IOUtils.copy(in, out);
- } catch (IOException e) {
- hook.destroy();
- throw e;
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- initHook(hook);
- }
-
- private void initHook(Hook hook) throws IOException, PackageException {
- try {
- hook.init();
- } catch (IOException e) {
- log.error("Error while initializing hook: {}", e.toString());
- hook.destroy();
- throw e;
- } catch (PackageException e) {
- log.error("Error while initializing hook: {}", e.toString());
- hook.destroy();
- throw e;
- }
- hooks.put(hook.name, hook);
- log.info("Hook {} registered.", hook.name);
- }
-
- public boolean hasHooks() {
- return !hooks.isEmpty();
- }
-
- public boolean execute(InstallContextImpl context) {
- for (Hook hook : hooks.values()) {
- try {
- hook.getHook().execute(context);
- } catch (PackageException e) {
- // abort processing only for prepare phase
- if (context.getPhase() == InstallContext.Phase.PREPARE) {
- log.warn("Hook " + hook.name +" threw package exception. Prepare aborted.", e);
- context.setPhase(InstallContext.Phase.PREPARE_FAILED);
- execute(context);
- return false;
- }
- log.warn("Hook " + hook.name +" threw package exception. Ignored", e);
- } catch (Throwable e) {
- log.warn("Hook " + hook.name +" threw runtime exception.", e);
- }
- // if in end phase, shutdown hooks
- if (context.getPhase() == InstallContext.Phase.END) {
- hook.destroy();
- }
- }
- return true;
- }
-
- private class Hook {
-
- private final String name;
-
- private final File jarFile;
-
- private ClassLoader classLoader;
-
- private ClassLoader parentClassLoader;
-
- private InstallHook hook;
-
- private String mainClassName;
-
- private Hook(String name, String mainClassName, ClassLoader parentClassLoader) {
- this.name = name;
- this.mainClassName = mainClassName;
- this.parentClassLoader = parentClassLoader;
- this.jarFile = null;
- }
-
- private Hook(String name, File jarFile, ClassLoader parentClassLoader) {
- this.name = name;
- this.jarFile = jarFile;
- this.parentClassLoader = parentClassLoader;
- }
-
- private void destroy() {
- parentClassLoader = null;
- classLoader = null;
- hook = null;
- if (jarFile != null) {
- FileUtils.deleteQuietly(jarFile);
- }
- }
-
- private void init() throws IOException, PackageException {
- // create classloader
- if (parentClassLoader == null) {
- parentClassLoader = Thread.currentThread().getContextClassLoader();
- }
-
- if (jarFile != null) {
- // open jar file and get manifest
- JarFile jar = new JarFile(jarFile);
- Manifest mf = jar.getManifest();
- if (mf == null) {
- throw new PackageException("hook jar file does not have a manifest: " + name);
- }
- mainClassName = mf.getMainAttributes().getValue("Main-Class");
- if (mainClassName == null) {
- throw new PackageException("hook manifest file does not have a Main-Class entry: " + name);
- }
- classLoader = URLClassLoader.newInstance(
- new URL[]{jarFile.toURL()},
- parentClassLoader);
- } else {
- classLoader = parentClassLoader;
- }
- loadMainClass();
- }
-
- private void loadMainClass() throws PackageException {
- log.info("Loading Hook {}: Main-Class = {}", name, mainClassName);
-
- // find main class
- Class clazz;
- try {
- clazz = classLoader.loadClass(mainClassName);
- } catch (ClassNotFoundException e) {
- throw new PackageException("hook's main class " + mainClassName + " not found: " + name, e);
- }
- if (!InstallHook.class.isAssignableFrom(clazz)) {
- throw new PackageException("hook's main class " + mainClassName + " does not implement the InstallHook interface: " + name);
- }
- // create instance
- try {
- hook = (InstallHook) clazz.newInstance();
- } catch (Exception e) {
- throw new PackageException("hook's main class " + mainClassName + " could not be instantiated.", e);
- }
- }
-
- public InstallHook getHook() {
- return hook;
- }
- }
-}
+ /**
+ * Executes the registered hooks with the current {@link InstallContext.Phase}.
+ * @param context the context
+ * @return <code>true</code> if successful.
+ */
+ boolean execute(InstallContext context);
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessorFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessorFactory.java?rev=1533228&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessorFactory.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/InstallHookProcessorFactory.java Thu Oct 17 19:49:48 2013
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * <code>InstallHookProcessorFactory</code>...
+ */
+public interface InstallHookProcessorFactory {
+
+ InstallHookProcessor createInstallHookProcessor();
+}
\ No newline at end of file
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallContextImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallContextImpl.java?rev=1533228&r1=1533227&r2=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallContextImpl.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallContextImpl.java Thu Oct 17 19:49:48 2013
@@ -24,6 +24,7 @@ import javax.jcr.Session;
import org.apache.jackrabbit.vault.fs.io.ImportOptions;
import org.apache.jackrabbit.vault.fs.io.Importer;
import org.apache.jackrabbit.vault.packaging.InstallContext;
+import org.apache.jackrabbit.vault.packaging.InstallHookProcessor;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
/**
Copied: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessorImpl.java (from r1526256, jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java)
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessorImpl.java?p2=jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessorImpl.java&p1=jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java&r1=1526256&r2=1533228&rev=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessor.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/InstallHookProcessorImpl.java Thu Oct 17 19:49:48 2013
@@ -35,6 +35,7 @@ import org.apache.jackrabbit.vault.fs.ap
import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.packaging.InstallContext;
import org.apache.jackrabbit.vault.packaging.InstallHook;
+import org.apache.jackrabbit.vault.packaging.InstallHookProcessor;
import org.apache.jackrabbit.vault.packaging.PackageException;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.jackrabbit.vault.util.Constants;
@@ -45,12 +46,12 @@ import org.slf4j.LoggerFactory;
/**
* processor for install hooks
*/
-public class InstallHookProcessor {
+public class InstallHookProcessorImpl implements InstallHookProcessor {
/**
* default logger
*/
- private static final Logger log = LoggerFactory.getLogger(InstallHookProcessor.class);
+ private static final Logger log = LoggerFactory.getLogger(InstallHookProcessorImpl.class);
private final TreeMap<String, Hook> hooks = new TreeMap<String, Hook>();
@@ -141,7 +142,7 @@ public class InstallHookProcessor {
return !hooks.isEmpty();
}
- public boolean execute(InstallContextImpl context) {
+ public boolean execute(InstallContext context) {
for (Hook hook : hooks.values()) {
try {
hook.getHook().execute(context);
@@ -149,7 +150,7 @@ public class InstallHookProcessor {
// abort processing only for prepare phase
if (context.getPhase() == InstallContext.Phase.PREPARE) {
log.warn("Hook " + hook.name +" threw package exception. Prepare aborted.", e);
- context.setPhase(InstallContext.Phase.PREPARE_FAILED);
+ ((InstallContextImpl) context).setPhase(InstallContext.Phase.PREPARE_FAILED);
execute(context);
return false;
}
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java?rev=1533228&r1=1533227&r2=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageImpl.java Thu Oct 17 19:49:48 2013
@@ -328,7 +328,7 @@ public class JcrPackageImpl implements J
throws RepositoryException, PackageException, IOException {
getPackage();
// get a copy of the import options (bug 35164)
- ImportOptions opts = new ImportOptions(options);
+ ImportOptions opts = options.copy();
// check for disable intermediate saves (GRANITE-1047)
if ( this.getDefinition().getBoolean(JcrPackageDefinition.PN_DISABLE_INTERMEDIATE_SAVE) ) {
// MAX_VALUE disables saving completely, therefore we have to use a lower value!
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java?rev=1533228&r1=1533227&r2=1533228&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/ZipVaultPackage.java Thu Oct 17 19:49:48 2013
@@ -37,6 +37,8 @@ import org.apache.jackrabbit.vault.fs.io
import org.apache.jackrabbit.vault.fs.io.ZipArchive;
import org.apache.jackrabbit.vault.packaging.Dependency;
import org.apache.jackrabbit.vault.packaging.InstallContext;
+import org.apache.jackrabbit.vault.packaging.InstallHookProcessor;
+import org.apache.jackrabbit.vault.packaging.InstallHookProcessorFactory;
import org.apache.jackrabbit.vault.packaging.PackageException;
import org.apache.jackrabbit.vault.packaging.PackageId;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
@@ -292,7 +294,9 @@ public class ZipVaultPackage implements
throw new IllegalStateException("Package not valid.");
}
// try to find any hooks
- InstallHookProcessor hooks = new InstallHookProcessor();
+ InstallHookProcessor hooks = opts instanceof InstallHookProcessorFactory ?
+ ((InstallHookProcessorFactory) opts).createInstallHookProcessor()
+ : new InstallHookProcessorImpl();
if (!opts.isDryRun()) {
hooks.registerHooks(archive, opts.getHookClassLoader());
}