KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > backend > ClientJarMakerImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployment.backend;
25
26 import java.util.*;
27 import java.util.jar.JarFile JavaDoc;
28 import java.util.zip.ZipException JavaDoc;
29 import java.io.*;
30
31 import com.sun.enterprise.deployment.Application;
32 import com.sun.enterprise.deployment.archivist.Archivist;
33 import com.sun.enterprise.deployment.archivist.ArchivistFactory;
34 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
35 import com.sun.enterprise.deployment.interfaces.ClientJarMaker;
36 import com.sun.enterprise.deployment.RootDeploymentDescriptor;
37 import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
38 import com.sun.enterprise.deployment.util.ModuleDescriptor;
39 import com.sun.enterprise.deployment.WebService;
40 import com.sun.enterprise.deployment.WebServicesDescriptor;
41 import com.sun.enterprise.deployment.io.DescriptorConstants;
42 import com.sun.enterprise.util.shared.ArchivistUtils;
43 import com.sun.enterprise.util.zip.ZipItem;
44
45 /**
46  * This class is responsible for creating an appclient jar file that
47  * will be used by the appclient container to run the appclients for
48  * the deployed application.
49  *
50  * @author Jerome Dochez
51  */

52 class ClientJarMakerImpl implements ClientJarMaker {
53     
54     /**
55      * Default constructor for this stateless object
56      * @param props are the implementation properties (if any)
57      */

58     public ClientJarMakerImpl(Properties props) {
59         this.props = props;
60     }
61     
62     /**
63      * creates the appclient container jar file
64      * @param descriptor is the loaded module's deployment descriptor
65      * @param source is the abstract archive for the source module deployed
66      * @param target is the abstract archive for the desired appclient container jar file
67      * @param stubs are the stubs generated by the deployment codegen
68      * @param props is a properties collection to pass implementation parameters
69      *
70      * @throws IOException when the jar file creation fail
71      */

72     public void create(RootDeploymentDescriptor descriptor, AbstractArchive source,
73         AbstractArchive target,ZipItem[] stubs, Properties props)
74         throws IOException {
75         create(descriptor, source, source, target, stubs, props);
76     }
77
78     /**
79      * creates the appclient container jar file
80      * @param descriptor is the loaded module's deployment descriptor
81      * @param source is the abstract archive for the source module deployed
82      * @param source is the abstract archive for the generated xml directory
83      * @param target is the abstract archive for the desired appclient container jar file
84      * @param stubs are the stubs generated by the deployment codegen
85      * @param props is a properties collection to pass implementation parameters
86      *
87      * @throws IOException when the jar file creation fail
88      */

89     public void create(RootDeploymentDescriptor descriptor, AbstractArchive source,
90         AbstractArchive source2, AbstractArchive target,ZipItem[] stubs,
91         Properties props) throws IOException {
92         
93         // in all cases we copy the stubs file in the target archive
94
Set elements = new HashSet();
95         for (int i=0; i<stubs.length;i++) {
96             ZipItem item = stubs[i];
97             if (elements.contains(item.getName())) {
98                 continue;
99             }
100             elements.add(item.getName());
101             OutputStream os = null;
102             InputStream is = null;
103             try {
104                 os = target.putNextEntry(item.getName());
105                 is = new BufferedInputStream(new FileInputStream(item.getFile()));
106                 ArchivistUtils.copyWithoutClose(is, os);
107             } finally {
108                 if (is != null) {
109                     is.close();
110                 }
111                 if (os != null) {
112                     target.closeEntry();
113                 }
114             }
115         }
116         Vector moduleNames = new Vector();
117         
118         if (descriptor.isApplication()) {
119             Application app = (Application) descriptor;
120             for (Iterator modules = app.getModules();modules.hasNext();) {
121                 ModuleDescriptor md = (ModuleDescriptor) modules.next();
122                 Archivist moduleArchivist = ArchivistFactory.getArchivistForType(md.getModuleType());
123                 
124                 AbstractArchive subSource = source.getEmbeddedArchive(md.getArchiveUri());
125                 AbstractArchive subSource2 = source2.getEmbeddedArchive(md.getArchiveUri());
126                 moduleNames.add(md.getArchiveUri());
127                 
128                 // any file that needs to be kept in the sub module should be
129
// calculated here
130
Vector subEntries = new Vector();
131                 // manifest file always stay in embedded jar
132
subEntries.add(JarFile.MANIFEST_NAME);
133                 
134                 // all mapping file stay within the embedded jar
135
WebServicesDescriptor wsd = md.getDescriptor().getWebServices();
136                 if (wsd!=null) {
137                     for (Iterator itr = wsd.getWebServices().iterator();itr.hasNext();) {
138                         WebService ws = (WebService) itr.next();
139                         subEntries.add(ws.getMappingFileUri());
140                     }
141                 }
142                 
143                 Set refs = md.getDescriptor().getServiceReferenceDescriptors();
144                 for (Iterator itr = refs.iterator();itr.hasNext();) {
145                     ServiceReferenceDescriptor srd = (ServiceReferenceDescriptor) itr.next();
146                     subEntries.add(srd.getMappingFileUri());
147                 }
148                 
149                 // first copy original module files in the root on the target
150
// except for .rar files contents.
151
// We need to do it first so we save the list of files to be saved in the
152
// embedded archive (for proper deployment descriptor loading)
153
List embeddedFiles = new ArrayList();
154                 for (Enumeration e = subSource.entries();e.hasMoreElements();) {
155                     
156                     String JavaDoc entryName = (String JavaDoc) e.nextElement();
157                     
158                     // Deployment Descriptors (and associated) go in the embedded files
159
if (entryName.endsWith(".xml") ||
160                         subEntries.contains(entryName) ||
161                         entryName.startsWith(md.getDescriptor().getWsdlDir())) {
162                         
163                             embeddedFiles.add(entryName);
164                     } else {
165                         try {
166                             copy(subSource, target, entryName);
167                         } catch(IOException ioe) {
168                             // dup, we ignore
169
}
170                     }
171                 }
172                 
173                 // now we need to copy the files we saved inside the embedded
174
// archive file
175

176                 AbstractArchive subTarget = target.getEmbeddedArchive(md.getArchiveUri());
177                 
178                 // and copy the list of identified files inside it
179

180                 // copy deployment descriptor files from generated xml directory
181
for (Iterator itr = embeddedFiles.iterator();itr.hasNext();) {
182                     String JavaDoc entryName = (String JavaDoc) itr.next();
183                     copyWithOverride(subSource, subSource2, subTarget, entryName);
184                 }
185
186                 copy(subSource, subSource2, subTarget,
187                     moduleArchivist.getStandardDDFile().getDeploymentDescriptorPath(),
188                     embeddedFiles);
189
190                 // every module may not have a sun descriptor, e.g. par file does not have one.
191
if(moduleArchivist.getConfigurationDDFile()!=null) {
192                     copy(subSource, subSource2, subTarget,
193                         moduleArchivist.getConfigurationDDFile().getDeploymentDescriptorPath(),
194                         embeddedFiles);
195                 }
196
197                 // and the manifest file since it does not appear in the list of files...
198
copy(subSource, subTarget, JarFile.MANIFEST_NAME);
199                 
200                 // we do not need to copy anything else from the source embedded module
201
// since all .class files and resources have moved at the top level of the target
202
// application client container jar, so we can close out both subarchives
203
target.closeEntry(subTarget);
204                 source.closeEntry(subSource);
205                 source2.closeEntry(subSource2);
206             }
207         }
208         // standalone modules and .ear file level entries fall back here, we
209
// just need to copy the original archive file elements at the root level
210
// of the target application client container jar file.
211
Archivist archivist = ArchivistFactory.getArchivistForType(descriptor.getModuleType());
212
213         // because of the backend layout, the appclient jar file appears in the list of files
214
// in the source archive (which is the exploded directory where we started writing
215
// the appclient file... this is also true when doing deploydir deployment
216
String JavaDoc appClientFileName = target.getArchiveUri().substring(target.getArchiveUri().lastIndexOf(File.separatorChar)+1);
217
218         // and the manifest file since it does not appear in the
219
// list of files...
220
copy(source, target, JarFile.MANIFEST_NAME);
221         
222         List xmlFiles = new ArrayList();
223         for (Enumeration e = source.entries(moduleNames.elements());e.hasMoreElements();) {
224             String JavaDoc entryName = (String JavaDoc) e.nextElement();
225             
226             // if this is the appclient we are creating, we pass
227
if (entryName.equals(appClientFileName)) {
228                 continue;
229             }
230             
231             // now we need to write the elements in the target file and explode
232
// if it is a utility jar file
233
if (entryName.endsWith(".jar")) {
234                 // explode
235
AbstractArchive subSource = null;
236                 try {
237                     subSource = source.getEmbeddedArchive(entryName);
238                     for (Enumeration subEntries = subSource.entries();subEntries.hasMoreElements();) {
239                         String JavaDoc subEntryName = (String JavaDoc) subEntries.nextElement();
240                         if(DescriptorConstants.PERSISTENCE_DD_ENTRY.equals(subEntryName)){
241                             // If we copy DescriptorConstants.PAR_DD_ENTRY into
242
// *Client.jar then during subsequent app loading time
243
// server will treat that jar as another PU Root and try to load it.
244
// so don't copy such a file.
245
continue;
246                         }
247                         copy(subSource, target, subEntryName);
248                     }
249                 } finally {
250                     if (subSource != null) {
251                         source.closeEntry(subSource);
252                     }
253                 }
254             } else {
255                 if (entryName.endsWith(".xml")) {
256                     xmlFiles.add(entryName);
257                 }
258                 copyWithOverride(source, source2, target, entryName);
259             }
260         }
261
262         copy(source, source2, target,
263             archivist.getStandardDDFile().getDeploymentDescriptorPath(),
264             xmlFiles);
265         copy(source, source2, target,
266             archivist.getConfigurationDDFile().getDeploymentDescriptorPath(),
267             xmlFiles);
268     }
269
270     /**
271      * copy corresponding deployment descriptor if necessary.
272      * @param source original source
273      * @param source2 overrided source
274      * @param target
275      * @param fileEntryName
276      * @param xmlFiles list of xml files no need to copy
277      * @exception IOException
278      */

279     private void copy(AbstractArchive source, AbstractArchive source2,
280             AbstractArchive target, String JavaDoc fileEntryName, List xmlFiles)
281             throws IOException {
282         if (!xmlFiles.contains(fileEntryName)) {
283             copyWithOverride(source, source2, target, fileEntryName);
284         }
285     }
286     
287     /**
288      * copy the entryName element from the source abstract archive into
289      * the target abstract archive
290      */

291     private void copy(AbstractArchive source, AbstractArchive target, String JavaDoc entryName)
292         throws IOException {
293             
294         InputStream is=null;
295         OutputStream os=null;
296         try {
297             is = source.getEntry(entryName);
298             if (is != null) {
299                 try {
300                     os = target.putNextEntry(entryName);
301                 } catch(ZipException JavaDoc ze) {
302                     // this is a dup...
303
return;
304                 }
305                 ArchivistUtils.copyWithoutClose(is, os);
306             }
307         } catch (IOException ioe) {
308             throw ioe;
309         } finally {
310             IOException closeEntryIOException = null;
311             if (os!=null) {
312                 try {
313                     target.closeEntry();
314                 } catch (IOException ioe) {
315                     closeEntryIOException = ioe;
316                 }
317             }
318             if (is!=null) {
319                 is.close();
320             }
321  
322             if (closeEntryIOException != null) {
323                 throw closeEntryIOException;
324             }
325         }
326     }
327     
328     /**
329      *Copy an entry from the overriding source to the target if it appears in
330      *the overriding source. Otherwise copy if from the normal source.
331      *@param normalSource the AbstractArchive from which to copy the entry if not present in overridingSource
332      *@param overridingSource the overriding AbstractArchive from which to copy the entry
333      *@param target the AbstractArchive into which to copy the entry
334      *@param entryName the name of the entry to copy
335      *@throws IOException in case of error attempting to get the specified entry
336      */

337     private void copyWithOverride(AbstractArchive normalSource, AbstractArchive overridingSource, AbstractArchive target, String JavaDoc entryName) throws IOException {
338         InputStream is = overridingSource.getEntry(entryName);
339         boolean result = (is != null);
340         if (is != null) {
341             /*
342              *If the getEntry succeeds, a stream has been opened so close it.
343              */

344             is.close();
345             copy(overridingSource, target, entryName);
346         } else {
347             /*
348              *The entry does not appear in the overriding source. Copy from
349              *the normal source.
350              */

351             copy(normalSource, target, entryName);
352         }
353     }
354         
355     protected Properties props;
356 }
357
Popular Tags