KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > appclient > NestedAppClientInfo


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.appclient;
25
26 import com.sun.enterprise.deployment.Application;
27 import com.sun.enterprise.deployment.ApplicationClientDescriptor;
28 import com.sun.enterprise.deployment.archivist.Archivist;
29 import com.sun.enterprise.deployment.archivist.ApplicationArchivist;
30 import com.sun.enterprise.deployment.backend.J2EEModuleExploder;
31 import com.sun.enterprise.deployment.BundleDescriptor;
32 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
33 import com.sun.enterprise.deployment.deploy.shared.FileArchive;
34 import com.sun.enterprise.deployment.RootDeploymentDescriptor;
35 import com.sun.enterprise.deployment.util.ModuleDescriptor;
36 import com.sun.enterprise.loader.EJBClassLoader;
37 import com.sun.enterprise.util.io.FileUtils;
38 import java.io.File JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.net.MalformedURLException JavaDoc;
41 import java.net.URI JavaDoc;
42 import java.net.URISyntaxException JavaDoc;
43 import java.net.URL JavaDoc;
44 import java.util.Enumeration JavaDoc;
45 import java.util.HashSet JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.Set JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.List JavaDoc;
50 import java.util.logging.Level JavaDoc;
51 import java.util.logging.Logger JavaDoc;
52 import javax.enterprise.deploy.shared.ModuleType JavaDoc;
53 import org.xml.sax.SAXParseException JavaDoc;
54
55 /**
56  * Represents an app client that is nested inside an enterprise app.
57  *
58  * Note that this could be either an undeployed ear that contains one or more
59  * embedded app clients or the generated jar file from the back-end that
60  * intentionally resembles an application archive because of other files that
61  * had to be packaged with the app client.
62  *
63  * @author tjquinn
64  */

