001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer(s): Florent BENOIT & Ludovic BERT
022: * --------------------------------------------------------------------------
023: * $Id: EarDeploymentDescManager.java 7467 2005-10-04 12:53:14Z sauthieg $
024: * --------------------------------------------------------------------------
025: */package org.objectweb.jonas_ear.deployment.lib;
026:
027: import java.io.File;
028: import java.io.FileInputStream;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.io.InputStreamReader;
032: import java.io.Reader;
033: import java.util.jar.JarFile;
034: import java.util.zip.ZipEntry;
035:
036: import org.objectweb.jonas_ear.deployment.api.EarDTDs;
037: import org.objectweb.jonas_ear.deployment.api.EarDeploymentDesc;
038: import org.objectweb.jonas_ear.deployment.api.EarDeploymentDescException;
039: import org.objectweb.jonas_ear.deployment.api.EarSchemas;
040: import org.objectweb.jonas_ear.deployment.api.JonasEarSchemas;
041: import org.objectweb.jonas_ear.deployment.rules.ApplicationRuleSet;
042: import org.objectweb.jonas_ear.deployment.rules.JonasApplicationRuleSet;
043: import org.objectweb.jonas_ear.deployment.xml.Application;
044: import org.objectweb.jonas_ear.deployment.xml.JonasApplication;
045:
046: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
047: import org.objectweb.jonas_lib.deployment.digester.JDigester;
048: import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
049:
050: import org.objectweb.jonas.common.Log;
051:
052: import org.objectweb.util.monolog.api.BasicLevel;
053: import org.objectweb.util.monolog.api.Logger;
054:
055: /**
056: * This class extends the AbsDeploymentDescriptor class of JOnAS It provides a
057: * description of the specific EAR desployment descriptor
058: * @author Florent Benoit
059: * @author Ludovic Bert
060: * @author Helene Joanin
061: */
062: public class EarDeploymentDescManager extends AbsDeploymentDescManager {
063:
064: /**
065: * Path of the application.xml deploymnet descriptor file
066: */
067: public static final String APPLICATION_FILE_NAME = "META-INF/application.xml";
068:
069: /**
070: * Path of the jonas-application.xml deploymnet descriptor file
071: */
072: public static final String JONAS_APPLICATION_FILE_NAME = "META-INF/jonas-application.xml";
073:
074: /**
075: * Digester used to parse application.xml
076: */
077: private static JDigester earDigester = null;
078:
079: /**
080: * Digester used to parse jonas-application.xml
081: */
082: private static JDigester jonasEarDigester = null;
083:
084: /**
085: * Rules to parse the application.xml
086: */
087: private static ApplicationRuleSet appRuleSet = new ApplicationRuleSet();
088:
089: /**
090: * Rules to parse the jonas-application.xml
091: */
092: private static JonasApplicationRuleSet jonasApplicationRuleSet = new JonasApplicationRuleSet();
093:
094: /**
095: * logger
096: */
097: private static Logger logger = Log.getLogger(Log.JONAS_EAR_PREFIX);
098:
099: /**
100: * Flag for parser validation
101: */
102: private static boolean parsingWithValidation = true;
103:
104: /**
105: * Private Empty constructor for utility class
106: */
107: private EarDeploymentDescManager() {
108: }
109:
110: /**
111: * Get an instance of an EAR deployment descriptor by parsing the
112: * application.xml deployment descriptor.
113: * @param earFileName the fileName of the war file for the deployment
114: * descriptors.
115: * @param classLoaderForCls the classloader for the classes.
116: * @return an EAR deployment descriptor by parsing the application.xml
117: * deployment descriptor.
118: * @throws EarDeploymentDescException if the deployment descriptor is
119: * corrupted.
120: */
121: public static EarDeploymentDesc getDeploymentDesc(
122: String earFileName, ClassLoader classLoaderForCls)
123: throws EarDeploymentDescException {
124:
125: //ear file
126: JarFile earFile = null;
127:
128: //Input Stream
129: InputStream appInputStream = null;
130: InputStream jonasApplicationInputStream = null;
131:
132: //ZipEntry
133: ZipEntry appZipEntry = null;
134: ZipEntry jonasApplicationZipEntry = null;
135:
136: Application application = null;
137: JonasApplication jonasApplication = null;
138:
139: String xmlContent = "";
140: String jonasXmlContent = "";
141:
142: //Check if the file exists.
143: File earF = new File(earFileName);
144: if (!earF.exists()) {
145: throw new EarDeploymentDescException("The file '"
146: + earFileName + "' was not found.");
147: }
148:
149: // load deployment descriptor data (META-INF/application.xml)
150: try {
151: // Is it a directory ?
152: if (earF.isDirectory()) {
153: //lookup a META-INF/application.xml file
154: File earXmlF = new File(earFileName,
155: APPLICATION_FILE_NAME);
156: if (!earXmlF.exists()) {
157: String err = "You have choose to deploy an ear directory but there is no "
158: + APPLICATION_FILE_NAME
159: + " file in the directory " + earFileName;
160: throw new EarDeploymentDescException(err);
161: }
162: appInputStream = new FileInputStream(earXmlF);
163: xmlContent = xmlContent(appInputStream);
164: // necessary to have a not empty InputStream !!!
165: appInputStream = new FileInputStream(earXmlF);
166:
167: //lookup a META-INF/jonas-application.xml file
168: File jonasEarXmlF = new File(earFileName,
169: JONAS_APPLICATION_FILE_NAME);
170: // file is optional
171: if (jonasEarXmlF.exists()) {
172: jonasApplicationInputStream = new FileInputStream(
173: jonasEarXmlF);
174: jonasXmlContent = xmlContent(jonasApplicationInputStream);
175: // necessary to have a not empty InputStream !!!
176: jonasApplicationInputStream = new FileInputStream(
177: jonasEarXmlF);
178: }
179: } else {
180: // it is an .ear file
181: earFile = new JarFile(earFileName);
182:
183: //Check the application entry
184: appZipEntry = earFile.getEntry(APPLICATION_FILE_NAME);
185: if (appZipEntry == null) {
186: throw new EarDeploymentDescException("The entry '"
187: + APPLICATION_FILE_NAME
188: + "' was not found in the file '"
189: + earFileName + "'.");
190: }
191:
192: //Get the stream
193: appInputStream = earFile.getInputStream(appZipEntry);
194: xmlContent = xmlContent(appInputStream);
195: // necessary to have a not empty InputStream !!!
196: appInputStream = earFile.getInputStream(appZipEntry);
197:
198: // Check the jonas-application entry
199: jonasApplicationZipEntry = earFile
200: .getEntry(JONAS_APPLICATION_FILE_NAME);
201: if (jonasApplicationZipEntry != null) {
202: //Get the stream
203: jonasApplicationInputStream = earFile
204: .getInputStream(jonasApplicationZipEntry);
205: jonasXmlContent = xmlContent(jonasApplicationInputStream);
206: // necessary to have a not empty InputStream !!!
207: jonasApplicationInputStream = earFile
208: .getInputStream(jonasApplicationZipEntry);
209: }
210: }
211: } catch (Exception e) {
212: if (earFile != null) {
213: try {
214: earFile.close();
215: } catch (IOException ioe) {
216: //We can't close the file
217: logger.log(BasicLevel.WARN,
218: "Cannot close InputStream for '"
219: + earFileName + "'");
220: }
221: }
222: throw new EarDeploymentDescException(
223: "Cannot read the XML deployment descriptors of the ear file '"
224: + earFileName + "'.", e);
225: }
226:
227: application = loadApplication(new InputStreamReader(
228: appInputStream), APPLICATION_FILE_NAME);
229: try {
230: appInputStream.close();
231: } catch (IOException e) {
232: // Can't close the file
233: logger.log(BasicLevel.WARN,
234: "Cannot close InputStream for META-INF/application.xml in '"
235: + earFileName + "'");
236: }
237:
238: // load jonas-client deployment descriptor data
239: // (META-INF/jonas-client.xml)
240: if (jonasApplicationInputStream != null) {
241: jonasApplication = loadJonasApplication(
242: new InputStreamReader(jonasApplicationInputStream),
243: JONAS_APPLICATION_FILE_NAME);
244: try {
245: jonasApplicationInputStream.close();
246: } catch (IOException e) {
247: //We can't close the file
248: logger.log(BasicLevel.WARN,
249: "Cannot close InputStream for '" + earFileName
250: + "'");
251: }
252: } else {
253: jonasApplication = new JonasApplication();
254: }
255:
256: // instantiate deployment descriptor
257: EarDeploymentDesc earDD = new EarDeploymentDesc(
258: classLoaderForCls, application, jonasApplication);
259: earDD.setXmlContent(xmlContent);
260: earDD.setJonasXmlContent(jonasXmlContent);
261: return earDD;
262: }
263:
264: /**
265: * Load the application.xml file.
266: * @param reader the Reader of the XML file.
267: * @param fileName the name of the file (application.xml).
268: * @throws EarDeploymentDescException if the deployment descriptor is
269: * corrupted.
270: * @return an application object.
271: */
272: public static Application loadApplication(Reader reader,
273: String fileName) throws EarDeploymentDescException {
274:
275: Application app = new Application();
276: // Create if earDigester is null
277: if (earDigester == null) {
278: try {
279: // Create and initialize the digester
280: earDigester = new JDigester(appRuleSet,
281: getParsingWithValidation(), true,
282: new EarDTDs(), new EarSchemas());
283: } catch (DeploymentDescException e) {
284: throw new EarDeploymentDescException(e);
285: }
286: }
287:
288: try {
289: earDigester.parse(reader, fileName, app);
290: } catch (DeploymentDescException e) {
291: throw new EarDeploymentDescException(e);
292: } finally {
293: earDigester.push(null);
294: }
295:
296: return app;
297: }
298:
299: /**
300: * Load the jonas-application.xml file.
301: * @param reader the stream of the XML file.
302: * @param fileName the name of the file (jonas-application.xml).
303: * @return a structure containing the result of the jonas-application.xml
304: * parsing.
305: * @throws EarDeploymentDescException if the deployment descriptor is
306: * corrupted.
307: */
308: public static JonasApplication loadJonasApplication(Reader reader,
309: String fileName) throws EarDeploymentDescException {
310:
311: JonasApplication ja = new JonasApplication();
312:
313: // Create if null
314: if (jonasEarDigester == null) {
315: try {
316: jonasEarDigester = new JDigester(
317: jonasApplicationRuleSet,
318: getParsingWithValidation(), true, null,
319: new JonasEarSchemas());
320: } catch (DeploymentDescException e) {
321: throw new EarDeploymentDescException(e);
322: }
323: }
324:
325: try {
326: jonasEarDigester.parse(reader, fileName, ja);
327:
328: } catch (DeploymentDescException e) {
329: throw new EarDeploymentDescException(e);
330: } finally {
331: jonasEarDigester.push(null);
332: }
333: return ja;
334: }
335:
336: /**
337: * Controls whether the parser is reporting all validity errors.
338: * @return if true, all external entities will be read.
339: */
340: public static boolean getParsingWithValidation() {
341: return parsingWithValidation;
342: }
343:
344: /**
345: * Controls whether the parser is reporting all validity errors.
346: * @param validation if true, all external entities will be read.
347: */
348: public static void setParsingWithValidation(boolean validation) {
349: EarDeploymentDescManager.parsingWithValidation = validation;
350: }
351: }
|