001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.ejb.load;
042:
043: import org.netbeans.modules.visualweb.ejb.datamodel.EjbContainerVendor;
044: import java.io.*;
045: import java.util.*;
046: import java.util.zip.*;
047: import org.openide.ErrorManager;
048: import org.openide.util.NbBundle;
049:
050: /**
051: * This class is used to extract the deployment descriptors from the given
052: * jar file. If the given jar file contains jar files, it'll recursively
053: * go through all the contained jar files and extract all the deployment
054: * descriptors.
055: */
056:
057: public final class DeploymentDescriptorExtractor {
058: public static final String JAR_FILE_EXTENSION = ".jar";
059:
060: /**@todo where should the tmp dir be*/
061: private String tmpDir = System.getProperty("java.io.tmpdir");
062: //private String tmpDir = "d:/home/cao/xmls";
063:
064: // A map of ( standard deployment descriptor name, vendor specific deployment descriptor name )
065: private Map deploymentDescriptors = new HashMap();
066:
067: // All the classes found from the jar file
068: private Set allClazz = new HashSet();
069:
070: // The inner jar files - the jar files contained in the original jar file
071: private ArrayList tmpJarFiles = new ArrayList();
072:
073: public DeploymentDescriptorExtractor(ArrayList jarFiles)
074: throws EjbLoadException {
075: for (Iterator iter = jarFiles.iterator(); iter.hasNext();) {
076: String jarFile = (String) iter.next();
077: extract(jarFile, this .deploymentDescriptors, this .allClazz);
078: }
079: }
080:
081: public Map getDeploymentDescriptors() {
082: return this .deploymentDescriptors;
083: }
084:
085: public Set getAllClazz() {
086: return this .allClazz;
087: }
088:
089: public ArrayList getTmpJarFiles() {
090: return this .tmpJarFiles;
091: }
092:
093: /**
094: * Extracts the deployment descriptor xml files
095: */
096: private void extract(String jarFileName, Map deploymentDescriptors,
097: Set allClazz) throws EjbLoadException {
098: try {
099: // First, just extract the entry size only
100: ZipFile zf = new ZipFile(jarFileName);
101: Map entrySizes = new HashMap();
102:
103: Enumeration e = zf.entries();
104: while (e.hasMoreElements()) {
105: ZipEntry ze = (ZipEntry) e.nextElement();
106:
107: entrySizes.put(ze.getName(), new Integer((int) ze
108: .getSize()));
109: }
110:
111: zf.close();
112:
113: // Now, extract resources and look for the deployment descriptors.
114:
115: FileInputStream fileInputStream = new FileInputStream(
116: jarFileName);
117: BufferedInputStream bufferedInputStream = new BufferedInputStream(
118: fileInputStream);
119: ZipInputStream zipInputStream = new ZipInputStream(
120: bufferedInputStream);
121:
122: String stdXml = null;
123: String vendorXml = null;
124: ZipEntry zipEntry = null;
125: while ((zipEntry = zipInputStream.getNextEntry()) != null) {
126: if (zipEntry.isDirectory()) {
127: continue;
128: }
129:
130: int size = (int) zipEntry.getSize();
131:
132: // -1 means unknown size.
133: if (size == -1) {
134: size = ((Integer) entrySizes
135: .get(zipEntry.getName())).intValue();
136: }
137:
138: // Read the content of this zip entry
139: byte[] b = new byte[(int) size];
140: int rb = 0;
141: int chunk = 0;
142: while (((int) size - rb) > 0) {
143: chunk = zipInputStream.read(b, rb, (int) size - rb);
144: if (chunk == -1) {
145: break;
146: }
147:
148: rb += chunk;
149: }
150:
151: String theEntry = zipEntry.getName();
152:
153: // If it is a class
154: if (theEntry.endsWith(".class")) {
155: int index = theEntry.indexOf('.');
156: allClazz.add(theEntry.substring(0, index).replace(
157: '/', '.'));
158: } else {
159: // If the file is a deployment descriptor, the save it to a tmp diretory.
160: // If the file is a jar file, save it and recursively extract it
161:
162: String fileName = getFileName(theEntry);
163:
164: if (fileName
165: .equalsIgnoreCase(EjbContainerVendor.STANDARD_DEPLOYMENT_DESCRIPTOR)
166: || fileName
167: .equalsIgnoreCase(EjbContainerVendor.SUN_DEPLOYMENT_DESCRIPTOR)
168: || fileName
169: .equalsIgnoreCase(EjbContainerVendor.WEBLOGIC_DEPLOYMENT_DESCRIPTOR)
170: || fileName
171: .equalsIgnoreCase(EjbContainerVendor.WEBSPHERE_DEPLOYMENT_DESCRIPTOR)) {
172: // Lets remember which xml file we're working on right now
173: boolean workingOnStdXml = true;
174: if (fileName
175: .equalsIgnoreCase(EjbContainerVendor.SUN_DEPLOYMENT_DESCRIPTOR)
176: || fileName
177: .equalsIgnoreCase(EjbContainerVendor.WEBLOGIC_DEPLOYMENT_DESCRIPTOR)
178: || fileName
179: .equalsIgnoreCase(EjbContainerVendor.WEBSPHERE_DEPLOYMENT_DESCRIPTOR))
180: workingOnStdXml = false;
181:
182: // Going to append a number to file name in case the jar file
183: // contains several deployment descriptor
184: // Note: need to deal with websphere deployment descriptors
185: // are little different because it is a .xmi not .xml
186: if (fileName
187: .equalsIgnoreCase(EjbContainerVendor.WEBSPHERE_DEPLOYMENT_DESCRIPTOR)) {
188: String newNamePart = deploymentDescriptors
189: .size()
190: + ".xmi";
191: fileName = fileName.replaceAll(".xmi",
192: newNamePart);
193: } else {
194: String newNamePart = deploymentDescriptors
195: .size()
196: + ".xml";
197: fileName = fileName.replaceAll(".xml",
198: newNamePart);
199: }
200:
201: String fileWithPath = writeXmlFile(fileName, b);
202:
203: if (workingOnStdXml)
204: stdXml = fileWithPath;
205: else
206: vendorXml = fileWithPath;
207:
208: // Add the file names to the map if both of them are ready
209: if (stdXml != null && vendorXml != null) {
210: deploymentDescriptors
211: .put(stdXml, vendorXml);
212: stdXml = null;
213: vendorXml = null;
214: }
215: }
216:
217: // It is jar file, recursively look for deployment descriptors
218: if (fileName.indexOf(JAR_FILE_EXTENSION) != -1) {
219: String tmpJarFile = writeXmlFile(fileName, b);
220: extract(tmpJarFile, deploymentDescriptors,
221: allClazz);
222: tmpJarFiles.add(tmpJarFile);
223: }
224: }
225: }
226: } catch (java.io.FileNotFoundException e) {
227: // Log error
228: String logMsg = "Error occurred when trying to extract the EJB deployment descriptors. Cannot find from jar file "
229: + jarFileName;
230: ErrorManager
231: .getDefault()
232: .getInstance(
233: "org.netbeans.modules.visualweb.ejb.load.DeploymentDescriptorExtractor")
234: .log(ErrorManager.ERROR, logMsg);
235: e.printStackTrace();
236:
237: // Throw up as USER_ERROR
238: // Client Jaf file {0} not found
239: String errMsg = NbBundle.getMessage(
240: DeploymentDescriptorExtractor.class,
241: "FILE_NOT_FOUND", jarFileName);
242: throw new EjbLoadException(EjbLoadException.USER_ERROR,
243: errMsg);
244: } catch (java.io.IOException e) {
245: // Log error
246: String logMsg = "Error occurred when trying to extract the EJB deployment descriptors. Cannot read from jar file "
247: + jarFileName;
248: ErrorManager
249: .getDefault()
250: .getInstance(
251: "org.netbeans.modules.visualweb.ejb.load.DeploymentDescriptorExtractor")
252: .log(ErrorManager.ERROR, logMsg);
253: e.printStackTrace();
254:
255: // Throw up as USER_ERROR
256: // Client Jar file {0} cannot be read
257: String errMsg = NbBundle.getMessage(
258: DeploymentDescriptorExtractor.class,
259: "CANNOT_READ_FILE", jarFileName);
260: throw new EjbLoadException(EjbLoadException.USER_ERROR,
261: errMsg);
262: }
263: }
264:
265: private String getFileName(String zipEntryName) {
266: int index = zipEntryName.lastIndexOf('/');
267:
268: if (index == -1)
269: return zipEntryName;
270: else {
271: return zipEntryName.substring(index + 1);
272: }
273: }
274:
275: private String writeXmlFile(String fileName, byte[] bytes)
276: throws EjbLoadException {
277: try {
278: File file = new File(getTempDir(), fileName);
279: file.deleteOnExit();
280:
281: FileOutputStream fos = new FileOutputStream(file);
282: BufferedOutputStream bos = new BufferedOutputStream(fos);
283: bos.write(bytes);
284: bos.flush();
285: bos.close();
286: fos.close();
287: return file.getAbsolutePath();
288: } catch (Exception e) {
289: ErrorManager
290: .getDefault()
291: .getInstance(
292: "org.netbeans.modules.visualweb.ejb.load.DeploymentDescriptorExtractor")
293: .log(ErrorManager.ERROR, e.getMessage());
294: e.printStackTrace();
295:
296: throw new EjbLoadException(e.getMessage());
297: }
298: }
299:
300: private File getTempDir() {
301: File file = new File(tmpDir);
302:
303: if (!file.exists())
304: file.mkdirs();
305:
306: return file;
307: }
308: }
|