65 public class NestedAppClientInfo extends AppClientInfo {
66
67     private Application appDesc = null;
68     
69     /** which of possibly several app clients in the app the user chose */
70     private ApplicationClientDescriptor selectedAppClientDescriptor = null;
71
72     /** display name specified (if any) on the command line to use in selecting the desired client main class */
73     private String JavaDoc displayNameFromCommandLine;
74     
75     public NestedAppClientInfo(
76             boolean isJWS, Logger JavaDoc logger, File JavaDoc archive,
77             Archivist archivist, String JavaDoc mainClassFromCommandLine,
78             String JavaDoc displayNameFromCommandLine) {
79         super(isJWS, logger, archive, archivist, mainClassFromCommandLine);
80         this.displayNameFromCommandLine = displayNameFromCommandLine;
81     }
82
83     /**
84      *Reports which app client embedded in the application archive is the
85      *one the user has selected using either the main class or display name
86      *arguments from the command line.
87      *@return the app client descriptor for the user-selected app client
88      */

89     protected ApplicationClientDescriptor getAppClient(Archivist archivist) {
90
91         if (selectedAppClientDescriptor != null) {
92             return selectedAppClientDescriptor;
93         }
94
95         Application app = Application.class.cast(archivist.getDescriptor());
96
97         /*
98          *There could be one or more app clients embedded in the enterprise app
99          *in the archive. Choose which one to run based on the user's
100          *command-line input.
101          */

102         Set JavaDoc<ApplicationClientDescriptor> embeddedAppClients =
103             (Set JavaDoc<ApplicationClientDescriptor>)
104                 app.getApplicationClientDescriptors();
105
106         /*
107          *Make sure the application module contains at least one app client.
108          */

109         if (embeddedAppClients.size() == 0) {
110             throw new IllegalArgumentException JavaDoc(
111                 localStrings.getString("appclient.noEmbeddedAppClients"));
112         }
113
114         /*
115          *If there is exactly one app client in the ear, then that's the app
116          *client to use.
117          */

118         if (embeddedAppClients.size() == 1) {
119             selectedAppClientDescriptor = useFirstEmbeddedAppClient(
120                     embeddedAppClients, mainClassFromCommandLine);
121         } else {
122             selectedAppClientDescriptor = chooseFromEmbeddedAppClients(
123                     embeddedAppClients, mainClassFromCommandLine,
124                     displayNameFromCommandLine);
125
126             /*
127              *Make sure that we've selected an app client.
128              */

129             if (selectedAppClientDescriptor == null) {
130                 if (mainClassFromCommandLine != null) {
131                     throw new IllegalArgumentException JavaDoc(localStrings.getString("appclient.noMatchingClientUsingMainClass", mainClassFromCommandLine));
132                 } else {
133                     throw new IllegalArgumentException JavaDoc(localStrings.getString("appclient.noMatchingClientUsingDisplayName", displayNameFromCommandLine));
134                 }
135             }
136         }
137         return selectedAppClientDescriptor;
138     }
139
140     private ApplicationClientDescriptor chooseFromEmbeddedAppClients(
141             Set JavaDoc<ApplicationClientDescriptor> embeddedAppClients,
142             String JavaDoc mainClassFromCommandLine,
143             String JavaDoc displayNameFromCommandLine) {
144         ApplicationClientDescriptor result = null;
145         
146         /*
147          *There are at least two app clients embedded in the ear.
148          *
149          *To remain compatible with earlier releases the logic below
150          *exits the loop immediately upon finding a matching app client
151          *using the user-provided main class name. If there are other
152          *app clients with the same main class those are ignored.
153          *
154          *On the other hand, if the user specified the target display name
155          *then the logic below makes sure that exactly one app client
156          *has that display name.
157          *
158          */

159         for (ApplicationClientDescriptor candidate : embeddedAppClients) {
160            /*
161             *If the user specified a main class name, use that value to
162             *match against the candiate.
163             */

164            if (mainClassFromCommandLine != null) {
165                if (candidate.getMainClassName().equals(mainClassFromCommandLine)) {
166                    result = candidate;
167                    /*
168                     *Because the main class name is used as the criteria,
169                     *exit the loop as soon as one matching app client if found.
170                     */

171                    break;
172                }
173            } else {
174                /*
175                 *We know at this point that the user provided a display name.
176                 */

177                if (candidate.getName().equals(displayNameFromCommandLine)) {
178                    /*
179                     *Make sure no other candidate already matched the
180                     *target display name.
181                     */

182                    if (result == null) {
183                        result = candidate;
184                        /*
185                         *Because the display name is used as the matching
186                         *criteria, continue the loop to make sure there are
187                         *not multiple app clients with the same display name
188                         */

189                    } else {
190                        throw new IllegalArgumentException JavaDoc(localStrings.getString("appclient.duplicate_display_name", displayNameFromCommandLine));
191                    }
192                }
193            }
194         }
195         return result;
196     }
197         
198     private ApplicationClientDescriptor useFirstEmbeddedAppClient(Set JavaDoc<ApplicationClientDescriptor> embeddedAppClients, String JavaDoc mainClassNameFromCommandLine) {
199         ApplicationClientDescriptor result = null;
200         
201         /*
202          *If the size is 1 then there is sure to be a non-null .next.
203          *Still, may as well be sure.
204          */

205         Iterator JavaDoc<ApplicationClientDescriptor> it = embeddedAppClients.iterator();
206         if ( ! it.hasNext()) {
207             throw new IllegalStateException JavaDoc(localStrings.getString("appclient.unexpectedEndOfEmbeddedClients"));
208         }
209
210         result = embeddedAppClients.iterator().next();
211
212         /*
213          *If, in addition, the user specified a main class on the command
214          *line, then use the user's class name as the main class name, rather
215          *than the class specified by the Main-Class attribute in the
216          *app client archive. This allows the user to override the Main-Class
217          *setting in the app client's manifest.
218          */

219         if (mainClassNameFromCommandLine != null) {
220             result.setMainClassName(mainClassNameFromCommandLine);
221         }
222         return result;
223     }
224
225     /**
226      *Expands the contents of the source archive into a temporary
227      *directory, using the same format as backend server expansions.
228      *@param file an archive file to be expanded
229      *@return an opened FileArchive for the expanded directory archive
230      *@exception IOException in case of errors during the expansion
231      */

232     protected AbstractArchive expand(File JavaDoc file)
233         throws IOException JavaDoc, Exception JavaDoc {
234
235         File JavaDoc tmpDir = createTmpArchiveDir(file);
236         _logger.fine("Expanding original archive " + file.getAbsolutePath() +
237                 " into " + tmpDir.getAbsolutePath());
238
239         // first explode the top level jar
240
J2EEModuleExploder.explodeJar(file, tmpDir);
241
242         // now we need to load the application standard deployment descriptor.
243
FileArchive appArchive = new FileArchive();
244         appArchive.open(tmpDir.getAbsolutePath());
245
246         ApplicationArchivist archivist = new ApplicationArchivist();
247         if (archivist.hasStandardDeploymentDescriptor(appArchive)) {
248             appDesc = (Application)
249             archivist.readStandardDeploymentDescriptor(appArchive);
250         } else {
251             appDesc = Application.createApplication(appArchive,true);
252         }
253         
254         // explode the sub modules, skipping the ones that do not exist since
255
// the generated appclient jar files do not contain web content
256
Iterator JavaDoc<ModuleDescriptor> bundles = appDesc.getModules();
257         while (bundles.hasNext()) {
258
259             ModuleDescriptor bundle = bundles.next();
260             
261             String JavaDoc moduleName = bundle.getArchiveUri();
262             File JavaDoc srcArchive = new File JavaDoc(tmpDir, moduleName);
263
264             if (srcArchive.exists()) {
265                 String JavaDoc massagedModuleName =
266                     FileUtils.makeFriendlyFilename(moduleName);
267                 File JavaDoc moduleDir =
268                     new File JavaDoc(tmpDir, massagedModuleName);
269                 J2EEModuleExploder.explodeJar(srcArchive, moduleDir);
270             
271                 // delete the original module file
272
srcArchive.delete();
273             }
274         }
275
276         /*
277          *Leave the new archive open so the caller can use it directly.
278          */

279         return appArchive;
280     }
281
282     /**
283      * Construct the classpaths. The classpaths constructed here is
284      * slightly different from the backend. It does not process any
285      * web module. The paths included are:
286      * 1. all the module root directory (since expansion is needed)
287      * 2. all the .jar files found in the archive
288      */

289     protected List JavaDoc<String JavaDoc> getClassPaths(AbstractArchive archive) {
290
291         List JavaDoc<String JavaDoc> paths = new ArrayList JavaDoc();
292         String JavaDoc appRoot = archive.getArchiveUri();
293         paths.add(appRoot);
294
295         if (appDesc != null) {
296             //add all module roots
297
Iterator JavaDoc<ModuleDescriptor> bundles = appDesc.getModules();
298             while (bundles.hasNext()) {
299                 ModuleDescriptor bundle = bundles.next();
300                 String JavaDoc moduleRoot = appRoot + File.separator +
301                     FileUtils.makeFriendlyFilename(bundle.getArchiveUri());
302                 paths.add(moduleRoot);
303             }
304         } else {
305             //@@@ read it from the archive
306
//shouldn't ever be here though since the appDesc should have been
307
//initialized when expand() is called.
308
}
309
310         //add all jar files
311
for (Enumeration JavaDoc en = archive.entries(); en.hasMoreElements(); ) {
312             String JavaDoc entryName = (String JavaDoc) en.nextElement();
313             if (entryName.endsWith(".jar")) {
314                 String JavaDoc entry = appRoot + File.separator + entryName;
315                 paths.add(entry);
316             }
317         }
318
319         return paths;
320     }
321
322     protected String JavaDoc getAppClientRoot(
323         AbstractArchive archive, ApplicationClientDescriptor descriptor) {
324         String JavaDoc appRoot = archive.getArchiveUri();
325         String JavaDoc moduleUri = descriptor.getModuleDescriptor().getArchiveUri();
326         String JavaDoc moduleRoot = appRoot + File.separator +
327                     FileUtils.makeFriendlyFilename(moduleUri);
328         return moduleRoot;
329     }
330 }
331
Popular Tags