001: /**
002: * $Id: WebAppExtractor.java,v 1.4 2006/08/22 10:50:11 nk137934 Exp $
003: * Copyright 2004 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.portlet.admin.mbeans.tasks;
014:
015: import java.io.File;
016: import java.io.FileInputStream;
017: import java.io.FileOutputStream;
018: import java.io.InputStream;
019: import java.io.IOException;
020: import java.io.FileNotFoundException;
021:
022: import java.util.ArrayList;
023: import java.util.List;
024: import java.util.Enumeration;
025: import java.util.Properties;
026:
027: import java.util.jar.Manifest;
028: import java.util.jar.JarEntry;
029: import java.util.jar.JarFile;
030: import java.util.jar.JarOutputStream;
031:
032: import java.util.logging.Logger;
033: import java.util.logging.Level;
034:
035: // This is a utility class used to extract portlet war files contained within
036: // an ear file
037: public class WebAppExtractor {
038:
039: private static final String DD_LOCATION = "DDFileLocation";
040: private static final String PORTLET_XML_DESCRIPTOR = "portlet.xml";
041: private static final String EXTENSION_XML_DESCRIPTOR = "sun-portlet.xml";
042: private static final String WEB_XML_DESCRIPTOR = "web.xml";
043: private static final String PORTLET_XML_PATH = "WEB-INF/portlet.xml";
044: private static final String EXTENSION_XML_PATH = "WEB-INF/sun-portlet.xml";
045: private static final String WEB_XML_PATH = "WEB-INF/web.xml";
046: private static final String TEMP_WAR_EXTN = ".tmp";
047:
048: private Properties configProps = null;
049: private JarFile earFile = null;
050: private String earApplicationName = null;
051: private String ddLocation = null;
052: private boolean verbose = false;
053: private Logger logger = null;
054:
055: private List descriptors = null;
056:
057: public WebAppExtractor(File earFile, Properties props,
058: boolean verbose, Logger logger) throws IOException {
059:
060: this .earFile = new JarFile(earFile);
061: this .earApplicationName = earFile.getName().substring(0,
062: earFile.getName().indexOf("."));
063: this .configProps = props;
064: this .verbose = verbose;
065: this .logger = logger;
066:
067: //location of portlet tmp dir
068: ddLocation = configProps.getProperty(DD_LOCATION);
069:
070: }
071:
072: // Returns a list of type File[] - represents portlet wars
073: // File[0] is a handle to the portlet.xml
074: // File[1] is a handle to the sun-portlet.xml. It is null if the file
075: // does not exist
076: // File[2] is a handle to the web.xml
077: // On any exception, an empty list will be returned
078: public List extractPortletWars() {
079:
080: if (verbose) {
081: logger.log(Level.INFO, "PSPL_CSPPAMT0034",
082: new Object[] { earFile });
083: }
084:
085: descriptors = new ArrayList();
086:
087: //List type-File
088: //All war files that have a portlet.xml
089: List allWarFiles = new ArrayList();
090:
091: // Find all content that are .war
092: List allWarEntries = new ArrayList();
093: for (Enumeration entries = earFile.entries(); entries
094: .hasMoreElements();) {
095: JarEntry earFileEntry = (JarEntry) entries.nextElement();
096: if (earFileEntry.getName().endsWith(".war")) {
097: allWarEntries.add(earFileEntry);
098: }
099: }
100:
101: // Extract all .war files
102: for (int i = 0; i < allWarEntries.size(); i++) {
103: File tempWarFile = getWarFromEar((JarEntry) allWarEntries
104: .get(i));
105: if (tempWarFile != null) {
106: allWarFiles.add(tempWarFile);
107: }
108: }
109:
110: for (int i = 0; i < allWarFiles.size(); i++) {
111: File file = (File) allWarFiles.get(i);
112: File sunDescriptor = null;
113: File webDescriptor = null;
114: File xmlDescriptor = getDescriptorFromWarFile(
115: PORTLET_XML_DESCRIPTOR, PORTLET_XML_PATH, file);
116: if (xmlDescriptor != null) {
117: sunDescriptor = getDescriptorFromWarFile(
118: EXTENSION_XML_DESCRIPTOR, EXTENSION_XML_PATH,
119: file);
120:
121: webDescriptor = getDescriptorFromWarFile(
122: WEB_XML_DESCRIPTOR, WEB_XML_PATH, file);
123: }
124: // We have got both descriptors. So delete file
125: file.delete();
126: if (xmlDescriptor != null) {
127: File[] fileArray = new File[] { xmlDescriptor,
128: sunDescriptor, webDescriptor };
129: descriptors.add(fileArray);
130: }
131: }
132:
133: return descriptors;
134: }
135:
136: // This method cleans all the files which are returned by the
137: // extractPortletWars method. This method is used to cleanup
138: // cached files in cases of failure
139: public void deleteExtractedWars() {
140:
141: // This means that the ear was not extracted at all
142: // Can happen if there is a failure before ear extraction
143: // eg. Trying to register the same ear twice
144: if (descriptors == null) {
145: return;
146: }
147:
148: for (int i = 0; i < descriptors.size(); i++) {
149:
150: File[] fileArray = (File[]) descriptors.get(i);
151: // Delete the portlet.xml
152: if (fileArray[0] != null) {
153: fileArray[0].delete();
154: }
155: // Delete the sun-portlet.xml
156: if (fileArray[1] != null) {
157: fileArray[1].delete();
158: }
159: // Delete the web.xml
160: if (fileArray[2] != null) {
161: fileArray[2].delete();
162: }
163: }
164: // create an empty list
165: descriptors = new ArrayList();
166: }
167:
168: // This method deletes all the sun-portlet.xml files and
169: // the web.xml files returned by the extractPortletWars method.
170: // portlet.xml files alone are preserved.
171: public void deleteAdditionalDescriptors() {
172:
173: for (int i = 0; i < descriptors.size(); i++) {
174:
175: File[] fileArray = (File[]) descriptors.get(i);
176: // Delete the sun-portlet.xml
177: if (fileArray[1] != null) {
178: fileArray[1].delete();
179: }
180: // Delete the web.xml
181: if (fileArray[2] != null) {
182: fileArray[2].delete();
183: }
184: }
185: }
186:
187: // Returns true if the given ear file is already registered
188: // Else returns false
189: public boolean isArchiveRegistered() {
190:
191: boolean isArchiveRegistered = true;
192: DeploymentDescriptorFinder finder = new DeploymentDescriptorFinder(
193: earApplicationName, configProps, verbose, logger);
194: try {
195:
196: List list = finder.findPortletDescriptors();
197:
198: } catch (PortletDeployerException pdExcp) {
199: // This is expected if no portlets are found
200: isArchiveRegistered = false;
201: }
202: return isArchiveRegistered;
203: }
204:
205: // Given a warEntry within the earFile, this method creates a temporary war
206: // On any exception, a null is returned
207: private File getWarFromEar(JarEntry warEntry) {
208:
209: File tempWarFile = null;
210: try {
211: String webAppName = warEntry.getName();
212: InputStream entryStream = earFile.getInputStream(warEntry);
213:
214: tempWarFile = new File(ddLocation, webAppName
215: + TEMP_WAR_EXTN);
216: FileOutputStream warOutput = new FileOutputStream(
217: tempWarFile);
218:
219: // Allocate a buffer for reading entry data.
220: byte[] buffer = new byte[1024];
221: int bytesRead;
222:
223: // Read the entry from the ear file and write to the temp war file
224: while ((bytesRead = entryStream.read(buffer)) != -1) {
225: warOutput.write(buffer, 0, bytesRead);
226:
227: }
228: entryStream.close();
229: warOutput.close();
230: } catch (IOException excp) {
231: logger.log(Level.SEVERE, "PSPL_CSPPAMT0017", new Object[] {
232: warEntry, earFile });
233: }
234: return tempWarFile;
235: }
236:
237: // returns a handle to the xml descriptor within a war file.
238: private File getDescriptorFromWarFile(String descriptorName,
239: String descriptorPath, File tempWarFile) {
240:
241: File tempXMLFile = null;
242: try {
243: JarFile warFile = new JarFile(tempWarFile);
244: for (Enumeration entries = warFile.entries(); entries
245: .hasMoreElements();) {
246: JarEntry this Entry = (JarEntry) entries.nextElement();
247:
248: if (this Entry.getName()
249: .equalsIgnoreCase(descriptorPath)) {
250: InputStream entryStream = warFile
251: .getInputStream(this Entry);
252: String webAppName = tempWarFile.getName()
253: .substring(0,
254: tempWarFile.getName().indexOf("."));
255: tempXMLFile = new File(ddLocation,
256: earApplicationName + "_" + webAppName + "_"
257: + descriptorName);
258:
259: FileOutputStream xmlOutput = new FileOutputStream(
260: tempXMLFile);
261: // Allocate a buffer for reading entry data.
262: byte[] buffer = new byte[1024];
263: int bytesRead;
264: while ((bytesRead = entryStream.read(buffer)) != -1) {
265: xmlOutput.write(buffer, 0, bytesRead);
266: }
267: entryStream.close();
268: xmlOutput.close();
269: }
270: }
271: warFile.close();
272: } catch (IOException e) {
273: // Log the exception
274: logger.log(Level.SEVERE, "PSPL_CSPPAMT0018", e);
275: }
276: return tempXMLFile;
277: }
278:
279: }
|