001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.test.server.appserver.deployment;
006:
007: import org.apache.commons.logging.Log;
008: import org.apache.commons.logging.LogFactory;
009: import org.apache.tools.ant.taskdefs.Jar;
010: import org.apache.tools.ant.taskdefs.Zip.Duplicate;
011: import org.apache.tools.ant.types.ZipFileSet;
012: import org.codehaus.cargo.util.AntUtils;
013:
014: import java.io.File;
015: import java.net.URL;
016: import java.net.URLClassLoader;
017: import java.util.ArrayList;
018: import java.util.HashSet;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Set;
022:
023: import junit.framework.Assert;
024:
025: public class JARBuilder {
026:
027: private static final Log logger = LogFactory
028: .getLog(JARBuilder.class);
029:
030: private FileSystemPath jarDirectoryPath;
031: private String jarFileName;
032: private Set classDirectories = new HashSet();
033: private Set libs = new HashSet();
034: private List resources = new ArrayList();
035: private final FileSystemPath tempDirPath;
036:
037: public JARBuilder(String warFileName, File tempDir) {
038: this .jarFileName = warFileName;
039: this .tempDirPath = new FileSystemPath(tempDir);
040:
041: }
042:
043: public JARBuilder addClassesDirectory(FileSystemPath path) {
044: classDirectories.add(path);
045: return this ;
046: }
047:
048: public void finish() throws Exception {
049: FileSystemPath jarFile = makejarFileName();
050: logger.debug("Creating jar file: " + jarFile);
051: jarFile.delete();
052:
053: Jar jarTask = (Jar) new AntUtils().createAntTask("jar");
054: jarTask.setUpdate(false);
055:
056: Duplicate df = new Duplicate();
057: df.setValue("preserve");
058: jarTask.setDuplicate(df);
059: jarTask.setDestFile(jarFile.getFile());
060:
061: addClassesDirectories(jarTask);
062: addLibs(jarTask);
063: addResources(jarTask);
064: jarTask.execute();
065: }
066:
067: private FileSystemPath makejarFileName() {
068: File f = new File(jarFileName);
069: if (f.isAbsolute()) {
070: return FileSystemPath.makeNewFile(jarFileName);
071: } else {
072: return tempDirPath.file(jarFileName);
073: }
074: }
075:
076: private void addLibs(Jar jarTask) {
077: for (Iterator it = libs.iterator(); it.hasNext();) {
078: FileSystemPath lib = (FileSystemPath) it.next();
079: ZipFileSet zipFileSet = new ZipFileSet();
080: zipFileSet.setFile(lib.getFile());
081: jarTask.addZipfileset(zipFileSet);
082: }
083: }
084:
085: private void addClassesDirectories(Jar jarTask) {
086: for (Iterator it = classDirectories.iterator(); it.hasNext();) {
087: FileSystemPath path = (FileSystemPath) it.next();
088: ZipFileSet zipFileSet = new ZipFileSet();
089: zipFileSet.setDir(path.getFile());
090: jarTask.addZipfileset(zipFileSet);
091: }
092: }
093:
094: private void addResources(Jar jarTask) {
095: for (Iterator it = resources.iterator(); it.hasNext();) {
096: ResourceDefinition definition = (ResourceDefinition) it
097: .next();
098: ZipFileSet zipfileset = new ZipFileSet();
099: zipfileset.setDir(definition.location);
100: zipfileset.setIncludes(definition.includes);
101: if (definition.prefix != null)
102: zipfileset.setPrefix(definition.prefix);
103: if (definition.fullpath != null)
104: zipfileset.setFullpath(definition.fullpath);
105: jarTask.addZipfileset(zipfileset);
106: }
107: }
108:
109: public JARBuilder addClassesDirectory(String directory) {
110: return addClassesDirectory(FileSystemPath
111: .existingDir(directory));
112: }
113:
114: void createJarDirectory() {
115: this .jarDirectoryPath = tempDirPath.mkdir("tempjar");
116: jarDirectoryPath.mkdir("META-INF");
117: }
118:
119: public JARBuilder addDirectoryOrJARContainingClass(Class type) {
120: return addDirectoryOrJar(calculatePathToClass(type));
121: }
122:
123: public JARBuilder addDirectoryContainingResource(String resource) {
124: return addDirectoryOrJar(calculatePathToResource(resource));
125: }
126:
127: public JARBuilder addResource(String location, String includes,
128: String prefix) {
129: FileSystemPath path = getResourceDirPath(location, includes);
130: resources.add(new ResourceDefinition(path.getFile(), includes,
131: prefix, null));
132: return this ;
133: }
134:
135: public JARBuilder addResourceFullpath(String location,
136: String includes, String fullpath) {
137: FileSystemPath path = getResourceDirPath(location, includes);
138: resources.add(new ResourceDefinition(path.getFile(), includes,
139: null, fullpath));
140: return this ;
141: }
142:
143: private FileSystemPath getResourceDirPath(String location,
144: String includes) {
145: String resource = location + "/" + includes;
146: URL url = getClass().getResource(resource);
147: Assert.assertNotNull("Not found: " + resource, url);
148: FileSystemPath path = calculateDirectory(url, includes);
149: return path;
150: }
151:
152: private JARBuilder addDirectoryOrJar(FileSystemPath path) {
153: if (path.isDirectory()) {
154: classDirectories.add(path);
155: } else {
156: libs.add(path);
157: }
158: return this ;
159: }
160:
161: public static FileSystemPath calculatePathToClass(Class type) {
162: URL url = type.getResource("/" + classToPath(type));
163: Assert.assertNotNull("Not found: " + type, url);
164: FileSystemPath filepath = calculateDirectory(url, "/"
165: + classToPath(type));
166: return filepath;
167: }
168:
169: static public FileSystemPath calculatePathToClass(Class type,
170: String pathString) {
171: String pathSeparator = System.getProperty("path.separator");
172: String[] tokens = pathString.split(pathSeparator);
173: URL[] urls = new URL[tokens.length];
174: for (int i = 0; i < tokens.length; i++) {
175: String token = tokens[i];
176: if (token.startsWith("/")) {
177: token = "/" + token;
178: }
179: URL u = null;
180: try {
181: if (token.endsWith(".jar")) {
182: u = new URL("jar", "", "file:/" + token + "!/");
183: } else {
184: u = new URL("file", "", token + "/");
185: }
186: urls[i] = u;
187: } catch (Exception ex) {
188: throw new RuntimeException(ex);
189: }
190: }
191: URL url = new URLClassLoader(urls, null)
192: .getResource(classToPath(type));
193: Assert.assertNotNull("Not found: " + type, url);
194: FileSystemPath filepath = calculateDirectory(url, "/"
195: + classToPath(type));
196: return filepath;
197: }
198:
199: public static FileSystemPath calculateDirectory(URL url,
200: String classNameAsPath) {
201:
202: String urlAsString = null;
203: try {
204: urlAsString = java.net.URLDecoder.decode(url.toString(),
205: "UTF-8");
206: } catch (Exception ex) {
207: throw new RuntimeException(ex);
208: }
209: Assert.assertTrue("URL should end with: " + classNameAsPath,
210: urlAsString.endsWith(classNameAsPath));
211: if (urlAsString.startsWith("file:")) {
212: return FileSystemPath.existingDir(urlAsString.substring(
213: "file:".length(), urlAsString.length()
214: - classNameAsPath.length()));
215: } else if (urlAsString.startsWith("jar:file:")) {
216: int n = urlAsString.indexOf('!');
217: return FileSystemPath.makeExistingFile(urlAsString
218: .substring("jar:file:".length(), n));
219: } else
220: throw new RuntimeException("unsupported protocol: " + url);
221: }
222:
223: private static String classToPath(Class type) {
224: return type.getName().replace('.', '/') + ".class";
225: }
226:
227: private FileSystemPath calculatePathToResource(String resource) {
228: URL url = getClass().getResource(resource);
229: Assert.assertNotNull("Not found: " + resource, url);
230: return calculateDirectory(url, resource);
231: }
232:
233: private static class ResourceDefinition {
234: public final File location;
235: public final String prefix;
236: public final String includes;
237: public final String fullpath;
238:
239: public ResourceDefinition(File location, String includes,
240: String prefix, String fullpath) {
241: this.location = location;
242: this.includes = includes;
243: this.prefix = prefix;
244: this.fullpath = fullpath;
245: }
246: }
247: }
|