001: package net.sf.invicta.ant.taskdef;
002:
003: import org.apache.tools.ant.BuildException;
004: import org.apache.tools.ant.Task;
005:
006: import java.io.File;
007: import java.io.FileInputStream;
008: import java.io.FileNotFoundException;
009: import java.io.FileOutputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.io.InputStreamReader;
013: import java.io.PrintWriter;
014: import java.util.ArrayList;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.jar.JarFile;
018: import java.util.zip.ZipEntry;
019:
020: /**
021: * ANT task for generating the 'application.xml' file that defines
022: * the modules of an EAR file.
023: *
024: */
025: public class ApplicationFileGenerator extends Task {
026:
027: private final static String EAR_APPLICATION_XML_PATH = "META-INF/application.xml";
028:
029: private final static String APPLICATION_CLOSING_TAG = "</application>";
030: private final String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
031: + "<!DOCTYPE application PUBLIC \"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN\""
032: +
033:
034: " \"http://java.sun.com/dtd/application_1_3.dtd\">";
035:
036: private final String TYPE_EJB = "ejb";
037: private final String TYPE_JAVA = "java";
038: private final String TYPE_WEB = "web";
039:
040: private String appxml;
041: private String projectName;
042: private List modules;
043: private String earFile;
044:
045: /***
046: * Default Constructor
047: */
048: public ApplicationFileGenerator() {
049: super ();
050: this .appxml = null;
051: this .modules = new ArrayList();
052: this .earFile = null;
053: }
054:
055: public void execute() throws BuildException {
056: // Make sure we got all parameters.
057: if (this .appxml == null)
058: throw new BuildException("Appxml file was not specified.");
059: if (this .projectName == null)
060: throw new BuildException("Project name was not specified.");
061:
062: StringBuffer existingApp = null;
063: if (this .earFile != null) {
064: log("Using application.xml from existing ear file '"
065: + this .earFile + "'");
066: existingApp = fetchExistingContent(this .earFile);
067: }
068:
069: // Read the current content of application.xml
070: byte[] buffer = new byte[1024];
071: InputStream inputStream;
072: StringBuffer previousFileContent = new StringBuffer();
073: try {
074: inputStream = new FileInputStream(this .appxml);
075: int res = 0;
076: while ((res = inputStream.read(buffer)) != -1)
077: previousFileContent.append(new String(buffer, 0, res));
078: inputStream.close();
079: } catch (FileNotFoundException e) {
080: } catch (IOException e) {
081: }
082:
083: // Write header
084: StringBuffer output = new StringBuffer();
085:
086: // Write the module elements for all given modules.
087: for (Iterator iter = this .modules.iterator(); iter.hasNext();) {
088: Module module = (Module) iter.next();
089:
090: // Make sure that the type and file were given
091: if (module.getType() == null)
092: throw new BuildException(
093: "Module type was not specified.");
094: if (module.getFile() == null)
095: throw new BuildException(
096: "Module file was not specified.");
097:
098: // Check if this module already defined
099: if ((this .earFile != null)
100: && (existingApp.toString().indexOf(
101: ">" + module.getFile() + "<") != -1)) {
102: log("Warning: Module '" + module.getFile()
103: + "' is already defined in application.xml");
104: continue;
105: }
106:
107: output.append("\t<module>\n");
108:
109: File file = new File(module.getFile());
110:
111: // Handle a Java module
112: if (module.getType().equalsIgnoreCase(TYPE_JAVA)) {
113: output.append("\t\t<java>" + file.getName()
114: + "</java>\n");
115:
116: // Handle an EJB module
117: } else if (module.getType().equalsIgnoreCase(TYPE_EJB)) {
118: output
119: .append("\t\t<ejb>" + file.getName()
120: + "</ejb>\n");
121:
122: // Handle a WEB module
123: } else if (module.getType().equalsIgnoreCase(TYPE_WEB)) {
124: if (module.getName() == null)
125: throw new BuildException(
126: "Module name was not specified.");
127:
128: output.append("\t\t<web>\n");
129: output.append("\t\t\t<web-uri>" + file.getName()
130: + "</web-uri>\n");
131: output.append("\t\t\t<context-root>" + module.getName()
132: + "</context-root>\n");
133: output.append("\t\t</web>\n");
134:
135: } else {
136: throw new BuildException("Unknown type: "
137: + module.getType());
138: }
139:
140: output.append("\t</module>\n");
141:
142: }
143:
144: if (this .earFile == null) {
145:
146: output.insert(0, header + "\n\n<application>\n"
147: + " <display-name>" + this .projectName
148: + "</display-name>\n" + " <description>'"
149: + this .projectName
150: + "' applications descriptor file</description>\n");
151:
152: // Print footer and close the file.
153: output.append("</application>\n");
154: } else {
155: int tagPos = existingApp.toString().indexOf(
156: APPLICATION_CLOSING_TAG);
157: if (tagPos == 1)
158: throw new BuildException(
159: "Invalid EAR application.xml (missing closing tag)");
160:
161: existingApp.insert(tagPos, output.toString());
162:
163: output = existingApp;
164: }
165:
166: // If the content is differnet from the existing output file,
167: // then write the output file.
168: if (!previousFileContent.toString().equals(output.toString())) {
169:
170: // Open the file for writing.
171: PrintWriter out = null;
172: try {
173: out = new PrintWriter(new FileOutputStream(this .appxml));
174: } catch (FileNotFoundException e) {
175: throw new BuildException(e.toString());
176: }
177: out.print(output.toString());
178:
179: out.close();
180: log("Application file was created successfully ("
181: + this .appxml + ")");
182: } else {
183: log("Application file should not be modified ("
184: + this .appxml + ")");
185: }
186:
187: }
188:
189: /**
190: * Method fetchExistingContent.
191: * @param string
192: * @return String
193: */
194: private StringBuffer fetchExistingContent(String earFile) {
195:
196: char[] buffer = new char[1024];
197: try {
198:
199: JarFile jarFile = new JarFile(earFile);
200: ZipEntry appEntry = jarFile
201: .getEntry(EAR_APPLICATION_XML_PATH);
202: if (appEntry == null)
203: throw new BuildException(
204: "No application.xml found in '" + earFile + "'");
205:
206: InputStreamReader appStream = new InputStreamReader(jarFile
207: .getInputStream(appEntry));
208:
209: StringBuffer appContent = new StringBuffer();
210: int res = 0;
211: while ((res = appStream.read(buffer)) != -1)
212: appContent.append(new String(buffer, 0, res));
213:
214: return appContent;
215: } catch (IOException e) {
216: throw new BuildException("Error in reading EAR file '"
217: + earFile + "': " + e.getMessage());
218: }
219: }
220:
221: public void setAppxml(String appxml) {
222: this .appxml = appxml;
223: }
224:
225: public void addConfiguredModule(Module module) {
226: this .modules.add(module);
227: }
228:
229: /**
230: * Sets the projectName.
231: * @param projectName The projectName to set
232: */
233: public void setProjectName(String projectName) {
234: this .projectName = projectName;
235: }
236:
237: /**
238: * Returns the earFile.
239: * @return String
240: */
241: public String getEarFile() {
242: return earFile;
243: }
244:
245: /**
246: * Sets the earFile.
247: * @param earFile The earFile to set
248: */
249: public void setEarFile(String earFile) {
250: this.earFile = earFile;
251: }
252:
253: }
|