/* | |
* 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.tools.pear.merger; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.Collection; | |
import java.util.Iterator; | |
import org.apache.uima.pear.tools.InstallationDescriptor; | |
import org.apache.uima.pear.tools.InstallationDescriptorHandler; | |
import org.apache.uima.pear.tools.InstallationProcessor; | |
import org.apache.uima.pear.tools.PackageBrowser; | |
import org.apache.uima.pear.util.FileUtil; | |
/** | |
* The <code>PMControllerHelper</code> class implements utility methods that are utilized by the | |
* <code>{@link PMController}</code> class. | |
*/ | |
public class PMControllerHelper { | |
// Macros | |
static final String MAIN_ROOT = "$main_root"; | |
static final String MAIN_ROOT_REGEX = "\\$main_root"; | |
static final String STANDARD_PATH_SEPARATOR = ";"; | |
static final char STANDARD_PATH_SEPARATOR_CHAR = ';'; | |
/** | |
* Creates a 'set_env_variable' action object based on given environment variable name and value. | |
* | |
* @param envVarName | |
* The given environment variable name. | |
* @param envVarValue | |
* The given environment variable value. | |
* @return The <code>InstallationDescriptor.ActionInfo</code> object, containing the | |
* 'set_env_variable' action. | |
*/ | |
private static InstallationDescriptor.ActionInfo createEnvAction(String envVarName, | |
String envVarValue) { | |
InstallationDescriptor.ActionInfo action = new InstallationDescriptor.ActionInfo( | |
InstallationDescriptor.ActionInfo.SET_ENV_VARIABLE_ACT); | |
action.params.setProperty(InstallationDescriptorHandler.VAR_NAME_TAG, envVarName); | |
action.params.setProperty(InstallationDescriptorHandler.VAR_VALUE_TAG, envVarValue); | |
return action; | |
} | |
/** | |
* Creates a 'find_and_replace_path' action object based on given file path and 'macro' path, | |
* which is used as both the search string and the replacement string. | |
* | |
* @param filePath | |
* The given file path, that specifies the target file for this action. | |
* @param macroPath | |
* The given 'macro' path that is used as both the search string and the replacement | |
* string (e.g. $main_root). | |
* @return The <code>InstallationDescriptor.ActionInfo</code> object, containing the | |
* 'find_and_replace_path' action. | |
*/ | |
private static InstallationDescriptor.ActionInfo createFileAction(String filePath, | |
String macroPath) { | |
InstallationDescriptor.ActionInfo action = new InstallationDescriptor.ActionInfo( | |
InstallationDescriptor.ActionInfo.FIND_AND_REPLACE_PATH_ACT); | |
action.params.setProperty(InstallationDescriptorHandler.FILE_TAG, filePath); | |
action.params.setProperty(InstallationDescriptorHandler.FIND_STRING_TAG, macroPath); | |
action.params.setProperty(InstallationDescriptorHandler.REPLACE_WITH_TAG, macroPath); | |
return action; | |
} | |
/** | |
* Creates and saves installation descriptor for the merged PEAR, based on given output root | |
* directory, output aggregate component descriptor file, output aggregate component name (ID), | |
* array of delegate (input) installation descriptors and array of output delegate root | |
* directories. Returns <code>InstallationDescriptor</code> object for the merged PEAR. | |
* | |
* @param rootDir | |
* The given output root directory. | |
* @param aggDescFile | |
* The given output aggregate component descriptor file. | |
* @param aggCompName | |
* The given output aggregate component name (ID). | |
* @param dlgInstDescs | |
* The given array of delegate (input) installation descriptors. | |
* @param dlgRootDirs | |
* The given array of output delegate root directories. | |
* @return The <code>InstallationDescriptor</code> object for the merged PEAR. | |
* @throws IOException | |
* If an I/O exception occurred. | |
*/ | |
static InstallationDescriptor generateMergedInstallationDescriptor(File rootDir, | |
String aggCompName, File aggDescFile, InstallationDescriptor[] dlgInstDescs, | |
File[] dlgRootDirs) throws IOException { | |
// create aggregate installation descriptor | |
File aggInsdFile = new File(rootDir, PackageBrowser.INSTALLATION_DESCRIPTOR_FILE); | |
InstallationDescriptor aggInsdObject = new InstallationDescriptor(aggInsdFile); | |
aggInsdObject.setMainComponent(aggCompName); | |
// 1st step: set aggregate component descriptor | |
String aggDescPath = MAIN_ROOT + "/" | |
+ FileUtil.getRelativePath(rootDir, aggDescFile.getAbsolutePath()); | |
aggInsdObject.setMainComponentDesc(aggDescPath); | |
// 2nd step: collect installation actions from delegates | |
for (int i = 0; i < dlgInstDescs.length; i++) { | |
InstallationDescriptor dlgInsdObject = dlgInstDescs[i]; | |
// add implicit installation actions | |
File dlgRootDir = dlgRootDirs[i]; | |
String adjMainRoot = MAIN_ROOT + "/" + dlgRootDir.getName(); | |
StringBuffer cpBuffer = new StringBuffer(); | |
// add JAR files in delegate lib dir to CLASSPATH | |
File dlgLibDir = new File(dlgRootDir, PackageBrowser.LIBRARY_DIR); | |
if (dlgLibDir.isDirectory()) { | |
// get list of JAR files | |
File[] jarFiles = dlgLibDir.listFiles(new FileUtil.ExtFilenameFilter(".jar")); | |
// build delegate CLASSPATH buffer | |
cpBuffer.setLength(0); | |
for (int n = 0; n < jarFiles.length; n++) { | |
if (cpBuffer.length() > 0) | |
cpBuffer.append(STANDARD_PATH_SEPARATOR_CHAR); | |
cpBuffer.append(adjMainRoot + "/" | |
+ FileUtil.getRelativePath(dlgRootDir, jarFiles[n].getAbsolutePath())); | |
} | |
// add 'set_env_variable' action | |
if (cpBuffer.length() > 0) | |
aggInsdObject.addInstallationAction(createEnvAction("CLASSPATH", cpBuffer.toString())); | |
} | |
// add delegate bin dir to CLASSPATH and PATH | |
File dlgBinDir = new File(dlgRootDir, PackageBrowser.BINARY_DIR); | |
if (dlgBinDir.isDirectory()) { | |
String adjBinDirPath = adjMainRoot + "/" | |
+ FileUtil.getRelativePath(dlgRootDir, dlgBinDir.getAbsolutePath()); | |
aggInsdObject.addInstallationAction(createEnvAction("CLASSPATH", adjBinDirPath)); | |
aggInsdObject.addInstallationAction(createEnvAction("PATH", adjBinDirPath)); | |
} | |
// add explicit installation actions | |
Collection dlgInstActs = dlgInsdObject.getInstallationActions(); | |
Iterator list = dlgInstActs.iterator(); | |
while (list.hasNext()) | |
aggInsdObject.addInstallationAction((InstallationDescriptor.ActionInfo) list.next()); | |
} | |
// save aggregate installation descriptor file | |
InstallationDescriptorHandler.saveInstallationDescriptor(aggInsdObject, aggInsdFile); | |
return aggInsdObject; | |
} | |
/** | |
* Processes all delegate installation descriptors, component descriptors and configuration files, | |
* adjusting 'macros' for a given delegate root directory. Returns the delegate installation | |
* descriptor with adjusted 'macros'. | |
* | |
* @param rootDir | |
* The given delegate root directory. | |
* @return The elegate installation descriptor with adjusted 'macros'. | |
* @throws IOException | |
* If an I/O exception occurred. | |
*/ | |
static InstallationDescriptor processDescriptors(File rootDir) throws IOException { | |
// build adjusted string for $main_root replacement | |
String adjMainRoot = MAIN_ROOT + "/" + rootDir.getName(); | |
// 1st: process installation descriptor file | |
File insdFile = new File(rootDir, InstallationProcessor.INSD_FILE_PATH); | |
FileUtil.replaceStringInFile(insdFile, MAIN_ROOT_REGEX, adjMainRoot); | |
// load installation descriptor | |
InstallationDescriptorHandler insdHandler = new InstallationDescriptorHandler(); | |
try { | |
insdHandler.parse(insdFile); | |
} catch (Exception e) { | |
throw new IOException(e.toString()); | |
} | |
InstallationDescriptor insdObject = insdHandler.getInstallationDescriptor(); | |
// add installation descriptor file to 'find_and_replace_path' actions | |
insdObject.addInstallationAction(createFileAction(adjMainRoot + "/" | |
+ InstallationProcessor.INSD_FILE_PATH, MAIN_ROOT)); | |
// 2nd: process files under 'desc' folder, if exists | |
processFiles(rootDir, PackageBrowser.DESCRIPTORS_DIR, insdObject); | |
// 3rd: process files under 'conf' folder, if exists | |
processFiles(rootDir, PackageBrowser.CONFIGURATION_DIR, insdObject); | |
return insdObject; | |
} | |
/** | |
* Processes all files in a given target directory, adjusting 'macros' for a given delegate root | |
* directory. Adds appropriate 'find_and_replace_path' actions to a specified delegate | |
* installation descriptor. | |
* | |
* @param rootDir | |
* The given delegate root directory. | |
* @param targetDirName | |
* The name of the given target directory in the delegate root directory. | |
* @param insdObject | |
* The given delegate installation descriptor. | |
* @throws IOException | |
* If an I/O exception occurred. | |
*/ | |
static void processFiles(File rootDir, String targetDirName, InstallationDescriptor insdObject) | |
throws IOException { | |
// build adjusted string for $main_root replacement | |
String adjMainRoot = MAIN_ROOT + "/" + rootDir.getName(); | |
// build list of files in target dir, including sub-dirs | |
File targetDir = new File(rootDir, targetDirName); | |
if (!targetDir.isDirectory()) | |
return; | |
Iterator fileList = FileUtil.createFileList(targetDir, true).iterator(); | |
while (fileList.hasNext()) { | |
File file = (File) fileList.next(); | |
// adjust $main_root in this file | |
int counter = FileUtil.replaceStringInFile(file, MAIN_ROOT_REGEX, adjMainRoot); | |
if (counter > 0) { | |
// add this file to 'find_and_replace_path' actions | |
String relFilePath = FileUtil.getRelativePath(rootDir, file.getAbsolutePath()); | |
insdObject.addInstallationAction(createFileAction(adjMainRoot + "/" + relFilePath, | |
MAIN_ROOT)); | |
} | |
} | |
} | |
} |