org.glassfish.appclient.client.acc.NestedAppClientInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-client Show documentation
Show all versions of payara-client Show documentation
Appclient for Payara Server
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.appclient.client.acc;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.ApplicationClientDescriptor;
import com.sun.enterprise.deployment.archivist.Archivist;
import com.sun.enterprise.deployment.archivist.ApplicationArchivist;
import org.glassfish.deployment.common.ModuleDescriptor;
import com.sun.enterprise.util.io.FileUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Logger;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.deployment.common.ModuleExploder;
/**
* Represents an app client that is nested inside an enterprise app.
*
* Note that this could be either an undeployed ear that contains one or more
* embedded app clients or the generated jar file from the back-end that
* intentionally resembles an application archive because of other files that
* had to be packaged with the app client.
*
* @author tjquinn
*/
public class NestedAppClientInfo extends AppClientInfo {
/** which of possibly several app clients in the app the user chose */
private ApplicationClientDescriptor selectedAppClientDescriptor = null;
/** display name specified (if any) on the command line to use in selecting the desired client main class */
private String displayNameFromCommandLine;
public NestedAppClientInfo(
boolean isJWS, Logger logger, File archive,
Archivist archivist, String mainClassFromCommandLine,
String displayNameFromCommandLine) {
// super(isJWS, logger, archive, archivist, mainClassFromCommandLine);
super(isJWS, logger, mainClassFromCommandLine);
this.displayNameFromCommandLine = displayNameFromCommandLine;
}
/**
*Reports which app client embedded in the application archive is the
*one the user has selected using either the main class or display name
*arguments from the command line.
*@return the app client descriptor for the user-selected app client
*/
@Override
protected ApplicationClientDescriptor getAppClient(Archivist archivist) {
if (selectedAppClientDescriptor != null) {
return selectedAppClientDescriptor;
}
Application app = Application.class.cast(archivist.getDescriptor());
/*
*There could be one or more app clients embedded in the enterprise app
*in the archive. Choose which one to run based on the user's
*command-line input.
*/
Set embeddedAppClients =
(Set)
app.getBundleDescriptors(ApplicationClientDescriptor.class);
/*
*Make sure the application module contains at least one app client.
*/
if (embeddedAppClients.size() == 0) {
throw new IllegalArgumentException(
getLocalString(
"appclient.noEmbeddedAppClients",
"The specified application module does not contain any app clients"));
}
/*
*If there is exactly one app client in the ear, then that's the app
*client to use.
*/
if (embeddedAppClients.size() == 1) {
selectedAppClientDescriptor = useFirstEmbeddedAppClient(
embeddedAppClients, mainClassFromCommandLine);
} else {
selectedAppClientDescriptor = chooseFromEmbeddedAppClients(
embeddedAppClients, mainClassFromCommandLine,
displayNameFromCommandLine);
/*
*Make sure that we've selected an app client.
*/
if (selectedAppClientDescriptor == null) {
if (mainClassFromCommandLine != null) {
throw new IllegalArgumentException(getLocalString(
"appclient.noMatchingClientUsingMainClass",
"Could not locate an embedded app client matching the main class name {0}",
mainClassFromCommandLine));
} else {
throw new IllegalArgumentException(getLocalString(
"appclient.noMatchingClientUsingDisplayName",
"Could not locate an embedded app client matching the display name {0}",
displayNameFromCommandLine));
}
}
}
return selectedAppClientDescriptor;
}
private ApplicationClientDescriptor chooseFromEmbeddedAppClients(
Set embeddedAppClients,
String mainClassFromCommandLine,
String displayNameFromCommandLine) {
ApplicationClientDescriptor result = null;
/*
*There are at least two app clients embedded in the ear.
*
*To remain compatible with earlier releases the logic below
*exits the loop immediately upon finding a matching app client
*using the user-provided main class name. If there are other
*app clients with the same main class those are ignored.
*
*On the other hand, if the user specified the target display name
*then the logic below makes sure that exactly one app client
*has that display name.
*
*/
for (ApplicationClientDescriptor candidate : embeddedAppClients) {
/*
*If the user specified a main class name, use that value to
*match against the candiate.
*/
if (mainClassFromCommandLine != null) {
if (candidate.getMainClassName().equals(mainClassFromCommandLine)) {
result = candidate;
/*
*Because the main class name is used as the criteria,
*exit the loop as soon as one matching app client if found.
*/
break;
}
} else {
/*
*We know at this point that the user provided a display name.
*/
if (candidate.getName().equals(displayNameFromCommandLine)) {
/*
*Make sure no other candidate already matched the
*target display name.
*/
if (result == null) {
result = candidate;
/*
*Because the display name is used as the matching
*criteria, continue the loop to make sure there are
*not multiple app clients with the same display name
*/
} else {
throw new IllegalArgumentException(getLocalString(
"appclient.duplicate_display_name",
"More than one nested app client was found with the display name {0}",
displayNameFromCommandLine));
}
}
}
}
return result;
}
private ApplicationClientDescriptor useFirstEmbeddedAppClient(Set embeddedAppClients, String mainClassNameFromCommandLine) {
ApplicationClientDescriptor result = null;
/*
*If the size is 1 then there is sure to be a non-null .next.
*Still, may as well be sure.
*/
Iterator it = embeddedAppClients.iterator();
if ( ! it.hasNext()) {
throw new IllegalStateException(getLocalString(
"appclient.unexpectedEndOfEmbeddedClients",
"The application module seems to contain one app client but the iterator reported no more elements prematurely"));
}
result = embeddedAppClients.iterator().next();
/*
*If, in addition, the user specified a main class on the command
*line, then use the user's class name as the main class name, rather
*than the class specified by the Main-Class attribute in the
*app client archive. This allows the user to override the Main-Class
*setting in the app client's manifest.
*/
if (mainClassNameFromCommandLine != null) {
result.setMainClassName(mainClassNameFromCommandLine);
}
return result;
}
// /**
// *Expands the contents of the source archive into a temporary
// *directory, using the same format as backend server expansions.
// *@param file an archive file to be expanded
// *@return an opened FileArchive for the expanded directory archive
// *@exception IOException in case of errors during the expansion
// */
// @Override
// protected ReadableArchive expand(File file)
// throws IOException, Exception {
//
// File tmpDir = createTmpArchiveDir(file);
// _logger.fine("Expanding original archive " + file.getAbsolutePath() +
// " into " + tmpDir.getAbsolutePath());
//
// // first explode the top level jar
// ModuleExploder.explodeJar(file, tmpDir);
//
// // now we need to load the application standard deployment descriptor.
// ReadableArchive appArchive = archiveFactory.openArchive(tmpDir);
//
// ApplicationArchivist archivist = new ApplicationArchivist();
// if (archivist.hasStandardDeploymentDescriptor(appArchive)) {
// appDesc = (Application)
// archivist.readStandardDeploymentDescriptor(appArchive);
// } else {
// appDesc = Application.createApplication(habitat, null, new ApplicationClientDescriptor().getModuleDescriptor());
// }
//
// // explode the sub modules, skipping the ones that do not exist since
// // the generated appclient jar files do not contain web content
// for (ModuleDescriptor bundle : appDesc.getModules()) {
//
// String moduleName = bundle.getArchiveUri();
// File srcArchive = new File(tmpDir, moduleName);
//
// if (srcArchive.exists()) {
// String massagedModuleName =
// FileUtils.makeFriendlyFilename(moduleName);
// File moduleDir =
// new File(tmpDir, massagedModuleName);
// ModuleExploder.explodeJar(srcArchive, moduleDir);
//
// // delete the original module file
// srcArchive.delete();
// }
// }
//
// /*
// *Leave the new archive open so the caller can use it directly.
// */
// return appArchive;
// }
/**
* Construct the classpaths. The classpaths constructed here is
* slightly different from the backend. It does not process any
* web module. The paths included are:
* 1. all the module root directory (since expansion is needed)
* 2. all the .jar files found in the archive
*/
@Override
protected List getClassPaths(ReadableArchive archive) {
List paths = new ArrayList();
String appRoot = archive.getURI().toASCIIString();
paths.add(appRoot);
//add all jar files
for (Enumeration en = archive.entries(); en.hasMoreElements(); ) {
String entryName = (String) en.nextElement();
if (entryName.endsWith(".jar")) {
String entry = appRoot + File.separator + entryName;
paths.add(entry);
}
}
return paths;
}
@Override
protected String getAppClientRoot(
ReadableArchive archive, ApplicationClientDescriptor descriptor) {
String appRoot = archive.getURI().toASCIIString();
String moduleUri = descriptor.getModuleDescriptor().getArchiveUri();
String moduleRoot = appRoot + File.separator +
FileUtils.makeFriendlyFilename(moduleUri);
return moduleRoot;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy