| /* |
| * 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.vlt; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.net.URISyntaxException; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.jcr.Credentials; |
| import javax.jcr.Repository; |
| import javax.jcr.RepositoryException; |
| import javax.jcr.Session; |
| |
| import org.apache.jackrabbit.vault.fs.Mounter; |
| import org.apache.jackrabbit.vault.fs.api.ImportMode; |
| import org.apache.jackrabbit.vault.fs.api.PathFilter; |
| import org.apache.jackrabbit.vault.fs.api.PathFilterSet; |
| import org.apache.jackrabbit.vault.fs.api.RepositoryAddress; |
| import org.apache.jackrabbit.vault.fs.api.VaultFileSystem; |
| import org.apache.jackrabbit.vault.fs.api.VaultFsConfig; |
| import org.apache.jackrabbit.vault.fs.config.ConfigurationException; |
| import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter; |
| import org.apache.jackrabbit.vault.fs.config.ExportRoot; |
| import org.apache.jackrabbit.vault.fs.config.MetaInf; |
| import org.apache.jackrabbit.vault.util.Constants; |
| import org.apache.jackrabbit.vault.util.PathUtil; |
| import org.apache.jackrabbit.vault.util.RepositoryProvider; |
| import org.apache.jackrabbit.vault.vlt.actions.Action; |
| import org.apache.jackrabbit.vault.vlt.meta.Ignored; |
| import org.apache.jackrabbit.vault.vlt.meta.MetaDirectory; |
| import org.apache.jackrabbit.vault.vlt.meta.xml.zip.ZipMetaDir; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * {@code VaultContext}... |
| * |
| */ |
| public class VltContext { |
| |
| protected static Logger log = LoggerFactory.getLogger(VltContext.class); |
| |
| private final File cwd; |
| |
| private final RepositoryProvider repProvider; |
| |
| private final CredentialsStore credsProvider; |
| |
| private final ExportRoot exportRoot; |
| |
| private Map<RepositoryAddress, VaultFileSystem> fileSystems |
| = new HashMap<RepositoryAddress, VaultFileSystem>(); |
| |
| private RepositoryAddress mountpoint; |
| |
| private boolean verbose; |
| |
| private boolean quiet; |
| |
| private boolean swallowErrors = true; |
| |
| private final PrintStream stdout; |
| |
| private String[] defaultFilterRoots = Constants.EMPTY_STRING_ARRAY; |
| |
| private String defaultFilter; |
| |
| private String fsRoot = ""; |
| |
| private PathFilter globalIgnored; |
| |
| public VltContext(File cwd, File localFile, |
| RepositoryProvider repProvider, |
| CredentialsStore credsProvider) |
| throws ConfigurationException, IOException { |
| this(cwd, localFile, repProvider, credsProvider, System.out); |
| } |
| |
| public VltContext(File cwd, File localFile, |
| RepositoryProvider repProvider, |
| CredentialsStore credsProvider, |
| PrintStream out) |
| throws ConfigurationException, IOException { |
| if (!cwd.exists()) { |
| throw new FileNotFoundException(cwd.getAbsolutePath()); |
| } |
| if (!localFile.exists()) { |
| throw new FileNotFoundException(localFile.getAbsolutePath()); |
| } |
| this.stdout = out; |
| this.cwd = cwd; |
| this.repProvider = repProvider; |
| this.credsProvider = credsProvider; |
| ExportRoot er = ExportRoot.findRoot(localFile); |
| if (er == null) { |
| er = new ExportRoot(localFile); |
| } |
| this.exportRoot = er; |
| } |
| |
| public RepositoryAddress getMountpoint() throws VltException { |
| if (mountpoint == null) { |
| File dir = new File(exportRoot.getJcrRoot(), VltDirectory.META_DIR_NAME); |
| MetaDirectory rootMeta = VltContext.createMetaDirectory(dir); |
| try { |
| String addr = rootMeta.getRepositoryUrl(); |
| if (addr == null) { |
| throw new VltException("Root directory must provide a repository url file."); |
| } |
| mountpoint = new RepositoryAddress(addr); |
| } catch (IOException e) { |
| throw new VltException("error while reading repository address.", e); |
| } catch (URISyntaxException e) { |
| throw new VltException("Illegal repository address.", e); |
| } |
| } |
| return mountpoint; |
| } |
| |
| public static MetaDirectory createMetaDirectory(File base) throws VltException { |
| //return new FileMetaDir(base); |
| try { |
| //return new TarMetaDir(base); |
| return new ZipMetaDir(base); |
| } catch (IOException e) { |
| throw new VltException("Error creating meta directory.", e); |
| } |
| } |
| |
| public String getFsRoot() { |
| return fsRoot; |
| } |
| |
| public void setFsRoot(String fsRoot) { |
| if (fsRoot == null || fsRoot.equals("/")) { |
| this.fsRoot = ""; |
| } else { |
| this.fsRoot = fsRoot; |
| } |
| } |
| |
| public PathFilter getGlobalIgnored() { |
| return globalIgnored; |
| } |
| |
| public void setGlobalIgnored(PathFilter globalIgnored) { |
| this.globalIgnored = globalIgnored; |
| } |
| |
| /** |
| * Sets the filesystem root to the aggregate path defined by the entries |
| * of the given directory. |
| * |
| * @param dir the directory |
| * @throws VltException if an error occurs |
| */ |
| public void setFsRoot(VltDirectory dir) throws VltException { |
| String aPath = dir.getAggregatePath(); |
| if (aPath != null) { |
| RepositoryAddress adr = getMountpoint().resolve(aPath); |
| setFsRoot(aPath); |
| setMountpoint(adr); |
| } |
| } |
| |
| public void setMountpoint(RepositoryAddress addr) throws VltException { |
| mountpoint = addr; |
| File dir = new File(exportRoot.getJcrRoot(), VltDirectory.META_DIR_NAME); |
| MetaDirectory rootMeta = VltContext.createMetaDirectory(dir); |
| try { |
| String url = addr.toString(); |
| if (fsRoot.length() > 0 && url.endsWith(fsRoot)) { |
| url = url.substring(0, url.length() - fsRoot.length()); |
| } |
| rootMeta.setRepositoryUrl(url); |
| } catch (IOException e) { |
| throw new VltException("error while writing repository address.", e); |
| } |
| } |
| |
| public Session login(RepositoryAddress mountpoint) throws RepositoryException { |
| Repository rep = repProvider.getRepository(mountpoint); |
| Credentials creds = credsProvider.getCredentials(mountpoint); |
| Session s = rep.login(creds); |
| // hack to store credentials |
| credsProvider.storeCredentials(mountpoint, creds); |
| return s; |
| } |
| |
| public VaultFileSystem getFileSystem(RepositoryAddress mountpoint) |
| throws VltException { |
| VaultFileSystem fs = fileSystems.get(mountpoint); |
| if (fs == null) { |
| try { |
| // check if export root already defines config and filter |
| DefaultWorkspaceFilter filter = null; |
| VaultFsConfig config = null; |
| if (exportRoot != null && exportRoot.getMetaInf() != null) { |
| filter = (DefaultWorkspaceFilter) exportRoot.getMetaInf().getFilter(); |
| config = exportRoot.getMetaInf().getConfig(); |
| } |
| if (filter == null && defaultFilterRoots.length > 0) { |
| filter = new DefaultWorkspaceFilter(); |
| for (String root: defaultFilterRoots) { |
| filter.add(new PathFilterSet(root)); |
| } |
| stdout.printf("Created default filter:%n%s", filter.getSourceAsString()); |
| } |
| if (filter == null && defaultFilter != null) { |
| filter = new DefaultWorkspaceFilter(); |
| try { |
| filter.load(new File(defaultFilter)); |
| } catch (ConfigurationException e) { |
| throw new VltException("Specified filter is not valid.", e); |
| } |
| } |
| // get .vltignore files |
| if (exportRoot != null && filter != null) { |
| if (globalIgnored == null) { |
| globalIgnored = new Ignored(this, cwd); |
| } |
| filter.setGlobalIgnored(globalIgnored); |
| } |
| // override any import mode defined in the filter as this is not expected when committing files (GRANITE-XYZ) |
| if (filter != null) { |
| filter.setImportMode(ImportMode.REPLACE); |
| } |
| |
| Repository rep = repProvider.getRepository(mountpoint); |
| Credentials creds = credsProvider.getCredentials(mountpoint); |
| fs = Mounter.mount(config, filter, rep, creds, mountpoint, fsRoot); |
| // hack to store credentials |
| credsProvider.storeCredentials(mountpoint, creds); |
| |
| } catch (RepositoryException e) { |
| throw new VltException("Unable to mount filesystem", e); |
| } catch (IOException e) { |
| throw new VltException("Unable to mount filesystem", e); |
| } |
| fileSystems.put(mountpoint, fs); |
| } |
| return fs; |
| } |
| |
| public ExportRoot getExportRoot() { |
| return exportRoot; |
| } |
| |
| public MetaInf getMetaInf() { |
| return exportRoot.isValid() ? exportRoot.getMetaInf() : null; |
| } |
| |
| public String[] getDefaultFilterRoots() { |
| return defaultFilterRoots; |
| } |
| |
| public void setDefaultFilterRoots(String[] defaultFilterRoots) { |
| this.defaultFilterRoots = defaultFilterRoots; |
| } |
| |
| public String getDefaultFilter() { |
| return defaultFilter; |
| } |
| |
| public void setDefaultFilter(String defaultFilter) { |
| this.defaultFilter = defaultFilter; |
| } |
| |
| public void close() { |
| for (RepositoryAddress addr: fileSystems.keySet()) { |
| VaultFileSystem fs = fileSystems.get(addr); |
| try { |
| fs.unmount(); |
| } catch (RepositoryException e) { |
| log.warn("Error while unmounting fs.", e); |
| } |
| } |
| fileSystems.clear(); |
| } |
| |
| public boolean execute(Action action) throws VltException { |
| try { |
| action.run(this); |
| } catch (VltException e) { |
| if (swallowErrors && e.isUserError()) { |
| printError(e); |
| return false; |
| } else { |
| throw e; |
| } |
| } |
| return true; |
| } |
| |
| public String getCwdRelativePath(String path) { |
| return PathUtil.getRelativeFilePath(cwd.getPath(), path); |
| } |
| |
| public VltException error(String path, String msg) { |
| path = getCwdRelativePath(path); |
| return new VltException(path, true, msg, null); |
| } |
| |
| public VltException exception(String path, String msg, Throwable cause) { |
| path = getCwdRelativePath(path); |
| return new VltException(path, false, msg, cause); |
| } |
| |
| public void printAction(VltFile file, FileAction action) { |
| printAction(file.getPath(), action, file.getContentType()); |
| } |
| |
| public void printAction(String path, FileAction action, String contentType) { |
| if (!quiet && (verbose || action != FileAction.VOID)) { |
| path = getCwdRelativePath(path); |
| if (action == FileAction.ADDED && contentType != null) { |
| stdout.printf("%s %s (%s)%n", action.letter, path, contentType); |
| } else { |
| stdout.printf("%s %s%n", action.letter, path); |
| } |
| stdout.flush(); |
| } |
| } |
| |
| public void printError(VltException e) { |
| stdout.println(e.getMessage()); |
| stdout.flush(); |
| } |
| |
| public void printMessage(VltFile file, String msg) { |
| if (!quiet) { |
| String path = getCwdRelativePath(file.getPath()); |
| stdout.printf("%s %s%n", path, msg); |
| stdout.flush(); |
| } |
| } |
| |
| public void printMessage(String msg, VltFile file) { |
| if (!quiet) { |
| String path = getCwdRelativePath(file.getPath()); |
| stdout.printf("%s %s%n", msg, path); |
| stdout.flush(); |
| } |
| } |
| |
| public void printMessage(String msg) { |
| if (!quiet) { |
| stdout.println(msg); |
| stdout.flush(); |
| } |
| } |
| |
| public void printStatus(VltFile file) |
| throws VltException { |
| String path = getCwdRelativePath(file.getPath()); |
| VltFile.State state = file.getStatus(); |
| if (quiet && state == VltFile.State.UNKNOWN) { |
| return; |
| } |
| if (verbose || state != VltFile.State.CLEAN) { |
| if (state == VltFile.State.ADDED && file.getContentType() != null) { |
| stdout.printf("%s %s (%s)%n", state.letter, path, file.getContentType()); |
| } else { |
| stdout.printf("%s %s%n", state.letter, path); |
| } |
| stdout.flush(); |
| } |
| } |
| |
| public void printRemoteStatus(VltFile file, FileAction action) |
| throws VltException { |
| String path = getCwdRelativePath(file.getPath()); |
| VltFile.State state = file.getStatus(); |
| if (quiet && state == VltFile.State.UNKNOWN && action == FileAction.VOID) { |
| return; |
| } |
| if (verbose || state != VltFile.State.CLEAN || action != FileAction.VOID) { |
| stdout.printf("%s%s %s%n", state.letter, action.letter, path); |
| stdout.flush(); |
| } |
| } |
| |
| public PrintStream getStdout() { |
| return stdout; |
| } |
| |
| public File getCwd() { |
| return cwd; |
| } |
| |
| public boolean isVerbose() { |
| return verbose; |
| } |
| |
| public void setVerbose(boolean verbose) { |
| this.verbose = verbose; |
| } |
| |
| public boolean isQuiet() { |
| return quiet; |
| } |
| |
| public void setQuiet(boolean quiet) { |
| this.quiet = quiet; |
| } |
| |
| } |