package com.razorfish.platforms.intellivault.services.impl; import com.intellij.openapi.diagnostic.Logger; import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; import com.razorfish.platforms.intellivault.services.VaultInvokerService; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * The Vault Invoker Service which handles actually calling vault to do import/export operations and dealng with the * classloaders to do so. */ public class VaultInvokerServiceImpl implements VaultInvokerService { private static final String VAULT_CLASS = "com.day.jcr.vault.cli.VaultFsApp"; private static final String VAULT3_CLASS = "org.apache.jackrabbit.vault.cli.VaultFsApp"; private static final String VAULT_METHOD = "main"; public static final String LIB = "lib"; public static final String BIN = "bin"; private ClassLoader vaultClassLoader; private boolean init = false; private boolean isVault3 = false; private static final Logger log = Logger.getInstance(VaultInvokerServiceImpl.class); @Override public void invokeVault(String vaultDir, String[] args) throws IntelliVaultException { try { initVault(vaultDir); log.info("executing vlt with params: " + Arrays.toString(args)); ClassLoader cl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(vaultClassLoader); //figure out which vlt class to use based on version String vltCLs = isVault3 ? VAULT3_CLASS : VAULT_CLASS; Class<?> vltClass = Class.forName(vltCLs, true, vaultClassLoader); Method vltMethod = vltClass.getMethod(VAULT_METHOD, String[].class); vltMethod.invoke(null, new Object[] {args}); } finally { Thread.currentThread().setContextClassLoader(cl); } } catch (ClassNotFoundException e) { throw new IntelliVaultException(e); } catch (NoSuchMethodException e) { throw new IntelliVaultException(e); } catch (InvocationTargetException e) { throw new IntelliVaultException(e); } catch (IllegalAccessException e) { throw new IntelliVaultException(e); } catch (IOException e) { throw new IntelliVaultException(e); } } @Override public void forceReInit() { init = false; } /** * Initialize vault. Basically finds all the jars in the vault folder and creates a custom class loader which * includes those jars. All vault operations are then executed using that class loader. * * @param vaultDir the vault home directory as specified in the settings diaog. Could be the root directory, or * potentially the bin or lib directory. * @throws IOException if an error occurs, sucha s the vault directory not being set. */ private void initVault(String vaultDir) throws IOException { if (!init) { if (vaultDir == null || vaultDir.trim().length() == 0) { throw new IOException("Vault Directory not set"); } if (vaultDir.endsWith(BIN)) { vaultDir = vaultDir.substring(0, vaultDir.lastIndexOf(File.separator)); } if (!vaultDir.endsWith(LIB)) { vaultDir += File.separator + LIB; } List<URL> libList = new ArrayList<URL>(); File libDir = new File(vaultDir.replace('/', File.separatorChar)); File[] libs = libDir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return (name.endsWith(".jar")) || (name.endsWith(".zip")); } }); if (libs != null) { for (File lib : libs) { try { libList.add(lib.toURI().toURL()); String libName = lib.getName(); if (libName.contains("vault-vlt-3")) { isVault3 = true; } } catch (IOException e) { log.error("error loading lib " + lib.getAbsolutePath(), e); } } vaultClassLoader = new URLClassLoader(libList.toArray(new URL[libList.size()])); init = true; } } } }