blob: f66308c3ad8fb96c6877f79e2af17ea7f8e75b66 [file] [log] [blame]
/*
* 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;
}
}