001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 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): Eric HARDESTY
022: * --------------------------------------------------------------------------
023: * $Id: RarDeploymentDescManager.java 9708 2006-10-10 06:12:37Z ehardesty $
024: * --------------------------------------------------------------------------
025: */package org.objectweb.jonas_rar.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 javax.naming.Context;
037: import javax.naming.NamingException;
038:
039: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
040: import org.objectweb.jonas_lib.deployment.digester.JDigester;
041: import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
042:
043: import org.objectweb.jonas_rar.deployment.api.ConnectorDTDs;
044: import org.objectweb.jonas_rar.deployment.api.ConnectorSchemas;
045: import org.objectweb.jonas_rar.deployment.api.JonasConnectorDTDs;
046: import org.objectweb.jonas_rar.deployment.api.JonasConnectorSchemas;
047: import org.objectweb.jonas_rar.deployment.api.RarDeploymentDesc;
048: import org.objectweb.jonas_rar.deployment.api.RarDeploymentDescException;
049: import org.objectweb.jonas_rar.deployment.rules.ConnectorRuleSet;
050: import org.objectweb.jonas_rar.deployment.rules.JonasConnectorRuleSet;
051: import org.objectweb.jonas_rar.deployment.xml.Connector;
052: import org.objectweb.jonas_rar.deployment.xml.JonasConnector;
053:
054: import org.objectweb.jonas.common.Log;
055: import org.objectweb.jonas.naming.CompNamingContext;
056:
057: import org.objectweb.util.monolog.api.BasicLevel;
058: import org.objectweb.util.monolog.api.Logger;
059:
060: /**
061: * Manage Rar deployment descriptors
062: * @author Guillaume Sauthier
063: */
064: public class RarDeploymentDescManager extends AbsDeploymentDescManager {
065:
066: /**
067: * Path of the ra.xml deploymnet descriptor file
068: */
069: public static final String RA_FILE_NAME = "META-INF/ra.xml";
070:
071: /**
072: * Path of the jonas-ra.xml deploymnet descriptor file
073: */
074: public static final String JONAS_RA_FILE_NAME = "META-INF/jonas-ra.xml";
075:
076: /**
077: * Flag for parser validation
078: */
079: private static boolean parsingWithValidation = true;
080:
081: /**
082: * Digester use to parse ra.xml
083: */
084: private static JDigester connectorDigester = null;
085:
086: /**
087: * Digester use to parse jonas-ra.xml
088: */
089: private static JDigester jonasConnectorDigester = null;
090:
091: /**
092: * Rules to parse the ra.xml
093: */
094: private static ConnectorRuleSet connectorRuleSet = new ConnectorRuleSet();
095:
096: /**
097: * Rules to parse the jonas-ra.xml
098: */
099: private static JonasConnectorRuleSet jonasConnectorRuleSet = new JonasConnectorRuleSet();
100:
101: /**
102: * logger TODO Get a Resource Logger
103: */
104: private static Logger logger = Log.getLogger(Log.JONAS_DBM_PREFIX);
105:
106: /**
107: * Private empty constructor for Utility Class
108: */
109: private RarDeploymentDescManager() {
110: }
111:
112: /**
113: * Get an instance of an RAR deployment descriptor by parsing the ra.xml and
114: * jonas-ra.xml deployment descriptors.
115: * @param rarFileName the fileName of the rar file for the deployment
116: * descriptors.
117: * @param classLoader the classloader for the classes.
118: * @return an RAR deployment descriptor by parsing the ra.xml & jonas-ra.xml
119: * deployment descriptors.
120: * @throws DeploymentDescException if the deployment descriptors are
121: * corrupted.
122: */
123: public static RarDeploymentDesc getInstance(String rarFileName,
124: ClassLoader classLoader) throws DeploymentDescException {
125:
126: // The context to give for the creation of an instance
127: // of RarDeploymentDesc
128: Context contctx = null;
129: try {
130: contctx = new CompNamingContext(rarFileName);
131: contctx.rebind("rarFileName", rarFileName);
132: contctx.rebind("classloader", classLoader);
133: } catch (Exception e) {
134: // An exception occurred trying to bind context
135: // logger.log(BasicLevel.ERROR, "Error when binding context for
136: // RarDeploymentDesc for '" + rarFileName + "'");
137: // logger.log(BasicLevel.ERROR, e.getMessage());
138:
139: throw new RarDeploymentDescException(
140: "Error during the deployment", e);
141: }
142: // want both ra.xml & jonas-ra.xml
143: return getInstance(contctx);
144: }
145:
146: /**
147: * Get an instance of an RAR deployment descriptor by parsing the ra.xml and
148: * jonas-ra.xml deployment descriptors.
149: * @param ctx the context which contains the configuration in order to load
150: * the deployment descriptors. There are 6 possible parameters : -
151: * rarFileName is the path of the RAR file (required param). -
152: * classLoader is the classloader (required param) - altDD is the
153: * optional deployment descriptor (optional param).
154: * @return an RAR deployment descriptor by parsing the ra.xml(or altdd) &
155: * jonas-ra.xml deployment descriptors.
156: * @throws DeploymentDescException if the deployment descriptors are
157: * corrupted.
158: */
159: public static RarDeploymentDesc getInstance(Context ctx)
160: throws DeploymentDescException {
161:
162: // init xml contents values;
163: String xmlContent = "";
164: String jonasXmlContent = "";
165: boolean altDD = false;
166:
167: String rarFileName = null;
168: ClassLoader classLoader = null;
169: try {
170: rarFileName = (String) ctx.lookup("rarFileName");
171: classLoader = (ClassLoader) ctx.lookup("classloader");
172: } catch (NamingException e) {
173: String err = "Error while getting parameter from context param ";
174: throw new RarDeploymentDescException(err, e);
175: }
176:
177: // optional parameter
178: String raDeployDesc;
179: try {
180: raDeployDesc = (String) ctx.lookup("altDD");
181: altDD = true;
182: } catch (NamingException e) {
183: // no alt DD
184: raDeployDesc = "";
185: }
186:
187: //rar file
188: JarFile rarFile = null;
189:
190: //Input Stream
191: InputStream raInputStream = null;
192: InputStream jonasRaInputStream = null;
193:
194: //ZipEntry
195: ZipEntry raZipEntry = null;
196: ZipEntry jonasRaZipEntry = null;
197:
198: Connector connector = null;
199: JonasConnector jonasConnector = null;
200:
201: //Build the file
202: File fRar = new File(rarFileName);
203:
204: //Check if the file exists.
205: if (!(fRar.exists())) {
206: throw new RarDeploymentDescException("The file '"
207: + rarFileName + "' was not found.");
208: }
209:
210: // load deployment descriptor data (META-INF/ra.xml)
211: boolean setupRa = true;
212: boolean setupJonasRa = true;
213: try {
214: if (!altDD) {
215:
216: // If rar is a directory, there is no jar, just read the file from
217: // the directory
218: if (fRar.isDirectory()) {
219: File rarXmlF = new File(rarFileName, RA_FILE_NAME);
220: if (!rarXmlF.exists()) {
221: connector = null;
222: setupRa = false;
223: } else {
224: raInputStream = new FileInputStream(rarXmlF);
225: xmlContent = xmlContent(raInputStream);
226: raInputStream = new FileInputStream(rarXmlF);
227: }
228: } else {
229: rarFile = new JarFile(rarFileName);
230:
231: //Check the ra entry
232: raZipEntry = rarFile.getEntry(RA_FILE_NAME);
233: if (raZipEntry == null) {
234: connector = null;
235: setupRa = false;
236: } else {
237: //Get the stream
238: raInputStream = rarFile
239: .getInputStream(raZipEntry);
240: xmlContent = xmlContent(raInputStream);
241: raInputStream = rarFile
242: .getInputStream(raZipEntry);
243: }
244: }
245: } else {
246: raInputStream = new FileInputStream(raDeployDesc);
247: xmlContent = xmlContent(raInputStream);
248: raInputStream = new FileInputStream(raDeployDesc);
249: }
250:
251: if (fRar.isDirectory()) {
252: //lookup a META-INF/jonas-ra.xml file
253: File rarJXmlF = new File(rarFileName,
254: JONAS_RA_FILE_NAME);
255: if (rarJXmlF.exists()) {
256: jonasRaInputStream = new FileInputStream(rarJXmlF);
257: jonasXmlContent = xmlContent(jonasRaInputStream);
258: jonasRaInputStream = new FileInputStream(rarJXmlF);
259: }
260: } else {
261: //Check the jonas-ra entry
262: rarFile = new JarFile(rarFileName);
263: jonasRaZipEntry = rarFile.getEntry(JONAS_RA_FILE_NAME);
264: if (jonasRaZipEntry == null) {
265: jonasConnector = null;
266: setupJonasRa = false;
267: } else {
268: //Get the stream
269: jonasRaInputStream = rarFile
270: .getInputStream(jonasRaZipEntry);
271: jonasXmlContent = xmlContent(jonasRaInputStream);
272: jonasRaInputStream = rarFile
273: .getInputStream(jonasRaZipEntry);
274: }
275: }
276: } catch (Exception e) {
277: if (rarFile != null) {
278: try {
279: rarFile.close();
280: } catch (IOException ioe) {
281: // Can't close the file
282: logger.log(BasicLevel.WARN, "Can't close '"
283: + rarFileName + "'");
284: }
285: }
286: throw new RarDeploymentDescException(
287: "Cannot read the XML deployment descriptors of the rar file '"
288: + rarFileName + "'.", e);
289: }
290:
291: if (setupRa) {
292: connector = loadConnector(new InputStreamReader(
293: raInputStream), raDeployDesc);
294: try {
295: raInputStream.close();
296: } catch (IOException e) {
297: // can't close
298: logger.log(BasicLevel.WARN,
299: "Can't close META-INF/ra.xml of '"
300: + rarFileName + "'");
301: }
302: }
303:
304: if (setupJonasRa) {
305: jonasConnector = loadJonasConnector(new InputStreamReader(
306: jonasRaInputStream), JONAS_RA_FILE_NAME);
307: try {
308: jonasRaInputStream.close();
309: } catch (IOException e) {
310: // can't close
311: logger.log(BasicLevel.WARN,
312: "Can't close META-INF/jonas-ra.xml of '"
313: + rarFileName + "'");
314: }
315: }
316:
317: // instantiate deployment descriptor
318: RarDeploymentDesc rdd = new RarDeploymentDesc(classLoader,
319: connector, jonasConnector);
320: rdd.setXmlContent(xmlContent);
321: rdd.setJOnASXmlContent(jonasXmlContent);
322: return rdd;
323: }
324:
325: /**
326: * Load the ra.xml file.
327: * @param reader the Reader of the XML file.
328: * @param fileName the name of the file (ra.xml).
329: * @throws DeploymentDescException if the deployment descriptor is
330: * corrupted.
331: * @return a connector object.
332: */
333: public static Connector loadConnector(Reader reader, String fileName)
334: throws DeploymentDescException {
335:
336: Connector connector = new Connector();
337:
338: // Create if null
339: if (connectorDigester == null) {
340: connectorDigester = new JDigester(connectorRuleSet,
341: parsingWithValidation, true, new ConnectorDTDs(),
342: new ConnectorSchemas());
343: }
344:
345: try {
346: connectorDigester.parse(reader, fileName, connector);
347: } catch (DeploymentDescException e) {
348: throw e;
349: } finally {
350: connectorDigester.push(null);
351: }
352: return connector;
353: }
354:
355: /**
356: * Load the jonas-ra.xml file.
357: * @param reader the Reader of the XML file.
358: * @param fileName the name of the file (jonas-ra.xml).
359: * @throws DeploymentDescException if the deployment descriptor is
360: * corrupted.
361: * @return a JonasConnector object.
362: */
363: public static JonasConnector loadJonasConnector(Reader reader,
364: String fileName) throws DeploymentDescException {
365:
366: JonasConnector jonasConnector = new JonasConnector();
367:
368: // Create if null
369: if (jonasConnectorDigester == null) {
370: jonasConnectorDigester = new JDigester(
371: jonasConnectorRuleSet, parsingWithValidation, true,
372: new JonasConnectorDTDs(),
373: new JonasConnectorSchemas());
374: }
375:
376: try {
377: jonasConnectorDigester.parse(reader, fileName,
378: jonasConnector);
379: } catch (DeploymentDescException e) {
380: throw e;
381: } finally {
382: jonasConnectorDigester.push(null);
383: }
384: return jonasConnector;
385: }
386:
387: /**
388: * Controls whether the parser is reporting all validity errors.
389: * @return if true, all external entities will be read.
390: */
391: public static boolean getParsingWithValidation() {
392: return RarDeploymentDescManager.parsingWithValidation;
393: }
394:
395: /**
396: * Controls whether the parser is reporting all validity errors.
397: * @param validation if true, all external entities will be read.
398: */
399: public static void setParsingWithValidation(boolean validation) {
400: RarDeploymentDescManager.parsingWithValidation = validation;
401: }
402:
403: }
|