blob: 5039ca11bd8676033dd56fe77b3de75741aef1a9 [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.uima.pear.tools;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.TreeSet;
import java.util.jar.JarFile;
import org.apache.uima.pear.util.FileUtil;
import org.apache.uima.pear.util.StringUtil;
import org.apache.uima.resource.RelativePathResolver;
import org.xml.sax.SAXException;
/**
* The <code>PackageBrowser</code> class allows browsing both archived and unarchived PEAR
* packages, finding package files and directories, loading installation descriptor files and
* returning run-time environment settings required for installed components.
*
* @see org.apache.uima.pear.tools.InstallationDescriptor
*/
public class PackageBrowser {
// standard directories
public static final String BINARY_DIR = File.separator + InstallationController.PACKAGE_BIN_DIR;
public static final String CONFIGURATION_DIR = File.separator
+ InstallationController.PACKAGE_CONF_DIR;
public static final String DATA_DIR = File.separator + InstallationController.PACKAGE_DATA_DIR;
public static final String DESCRIPTORS_DIR = File.separator
+ InstallationController.PACKAGE_DESC_DIR;
public static final String DOCUMENTATION_DIR = File.separator
+ InstallationController.PACKAGE_DOC_DIR;
public static final String LIBRARY_DIR = File.separator + InstallationController.PACKAGE_LIB_DIR;
public static final String METADATA_DIR = File.separator
+ InstallationController.PACKAGE_METADATA_DIR;
public static final String RESOURCES_DIR = File.separator
+ InstallationController.PACKAGE_RESOURCES_DIR;
public static final String SOURCES_DIR = File.separator
+ InstallationController.PACKAGE_SOURCES_DIR;
// standard files
public static final String INSTALLATION_DESCRIPTOR_FILE = File.separator
+ InstallationProcessor.INSD_FILE_PATH;
public static final String PEAR_PROPERTIES_FILE = File.separator
+ InstallationController.PACKAGE_CONFIG_FILE;
public static final String SUBMISSION_PROPERTIES_FILE = METADATA_DIR + "/submission.properties";
public static final String SETENV_TXT_FILE = File.separator + InstallationController.SET_ENV_FILE;
// attributes
private File _rootDir;
private JarFile _pearPackage;
private File _pearFile;
private boolean _archived;
private TreeSet _allFiles = new TreeSet();
private TreeSet _allDirs = new TreeSet();
/**
* Constructor that allows browsing a given PEAR package without unarchiving it.
*
* @param pearPackage
* The given archived PEAR package to browse.
*/
public PackageBrowser(JarFile pearPackage) throws IOException {
_pearPackage = pearPackage;
_pearFile = new File(pearPackage.getName());
int nameEndIndex = _pearFile.getAbsolutePath().lastIndexOf('.');
// set root dir = PEAR file path (w/o file name extension)
String rootDirPath = (nameEndIndex > 0) ? _pearFile.getAbsolutePath()
.substring(0, nameEndIndex) : _pearFile.getAbsolutePath();
_rootDir = new File(rootDirPath);
_archived = true;
// add directories and files to the lists
_allDirs.addAll(FileUtil.createDirList(pearPackage));
_allFiles.addAll(FileUtil.createFileList(pearPackage));
}
/**
* Constructor that allows browsing a given unacrhived PEAR package before or after its
* installation.
*
* @param pearPackageDir
* The root directory where the PEAR package was unarchived.
*/
public PackageBrowser(File pearPackageDir) throws IOException {
_rootDir = pearPackageDir;
_archived = false;
// add directories and files to the lists
_allFiles.addAll(FileUtil.createFileList(_rootDir, true));
_allDirs.addAll(FileUtil.createDirList(_rootDir, true));
}
/**
* Creates a string that should be added to the CLASSPATH to run the given installed component,
* based on its installation descriptor specifications, as well as the contents of its
* <code>lib</code> directory. The output string includes absolute path expressions for all
* relevant objects containing in the component PEAR package. If the component package is
* archived, returns <code>null</code>.
*
* @return The string that needs to be added to the CLASSPATH to run the given installed
* component.
* @throws IOException
* If any I/O exception occurred.
*/
public String buildComponentClassPath() throws IOException {
return buildComponentClassPath(false);
}
/**
* Creates a string that should be added to the CLASSPATH to run the given installed component,
* based on its installation descriptor specifications, as well as the contents of its
* <code>lib</code> directory. The output string includes absolute or relative path expressions
* for all relevant objects containing in the component PEAR package, depending on the value of a
* given <code>boolean</code> argument. If the component package is archived, returns
* <code>null</code>.
*
* @param relativePath
* If <code>true</code>, the output string will include relative path expressions for
* all relevant objects containing in the component PEAR package, otherwise it will
* contain absolute path expressions for these objects.
* @return The string that should be added to the CLASSPATH to run the given installed component.
* @throws IOException
* If any I/O exception occurred.
*/
public String buildComponentClassPath(boolean relativePath) throws IOException {
if (!isArchived()) {
InstallationDescriptor insdObject = getInstallationDescriptor();
if (insdObject != null) {
String absoluteClassPath = InstallationController.buildComponentClassPath(
getRootDirectory().getAbsolutePath(), insdObject);
String absoluteRootDirPathExp = StringUtil.toRegExpReplacement(getRootDirectory()
.getAbsolutePath().replace('\\', '/'));
return relativePath ? absoluteClassPath.replaceAll(absoluteRootDirPathExp, "\\.")
: absoluteClassPath;
}
}
return null;
}
/**
* Creates a string that should be added to the PATH to run the given installed component, based
* on the PEAR package defaults and its installation descriptor specifications. The output string
* includes absolute path expressions for all relevant objects containing in the component PEAR
* package. If the component package is archived, returns <code>null</code>.
*
* @return The string that needs to be added to the PATH to run the given installed component.
* @throws IOException
* If any I/O exception occurred.
*/
public String buildComponentPath() throws IOException {
return buildComponentPath(false);
}
/**
* Creates a string that should be added to the PATH to run the given installed component, based
* on the PEAR package defaults and its installation descriptor specifications. The output string
* includes absolute or relative path expressions for all relevant objects containing in the
* component PEAR package, depending on the value of a given <code>boolean</code> argument. If
* the component package is archived, returns <code>null</code>.
*
* @param relativePath
* If <code>true</code>, the output string will include relative path expressions for
* all relevant objects containing in the component PEAR package, otherwise it will
* contain absolute path expressions for these objects.
* @return The string that needs to be added to the PATH to run the given installed component.
* @throws IOException
* If any I/O exception occurred.
*/
public String buildComponentPath(boolean relativePath) throws IOException {
if (!isArchived()) {
InstallationDescriptor insdObject = getInstallationDescriptor();
if (insdObject != null) {
String absolutePath = InstallationController.buildComponentPath(getRootDirectory()
.getAbsolutePath(), insdObject);
String absoluteRootDirPathExp = StringUtil.toRegExpReplacement(getRootDirectory()
.getAbsolutePath().replace('\\', '/'));
return relativePath ? absolutePath.replaceAll(absoluteRootDirPathExp, "\\.") : absolutePath;
}
}
return null;
}
/**
* Looks for package directories matching a given directory name pattern in the PEAR package. If
* the given directory name pattern starts with '/' or '\', the method looks for directory names
* that start with the given name pattern, otherwise it looks for directory names that contain the
* given name pattern as a substring. The method does not support wild cards.
*
* @param dirNamePattern
* The given directory name pattern to look for.
* @return The array of matching package directories.
*/
public File[] findDirectory(String dirNamePattern) {
String pattern = dirNamePattern.replace('\\', '/');
File[] foundDirs = new File[0];
ArrayList foundDirList = new ArrayList();
Iterator list = _allDirs.iterator();
while (list.hasNext()) {
File dir = (File) list.next();
String dirName = dir.getAbsolutePath().substring(_rootDir.getAbsolutePath().length())
.replace('\\', '/');
if (pattern.startsWith(File.separator)) {
if (dirName.startsWith(pattern))
foundDirList.add(dir);
} else if (dirName.indexOf(pattern) >= 0)
foundDirList.add(dir);
}
if (foundDirList.size() > 0) {
foundDirs = new File[foundDirList.size()];
foundDirList.toArray(foundDirs);
}
return foundDirs;
}
/**
* Looks for package files matching a given file name pattern in the PEAR package. If the given
* file name pattern starts with '/' or '\', the method looks for file names that start from the
* given name pattern, otherwise it looks for file names that contain the given name pattern as a
* substring. The method does not support wild cards.
*
* @param fileNamePattern
* The given file name pattern to look for.
* @return The array of matching package files.
*/
public File[] findFile(String fileNamePattern) {
String pattern = fileNamePattern.replace('\\', '/');
File[] foundFiles = new File[0];
ArrayList foundFileList = new ArrayList();
Iterator list = _allFiles.iterator();
while (list.hasNext()) {
File file = (File) list.next();
String fileName = file.getAbsolutePath().substring(_rootDir.getAbsolutePath().length())
.replace('\\', '/');
if (pattern.startsWith(File.separator)) {
if (fileName.startsWith(pattern))
foundFileList.add(file);
}
if (fileName.indexOf(pattern) >= 0)
foundFileList.add(file);
}
if (foundFileList.size() > 0) {
foundFiles = new File[foundFileList.size()];
foundFileList.toArray(foundFiles);
}
return foundFiles;
}
/**
* Looks for a given standard package directory. This method assumes that the given standard
* directory name is the full name of the directory in the package root directory.
*
* @param stdDirName
* The given full standard package directory name.
* @return The specified standard package directory, if this directory exists in the package,
* <code>null</code> otherwise.
*/
public File findStandardDirectory(String stdDirName) {
String dirName = stdDirName.replace('\\', File.separatorChar).replace('/', File.separatorChar);
File dir = new File(_rootDir, dirName);
File foundDir = (_allDirs.contains(dir)) ? dir : null;
return foundDir;
}
/**
* Looks for a given standard package file. This method assumes that the given standard file name
* is the full name of the file in the package root directory.
*
* @param stdFileName
* The given full standard package file name.
* @return The specified standard package file, if this file exists in the package,
* <code>null</code> otherwise.
*/
public File findStandardFile(String stdFileName) {
String fileName = stdFileName.replace('\\', File.separatorChar)
.replace('/', File.separatorChar);
File file = new File(_rootDir, fileName);
File foundFile = (_allFiles.contains(file)) ? file : null;
return foundFile;
}
/**
* @return Array of <code>File</code> objects representing all directories existing in the
* package.
*/
public File[] getAllDirectories() {
File[] array = new File[_allDirs.size()];
_allDirs.toArray(array);
return array;
}
/**
* @return Array of <code>File</code> objects representing all files existing in the package.
*/
public File[] getAllFiles() {
File[] array = new File[_allFiles.size()];
_allFiles.toArray(array);
return array;
}
/**
* Loads the <code>INSTALLATION_DESCRIPTOR_FILE</code> file, and creates the
* <code>InstallationDescriptor</code> (InsD) object. <b>Note:</b> if the component package has
* been installed, the InsD object contains real specifications of package directories, otherwise
* it may contain macros like <code>$main_root</code>.
*
* @return The InsD object corresponding the installation descriptor file.
* @throws IOException
* If any I/O exception occurred.
*/
public InstallationDescriptor getInstallationDescriptor() throws IOException {
InstallationDescriptorHandler insdHandler = new InstallationDescriptorHandler();
InstallationDescriptor insdObject = null;
if (isArchived()) {
try {
insdHandler.parseInstallationDescriptor(_pearPackage);
insdObject = insdHandler.getInstallationDescriptor();
} catch (SAXException err) {
throw new IOException(err.toString());
}
} else {
File insdFile = findStandardFile(INSTALLATION_DESCRIPTOR_FILE);
if (insdFile != null) {
try {
insdHandler.parse(insdFile);
insdObject = insdHandler.getInstallationDescriptor();
insdObject.setMainComponentRoot(getRootDirectory().getAbsolutePath());
} catch (SAXException err) {
throw new IOException(err.toString());
}
}
}
return insdObject;
}
/**
* @return The package root directory, where the package was unarchived, or the directory
* corresponding to the package file path without its extension, if the archived package
* was specified.
*/
public File getRootDirectory() {
return _rootDir;
}
/**
* @return <code>true</code>, if the archived package was specified, <code>false</code>
* otherwise.
*/
public boolean isArchived() {
return _archived;
}
/**
* returns the pear component pearSpecifier file path.
*
* @return returns the pear component pearSpecifier file path or null if an archived package was
* used.
*
* @throws IOException
*/
public String getComponentPearDescPath() throws IOException {
// if the package is not installed, return null
if (_archived) {
return null;
} else {
// get pear descriptor file and return it as file path
File pearDescFile = new File(this._rootDir, this.getInstallationDescriptor()
.getMainComponentId()
+ InstallationController.PEAR_DESC_FILE_POSTFIX);
return pearDescFile.getAbsolutePath();
}
}
/**
* Returns the UIMA datapath setting for the component.
*
* The datapath of the component must be specified as environment variable with the key
* <code>uima.datapath</code>.
*
* @return the datapath setting for the component or null if the datapath is not specified.
*
* @throws IOException
* If any I/O exception occurred while reading the component meta data.
*/
public String getComponentDataPath() throws IOException {
// get all environment variables that are specified for the current pear file
Properties pearEnvProps = InstallationController.buildTableOfEnvVars(this
.getInstallationDescriptor());
// return the uima datapath setting if available. If not return null
return (String) pearEnvProps.get(RelativePathResolver.UIMA_DATAPATH_PROP);
}
/**
* Returns the environment variable settings for the component. The variable settings does not
* contain the <code>classpath</code> and <code>uima.datapath</code> settings for the
* component.
*
* @return returns the environment variable settings for the component
*
* @throws IOException
* If any I/O exception occurred while reading the component meta data.
*/
public Properties getComponentEnvVars() throws IOException {
// get all environment variables that are specified for the current pear file
Properties pearEnvProps = InstallationController.buildTableOfEnvVars(this
.getInstallationDescriptor());
// removes the UIMA datapath setting if available since it is already returned with the
// getComponentDataPath() method.
pearEnvProps.remove(RelativePathResolver.UIMA_DATAPATH_PROP);
// return the environment variables specified for the component
return pearEnvProps;
}
}