libreccm-legacy/ccm-core/src/com/arsdigita/packaging/HostInit.java

358 lines
12 KiB
Java
Executable File
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.packaging;
import com.arsdigita.runtime.ConfigRegistry;
import com.arsdigita.util.Files;
import com.arsdigita.util.StringUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
/**
* Populates the CCM application directory in webapps.
*
* Implements the "hostinit" command and is called by the
* ccm hostinit / ccm hostinit-bundle command of the ccm PERL based
* script system (up to APLAWS 1.0.5 / CCM 6.5).
*
* In addition to populating the webapp directory the ccm command
* used to configure the servlet container (hence to information
* about servlet container and http port below).
* Does not create the database nor the config registry.
*
* Options:
* --help Display help
* --usage Print this message
* --container Specify the servlet container to initialize
* --clean REQUIRED: Delete the existing webapp directories
* before performing file copy.
*
* Command line call of hostinit via ccm scripts (shell, perl)
* root@localhost# ccm hostinit­bundle \
* ­­clean \
* ­­name aplaws­plus­standard ­­container=tomcat \
* http­port=8080 shutdown­port=8081 ajp­port=8009
*
* @author Rafael H. Schloming <rhs@mit.edu>
* @version $Revision: #16 $ $Date: 2004/08/16 $
**/
public class HostInit {
public final static String versionId =
"$Id: HostInit.java 736 2005-09-01 10:46:05Z sskracic $" +
"by $Author: sskracic $, " +
"$DateTime: 2004/08/16 18:10:38 $";
private static final Logger s_log =
Logger.getLogger(HostInit.class);
private static final Options OPTIONS = new Options();
static {
OPTIONS.addOption
(OptionBuilder
.hasArg()
.isRequired()
.withLongOpt("classpath")
.withArgName("FILE")
.create());
OPTIONS.addOption
(OptionBuilder
.hasArg()
.isRequired()
.withLongOpt("webapps")
.withArgName("FILE")
.create());
OPTIONS.addOption
(OptionBuilder
.hasArg()
.isRequired()
.withLongOpt("destination")
.withArgName("DIRECTORY")
.create());
OPTIONS.addOption
(OptionBuilder
.hasArg(false)
.withLongOpt("clean")
.withDescription("Remove the destination directory before copying files")
.create());
}
private static final void err(String msg) {
System.err.println(msg);
System.exit(1);
}
public static final void main(String[] args) {
if (args.length == 0) {
Command.usage(OPTIONS, System.err,
"com.arsdigita.packaging.HostInit", null);
System.exit(1);
}
// Register custom protocol handlers
// No longer needed as of CCM 6.6
// com.arsdigita.runtime.Startup.startup();
CommandLine line;
try {
line = new PosixParser().parse(OPTIONS, args);
} catch (ParseException e) {
err(e.getMessage());
return;
}
String classpath = line.getOptionValue("classpath");
String webapps = line.getOptionValue("webapps");
String destination = line.getOptionValue("destination");
boolean clean = line.hasOption("clean");
// base dir for all webapps, same as CATALINA_HOME
// same as CCM_HOME
File dest = new File(destination);
// Currently: non-standard location of lib and classes
File inf = new File(dest, "WEB-INF");
// Currentliy: non-standard location of lib
File lib = new File(inf, "lib");
// currently (<=6.5): non-standard, special URL:resource handler, to be discarded
// Removed on >= 6.6
// File system = new File(inf, "system");
if (!dest.exists()) {
dest.mkdir();
if (!dest.exists()) {
err("unable to create destination: " + dest);
}
}
if (clean) {
File[] contents = dest.listFiles();
if (contents == null) {
err("unable to get directory listing: " + dest);
}
for (int i = 0; i < contents.length; i++) {
Files.delete(contents[i]);
}
}
lib.mkdirs();
if (!(lib.exists() && lib.isDirectory())) {
err("unable to create lib: " + lib);
}
// >= 6.6 system jar removed
// system.mkdirs();
// if (!(system.exists() && system.isDirectory())) {
// err("unable to create system: " + system);
// }
// check the configuration database (registry) for packages (modules)
// retrieve a list of packages to deal with
ConfigRegistry reg = new ConfigRegistry();
List packages = reg.getPackages();
// Do the real work now.
try {
copy(classpath, packages, lib);
// no longer used >= 6.6
// copySystem(classpath, packages, system);
copy(webapps, packages, dest);
} catch (IOException e) {
err(e.getMessage());
}
}
/**
* Internal general helper method to copy files from one location to a
* destination dir using a list of files (packages) to copy.
*
* @param pathfile Path where to look for files specified in packages
* @param packages List of files to copy
* @param dest Destination directory
* @throws java.io.IOException
*/
private static void copy(String pathfile, List packages, File dest)
throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(pathfile));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("#")) {
continue;
}
if (line.equals("")) {
continue;
}
if (contains(line, packages)) {
File file = new File(line);
if (line.endsWith(File.separator)) {
copyDirectory(file, dest);
} else {
if (file.isFile() && line.endsWith(".jar")) {
copyJar(file, dest);
} else {
if (s_log.isInfoEnabled()) {
s_log.info("Copying " + file.toString());
}
Files.copy(file, dest, Files.IGNORE_EXISTING);
}
}
} else {
if (s_log.isInfoEnabled()) {
s_log.info("Entry found in file that does not correspond " +
"to an installed package: " + line);
}
}
}
reader.close();
}
/**
* Internal helper method to copy all files in a given directory (dir)
* to a destination directory (dest).
*
* @param dir source directory path
* @param dest destination direcotry path
* @throws java.io.IOException
*/
private static void copyDirectory(File dir, File dest) throws IOException {
if (s_log.isInfoEnabled()) {
s_log.info("Copying directory " + dir.toString());
}
if (!dir.isDirectory()) {
err("directory does not exist: " + dir);
}
File[] files = dir.listFiles();
if (files == null) {
err("unable to get directory listing: " + dir);
}
for (int i = 0; i < files.length; i++) {
Files.copy(files[i], dest, Files.IGNORE_EXISTING);
}
}
/**
* Copies ..... (currently not used.)
*
* @param file
* @param dest
* @throws java.io.IOException
*/
private static void copyJar(File file, File dest) throws IOException {
if (s_log.isInfoEnabled()) {
s_log.info("Copying JAR " + file.toString());
}
Files.copy(file, dest, Files.IGNORE_EXISTING);
File dir = file.getParentFile();
JarFile jar = new JarFile(file);
Manifest manifest = jar.getManifest();
if (manifest == null) { return; }
Attributes attrs = manifest.getMainAttributes();
if (attrs == null) { return; }
String path = attrs.getValue("Class-Path");
if (path == null) { return; }
String[] jars = StringUtils.split(path, ' ');
for (int i = 0; i < jars.length; i++) {
String rel = jars[i].trim();
if (rel.length() == 0) { continue; }
File sub = new File(dir, rel);
if (sub.exists()) {
if (s_log.isInfoEnabled()) {
s_log.info("Copying referenced JAR " + sub.toString());
}
Files.copy(sub, dest, Files.IGNORE_EXISTING);
}
}
}
/**
*
*/
private static boolean contains(String line, List packages) {
for (Iterator it = packages.iterator(); it.hasNext(); ) {
String key = (String) it.next();
if (line.indexOf(key) >= 0) {
return true;
}
}
return false;
}
// As of version 6.6 system.jar is no longer used. Code kept here as
// an example just in case the mechanism is required for another purpose.
// /**
// * Copies the ccm-core-6.y.z-system.jar (java extension for URL:resource
// * protocol handler) to its special location.
// *
// * Will not be used as soon as the resource protocol is replaced by a
// * standard compliant mechanism.
// *
// * @param pathfile
// * @param packages
// * @param dest
// * @throws java.io.IOException
// * @deprecated
// */
// private static void copySystem(String pathfile, List packages, File dest)
// throws IOException {
// BufferedReader reader = new BufferedReader(new FileReader(pathfile));
// String line;
// while ((line = reader.readLine()) != null) {
// line = line.trim();
// if (contains(line, packages) && line.endsWith(".jar")) {
// String newline = line.substring(0, line.lastIndexOf(".jar")) +
// "-system.jar";
// File file = new File(newline);
// if (file.isFile()) {
// if (s_log.isInfoEnabled()) {
// s_log.info("Copying System JAR " + file.toString());
// }
// Files.copy(file, dest, Files.IGNORE_EXISTING);
// }
// }
// }
// reader.close();
// }
}