001: /**
002: * JOnAS : Java(TM) OpenSource Application Server
003: * Copyright (C) 1999-2007 Bull S.A.S.
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: * --------------------------------------------------------------------------
022: * $Id: Client.java 10109 2007-03-28 09:25:41Z sauthieg $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_lib.genbase.archive;
025:
026: import java.io.File;
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.net.URL;
030: import java.util.Hashtable;
031: import java.util.List;
032: import java.util.Map;
033: import java.util.Vector;
034: import java.util.jar.Attributes;
035:
036: import javax.xml.parsers.ParserConfigurationException;
037:
038: import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDesc;
039: import org.objectweb.jonas_client.deployment.lib.ClientDeploymentDescManager;
040: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
041: import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
042: import org.objectweb.jonas_lib.genbase.GenBaseException;
043: import org.objectweb.jonas_lib.genbase.utils.XMLUtils;
044: import org.objectweb.jonas_lib.loader.ClientClassLoader;
045: import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
046: import org.objectweb.util.monolog.api.BasicLevel;
047: import org.w3c.dom.Document;
048: import org.xml.sax.SAXException;
049:
050: /**
051: * Client represnets a J2EE Client Archive.
052: *
053: * @author Guillaume Sauthier
054: */
055: public class Client extends J2EEArchive implements EjbRefModule,
056: WsClient {
057:
058: /** Container application (can be null) */
059: private Application app = null;
060:
061: /** Client Deployment Desc */
062: private ClientContainerDeploymentDesc clientDD = null;
063:
064: /** service-ref list */
065: private List sRefs;
066:
067: /**
068: * ejb-ref list
069: */
070: private List ejbRefs;
071:
072: /** jonas client descriptors */
073: private Map descriptors;
074:
075: /**
076: * jonas-client.xml
077: */
078: private Document jclientDoc;
079:
080: /**
081: * Create a new Client not contained in Application
082: *
083: * @param archive the archive file
084: *
085: * @throws GenBaseException When Init fails.
086: */
087: public Client(Archive archive) throws GenBaseException {
088: super (archive);
089: if (getLogger().isLoggable(BasicLevel.DEBUG)) {
090: getLogger().log(BasicLevel.DEBUG,
091: "Wrapping '" + archive.getName() + "' in Client");
092: }
093: init();
094: }
095:
096: /**
097: * Create a new Client contained in Application
098: *
099: * @param archive the archive file
100: * @param app the container Application
101: *
102: * @throws GenBaseException When Init fails
103: */
104: public Client(Archive archive, Application app)
105: throws GenBaseException {
106: super (archive);
107: setApplication(app);
108: if (getLogger().isLoggable(BasicLevel.DEBUG)) {
109: getLogger().log(BasicLevel.DEBUG,
110: "Wrapping '" + archive.getName() + "' in Client");
111: }
112: init();
113: }
114:
115: /**
116: * Initialize the Client module.
117: *
118: * @throws GenBaseException When client classloader cannot be created or when
119: * client deployment desc cannot be parsed.
120: */
121: private void init() throws GenBaseException {
122: loadDescriptors();
123: }
124:
125: /**
126: * Load Deployment Descriptor of a Client.
127: *
128: * @throws GenBaseException when jonas-client.xml cannot be parsed
129: */
130: private void loadDescriptors() throws GenBaseException {
131:
132: descriptors = new Hashtable();
133: try {
134: InputStream jcis = getJonasClientInputStream();
135: if (jcis != null) {
136: jclientDoc = XMLUtils.newDocument(jcis,
137: "META-INF/jonas-client.xml", isDTDsAllowed());
138: descriptors
139: .put("META-INF/jonas-client.xml", jclientDoc);
140: }
141: } catch (SAXException saxe) {
142: String err = getI18n().getMessage(
143: "Client.loadDescriptors.parseError");
144: throw new GenBaseException(err, saxe);
145: } catch (ParserConfigurationException pce) {
146: String err = getI18n().getMessage(
147: "Client.loadDescriptors.prepare");
148: throw new GenBaseException(err, pce);
149: } catch (IOException ioe) {
150: String err = getI18n().getMessage(
151: "Client.loadDescriptors.parseError");
152: throw new GenBaseException(err, ioe);
153: }
154: }
155:
156: /**
157: * Set the container application.
158: *
159: * @param app the container application.
160: */
161: public void setApplication(Application app) {
162: this .app = app;
163: }
164:
165: /**
166: * Returns the container application (can be null).
167: *
168: * @return the container application (can be null).
169: */
170: public Application getApplication() {
171: return app;
172: }
173:
174: /**
175: * Returns the list of service-ref elements contained by a module.
176: *
177: * @return the list of service-ref elements contained by a module.
178: */
179: public List getServiceRefDescs() {
180: return sRefs;
181: }
182:
183: /**
184: * add *.class from directory in the archive.
185: *
186: * @param classes directory with classes.
187: */
188: public void addClasses(File classes) {
189: addDirectory(classes);
190: }
191:
192: /**
193: * Returns a Map of name to Document for each modified Descriptor of the
194: * archive.
195: *
196: * @return a Map of name to Document
197: */
198: public Map getDescriptors() {
199: return descriptors;
200: }
201:
202: /**
203: * Returns true if filename must be omitted in the archive.
204: *
205: * @param name filename to be tested
206: *
207: * @return true if filename must be omitted.
208: */
209: public boolean omit(String name) {
210: return (name.equals("META-INF/jonas-client.xml") || name
211: .equals("META-INF\\jonas-client.xml"));
212: }
213:
214: /**
215: * Returns the Document of the jonas-client.xml file.
216: *
217: * @return the Document of the jonas-client.xml file.
218: */
219: public Document getJonasClientDoc() {
220: return jclientDoc;
221: }
222:
223: /**
224: * Returns the InputStream of the jonas-client.xml file.
225: *
226: * @return the InputStream of the jonas-client.xml file.
227: *
228: * @throws IOException When InputStream of jonas-client.xml cannot be
229: * returned.
230: */
231: public InputStream getJonasClientInputStream() throws IOException {
232: InputStream is = null;
233:
234: if (isPacked()) {
235: is = getInputStream("META-INF/jonas-client.xml");
236: } else {
237: is = getInputStream("META-INF" + File.separator
238: + "jonas-client.xml");
239: }
240:
241: return is;
242: }
243:
244: /**
245: * Initialize the Archive.
246: * @throws GenBaseException When initialization fails.
247: */
248: public void initialize() throws GenBaseException {
249: // if client in application, clientClassLoader includes ejbClassLoader too
250:
251: try {
252: if (app == null) {
253: // simple client case
254: setModuleClassloader(new ClientClassLoader(getArchive()
255: .getRootFile().toURL(), Thread.currentThread()
256: .getContextClassLoader()));
257: } else {
258: // embedded client case
259: setModuleClassloader(createClientClassLoaderWithinApplication(getApplication()
260: .getEJBClassLoader()));
261: }
262: } catch (IOException ioe) {
263: String err = getI18n().getMessage("Client.init.loader",
264: getArchive().getRootFile());
265: throw new GenBaseException(err, ioe);
266: }
267:
268: try {
269: clientDD = ClientDeploymentDescManager.getInstance(
270: getRootFile().getAbsolutePath(),
271: getModuleClassloader());
272: } catch (DeploymentDescException dde) {
273: throw new GenBaseException(dde);
274: }
275:
276: // we want a List of service-ref
277: sRefs = new Vector();
278: ServiceRefDesc[] refs = clientDD.getServiceRefDesc();
279: for (int i = 0; i < refs.length; i++) {
280: sRefs.add(refs[i]);
281: }
282:
283: // List of ejb-refs
284: ejbRefs = new Vector();
285: EjbRefDesc[] refDesc = clientDD.getEjbRefDesc();
286:
287: for (int i = 0; i < refDesc.length; i++) {
288: ejbRefs.add(refDesc[i]);
289: }
290:
291: }
292:
293: private ClientClassLoader createClientClassLoaderWithinApplication(
294: ClassLoader parent) throws GenBaseException {
295:
296: // get Manifest Attributes if any
297: String classpath = getManifest().getMainAttributes().getValue(
298: Attributes.Name.CLASS_PATH);
299: // Default size : 1 (the client jar file itself)
300: URL[] urls = new URL[1];
301: if (classpath != null) {
302: // Lookup specified files.
303: String[] paths = classpath.split(" ");
304: urls = new URL[paths.length + 1];
305: for (int i = 0; i < paths.length; i++) {
306: try {
307: URL path = new File(app.getRootFile(), paths[i])
308: .toURL();
309: urls[i] = path;
310: } catch (IOException ioe) {
311: String err = "Cannot transform '" + paths[i]
312: + "' as a URL";
313: throw new GenBaseException(err, ioe);
314: }
315: }
316: }
317:
318: ClientClassLoader ccl = null;
319: try {
320: urls[urls.length - 1] = getArchive().getRootFile().toURL();
321: ccl = new ClientClassLoader(urls, parent);
322: } catch (IOException e) {
323: String err = "Cannot create Client ClassLoader for "
324: + getArchive().getName();
325: throw new GenBaseException(err, e);
326: }
327:
328: return ccl;
329: }
330:
331: /**
332: * Returns the list of ejb-ref elements contained by a module.
333: * @return the list of ejb-ref elements contained by a module.
334: */
335: public List getEjbRefDescs() {
336: return ejbRefs;
337: }
338:
339: /**
340: * Close this archive
341: */
342: public void close() {
343: super.close();
344: ejbRefs = null;
345: clientDD = null;
346: app = null;
347: descriptors = null;
348: jclientDoc = null;
349: }
350: }
|