org.apache.geronimo.deployment.DeploymentContext Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.deployment;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.deployment.util.DeploymentUtil;
import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.AbstractNameQuery;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GReferenceInfo;
import org.apache.geronimo.gbean.ReferencePatterns;
import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
import org.apache.geronimo.kernel.GBeanNotFoundException;
import org.apache.geronimo.kernel.Naming;
import org.apache.geronimo.kernel.config.Configuration;
import org.apache.geronimo.kernel.config.ConfigurationData;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.ConfigurationModuleType;
import org.apache.geronimo.kernel.config.NoSuchConfigException;
import org.apache.geronimo.kernel.repository.Artifact;
import org.apache.geronimo.kernel.repository.Environment;
/**
* @version $Rev:385232 $ $Date: 2009-07-01 12:22:07 -0700 (Wed, 01 Jul 2009) $
*/
public class DeploymentContext {
private static final Logger log = LoggerFactory.getLogger(DeploymentContext.class);
private final File baseDir;
private final File inPlaceConfigurationDir;
private final ResourceContext resourceContext;
private final Map childConfigurationDatas = new LinkedHashMap();
private final ConfigurationManager configurationManager;
private final Configuration configuration;
private final Naming naming;
private final List additionalDeployment = new ArrayList();
protected final AbstractName moduleName;
// values for lenience vs. strict manifest classpath interpretation
private final static int manifestClassLoaderMode;
private final static String manifestClassLoaderMessage;
private final static int MFCP_LENIENT = 1;
private final static int MFCP_STRICT = 2;
static {
// Extract the LenientMFCP value if specified. If not, default to strict..
String mode = System.getProperty("Xorg.apache.geronimo.deployment.LenientMFCP");
int mfcpMode = MFCP_STRICT; // Default to strict
String mfcpModeMessage = "Strict Manifest Classpath";
if (mode != null) {
if (mode.equals("true")) {
mfcpMode = MFCP_LENIENT;
mfcpModeMessage = "Lenient Manifest Classpath";
}
}
manifestClassLoaderMode = mfcpMode;
manifestClassLoaderMessage = mfcpModeMessage;
LoggerFactory.getLogger(DeploymentContext.class).info(
"The "+manifestClassLoaderMessage+" processing mode is in effect.\n"+
"This option can be altered by specifying -DXorg.apache.geronimo.deployment.LenientMFCP=true|false\n"+
"Specify =\"true\" for more lenient processing such as ignoring missing jars and references that are not spec compliant.");
}
public DeploymentContext(File baseDir, File inPlaceConfigurationDir, Environment environment, AbstractName moduleName, ConfigurationModuleType moduleType, Naming naming, ConfigurationManager configurationManager, Collection repositories) throws DeploymentException {
this(baseDir, inPlaceConfigurationDir, environment, moduleName, moduleType, naming, createConfigurationManager(configurationManager, repositories));
}
public DeploymentContext(File baseDir, File inPlaceConfigurationDir, Environment environment, AbstractName moduleName, ConfigurationModuleType moduleType, Naming naming, ConfigurationManager configurationManager) throws DeploymentException {
if (baseDir == null) throw new NullPointerException("baseDir is null");
if (environment == null) throw new NullPointerException("environment is null");
if (moduleType == null) throw new NullPointerException("type is null");
if (configurationManager == null) throw new NullPointerException("configurationManager is null");
if (!baseDir.exists()) {
baseDir.mkdirs();
}
this.baseDir = baseDir;
this.inPlaceConfigurationDir = inPlaceConfigurationDir;
this.moduleName = moduleName;
this.naming = naming;
this.configuration = createTempConfiguration(environment, moduleType, baseDir, inPlaceConfigurationDir, configurationManager, naming);
this.configurationManager = configurationManager;
if (null == inPlaceConfigurationDir) {
resourceContext = new CopyResourceContext(configuration, baseDir);
} else {
resourceContext = new InPlaceResourceContext(configuration, inPlaceConfigurationDir);
}
}
private static ConfigurationManager createConfigurationManager(ConfigurationManager configurationManager, Collection repositories) {
return new DeploymentConfigurationManager(configurationManager, repositories);
}
private static Configuration createTempConfiguration(Environment environment, ConfigurationModuleType moduleType, File baseDir, File inPlaceConfigurationDir, ConfigurationManager configurationManager, Naming naming) throws DeploymentException {
try {
configurationManager.loadConfiguration(new ConfigurationData(moduleType, null, null, null, environment, baseDir, inPlaceConfigurationDir, naming));
return configurationManager.getConfiguration(environment.getConfigId());
} catch (Exception e) {
throw new DeploymentException("Unable to create configuration for deployment", e);
}
}
public ConfigurationManager getConfigurationManager() {
return configurationManager;
}
public Artifact getConfigID() {
return configuration.getId();
}
public File getBaseDir() {
return baseDir;
}
public File getInPlaceConfigurationDir() {
return inPlaceConfigurationDir;
}
public Naming getNaming() {
return naming;
}
public GBeanData addGBean(String name, GBeanInfo gbeanInfo) throws GBeanAlreadyExistsException {
if (name == null) throw new NullPointerException("name is null");
if (gbeanInfo == null) throw new NullPointerException("gbean is null");
GBeanData gbean = new GBeanData(gbeanInfo);
configuration.addGBean(name, gbean);
return gbean;
}
public void addGBean(GBeanData gbean) throws GBeanAlreadyExistsException {
if (gbean == null) throw new NullPointerException("gbean is null");
if (gbean.getAbstractName() == null) throw new NullPointerException("gbean.getAbstractName() is null");
configuration.addGBean(gbean);
}
public void removeGBean(AbstractName name) throws GBeanNotFoundException {
if (name == null) throw new NullPointerException("name is null");
configuration.removeGBean(name);
}
public Set getGBeanNames() {
return new HashSet(configuration.getGBeans().keySet());
}
/**
* @deprecated use findGBeans(pattern)
* @param pattern Search for gbeans whose name matches pattern.
* @return the set of gbeans whose name matches the pattern.
*/
public Set listGBeans(AbstractNameQuery pattern) {
return findGBeans(pattern);
}
public AbstractName findGBean(AbstractNameQuery pattern) throws GBeanNotFoundException {
return configuration.findGBean(pattern);
}
public AbstractName findGBean(Set patterns) throws GBeanNotFoundException {
return configuration.findGBean(patterns);
}
public LinkedHashSet findGBeans(AbstractNameQuery pattern) {
return configuration.findGBeans(pattern);
}
public LinkedHashSet findGBeanDatas(Configuration configuration, AbstractNameQuery pattern) {
return configuration.findGBeanDatas(configuration, Collections.singleton(pattern));
}
public LinkedHashSet findGBeans(Set patterns) {
return configuration.findGBeans(patterns);
}
public GBeanData getGBeanInstance(AbstractName name) throws GBeanNotFoundException {
Map gbeans = configuration.getGBeans();
GBeanData gbeanData = (GBeanData) gbeans.get(name);
if (gbeanData == null) {
throw new GBeanNotFoundException(name);
}
return gbeanData;
}
/**
* Add a packed jar file into the deployment context and place it into the
* path specified in the target path. The newly added packed jar is added
* to the classpath of the configuration.
*
* @param targetPath where the packed jar file should be placed
* @param jarFile the jar file to copy
* @throws IOException if there's a problem copying the jar file
*/
public void addIncludeAsPackedJar(URI targetPath, JarFile jarFile) throws IOException {
resourceContext.addIncludeAsPackedJar(targetPath, jarFile);
}
/**
* Add a ZIP file entry into the deployment context and place it into the
* path specified in the target path. The newly added entry is added
* to the classpath of the configuration.
*
* @param targetPath where the ZIP file entry should be placed
* @param zipFile the ZIP file
* @param zipEntry the ZIP file entry
* @throws IOException if there's a problem copying the ZIP entry
*/
public void addInclude(URI targetPath, ZipFile zipFile, ZipEntry zipEntry) throws IOException {
resourceContext.addInclude(targetPath, zipFile, zipEntry);
}
/**
* Add a file into the deployment context and place it into the
* path specified in the target path. The newly added file is added
* to the classpath of the configuration.
*
* @param targetPath where the file should be placed
* @param source the URL of file to be copied
* @throws IOException if there's a problem copying the ZIP entry
*/
public void addInclude(URI targetPath, URL source) throws IOException {
resourceContext.addInclude(targetPath, source);
}
/**
* Add a file into the deployment context and place it into the
* path specified in the target path. The newly added file is added
* to the classpath of the configuration.
*
* @param targetPath where the file should be placed
* @param source the file to be copied
* @throws IOException if there's a problem copying the ZIP entry
*/
public void addInclude(URI targetPath, File source) throws IOException {
resourceContext.addInclude(targetPath, source);
}
interface JarFileFactory {
JarFile newJarFile(URI relativeURI) throws IOException;
String getManifestClassPath(JarFile jarFile) throws IOException;
boolean isDirectory(URI relativeURI) throws IOException;
File[] listFiles(URI relativeURI) throws IOException;
}
private class DefaultJarFileFactory implements JarFileFactory {
public JarFile newJarFile(URI relativeURI) throws IOException {
File targetFile = getTargetFile(relativeURI);
try {
return new JarFile(targetFile);
} catch (IOException e) {
throw (IOException)new IOException("Could not create JarFile for file: " + targetFile).initCause(e);
}
}
public String getManifestClassPath(JarFile jarFile) throws IOException {
Manifest manifest = jarFile.getManifest();
if (manifest == null) {
return null;
}
return manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
}
public boolean isDirectory(URI relativeURI) {
File targetFile = getTargetFile(relativeURI);
return targetFile.isDirectory();
}
public File[] listFiles(URI relativeURI) throws IOException {
File targetFile = getTargetFile(relativeURI);
if (targetFile.isDirectory()) {
File[] files = targetFile.listFiles();
return (files == null) ? new File[0] : files;
} else {
throw new IOException(targetFile + " is not a directory");
}
}
}
public void getCompleteManifestClassPath(JarFile moduleFile, URI moduleBaseUri, URI resolutionUri, ClassPathList classpath, ModuleList exclusions) throws DeploymentException {
List problems = new ArrayList();
getCompleteManifestClassPath(moduleFile, moduleBaseUri, resolutionUri, classpath, exclusions, new DefaultJarFileFactory(), problems);
if (!problems.isEmpty()) {
if (problems.size() == 1) {
throw problems.get(0);
}
throw new DeploymentException("Determining complete manifest classpath unsuccessful: ", problems);
}
}
/**
* Recursively construct the complete set of paths in the ear for the manifest classpath of the supplied modulefile.
* Used only in PersistenceUnitBuilder to figure out if a persistence.xml relates to the starting module. Having a classloader for
* each ejb module would eliminate the need for this and be more elegant.
*
* @param moduleFile the module that we start looking at classpaths at, in the car.
* @param moduleBaseUri where the moduleFile is inside the car file. For an (unpacked) war this ends with / which means we also need:
* @param resolutionUri the uri to resolve all entries against. For a module such as an ejb jar that is part of the
* root ear car it is ".". For a sub-configuration such as a war it is the "reverse" of the path to the war file in the car.
* For instance, if the war file is foo/bar/myweb.war, the resolutionUri is "../../..".
* @param classpath the classpath list we are constructing.
* @param exclusions the paths to not investigate. These are typically the other modules in the ear/car file: they will have their contents processed for themselves.
* @param factory the factory for constructing JarFiles and the way to extract the manifest classpath from a JarFile. Introduced to make
* testing plausible, but may be useful for in-IDE deployment.
* @param problems List to save all the problems we encounter.
* @throws org.apache.geronimo.common.DeploymentException
* if something goes wrong.
*/
public void getCompleteManifestClassPath(JarFile moduleFile, URI moduleBaseUri, URI resolutionUri, ClassPathList classpath, ModuleList exclusions, JarFileFactory factory, List problems) throws DeploymentException {
String manifestClassPath;
try {
manifestClassPath = factory.getManifestClassPath(moduleFile);
} catch (IOException e) {
problems.add(new DeploymentException(printInfo("Could not read manifest: " + moduleBaseUri, moduleBaseUri, classpath, exclusions), e));
return;
}
if (manifestClassPath == null) {
return;
}
for (StringTokenizer tokenizer = new StringTokenizer(manifestClassPath, " "); tokenizer.hasMoreTokens();) {
String path = tokenizer.nextToken();
URI pathUri;
try {
pathUri = new URI(path);
} catch (URISyntaxException e) {
problems.add(new DeploymentException(printInfo("Invalid manifest classpath entry, path= " + path, moduleBaseUri, classpath, exclusions)));
continue;
}
if (pathUri.isAbsolute()) {
problems.add(new DeploymentException(printInfo("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path= " + path, moduleBaseUri, classpath, exclusions)));
continue;
}
URI targetUri = moduleBaseUri.resolve(pathUri);
try {
if (factory.isDirectory(targetUri)) {
if (!targetUri.getPath().endsWith("/")) {
targetUri = URI.create(targetUri.getPath() + "/");
}
for (File file : factory.listFiles(targetUri)) {
if (file.isDirectory()) {
log.debug("Sub directory [" + file.getAbsolutePath() + "] in the manifest entry directory is ignored");
continue;
}
if (!file.getName().endsWith(".jar")) {
log.debug("Only jar files are added to classpath, file [" + file.getAbsolutePath() + "] is ignored");
continue;
}
addToClassPath(moduleBaseUri, resolutionUri, targetUri.resolve(file.getName()), classpath, exclusions, factory, problems);
}
} else {
if (!pathUri.getPath().endsWith(".jar")) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(printInfo(
"Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path= "
+ path, moduleBaseUri, classpath, exclusions)));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, a manifest classpath entry which does not end with .jar, "
+ pathUri + " is being permitted and ignored.");
}
continue;
}
addToClassPath(moduleBaseUri, resolutionUri, targetUri, classpath, exclusions, factory, problems);
}
} catch (IOException e) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(
"An IOException resulting from manifest classpath : targetUri= " + targetUri, e));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, an IOException resulting from manifest classpath " + targetUri
+ " is being ignored.");
}
}
}
}
private void addToClassPath(URI moduleBaseUri, URI resolutionUri, URI targetUri, ClassPathList classpath, ModuleList exclusions, JarFileFactory factory, List problems) throws DeploymentException {
String targetEntry = targetUri.toString();
if (exclusions.contains(targetEntry)) {
return;
}
URI resolvedUri = resolutionUri.resolve(targetUri);
String classpathEntry = resolvedUri.toString();
//don't get caught in circular references
if (classpath.contains(classpathEntry)) {
return;
}
classpath.add(classpathEntry);
JarFile classPathJarFile;
try {
classPathJarFile = factory.newJarFile(targetUri);
} catch (IOException e) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(
printInfo(
"Manifest class path entries must be a valid jar file, or if it is a directory, all the files with jar suffix in it must be a valid jar file (JAVAEE 5 Section 8.2): resolved to targetURI= "
+ targetUri, moduleBaseUri, classpath, exclusions), e));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, an IOException resulting from manifest classpath " + targetUri
+ " is being ignored.");
}
return;
}
getCompleteManifestClassPath(classPathJarFile, targetUri, resolutionUri, classpath, exclusions, factory, problems);
}
private String printInfo(String message, URI moduleBaseUri, ClassPathList classpath, ModuleList exclusions) {
StringBuffer buf = new StringBuffer(message).append("\n");
buf.append(" looking at: ").append(moduleBaseUri);
buf.append(" current classpath: ").append(classpath);
buf.append(" ignoring modules: ").append(exclusions);
return buf.toString();
}
public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri) throws DeploymentException {
List problems = new ArrayList();
addManifestClassPath(moduleFile, moduleBaseUri, new DefaultJarFileFactory(), problems);
if (!problems.isEmpty()) {
if (problems.size() == 1) {
throw problems.get(0);
}
throw new DeploymentException("Determining complete manifest classpath unsuccessful: ", problems);
}
}
/**
* Import the classpath from a jar file's manifest. The imported classpath
* is crafted relative to moduleBaseUri
.
*
* @param moduleFile the jar file from which the manifest is obtained.
* @param moduleBaseUri the base for the imported classpath
* @param factory the factory for constructing JarFiles and the way to extract the manifest classpath from a JarFile. Introduced to make
* testing plausible, but may be useful for in-IDE deployment.
* @param problems List to save all the problems we encounter.
* @throws DeploymentException if there is a problem with the classpath in
* the manifest
*/
public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri, JarFileFactory factory, List problems) throws DeploymentException {
String manifestClassPath;
try {
manifestClassPath = factory.getManifestClassPath(moduleFile);
} catch (IOException e) {
problems.add(new DeploymentException("Could not read manifest: " + moduleBaseUri, e));
return;
}
if (manifestClassPath == null) {
return;
}
for (StringTokenizer tokenizer = new StringTokenizer(manifestClassPath, " "); tokenizer.hasMoreTokens();) {
String path = tokenizer.nextToken();
URI pathUri;
try {
pathUri = new URI(path);
} catch (URISyntaxException e) {
problems.add(new DeploymentException("Invalid manifest classpath entry: module= " + moduleBaseUri + ", path= " + path));
continue;
}
if (pathUri.isAbsolute()) {
problems.add(new DeploymentException("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path= " + path + ", module= " + moduleBaseUri));
continue;
}
URI targetUri = moduleBaseUri.resolve(pathUri);
try {
if (factory.isDirectory(targetUri)) {
if (!targetUri.getPath().endsWith("/")) {
targetUri = URI.create(targetUri.getPath() + "/");
}
for (File file : factory.listFiles(targetUri)) {
if (file.isDirectory()) {
log.debug("Sub directory [" + file.getAbsolutePath() + "] in the manifest entry directory is ignored");
continue;
}
if (!file.getName().endsWith(".jar")) {
log.debug("Only jar files are added to classpath, file [" + file.getAbsolutePath() + "] is ignored");
continue;
}
addToClassPath(targetUri.resolve(file.getName()), problems);
}
} else {
if (!pathUri.getPath().endsWith(".jar")) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(
"Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path= "
+ path + ", module= " + moduleBaseUri));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, a manifest classpath entry which does not end with .jar, "
+ pathUri + " is being permitted and ignored.");
}
continue;
}
addToClassPath(targetUri, problems);
}
} catch (IOException e) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(
"An IOException resulting from manifest classpath : targetUri= " + targetUri, e));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, an IOException resulting from manifest classpath " + targetUri
+ " is being ignored.");
}
}
}
}
private void addToClassPath(URI targetUri, List problems) throws DeploymentException {
try {
configuration.addToClassPath(targetUri.getPath());
} catch (IOException e) {
if (manifestClassLoaderMode == MFCP_STRICT) {
problems.add(new DeploymentException(
"Failure to add targetURI to configuration classpath: " + targetUri.getPath(), e));
} else {
log.info("The " + manifestClassLoaderMessage + " processing mode is in effect.\n"
+ "Therefore, an IOException resulting from manifest classpath " + targetUri.getPath()
+ " is being ignored.");
}
return;
}
}
public void addClass(URI targetPath, String fqcn, byte[] bytes) throws IOException, URISyntaxException {
if (!targetPath.getPath().endsWith("/"))
throw new IllegalStateException("target path must end with a '/' character: " + targetPath);
String classFileName = fqcn.replace('.', '/') + ".class";
resourceContext.addFile(new URI(targetPath.toString() + classFileName), bytes);
configuration.addToClassPath(targetPath.toString());
}
public void addFile(URI targetPath, ZipFile zipFile, ZipEntry zipEntry) throws IOException {
resourceContext.addFile(targetPath, zipFile, zipEntry);
}
public void addFile(URI targetPath, URL source) throws IOException {
resourceContext.addFile(targetPath, source);
}
public void addFile(URI targetPath, File source) throws IOException {
resourceContext.addFile(targetPath, source);
}
public void addFile(URI targetPath, String source) throws IOException {
resourceContext.addFile(targetPath, source);
}
public File getTargetFile(URI targetPath) {
return resourceContext.getTargetFile(targetPath);
}
public ClassLoader getClassLoader() throws DeploymentException {
return configuration.getConfigurationClassLoader();
}
public Configuration getConfiguration() {
return configuration;
}
public void flush() throws IOException {
resourceContext.flush();
}
public void close() throws IOException, DeploymentException {
if (configurationManager != null) {
try {
configurationManager.unloadConfiguration(configuration.getId());
} catch (NoSuchConfigException ignored) {
//ignore
}
}
}
public void addChildConfiguration(String moduleName, ConfigurationData configurationData) {
childConfigurationDatas.put(moduleName, configurationData);
}
public ConfigurationData getConfigurationData() throws DeploymentException {
List failures = verify(configuration);
if (!failures.isEmpty()) {
StringBuffer message = new StringBuffer();
for (String failure : failures) {
if (message.length() > 0) message.append("\n");
message.append(failure);
}
throw new DeploymentException(message.toString());
}
List gbeans = new ArrayList(configuration.getGBeans().values());
Collections.sort(gbeans, new GBeanData.PriorityComparator());
ConfigurationData configurationData = new ConfigurationData(configuration.getModuleType(),
new LinkedHashSet(configuration.getClassPath()),
gbeans,
childConfigurationDatas,
configuration.getEnvironment(),
baseDir,
inPlaceConfigurationDir,
naming);
for (ConfigurationData ownedConfiguration : additionalDeployment) {
configurationData.addOwnedConfigurations(ownedConfiguration.getId());
}
return configurationData;
}
public void addAdditionalDeployment(ConfigurationData configurationData) {
additionalDeployment.add(configurationData);
}
public List getAdditionalDeployment() {
return additionalDeployment;
}
public AbstractName getModuleName() {
return moduleName;
}
public List verify(Configuration configuration) throws DeploymentException {
List failures = new ArrayList();
for (Map.Entry entry : this.configuration.getGBeans().entrySet()) {
AbstractName name = entry.getKey();
GBeanData gbean = entry.getValue();
for (Map.Entry referenceEntry : gbean.getReferences().entrySet()) {
String referenceName = referenceEntry.getKey();
ReferencePatterns referencePatterns = referenceEntry.getValue();
String failure = verifyReference(gbean, referenceName, referencePatterns, configuration);
if (failure != null) {
failures.add(failure);
}
}
for (ReferencePatterns referencePatterns : gbean.getDependencies()) {
String failure = verifyDependency(name, referencePatterns, configuration);
if (failure != null) {
failures.add(failure);
}
}
}
return failures;
}
private String verifyReference(GBeanData gbean, String referenceName, ReferencePatterns referencePatterns, Configuration configuration) {
GReferenceInfo referenceInfo = gbean.getGBeanInfo().getReference(referenceName);
// if there is no reference info we can't verify
if (referenceInfo == null) return null;
// A collection valued reference doesn't need to be verified
if (referenceInfo.getProxyType().equals(Collection.class.getName())) return null;
String message = isVerifyReference(referencePatterns, configuration);
if (message != null) {
return "Unable to resolve reference \"" + referenceName + "\"\n" +
" in gbean " + gbean.getAbstractName() + "\n to a gbean matching the pattern " + referencePatterns.getPatterns() + "\n due to: " + message;
}
return null;
}
private String verifyDependency(AbstractName name, ReferencePatterns referencePatterns, Configuration configuration) {
String message = isVerifyReference(referencePatterns, configuration);
if (message != null) {
return "Unable to resolve dependency in gbean " + name +
"\n to a gbean matching the pattern " + referencePatterns.getPatterns() + "\n due to: " + message;
}
return null;
}
private String isVerifyReference(ReferencePatterns referencePatterns, Configuration configuration) {
// we can't verify a resolved reference since it will have a specific artifact already set...
// hopefully the deployer won't generate bad resolved references
if (referencePatterns.isResolved()) return null;
// Do not verify the reference if it has an explicit depenency on another artifact, because it it likely
// that the other artifact is not in the "environment" (if it were you wouldn't use the long form)
Set patterns = referencePatterns.getPatterns();
for (AbstractNameQuery query : patterns) {
if (query.getArtifact() != null) return null;
}
// attempt to find the bean
try {
configuration.findGBean(patterns);
return null;
} catch (GBeanNotFoundException e) {
//TODO bug!! GERONIMO-3140 Multiple matches may be caused by using an already-loaded configuration rather than reloading one
// using the client_artifact_aliases.properties which e.g. remap the server tm to the client tm.
if (e.hasMatches()) {
return null;
}
return e.getMessage();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy