blob: 2d3d6fb71809c61fef17596509a11bb501e0cdb3 [file] [log] [blame]
/*
* 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.openejb.config;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.Vendor;
import org.apache.openejb.api.Proxy;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.BmpEntityContainerInfo;
import org.apache.openejb.assembler.classic.ClientInfo;
import org.apache.openejb.assembler.classic.CmpEntityContainerInfo;
import org.apache.openejb.assembler.classic.ConnectionManagerInfo;
import org.apache.openejb.assembler.classic.ConnectorInfo;
import org.apache.openejb.assembler.classic.ContainerInfo;
import org.apache.openejb.assembler.classic.ContainerSystemInfo;
import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
import org.apache.openejb.assembler.classic.EjbJarInfo;
import org.apache.openejb.assembler.classic.FacilitiesInfo;
import org.apache.openejb.assembler.classic.HandlerChainInfo;
import org.apache.openejb.assembler.classic.HandlerInfo;
import org.apache.openejb.assembler.classic.JndiContextInfo;
import org.apache.openejb.assembler.classic.ManagedContainerInfo;
import org.apache.openejb.assembler.classic.MdbContainerInfo;
import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
import org.apache.openejb.assembler.classic.OpenEjbConfigurationFactory;
import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
import org.apache.openejb.assembler.classic.ResourceInfo;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
import org.apache.openejb.assembler.classic.ServiceInfo;
import org.apache.openejb.assembler.classic.SingletonSessionContainerInfo;
import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.assembler.classic.WebAppInfo;
import org.apache.openejb.component.ClassLoaderEnricher;
import org.apache.openejb.config.sys.AbstractService;
import org.apache.openejb.config.sys.AdditionalDeployments;
import org.apache.openejb.config.sys.ConnectionManager;
import org.apache.openejb.config.sys.Container;
import org.apache.openejb.config.sys.Deployments;
import org.apache.openejb.config.sys.JaxbOpenejb;
import org.apache.openejb.config.sys.JndiProvider;
import org.apache.openejb.config.sys.Openejb;
import org.apache.openejb.config.sys.ProxyFactory;
import org.apache.openejb.config.sys.Resource;
import org.apache.openejb.config.sys.SecurityService;
import org.apache.openejb.config.sys.Service;
import org.apache.openejb.config.sys.ServiceProvider;
import org.apache.openejb.config.sys.TransactionManager;
import org.apache.openejb.jee.Application;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.EnterpriseBean;
import org.apache.openejb.jee.EnvEntry;
import org.apache.openejb.jee.Handler;
import org.apache.openejb.jee.HandlerChain;
import org.apache.openejb.jee.HandlerChains;
import org.apache.openejb.jee.ParamValue;
import org.apache.openejb.jee.SessionBean;
import org.apache.openejb.loader.FileUtils;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.Options;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.monitoring.LocalMBeanServer;
import org.apache.openejb.resource.jdbc.DataSourceFactory;
import org.apache.openejb.resource.jdbc.pool.DataSourceCreator;
import org.apache.openejb.resource.jdbc.pool.DefaultDataSourceCreator;
import org.apache.openejb.util.EventHelper;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.Messages;
import org.apache.openejb.util.SuperProperties;
import org.apache.openejb.util.URISupport;
import org.apache.openejb.util.URLs;
import org.apache.openejb.util.proxy.QueryProxy;
import org.apache.xbean.finder.MetaAnnotatedClass;
import org.apache.xbean.finder.ResourceFinder;
import javax.ejb.embeddable.EJBContainer;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import static org.apache.openejb.config.DeploymentsResolver.DEPLOYMENTS_CLASSPATH_PROPERTY;
import static org.apache.openejb.config.ServiceUtils.implies;
public class ConfigurationFactory implements OpenEjbConfigurationFactory {
public static final String OPENEJB_JDBC_DATASOURCE_CREATOR = "openejb.jdbc.datasource-creator";
public static final String ADDITIONAL_DEPLOYMENTS = "conf/deployments.xml";
static final String CONFIGURATION_PROPERTY = "openejb.configuration";
static final String CONF_FILE_PROPERTY = "openejb.conf.file";
private static final String DEBUGGABLE_VM_HACKERY_PROPERTY = "openejb.debuggable-vm-hackery";
protected static final String VALIDATION_SKIP_PROPERTY = "openejb.validation.skip";
private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, ConfigurationFactory.class);
private static final Messages messages = new Messages(ConfigurationFactory.class);
private static final String IGNORE_DEFAULT_VALUES_PROP = "IgnoreDefaultValues";
private String configLocation;
private OpenEjbConfiguration sys;
private Openejb openejb;
private DynamicDeployer deployer;
private final DeploymentLoader deploymentLoader;
private final boolean offline;
private final boolean serviceTypeIsAdjustable; // offline is a bit different from this and offline could be off and this on
private static final String CLASSPATH_AS_EAR = "openejb.deployments.classpath.ear";
static final String WEBSERVICES_ENABLED = "openejb.webservices.enabled";
static final String OFFLINE_PROPERTY = "openejb.offline";
public ConfigurationFactory() {
this(!shouldAutoDeploy());
}
private static boolean shouldAutoDeploy() {
final Options options = SystemInstance.get().getOptions();
final boolean b = options.get(ConfigurationFactory.OFFLINE_PROPERTY, false);
return options.get("tomee.autoconfig", !b);
}
public ConfigurationFactory(final boolean offline) {
this(offline, (DynamicDeployer) null);
}
public ConfigurationFactory(final boolean offline, final DynamicDeployer preAutoConfigDeployer) {
this.offline = offline;
this.serviceTypeIsAdjustable = SystemInstance.get().getOptions().get("openejb.service-type-adjustement", true);
this.deploymentLoader = new DeploymentLoader();
LocalMBeanServer.reset();
final Options options = SystemInstance.get().getOptions();
if (SystemInstance.get().getComponent(DataSourceCreator.class) == null) {
final String creator = options.get(OPENEJB_JDBC_DATASOURCE_CREATOR, (String) null);
if (creator == null) {
SystemInstance.get().setComponent(DataSourceCreator.class, new DefaultDataSourceCreator());
} else {
try {
SystemInstance.get().setComponent(DataSourceCreator.class, DataSourceFactory.creator(creator, false));
} catch (Exception e) {
logger.error("can't load " + creator + " will use the default creator", e);
SystemInstance.get().setComponent(DataSourceCreator.class, new DefaultDataSourceCreator());
}
}
}
if (SystemInstance.get().getComponent(ClassLoaderEnricher.class) == null) {
SystemInstance.get().setComponent(ClassLoaderEnricher.class, new ClassLoaderEnricher());
}
// annotation deployer encapsulate some logic, to be able to push to it some config
// we give the ability here to get the internal deployer to push the config values
final AnnotationDeployer annotationDeployer = new AnnotationDeployer();
final BeanProperties beanProperties = new BeanProperties();
final AppContextConfigDeployer appContextConfigDeployer = new AppContextConfigDeployer(annotationDeployer.getEnvEntriesPropertiesDeployer(), beanProperties);
final Chain chain = new Chain();
chain.add(new SystemPropertiesOverride());
chain.add(new GeneratedClientModules.Add());
chain.add(new ReadDescriptors());
chain.add(appContextConfigDeployer);
chain.add(new ApplicationProperties());
chain.add(new ModuleProperties());
chain.add(new LegacyProcessor());
chain.add(annotationDeployer);
chain.add(beanProperties);
chain.add(new ProxyBeanClassUpdate());
chain.add(new GeneratedClientModules.Prune());
chain.add(new ClearEmptyMappedName());
//START SNIPPET: code
if (!options.get(VALIDATION_SKIP_PROPERTY, false)) {
chain.add(new ValidateModules());
} else {
DeploymentLoader.logger.info("validationDisabled", VALIDATION_SKIP_PROPERTY);
}
//END SNIPPET: code
chain.add(new InitEjbDeployments());
if (options.get(DEBUGGABLE_VM_HACKERY_PROPERTY, false)) {
chain.add(new DebuggableVmHackery());
}
if (options.get(WEBSERVICES_ENABLED, true)) {
chain.add(new WsDeployer());
} else {
chain.add(new RemoveWebServices());
}
chain.add(new CmpJpaConversion());
// By default all vendor support is enabled
final Set<Vendor> support = SystemInstance.get().getOptions().getAll("openejb.vendor.config", Vendor.values());
if (support.contains(Vendor.GERONIMO) || SystemInstance.get().hasProperty("openejb.geronimo")) {
chain.add(new OpenEjb2Conversion());
}
if (support.contains(Vendor.GLASSFISH)) {
chain.add(new SunConversion());
}
if (support.contains(Vendor.WEBLOGIC)) {
chain.add(new WlsConversion());
}
if (SystemInstance.get().hasProperty("openejb.geronimo")) {
// must be after CmpJpaConversion since it adds new persistence-context-refs
chain.add(new GeronimoMappedName());
}
if (null != preAutoConfigDeployer) {
chain.add(preAutoConfigDeployer);
}
chain.add(new ConvertDataSourceDefinitions());
chain.add(new CleanEnvEntries());
chain.add(new LinkBuiltInTypes());
if (offline) {
final AutoConfig autoConfig = new AutoConfig(this);
autoConfig.autoCreateResources(false);
autoConfig.autoCreateContainers(false);
chain.add(autoConfig);
} else {
chain.add(new AutoConfig(this));
}
chain.add(new ApplyOpenejbJar());
chain.add(new MappedNameBuilder());
chain.add(new ActivationConfigPropertyOverride());
chain.add(new OutputGeneratedDescriptors());
// chain.add(new MergeWebappJndiContext());
this.deployer = chain;
}
public ConfigurationFactory(final boolean offline, final OpenEjbConfiguration configuration) {
this(offline, (DynamicDeployer) null, configuration);
}
public ConfigurationFactory(final boolean offline,
final DynamicDeployer preAutoConfigDeployer,
final OpenEjbConfiguration configuration) {
this(offline, preAutoConfigDeployer);
sys = configuration;
}
public ConfigurationFactory(final boolean offline, final Chain deployerChain, final OpenEjbConfiguration configuration) {
this.offline = offline;
this.deploymentLoader = new DeploymentLoader();
this.deployer = deployerChain;
this.sys = configuration;
this.serviceTypeIsAdjustable = true;
}
public static List<HandlerChainInfo> toHandlerChainInfo(final HandlerChains chains) {
final List<HandlerChainInfo> handlerChains = new ArrayList<HandlerChainInfo>();
if (chains == null)
return handlerChains;
for (final HandlerChain handlerChain : chains.getHandlerChain()) {
final HandlerChainInfo handlerChainInfo = new HandlerChainInfo();
handlerChainInfo.serviceNamePattern = handlerChain.getServiceNamePattern();
handlerChainInfo.portNamePattern = handlerChain.getPortNamePattern();
handlerChainInfo.protocolBindings.addAll(handlerChain.getProtocolBindings());
for (final Handler handler : handlerChain.getHandler()) {
final HandlerInfo handlerInfo = new HandlerInfo();
handlerInfo.handlerName = handler.getHandlerName();
handlerInfo.handlerClass = handler.getHandlerClass();
handlerInfo.soapHeaders.addAll(handler.getSoapHeader());
handlerInfo.soapRoles.addAll(handler.getSoapRole());
for (final ParamValue param : handler.getInitParam()) {
handlerInfo.initParams.setProperty(param.getParamName(), param.getParamValue());
}
handlerChainInfo.handlers.add(handlerInfo);
}
handlerChains.add(handlerChainInfo);
}
return handlerChains;
}
public static class ProxyBeanClassUpdate implements DynamicDeployer {
@Override
public AppModule deploy(final AppModule appModule) throws OpenEJBException {
for (final EjbModule module : appModule.getEjbModules()) {
for (final EnterpriseBean eb : module.getEjbJar().getEnterpriseBeans()) {
if (!(eb instanceof SessionBean)) {
continue;
}
final SessionBean bean = (SessionBean) eb;
final Class<?> ejbClass;
try {
ejbClass = module.getClassLoader().loadClass(bean.getEjbClass());
} catch (ClassNotFoundException e) {
logger.warning("can't load " + bean.getEjbClass());
continue;
}
final Class<?> proxyClass;
if (ejbClass.isInterface()) { // dynamic proxy implementation
bean.setLocal(ejbClass.getName());
final Proxy proxyAnnotation = (Proxy) new MetaAnnotatedClass(ejbClass).getAnnotation(Proxy.class);
if (proxyAnnotation != null) {
proxyClass = proxyAnnotation.value();
} else {
proxyClass = QueryProxy.class;
}
bean.setProxy(proxyClass.getName());
} else {
continue;
}
for (final EnvEntry entry : bean.getEnvEntry()) {
if ("java:comp/env/implementingInterfaceClass".equals(entry.getName())) {
entry.setEnvEntryValue(ejbClass.getName());
}
}
}
}
return appModule;
}
}
public static class Chain implements DynamicDeployer {
private final List<DynamicDeployer> chain = new ArrayList<DynamicDeployer>();
public boolean add(final DynamicDeployer o) {
return chain.add(o);
}
@Override
public AppModule deploy(AppModule appModule) throws OpenEJBException {
for (final DynamicDeployer deployer : chain) {
appModule = deployer.deploy(appModule);
}
return appModule;
}
}
@Override
public void init(final Properties props) throws OpenEJBException {
configLocation = props.getProperty(CONF_FILE_PROPERTY);
if (configLocation == null) {
configLocation = props.getProperty(CONFIGURATION_PROPERTY);
}
configLocation = ConfigUtils.searchForConfiguration(configLocation, props);
if (configLocation != null) {
logger.info("openejb configuration file is '" + configLocation + "'");
props.setProperty(CONFIGURATION_PROPERTY, configLocation);
}
}
protected void install(final ContainerInfo serviceInfo) throws OpenEJBException {
if (sys != null) {
sys.containerSystem.containers.add(serviceInfo);
} else if (!offline) {
final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
assembler.createContainer(serviceInfo);
}
}
protected void install(final ResourceInfo serviceInfo) throws OpenEJBException {
if (sys != null) {
sys.facilities.resources.add(serviceInfo);
} else if (!offline) {
final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
assembler.createResource(serviceInfo);
}
}
/**
* Main loop that gets executed when OpenEJB starts up Reads config files and produces the basic "AST" the assembler needs to actually build the contianer system
* <p/>
* This method is called by the Assembler once at startup.
*
* @return OpenEjbConfiguration
* @throws OpenEJBException
*/
@Override
public OpenEjbConfiguration getOpenEjbConfiguration() throws OpenEJBException {
if (sys != null) {
return sys;
}
if (configLocation != null) {
openejb = JaxbOpenejb.readConfig(configLocation);
} else {
openejb = JaxbOpenejb.createOpenejb();
}
loadPropertiesDeclaredConfiguration(openejb);
sys = new OpenEjbConfiguration();
sys.containerSystem = new ContainerSystemInfo();
sys.facilities = new FacilitiesInfo();
// listener + some config can be defined as service
for (final Service service : openejb.getServices()) {
final ServiceInfo info = configureService(service, ServiceInfo.class);
sys.facilities.services.add(info);
}
for (final JndiProvider provider : openejb.getJndiProvider()) {
final JndiContextInfo info = configureService(provider, JndiContextInfo.class);
sys.facilities.remoteJndiContexts.add(info);
}
sys.facilities.securityService = configureService(openejb.getSecurityService(), SecurityServiceInfo.class);
sys.facilities.transactionService = configureService(openejb.getTransactionManager(), TransactionServiceInfo.class);
final List<ResourceInfo> resources = new ArrayList<ResourceInfo>();
for (final Resource resource : openejb.getResource()) {
final ResourceInfo resourceInfo = configureService(resource, ResourceInfo.class);
resources.add(resourceInfo);
}
Collections.sort(resources, new ResourceInfoComparator(resources));
sys.facilities.resources.addAll(resources);
// ConnectionManagerInfo service = configureService(openejb.getConnectionManager(), ConnectionManagerInfo.class);
// sys.facilities.connectionManagers.add(service);
if (openejb.getProxyFactory() != null) {
sys.facilities.intraVmServer = configureService(openejb.getProxyFactory(), ProxyFactoryInfo.class);
}
for (final Container declaration : openejb.getContainer()) {
final ContainerInfo info = createContainerInfo(declaration);
sys.containerSystem.containers.add(info);
}
final List<File> declaredApps = getDeclaredApps();
for (final File jarFile : declaredApps) {
try {
final AppInfo appInfo = configureApplication(jarFile);
sys.containerSystem.applications.add(appInfo);
} catch (OpenEJBException alreadyHandled) {
final DeploymentExceptionManager exceptionManager = SystemInstance.get().getComponent(DeploymentExceptionManager.class);
exceptionManager.pushDelpoymentException(alreadyHandled);
}
}
final boolean embedded = SystemInstance.get().hasProperty(EJBContainer.class.getName());
final Options options = SystemInstance.get().getOptions();
if (options.get("openejb.system.apps", false)) {
try {
final AppInfo appInfo = configureApplication(new AppModule(SystemApps.getSystemModule()));
sys.containerSystem.applications.add(appInfo);
} catch (OpenEJBException e) {
logger.error("Unable to load the system applications.", e);
}
} else if (options.get(DEPLOYMENTS_CLASSPATH_PROPERTY, !embedded)) {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final ArrayList<File> jarFiles = getModulesFromClassPath(declaredApps, classLoader);
final String appId = "classpath.ear";
final boolean classpathAsEar = options.get(CLASSPATH_AS_EAR, true);
try {
if (classpathAsEar && !jarFiles.isEmpty()) {
final AppInfo appInfo = configureApplication(classLoader, appId, jarFiles);
sys.containerSystem.applications.add(appInfo);
} else
for (final File jarFile : jarFiles) {
final AppInfo appInfo = configureApplication(jarFile);
sys.containerSystem.applications.add(appInfo);
}
if (jarFiles.size() == 0) {
logger.warning("config.noModulesFoundToDeploy");
}
} catch (OpenEJBException alreadyHandled) {
logger.debug("config.alreadyHandled");
}
}
for (final Deployments deployments : openejb.getDeployments()) {
if (deployments.isAutoDeploy()) {
if (deployments.getDir() != null) {
sys.containerSystem.autoDeploy.add(deployments.getDir());
}
}
}
final OpenEjbConfiguration finished = sys;
sys = null;
openejb = null;
return finished;
}
private List<File> getDeclaredApps() {
// make a copy of the list because we update it
final List<Deployments> deployments = new ArrayList<Deployments>();
if (openejb != null) {
deployments.addAll(openejb.getDeployments());
}
try {
final File additionalDeploymentFile = SystemInstance.get().getBase().getFile(ADDITIONAL_DEPLOYMENTS, false);
if (additionalDeploymentFile.exists()) {
InputStream fis = null;
try {
fis = IO.read(additionalDeploymentFile);
final AdditionalDeployments additionalDeployments = JaxbOpenejb.unmarshal(AdditionalDeployments.class, fis);
deployments.addAll(additionalDeployments.getDeployments());
} catch (Exception e) {
logger.error("can't read " + ADDITIONAL_DEPLOYMENTS, e);
} finally {
IO.close(fis);
}
}
} catch (Exception e) {
logger.info("No additional deployments found: " + e);
}
// resolve jar locations ////////////////////////////////////// BEGIN ///////
final FileUtils base = SystemInstance.get().getBase();
final List<Deployments> autoDeploy = new ArrayList<Deployments>();
final List<File> declaredAppsUrls = new ArrayList<File>();
for (final Deployments deployment : deployments) {
try {
DeploymentsResolver.loadFrom(deployment, base, declaredAppsUrls);
if (deployment.isAutoDeploy())
autoDeploy.add(deployment);
} catch (SecurityException se) {
logger.warning("Security check failed on deployment: " + deployment.getFile(), se);
}
}
if (autoDeploy.size() > 0) {
SystemInstance.get().addObserver(new AutoDeployer(this, autoDeploy));
}
return declaredAppsUrls;
}
public ArrayList<File> getModulesFromClassPath(final List<File> declaredApps, final ClassLoader classLoader) {
final FileUtils base = SystemInstance.get().getBase();
final List<URL> classpathAppsUrls = new ArrayList<URL>();
DeploymentsResolver.loadFromClasspath(base, classpathAppsUrls, classLoader);
final ArrayList<File> jarFiles = new ArrayList<File>();
for (final URL path : classpathAppsUrls) {
final File file = URLs.toFile(path);
if (declaredApps != null && declaredApps.contains(file))
continue;
jarFiles.add(file);
}
return jarFiles;
}
public ContainerInfo createContainerInfo(final Container container) throws OpenEJBException {
final Class<? extends ContainerInfo> infoClass = getContainerInfoType(container.getType());
if (infoClass == null) {
throw new OpenEJBException(messages.format("unrecognizedContainerType", container.getType()));
}
return configureService(container, infoClass);
}
private void loadPropertiesDeclaredConfiguration(final Openejb openejb) {
final Properties sysProps = new Properties(System.getProperties());
sysProps.putAll(SystemInstance.get().getProperties());
for (final Map.Entry<Object, Object> entry : sysProps.entrySet()) {
final Object o = entry.getValue();
if (!(o instanceof String))
continue;
if (!((String) o).startsWith("new://"))
continue;
final String name = (String) entry.getKey();
final String value = (String) entry.getValue();
try {
final Object service = toConfigDeclaration(name, value);
openejb.add(service);
} catch (URISyntaxException e) {
logger.error("Error declaring service '" + name + "'. Invalid Service URI '" + value + "'. java.net.URISyntaxException: " + e.getMessage());
} catch (OpenEJBException e) {
logger.error(e.getMessage());
}
}
}
protected Object toConfigDeclaration(final String name, String value) throws URISyntaxException, OpenEJBException {
// value = value.replaceFirst("(.)#", "$1%23");
value = value.replaceFirst("(provider=[^#=&]+)#", "$1%23");
final URI uri = URLs.uri(value);
return toConfigDeclaration(name, uri);
}
public Object toConfigDeclaration(final String id, final URI uri) throws OpenEJBException {
final String serviceType;
try {
serviceType = uri.getHost();
final Object object;
try {
object = JaxbOpenejb.create(serviceType);
} catch (Exception e) {
throw new OpenEJBException("Invalid URI '" + uri + "'. " + e.getMessage());
}
final Map<String, String> map;
try {
map = URISupport.parseParamters(uri);
} catch (URISyntaxException e) {
throw new OpenEJBException("Unable to parse URI parameters '" + uri + "'. URISyntaxException: " + e.getMessage());
}
if (object instanceof AbstractService) {
final AbstractService service = (AbstractService) object;
service.setId(id);
service.setType(map.remove("type"));
service.setProvider(map.remove("provider"));
service.setClassName(map.remove("class-name"));
service.setConstructor(map.remove("constructor"));
service.setFactoryName(map.remove("factory-name"));
if (object instanceof Resource) {
final String aliases = map.remove("aliases");
if (aliases != null) {
((Resource) object).getAliases().addAll(Arrays.asList(aliases.split(",")));
}
}
service.getProperties().putAll(map);
} else if (object instanceof Deployments) {
final Deployments deployments = (Deployments) object;
deployments.setDir(map.remove("dir"));
deployments.setFile(map.remove("jar"));
final String cp = map.remove("classpath");
if (cp != null) {
final String[] paths = cp.split(File.pathSeparator);
final List<URL> urls = new ArrayList<URL>();
for (final String path : paths) {
urls.add(new File(path).toURI().normalize().toURL());
}
deployments.setClasspath(new URLClassLoader(urls.toArray(new URL[urls.size()])));
}
}
return object;
} catch (Exception e) {
throw new OpenEJBException("Error declaring service '" + id + "'. Unable to create Service definition from URI '" + uri.toString() + "'", e);
}
}
public AppInfo configureApplication(final File jarFile) throws OpenEJBException {
logger.debug("Beginning load: " + jarFile.getAbsolutePath());
try {
final AppModule appModule = deploymentLoader.load(jarFile);
final AppInfo appInfo = configureApplication(appModule);
// TODO This is temporary -- we need to do this in AppInfoBuilder
appInfo.paths.add(appInfo.path);
appInfo.paths.add(jarFile.getAbsolutePath());
return appInfo;
} catch (ValidationFailedException e) {
logger.warning("configureApplication.loadFailed", jarFile.getAbsolutePath(), e.getMessage()); // DO not include the stacktrace in the message
throw e;
} catch (OpenEJBException e) {
// DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
// removing this message causes NO messages to be printed when embedded
logger.warning("configureApplication.loadFailed", e, jarFile.getAbsolutePath(), e.getMessage());
throw e;
}
}
/**
* embedded usage
*
* @param classLoader classloader
* @param id id supplied from embedded properties or null
* @param jarFiles list of ejb modules
* @return configured AppInfo
* @throws OpenEJBException on error
*/
public AppInfo configureApplication(final ClassLoader classLoader, final String id, final List<File> jarFiles) throws OpenEJBException {
final AppModule collection = loadApplication(classLoader, id, jarFiles);
final AppInfo appInfo;
try {
appInfo = configureApplication(collection);
} catch (ValidationFailedException e) {
logger.warning("configureApplication.loadFailed", collection.getModuleId(), e.getMessage()); // DO not include the stacktrace in the message
throw e;
} catch (OpenEJBException e) {
// DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
// removing this message causes NO messages to be printed when embedded
logger.warning("configureApplication.loadFailed", e, collection.getModuleId(), e.getMessage());
throw e;
}
return appInfo;
}
@SuppressWarnings("unchecked")
public AppModule loadApplication(final ClassLoader classLoader, String id, final List<File> jarFiles) throws OpenEJBException {
final boolean standaloneModule = id == null;
if (standaloneModule) {
id = "";
}
final Application application = new Application();
application.setApplicationName(id);
final AppModule collection = new AppModule(classLoader, id, application, standaloneModule);
final Map<String, Object> altDDs = collection.getAltDDs();
for (final File jarFile : jarFiles) {
logger.info("Beginning load: " + jarFile.getAbsolutePath());
try {
final AppModule module = deploymentLoader.load(jarFile);
collection.getAdditionalLibraries().addAll(module.getAdditionalLibraries());
collection.getClientModules().addAll(module.getClientModules());
collection.getEjbModules().addAll(module.getEjbModules());
collection.addPersistenceModules(module.getPersistenceModules());
collection.getConnectorModules().addAll(module.getConnectorModules());
collection.getWebModules().addAll(module.getWebModules());
collection.getWatchedResources().addAll(module.getWatchedResources());
// Merge altDDs
for (final Map.Entry<String, Object> entry : module.getAltDDs().entrySet()) {
final Object existingValue = altDDs.get(entry.getKey());
if (existingValue == null) {
altDDs.put(entry.getKey(), entry.getValue());
} else if (entry.getValue() instanceof Collection) {
if (existingValue instanceof Collection) {
final Collection values = (Collection) existingValue;
values.addAll((Collection) entry.getValue());
}
} else if (entry.getValue() instanceof Map) {
if (existingValue instanceof Map) {
final Map values = (Map) existingValue;
values.putAll((Map) entry.getValue());
}
}
}
} catch (ValidationFailedException e) {
logger.warning("configureApplication.loadFailed", jarFile.getAbsolutePath(), e.getMessage()); // DO not include the stacktrace in the message
throw e;
} catch (OpenEJBException e) {
// DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
// removing this message causes NO messages to be printed when embedded
logger.warning("configureApplication.loadFailed", e, jarFile.getAbsolutePath(), e.getMessage());
throw e;
}
}
return collection;
}
public EjbJarInfo configureApplication(final EjbJar ejbJar) throws OpenEJBException {
final EjbModule ejbModule = new EjbModule(ejbJar);
return configureApplication(ejbModule);
}
public EjbJarInfo configureApplication(final EjbModule ejbModule) throws OpenEJBException {
final AppInfo appInfo = configureApplication(new AppModule(ejbModule));
return appInfo.ejbJars.get(0);
}
public ClientInfo configureApplication(final ClientModule clientModule) throws OpenEJBException {
final AppInfo appInfo = configureApplication(new AppModule(clientModule));
return appInfo.clients.get(0);
}
public ConnectorInfo configureApplication(final ConnectorModule connectorModule) throws OpenEJBException {
final AppInfo appInfo = configureApplication(new AppModule(connectorModule));
return appInfo.connectors.get(0);
}
public WebAppInfo configureApplication(final WebModule webModule) throws OpenEJBException {
final AppInfo appInfo = configureApplication(new AppModule(webModule));
return appInfo.webApps.get(0);
}
public AppInfo configureApplication(final AppModule appModule) throws OpenEJBException {
final List<URL> libs = appModule.getAdditionalLibraries();
if (libs != null && libs.size() > 0) {
EventHelper.installExtensions(new ResourceFinder("META-INF", libs.toArray(new URL[libs.size()])));
}
for (final EjbModule ejb : appModule.getEjbModules()) {
try {
final URI uri = ejb.getModuleUri();
if (uri.isAbsolute()) {
final URL url = uri.toURL();
if (libs != null && !libs.contains(url)) {
EventHelper.installExtensions(new ResourceFinder("META-INF", url));
}
}
} catch (IllegalArgumentException iae) {
logger.debug("can't look for server event listener for module " + ejb.getModuleUri(), iae);
} catch (MalformedURLException mue) {
logger.debug("can't look for server event listener for module " + ejb.getModuleUri(), mue);
} catch (Exception e) {
logger.error("can't look for server event listener for module " + ejb.getJarLocation());
}
}
for (final WebModule web : appModule.getWebModules()) {
final List<URL> webLibs = web.getScannableUrls();
if (webLibs != null && webLibs.size() > 0) {
EventHelper.installExtensions(new ResourceFinder("META-INF", webLibs.toArray(new URL[webLibs.size()])));
}
}
final String location = appModule.getJarLocation();
logger.info("config.configApp", null != location ? location : appModule.getModuleId());
deployer.deploy(appModule);
final AppInfoBuilder appInfoBuilder = new AppInfoBuilder(this);
return appInfoBuilder.build(appModule);
}
private static class DefaultService {
private final Class<? extends org.apache.openejb.config.Service> type;
private final String id;
public DefaultService(final String id, final Class<? extends org.apache.openejb.config.Service> type) {
this.id = id;
this.type = type;
}
}
private static final Map<Class<? extends ServiceInfo>, DefaultService> defaultProviders = new HashMap<Class<? extends ServiceInfo>, DefaultService>();
private static final Map<Class<? extends ServiceInfo>, Class<? extends org.apache.openejb.config.Service>> types = new HashMap<Class<? extends ServiceInfo>, Class<? extends org.apache.openejb.config.Service>>();
/**
* This is the magic that allows people to be really vague in their openejb.xml and not specify
* the provider for one of their declared services. We look here for the default service id
*
* We then look in the default provider "namespace" that is setup, which will usually be either one of:
*
* - org.apache.openejb
* - org.apache.openejb.embedded
* - org.apache.openejb.tomcat
* - org.apache.openejb.jetty
*
* As in:
*
* - META-INF/<provider>/service-jar.xml
*
*/
static {
defaultProviders.put(MdbContainerInfo.class, new DefaultService("MESSAGE", Container.class));
defaultProviders.put(ManagedContainerInfo.class, new DefaultService("MANAGED", Container.class));
defaultProviders.put(StatefulSessionContainerInfo.class, new DefaultService("STATEFUL", Container.class));
defaultProviders.put(StatelessSessionContainerInfo.class, new DefaultService("STATELESS", Container.class));
defaultProviders.put(SingletonSessionContainerInfo.class, new DefaultService("SINGLETON", Container.class));
defaultProviders.put(CmpEntityContainerInfo.class, new DefaultService("CMP_ENTITY", Container.class));
defaultProviders.put(BmpEntityContainerInfo.class, new DefaultService("BMP_ENTITY", Container.class));
defaultProviders.put(SecurityServiceInfo.class, new DefaultService("SecurityService", SecurityService.class));
defaultProviders.put(TransactionServiceInfo.class, new DefaultService("TransactionManager", TransactionManager.class));
defaultProviders.put(ConnectionManagerInfo.class, new DefaultService("ConnectionManager", ConnectionManager.class));
defaultProviders.put(ProxyFactoryInfo.class, new DefaultService("ProxyFactory", ProxyFactory.class));
for (final Map.Entry<Class<? extends ServiceInfo>, DefaultService> entry : defaultProviders.entrySet()) {
types.put(entry.getKey(), entry.getValue().type);
}
types.put(ResourceInfo.class, Resource.class);
}
public <T extends ServiceInfo> T configureService(final Class<? extends T> type) throws OpenEJBException {
return configureService((org.apache.openejb.config.Service) null, type);
}
private <T extends ServiceInfo> org.apache.openejb.config.Service getDefaultService(final Class<? extends T> type) throws OpenEJBException {
final DefaultService defaultService = defaultProviders.get(type);
if (defaultService == null)
return null;
final org.apache.openejb.config.Service service;
try {
service = JaxbOpenejb.create(defaultService.type);
service.setType(defaultService.id);
} catch (Exception e) {
final String name = (defaultService.type == null) ? "null" : defaultService.type.getName();
throw new OpenEJBException("Cannot instantiate class " + name, e);
}
return service;
}
/**
* This is the major piece of code that configures services.
* It merges the data from the <ServiceProvider> declaration
* with the data from the openejb.xml file (say <Resource>)
* <p/>
* The end result is a canonical (i.e. flattened) ServiceInfo
* The ServiceInfo will be of a specific type (ContainerInfo, ResourceInfo, etc)
*
* @param service Service
* @param infoType Class
* @param <T> infoType
* @return ServiceInfo
* @throws OpenEJBException On error
*/
public <T extends ServiceInfo> T configureService(org.apache.openejb.config.Service service, final Class<? extends T> infoType) throws OpenEJBException {
try {
if (infoType == null)
throw new NullPointerException("type");
if (service == null) {
service = getDefaultService(infoType);
if (service == null) {
throw new OpenEJBException(messages.format("configureService.noDefaultService", infoType.getName()));
}
}
final String providerType = getProviderType(service);
final ServiceProvider provider = resolveServiceProvider(service, infoType);
if (provider == null) {
final List<ServiceProvider> providers = ServiceUtils.getServiceProvidersByServiceType(providerType);
final StringBuilder sb = new StringBuilder();
final List<String> types = new ArrayList<String>();
for (final ServiceProvider p : providers) {
for (final String type : p.getTypes()) {
if (types.contains(type))
continue;
types.add(type);
sb.append(System.getProperty("line.separator"));
sb.append(" <").append(p.getService());
sb.append(" id=\"").append(service.getId()).append('"');
sb.append(" type=\"").append(type).append("\"/>");
}
}
final String noProviderMessage = messages.format("configureService.noProviderForService", providerType, service.getId(), service.getType(), service.getProvider(), sb.toString());
throw new NoSuchProviderException(noProviderMessage);
}
if (service.getId() == null)
service.setId(provider.getId());
final Properties overrides = trim(getSystemProperties(service.getId(), provider.getService()));
final Properties serviceProperties = service.getProperties();
trim(serviceProperties);
trim(provider.getProperties());
logger.info("configureService.configuring", service.getId(), provider.getService(), provider.getId());
if (logger.isDebugEnabled()) {
for (final Map.Entry<Object, Object> entry : serviceProperties.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("[" + key + "=" + value + "]");
}
for (final Map.Entry<Object, Object> entry : overrides.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("Override [" + key + "=" + value + "]");
}
}
final Properties props = new SuperProperties().caseInsensitive(true);
// weird hack but sometimes we don't want default values when we want null for instance
if (serviceProperties == null || "false".equals(serviceProperties.getProperty(IGNORE_DEFAULT_VALUES_PROP, "false"))) {
props.putAll(provider.getProperties());
}
props.putAll(serviceProperties);
props.putAll(overrides);
props.remove(IGNORE_DEFAULT_VALUES_PROP);
if (providerType != null && !provider.getService().equals(providerType)) {
throw new OpenEJBException(messages.format("configureService.wrongProviderType", service.getId(), providerType));
}
final T info;
try {
info = infoType.newInstance();
} catch (Exception e) {
throw new OpenEJBException(messages.format("configureService.cannotInstantiateClass", infoType.getName()), e);
}
info.service = provider.getService();
info.types.addAll(provider.getTypes());
info.description = provider.getDescription();
info.displayName = provider.getDisplayName();
info.className = provider.getClassName();
info.factoryMethod = provider.getFactoryName();
info.id = service.getId();
info.properties = props;
info.constructorArgs.addAll(parseConstructorArgs(provider));
if (info instanceof ResourceInfo && service instanceof Resource) {
((ResourceInfo) info).jndiName = ((Resource) service).getJndi();
((ResourceInfo) info).aliases.addAll(((Resource) service).getAliases());
}
specialProcessing(info);
return info;
} catch (NoSuchProviderException e) {
final String message = logger.fatal("configureService.failed", e, service.getId());
throw new OpenEJBException(message + ": " + e.getMessage());
} catch (Throwable e) {
final String message = logger.fatal("configureService.failed", e, service.getId());
throw new OpenEJBException(message, e);
}
}
private static String getProviderType(final org.apache.openejb.config.Service service) {
Class<?> clazz = service.getClass();
if (AbstractService.class.isAssignableFrom(clazz)) {
while (!clazz.getSuperclass().equals(AbstractService.class)) {
clazz = clazz.getSuperclass();
}
}
return clazz.getSimpleName();
}
private static Properties trim(final Properties properties) {
for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
final Object o = entry.getValue();
if (o instanceof String) {
final String value = (String) o;
final String trimmed = value.trim();
if (value.length() != trimmed.length()) {
properties.put(entry.getKey(), trimmed);
}
}
}
return properties;
}
private <T extends ServiceInfo> void specialProcessing(final T info) {
TopicOrQueueDefaults.process(info);
}
@SuppressWarnings({"unchecked"})
private ServiceProvider resolveServiceProvider(final org.apache.openejb.config.Service service, final Class infoType) throws OpenEJBException {
if (service.getClassName() != null) {
if (service.getType() == null) {
service.setType(service.getClassName());
}
final ServiceProvider provider = new ServiceProvider();
provider.setId(service.getId());
provider.setService(getProviderType(service));
provider.getTypes().add(service.getType());
provider.setClassName(service.getClassName());
provider.setConstructor(service.getConstructor());
provider.setFactoryName(service.getFactoryName());
return provider;
}
if (service.getProvider() != null) {
return ServiceUtils.getServiceProvider(service.getProvider());
}
if (service.getType() == null && serviceTypeIsAdjustable) {
// try to guess quickly for know type
// -> DataSource
// the algo is weird but works, don't try to simplify it too much
// because we just have the service properties, not our defaults
final Properties properties = service.getProperties();
if ((properties.containsKey("JdbcDriver") || properties.containsKey("JdbcUrl") || properties.containsKey("url"))
&& (properties.containsKey("JtaManaged") || properties.containsKey("UserName") || properties.containsKey("Password"))) {
service.setType("javax.sql.DataSource");
}
}
if (service.getType() != null) {
return ServiceUtils.getServiceProviderByType(getProviderType(service), service.getType());
}
if (service.getId() != null) {
try {
return ServiceUtils.getServiceProvider(service.getId());
} catch (NoSuchProviderException e) {
logger.debug("resolveServiceProvider", e);
}
}
if (infoType != null) {
final org.apache.openejb.config.Service defaultService = getDefaultService(infoType);
if (defaultService != null) {
return resolveServiceProvider(defaultService, null);
}
}
return null;
}
public <T extends ServiceInfo> T configureService(final String id, final Class<? extends T> type) throws OpenEJBException {
return configureService(type, id, null, id, null);
}
/**
* Resolving the provider for a particular service follows this algorithm:
* <p/>
* 1. Attempt to load the provider specified by the 'providerId'.
* 2. If this fails, throw NoSuchProviderException
* 3. If providerId is null, attempt to load the specified provider using the 'serviceId' as the 'providerId'
* 4. If this fails, check the hardcoded defaults for a default providerId using the supplied 'type'
* 5. If this fails, throw NoSuchProviderException
*
* @param type
* @param serviceId
* @param declaredProperties
* @param providerId
* @param serviceType
* @return
* @throws org.apache.openejb.OpenEJBException
*
*/
public <T extends ServiceInfo> T configureService(final Class<? extends T> type, final String serviceId, final Properties declaredProperties, final String providerId, final String serviceType) throws OpenEJBException {
if (type == null)
throw new NullPointerException("type is null");
final Class<? extends org.apache.openejb.config.Service> serviceClass = types.get(type);
if (serviceClass == null)
throw new OpenEJBException("Unsupported service info type: " + type.getName());
final org.apache.openejb.config.Service service;
try {
service = serviceClass.newInstance();
} catch (Exception e) {
throw new OpenEJBException(messages.format("configureService.cannotInstantiateClass", serviceClass.getName()), e);
}
service.setId(serviceId);
service.setProvider(providerId);
if (declaredProperties != null) {
service.getProperties().putAll(declaredProperties);
}
return configureService(service, type);
}
protected static Properties getSystemProperties(final String serviceId, final String serviceType) {
// Override with system properties
final Properties sysProps = new Properties(System.getProperties());
sysProps.putAll(SystemInstance.get().getProperties());
return getOverrides(sysProps, serviceId, serviceType);
}
protected static Properties getOverrides(final Properties properties, final String serviceId, final String serviceType) {
final String fullPrefix = serviceType.toUpperCase() + "." + serviceId + ".";
final String fullPrefix2 = serviceType.toUpperCase() + "." + serviceId + "|";
final String shortPrefix = serviceId + ".";
final String shortPrefix2 = serviceId + "|";
final Properties overrides = new Properties();
for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
String name = (String) entry.getKey();
for (final String prefix : Arrays.asList(fullPrefix, fullPrefix2, shortPrefix, shortPrefix2)) {
if (name.toLowerCase().startsWith(prefix.toLowerCase())) {
name = name.substring(prefix.length());
// TODO: Maybe use xbean-reflect to get the string value
final String value = entry.getValue().toString();
overrides.setProperty(name, value);
break;
}
}
}
return overrides;
}
static Map<String, Class<? extends ContainerInfo>> containerTypes = new HashMap<String, Class<? extends ContainerInfo>>();
static {
containerTypes.put(BeanTypes.SINGLETON, SingletonSessionContainerInfo.class);
containerTypes.put(BeanTypes.MANAGED, ManagedContainerInfo.class);
containerTypes.put(BeanTypes.STATELESS, StatelessSessionContainerInfo.class);
containerTypes.put(BeanTypes.STATEFUL, StatefulSessionContainerInfo.class);
containerTypes.put(BeanTypes.BMP_ENTITY, BmpEntityContainerInfo.class);
containerTypes.put(BeanTypes.CMP_ENTITY, CmpEntityContainerInfo.class);
containerTypes.put(BeanTypes.MESSAGE, MdbContainerInfo.class);
}
protected static Class<? extends ContainerInfo> getContainerInfoType(final String ctype) {
return containerTypes.get(ctype);
}
private List<String> parseConstructorArgs(final ServiceProvider service) {
final String constructor = service.getConstructor();
if (constructor == null) {
return Collections.emptyList();
}
return Arrays.asList(constructor.split("[ ,]+"));
}
protected List<String> getResourceIds() {
return getResourceIds(null);
}
protected List<String> getResourceIds(final String type) {
return getResourceIds(type, null);
}
protected List<String> getResourceIds(final String type, Properties required) {
final List<String> resourceIds = new ArrayList<String>();
if (required == null)
required = new Properties();
final OpenEjbConfiguration runningConfig = getRunningConfig();
if (runningConfig != null) {
for (final ResourceInfo resourceInfo : runningConfig.facilities.resources) {
if (isResourceType(resourceInfo.service, resourceInfo.types, type) && implies(required, resourceInfo.properties)) {
resourceIds.add(resourceInfo.id);
resourceIds.addAll(resourceInfo.aliases);
}
}
}
if (sys != null) {
for (final ResourceInfo resourceInfo : sys.facilities.resources) {
if (isResourceType(resourceInfo.service, resourceInfo.types, type) && implies(required, resourceInfo.properties)) {
resourceIds.add(resourceInfo.id);
resourceIds.addAll(resourceInfo.aliases);
}
}
// The only time we'd have one of these is if we were building
// the above sys instance
if (openejb != null) {
for (final Resource resource : openejb.getResource()) {
final ArrayList<String> types = new ArrayList<String>();
if (resource.getType() != null) {
types.add(resource.getType());
}
if (isResourceType("Resource", types, type) && implies(required, resource.getProperties())) {
resourceIds.add(resource.getId());
resourceIds.addAll(resource.getAliases());
}
}
}
}
return resourceIds;
}
protected ResourceInfo getResourceInfo(final String id) {
final OpenEjbConfiguration runningConfig = getRunningConfig();
if (runningConfig != null) {
for (final ResourceInfo resourceInfo : runningConfig.facilities.resources) {
if (id.equals(resourceInfo.id)) {
return resourceInfo;
}
for (final String alias : resourceInfo.aliases) {
if (alias.equals(id)) {
return resourceInfo;
}
}
}
}
if (sys != null) {
for (final ResourceInfo resourceInfo : sys.facilities.resources) {
if (id.equals(resourceInfo.id)) {
return resourceInfo;
}
for (final String alias : resourceInfo.aliases) {
if (alias.equals(id)) {
return resourceInfo;
}
}
}
}
return null;
}
public static boolean isResourceType(final String service, final List<String> types, final String type) {
return type == null || service != null && types.contains(type);
}
protected List<String> getContainerIds() {
final List<String> containerIds = new ArrayList<String>();
final OpenEjbConfiguration runningConfig = getRunningConfig();
if (runningConfig != null) {
for (final ContainerInfo containerInfo : runningConfig.containerSystem.containers) {
containerIds.add(containerInfo.id);
}
}
if (sys != null) {
for (final ContainerInfo containerInfo : sys.containerSystem.containers) {
containerIds.add(containerInfo.id);
}
// The only time we'd have one of these is if we were building
// the above sys instance
if (openejb != null) {
for (final Container container : openejb.getContainer()) {
containerIds.add(container.getId());
}
}
}
return containerIds;
}
protected List<ContainerInfo> getContainerInfos() {
final List<ContainerInfo> containers = new ArrayList<ContainerInfo>();
final OpenEjbConfiguration runningConfig = getRunningConfig();
if (runningConfig != null) {
for (final ContainerInfo containerInfo : runningConfig.containerSystem.containers) {
containers.add(containerInfo);
}
}
if (sys != null) {
for (final ContainerInfo containerInfo : sys.containerSystem.containers) {
containers.add(containerInfo);
}
}
return containers;
}
private OpenEjbConfiguration getRunningConfig() {
return SystemInstance.get().getComponent(OpenEjbConfiguration.class);
}
private static class TopicOrQueueDefaults {
public static void process(final ServiceInfo provider) {
if (!provider.service.equals("Resource"))
return;
if (!provider.types.contains("Topic") && !provider.types.contains("Queue"))
return;
if (!provider.className.matches("org.apache.activemq.command.ActiveMQ(Topic|Queue)"))
return;
final String dest = provider.properties.getProperty("destination");
if (dest == null || dest.length() == 0) {
provider.properties.setProperty("destination", provider.id);
}
}
}
public static class ResourceInfoComparator implements Comparator<ResourceInfo> {
private final List<String> ids;
private static final int EQUAL = 0;
private static final int GREATER = 1;
private static final int LESS = -1;
public ResourceInfoComparator(final List<ResourceInfo> resources) {
ids = new ArrayList<String>();
for (final ResourceInfo info : resources) {
ids.add(info.id);
}
}
@Override
public int compare(final ResourceInfo a, final ResourceInfo b) {
final String refA = getReference(a);
final String refB = getReference(b);
// both null or the same id
if (refA == null && refB == null ||
refA != null && refA.equals(refB)) {
return EQUAL;
}
// b is referencing a
if (a.id.equals(refB)) {
return LESS;
}
// a is referencing b
if (b.id.equals(refA)) {
return GREATER;
}
// a has a ref and b doesn't
if (refA != null && refB == null) {
return GREATER;
}
// b has a ref and a doesn't
if (refA == null) {
return LESS;
}
return EQUAL;
}
public int hasReference(final ResourceInfo info) {
for (final Object value : info.properties.values()) {
if (String.class.isInstance(value)) {
//noinspection SuspiciousMethodCalls
if (ids.contains(value)) {
return GREATER;
}
}
}
return EQUAL;
}
public String getReference(final ResourceInfo info) {
for (Object value : info.properties.values()) {
if (String.class.isInstance(value)) {
value = ((String) value).trim();
if (ids.contains(value)) {
return (String) value;
}
}
}
return null;
}
}
}