| package org.apache.chainsaw.ant; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Vector; |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.DirectoryScanner; |
| import org.apache.tools.ant.Task; |
| import org.apache.tools.ant.types.FileSet; |
| |
| /** |
| * This Ant task creates the necessary .bat and .sh files required to run Chainsaw |
| * on the commandline. This task was created because it was getting VERY annoying |
| * to constantly maintain 2 script files as the Jar file names kept changing during |
| * the log4j 1.3 alpha stage, and as we (the Chainsaw developers) added dependencies |
| * as we added functionality. |
| * |
| * This task takes and outputLocation as a , and a set of FileSets which form the |
| * basis of the classpath that is required to run Chainsaw. |
| * |
| * @author psmith |
| * |
| */ |
| public class CreateShellScripts extends Task { |
| |
| |
| private String outputLocation; |
| |
| private Vector fileSets = new Vector(); |
| private String scriptType=""; |
| |
| private Collection KNOWN_SCRIPT_TYPES = Arrays.asList(new String[] {"shell", "webstart"}); |
| |
| public String getOutputLocation() { |
| return outputLocation; |
| } |
| |
| public void setOutputLocation(String outputLocation) { |
| this.outputLocation = outputLocation; |
| } |
| |
| public void execute() throws BuildException { |
| super.execute(); |
| if(getScriptType().length()==0) { |
| throw new BuildException("scriptType property has not been set"); |
| }else if (!KNOWN_SCRIPT_TYPES.contains(getScriptType())) { |
| throw new BuildException("scriptType '"+ getScriptType() + "' is not one of then known types: " + KNOWN_SCRIPT_TYPES); |
| } |
| File outputLocationDir = new File(getOutputLocation()); |
| if(!outputLocationDir.exists()) { |
| log("Creating director(ies) ->" + getOutputLocation()); |
| outputLocationDir.mkdirs(); |
| } |
| Collection filenames = getFilenames(); |
| try { |
| if (getScriptType().equals("shell")) { |
| createUnixShellScript(outputLocationDir, filenames); |
| createBatShellScript(outputLocationDir, filenames); |
| }else { |
| createJNLP(outputLocationDir, filenames); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| throw new BuildException("Failed to create Scripts",e); |
| } |
| } |
| |
| |
| /** |
| * Creates a JNLP file for launching Chainsaw |
| * @param outputLocationDir |
| * @param filenames |
| * @throws IOException |
| */ |
| private void createJNLP(File outputLocationDir, Collection filenames) throws IOException { |
| // String templateName = CreateShellScripts.class.getPackage().toString().replace('.', '/')+"/chainsawWebStart.jnlp"; |
| // log("Using JNLP template: " + templateName); |
| BufferedReader reader = new BufferedReader(new FileReader(new File("packaging/chainsawWebStart.jnlp"))); |
| |
| // convert the file to a String |
| StringBuffer buf = new StringBuffer(1024); |
| String line; |
| while((line=reader.readLine())!=null) { |
| buf.append(line).append("\n"); |
| } |
| |
| StringBuffer jarBuf = new StringBuffer(); |
| |
| /** |
| * Good one Sun! For some stupid reason, we MUST list the jar that contains the main-class |
| * FIRST. Why? Why? WHYYYYYYYYYYYYYYYYYY? |
| * |
| * So, we sort a copied list and make sure that the chainsaw jar is first. |
| */ |
| List list = new ArrayList(filenames); |
| Collections.sort(list, new Comparator() { |
| |
| public int compare(Object o1, Object o2) { |
| if(o1.toString().toLowerCase().indexOf("chainsaw")>-1) { |
| return -1; |
| }else if(o2.toString().toLowerCase().indexOf("chainsaw")>-1) { |
| return 1; |
| }else { |
| return 0; |
| } |
| }}); |
| for (Iterator iter = list.iterator(); iter.hasNext();) { |
| String jar = (String) iter.next(); |
| jarBuf.append("\t<jar href=\"lib/"+jar + "\"/>\n"); |
| } |
| // now replace the bits we want |
| int jarStringLocation = buf.indexOf("@JARS@"); |
| buf.replace(jarStringLocation, jarStringLocation + 6, jarBuf.toString()); |
| |
| File jnlp = new File(outputLocationDir, "chainsawWebStart.jnlp"); |
| Writer writer = new FileWriter(jnlp); |
| writer.write(buf.toString()); |
| writer.close(); |
| } |
| |
| public void addFileSet(FileSet fileSet) { |
| fileSets.add(fileSet); |
| } |
| |
| private void createBatShellScript(File outputLocationDir, Collection filenames) throws IOException { |
| File unixScript = new File(outputLocationDir, "chainsaw.bat"); |
| |
| log("Creating Windows .bat script: " + unixScript.getAbsolutePath()); |
| |
| Writer writer = new FileWriter(unixScript); |
| writeExecutionLine(filenames, writer, ';'); |
| writer.close(); |
| } |
| |
| private void createUnixShellScript(File outputLocationDir, Collection fileNames) throws IOException { |
| File unixScript = new File(outputLocationDir, "chainsaw.sh"); |
| |
| log("Creating Unix script: " + unixScript.getAbsolutePath()); |
| |
| Writer writer = new FileWriter(unixScript); |
| writer.write("#!/bin/sh\n"); |
| writeExecutionLine(fileNames, writer, ':'); |
| writer.close(); |
| } |
| |
| |
| private void writeExecutionLine(Collection fileNames, Writer writer, char jarSeparator) throws IOException { |
| writer.write("java -classpath "); |
| for (Iterator iter = fileNames.iterator(); iter.hasNext();) { |
| String fileName = (String) iter.next(); |
| writer.write(fileName); |
| if(iter.hasNext()) { |
| writer.write(jarSeparator); |
| } |
| } |
| writer.write(" org.apache.log4j.chainsaw.LogUI" ); |
| writer.write("\n"); |
| } |
| |
| private Collection getFilenames() { |
| List jars = new ArrayList(); |
| for (Iterator iter = fileSets.iterator(); iter.hasNext();) { |
| FileSet fileSet = (FileSet) iter.next(); |
| DirectoryScanner ds = fileSet.getDirectoryScanner(getProject()); // 3 |
| String[] includedFiles = ds.getIncludedFiles(); |
| for (int i = 0; i < includedFiles.length; i++) { |
| String filename = includedFiles[i].replace('\\', '/'); // 4 |
| filename = filename.substring(filename.lastIndexOf("/") + 1); |
| // if (foundLocation==null && file.equals(filename)) { |
| // File base = ds.getBasedir(); // 5 |
| // File found = new File(base, includedFiles[i]); |
| // foundLocation = found.getAbsolutePath(); |
| // } |
| jars.add(filename); |
| } |
| } |
| return jars; |
| } |
| |
| public String getScriptType() { |
| return scriptType; |
| } |
| |
| public void setScriptType(String scriptType) { |
| this.scriptType = scriptType.toLowerCase(); |
| } |
| |
| } |