0001: /**
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */package org.apache.openejb.config;
0017:
0018: import java.io.File;
0019: import java.net.URI;
0020: import java.net.URISyntaxException;
0021: import java.util.ArrayList;
0022: import java.util.Arrays;
0023: import java.util.Collections;
0024: import java.util.Comparator;
0025: import java.util.HashMap;
0026: import java.util.List;
0027: import java.util.Map;
0028: import java.util.Properties;
0029:
0030: import org.apache.openejb.OpenEJBException;
0031: import org.apache.openejb.assembler.classic.AppInfo;
0032: import org.apache.openejb.assembler.classic.Assembler;
0033: import org.apache.openejb.assembler.classic.BmpEntityContainerInfo;
0034: import org.apache.openejb.assembler.classic.ClientInfo;
0035: import org.apache.openejb.assembler.classic.CmpEntityContainerInfo;
0036: import org.apache.openejb.assembler.classic.ConnectionManagerInfo;
0037: import org.apache.openejb.assembler.classic.ConnectorInfo;
0038: import org.apache.openejb.assembler.classic.ContainerInfo;
0039: import org.apache.openejb.assembler.classic.ContainerSystemInfo;
0040: import org.apache.openejb.assembler.classic.EjbJarInfo;
0041: import org.apache.openejb.assembler.classic.FacilitiesInfo;
0042: import org.apache.openejb.assembler.classic.HandlerChainInfo;
0043: import org.apache.openejb.assembler.classic.HandlerInfo;
0044: import org.apache.openejb.assembler.classic.JndiContextInfo;
0045: import org.apache.openejb.assembler.classic.MdbContainerInfo;
0046: import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
0047: import org.apache.openejb.assembler.classic.OpenEjbConfigurationFactory;
0048: import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
0049: import org.apache.openejb.assembler.classic.ResourceInfo;
0050: import org.apache.openejb.assembler.classic.SecurityServiceInfo;
0051: import org.apache.openejb.assembler.classic.ServiceInfo;
0052: import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
0053: import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
0054: import org.apache.openejb.assembler.classic.TransactionServiceInfo;
0055: import org.apache.openejb.assembler.classic.WebAppInfo;
0056: import static org.apache.openejb.config.ServiceUtils.implies;
0057: import org.apache.openejb.config.sys.AbstractService;
0058: import org.apache.openejb.config.sys.ConnectionManager;
0059: import org.apache.openejb.config.sys.Container;
0060: import org.apache.openejb.config.sys.Deployments;
0061: import org.apache.openejb.config.sys.JaxbOpenejb;
0062: import org.apache.openejb.config.sys.JndiProvider;
0063: import org.apache.openejb.config.sys.Openejb;
0064: import org.apache.openejb.config.sys.ProxyFactory;
0065: import org.apache.openejb.config.sys.Resource;
0066: import org.apache.openejb.config.sys.SecurityService;
0067: import org.apache.openejb.config.sys.ServiceProvider;
0068: import org.apache.openejb.config.sys.TransactionManager;
0069: import org.apache.openejb.jee.EjbJar;
0070: import org.apache.openejb.jee.Handler;
0071: import org.apache.openejb.jee.HandlerChain;
0072: import org.apache.openejb.jee.HandlerChains;
0073: import org.apache.openejb.jee.ParamValue;
0074: import org.apache.openejb.loader.SystemInstance;
0075: import org.apache.openejb.util.LogCategory;
0076: import org.apache.openejb.util.Logger;
0077: import org.apache.openejb.util.Messages;
0078: import org.apache.openejb.util.SuperProperties;
0079: import org.apache.openejb.util.URISupport;
0080:
0081: public class ConfigurationFactory implements
0082: OpenEjbConfigurationFactory {
0083:
0084: private static final Logger logger = Logger.getInstance(
0085: LogCategory.OPENEJB_STARTUP_CONFIG,
0086: ConfigurationFactory.class);
0087: private static final Messages messages = new Messages(
0088: ConfigurationFactory.class);
0089:
0090: private String configLocation = "";
0091:
0092: private OpenEjbConfiguration sys;
0093:
0094: private Openejb openejb;
0095:
0096: private DynamicDeployer deployer;
0097: private final DeploymentLoader deploymentLoader;
0098: private final boolean offline;
0099:
0100: public ConfigurationFactory() {
0101: this (false);
0102: }
0103:
0104: public ConfigurationFactory(boolean offline,
0105: OpenEjbConfiguration configuration) {
0106: this (offline, (DynamicDeployer) null);
0107: sys = configuration;
0108: }
0109:
0110: public ConfigurationFactory(boolean offline,
0111: DynamicDeployer preAutoConfigDeployer,
0112: OpenEjbConfiguration configuration) {
0113: this (offline, preAutoConfigDeployer);
0114: sys = configuration;
0115: }
0116:
0117: public static List<HandlerChainInfo> toHandlerChainInfo(
0118: HandlerChains chains) {
0119: List<HandlerChainInfo> handlerChains = new ArrayList<HandlerChainInfo>();
0120: if (chains == null)
0121: return handlerChains;
0122:
0123: for (HandlerChain handlerChain : chains.getHandlerChain()) {
0124: HandlerChainInfo handlerChainInfo = new HandlerChainInfo();
0125: handlerChainInfo.serviceNamePattern = handlerChain
0126: .getServiceNamePattern();
0127: handlerChainInfo.portNamePattern = handlerChain
0128: .getPortNamePattern();
0129: handlerChainInfo.protocolBindings.addAll(handlerChain
0130: .getProtocolBindings());
0131: for (Handler handler : handlerChain.getHandler()) {
0132: HandlerInfo handlerInfo = new HandlerInfo();
0133: handlerInfo.handlerName = handler.getHandlerName();
0134: handlerInfo.handlerClass = handler.getHandlerClass();
0135: handlerInfo.soapHeaders.addAll(handler.getSoapHeader());
0136: handlerInfo.soapRoles.addAll(handler.getSoapRole());
0137: for (ParamValue param : handler.getInitParam()) {
0138: handlerInfo.initParams.setProperty(param
0139: .getParamName(), param.getParamValue());
0140: }
0141: handlerChainInfo.handlers.add(handlerInfo);
0142: }
0143: handlerChains.add(handlerChainInfo);
0144: }
0145: return handlerChains;
0146: }
0147:
0148: public static class Chain implements DynamicDeployer {
0149: private final List<DynamicDeployer> chain = new ArrayList<DynamicDeployer>();
0150:
0151: public boolean add(DynamicDeployer o) {
0152: return chain.add(o);
0153: }
0154:
0155: public AppModule deploy(AppModule appModule)
0156: throws OpenEJBException {
0157: for (DynamicDeployer deployer : chain) {
0158: appModule = deployer.deploy(appModule);
0159: }
0160: return appModule;
0161: }
0162: }
0163:
0164: public ConfigurationFactory(boolean offline) {
0165: this (offline, (DynamicDeployer) null);
0166: }
0167:
0168: public ConfigurationFactory(boolean offline,
0169: DynamicDeployer preAutoConfigDeployer) {
0170: this .offline = offline;
0171: deploymentLoader = new DeploymentLoader();
0172:
0173: Chain chain = new Chain();
0174:
0175: chain.add(new ReadDescriptors());
0176:
0177: chain.add(new AnnotationDeployer());
0178:
0179: chain.add(new ClearEmptyMappedName());
0180:
0181: boolean shouldValidate = !SystemInstance.get().getProperty(
0182: "openejb.validation.skip", "false").equalsIgnoreCase(
0183: "true");
0184: if (shouldValidate) {
0185: chain.add(new ValidateModules());
0186: } else {
0187: DeploymentLoader.logger.info("Validation is disabled.");
0188: }
0189:
0190: chain.add(new InitEjbDeployments());
0191:
0192: String debuggableVmHackery = SystemInstance.get().getProperty(
0193: "openejb.debuggable-vm-hackery", "false");
0194: if (debuggableVmHackery.equalsIgnoreCase("true")) {
0195: chain.add(new DebuggableVmHackery());
0196: }
0197:
0198: chain.add(new WsDeployer());
0199:
0200: chain.add(new CmpJpaConversion());
0201: chain.add(new OpenEjb2Conversion());
0202: chain.add(new SunConversion());
0203: chain.add(new WlsConversion());
0204:
0205: if (System.getProperty("duct tape") != null) {
0206: // must be after CmpJpaConversion since it adds new persistence-context-refs
0207: chain.add(new GeronimoMappedName());
0208: }
0209:
0210: if (null != preAutoConfigDeployer) {
0211: chain.add(preAutoConfigDeployer);
0212: }
0213:
0214: if (offline) {
0215: AutoConfig autoConfig = new AutoConfig(this );
0216: autoConfig.autoCreateResources(false);
0217: autoConfig.autoCreateContainers(false);
0218: chain.add(autoConfig);
0219: } else {
0220: chain.add(new AutoConfig(this ));
0221: }
0222:
0223: chain.add(new ApplyOpenejbJar());
0224:
0225: // TODO: How do we want this plugged in?
0226: chain.add(new OutputGeneratedDescriptors());
0227:
0228: this .deployer = chain;
0229: }
0230:
0231: public void init(Properties props) throws OpenEJBException {
0232:
0233: configLocation = props.getProperty("openejb.conf.file");
0234:
0235: if (configLocation == null) {
0236: configLocation = props.getProperty("openejb.configuration");
0237: }
0238:
0239: configLocation = ConfigUtils.searchForConfiguration(
0240: configLocation, props);
0241: if (configLocation != null) {
0242: props.setProperty("openejb.configuration", configLocation);
0243: }
0244:
0245: }
0246:
0247: protected void install(ContainerInfo serviceInfo)
0248: throws OpenEJBException {
0249: if (sys != null) {
0250: sys.containerSystem.containers.add(serviceInfo);
0251: } else if (!offline) {
0252: Assembler assembler = SystemInstance.get().getComponent(
0253: Assembler.class);
0254: assembler.createContainer(serviceInfo);
0255: }
0256: }
0257:
0258: protected void install(ResourceInfo serviceInfo)
0259: throws OpenEJBException {
0260: if (sys != null) {
0261: sys.facilities.resources.add(serviceInfo);
0262: } else if (!offline) {
0263: Assembler assembler = SystemInstance.get().getComponent(
0264: Assembler.class);
0265: assembler.createResource(serviceInfo);
0266: }
0267: }
0268:
0269: public OpenEjbConfiguration getOpenEjbConfiguration()
0270: throws OpenEJBException {
0271:
0272: if (configLocation != null) {
0273: openejb = JaxbOpenejb.readConfig(configLocation);
0274: } else {
0275: openejb = JaxbOpenejb.createOpenejb();
0276: }
0277:
0278: loadPropertiesDeclaredConfiguration(openejb);
0279:
0280: sys = new OpenEjbConfiguration();
0281: sys.containerSystem = new ContainerSystemInfo();
0282: sys.facilities = new FacilitiesInfo();
0283:
0284: for (JndiProvider provider : openejb.getJndiProvider()) {
0285: JndiContextInfo info = configureService(provider,
0286: JndiContextInfo.class);
0287: sys.facilities.remoteJndiContexts.add(info);
0288: }
0289:
0290: sys.facilities.securityService = configureService(openejb
0291: .getSecurityService(), SecurityServiceInfo.class);
0292:
0293: sys.facilities.transactionService = configureService(openejb
0294: .getTransactionManager(), TransactionServiceInfo.class);
0295:
0296: List<ResourceInfo> resources = new ArrayList<ResourceInfo>();
0297: for (Resource resource : openejb.getResource()) {
0298: ResourceInfo resourceInfo = configureService(resource,
0299: ResourceInfo.class);
0300: resources.add(resourceInfo);
0301: }
0302: Collections.sort(resources, new ResourceInfoComparator(
0303: resources));
0304:
0305: sys.facilities.resources.addAll(resources);
0306:
0307: // ConnectionManagerInfo service = configureService(openejb.getConnectionManager(), ConnectionManagerInfo.class);
0308: // sys.facilities.connectionManagers.add(service);
0309:
0310: sys.facilities.intraVmServer = configureService(openejb
0311: .getProxyFactory(), ProxyFactoryInfo.class);
0312:
0313: for (Container declaration : openejb.getContainer()) {
0314: Class<? extends ContainerInfo> infoClass = getContainerInfoType(declaration
0315: .getType());
0316:
0317: if (infoClass == null) {
0318: throw new OpenEJBException(
0319: "Unrecognized container type "
0320: + declaration.getType());
0321: }
0322:
0323: ContainerInfo info = configureService(declaration,
0324: infoClass);
0325:
0326: sys.containerSystem.containers.add(info);
0327: }
0328:
0329: List<String> jarList = DeploymentsResolver
0330: .resolveAppLocations(openejb.getDeployments());
0331: for (String pathname : jarList) {
0332:
0333: try {
0334: File jarFile = new File(pathname);
0335:
0336: AppInfo appInfo = configureApplication(jarFile);
0337:
0338: sys.containerSystem.applications.add(appInfo);
0339: } catch (OpenEJBException alreadyHandled) {
0340: }
0341: }
0342:
0343: return sys;
0344: }
0345:
0346: private void loadPropertiesDeclaredConfiguration(Openejb openejb) {
0347:
0348: Properties sysProps = new Properties(System.getProperties());
0349: sysProps.putAll(SystemInstance.get().getProperties());
0350:
0351: for (Map.Entry<Object, Object> entry : sysProps.entrySet()) {
0352:
0353: Object o = entry.getValue();
0354: if (!(o instanceof String))
0355: continue;
0356: if (!((String) o).startsWith("new://"))
0357: continue;
0358:
0359: String name = (String) entry.getKey();
0360: String value = (String) entry.getValue();
0361:
0362: try {
0363: URI uri = new URI(value);
0364:
0365: openejb.add(toConfigDeclaration(name, uri));
0366: } catch (URISyntaxException e) {
0367: logger.error("Error declaring service '" + name
0368: + "'. Invalid Service URI '" + value
0369: + "'. java.net.URISyntaxException: "
0370: + e.getMessage());
0371: } catch (OpenEJBException e) {
0372: logger.error(e.getMessage());
0373: }
0374: }
0375: }
0376:
0377: public Object toConfigDeclaration(String id, URI uri)
0378: throws OpenEJBException {
0379: String serviceType = null;
0380: try {
0381: serviceType = uri.getHost();
0382:
0383: Object object = null;
0384: try {
0385: object = JaxbOpenejb.create(serviceType);
0386: } catch (Exception e) {
0387: throw new OpenEJBException("Invalid URI '" + uri
0388: + "'. " + e.getMessage());
0389: }
0390:
0391: Map<String, String> map = null;
0392: try {
0393: map = URISupport.parseParamters(uri);
0394: } catch (URISyntaxException e) {
0395: throw new OpenEJBException(
0396: "Unable to parse URI parameters '" + uri
0397: + "'. URISyntaxException: "
0398: + e.getMessage());
0399: }
0400:
0401: if (object instanceof AbstractService) {
0402: AbstractService service = (AbstractService) object;
0403:
0404: service.setId(id);
0405:
0406: service.setType(map.remove("type"));
0407: service.setProvider(map.remove("provider"));
0408: service.getProperties().putAll(map);
0409: } else if (object instanceof Deployments) {
0410: Deployments deployments = (Deployments) object;
0411: deployments.setDir(map.remove("dir"));
0412: deployments.setJar(map.remove("jar"));
0413: }
0414:
0415: return object;
0416: } catch (Exception e) {
0417: throw new OpenEJBException(
0418: "Error declaring service '"
0419: + id
0420: + "'. Unable to create Service definition from URI '"
0421: + uri.toString() + "'", e);
0422: }
0423: }
0424:
0425: public AppInfo configureApplication(File jarFile)
0426: throws OpenEJBException {
0427: logger.debug("Beginning load: " + jarFile.getAbsolutePath());
0428:
0429: AppInfo appInfo;
0430: try {
0431: AppModule appModule = deploymentLoader.load(jarFile);
0432: appInfo = configureApplication(appModule);
0433: } catch (ValidationFailedException e) {
0434: logger.warning("configureApplication.loadFailed", jarFile
0435: .getAbsolutePath(), e.getMessage()); // DO not include the stacktrace in the message
0436: throw e;
0437: } catch (OpenEJBException e) {
0438: // DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
0439: // removing this message causes NO messages to be printed when embedded
0440: logger.warning("configureApplication.loadFailed", e,
0441: jarFile.getAbsolutePath(), e.getMessage());
0442: throw e;
0443: }
0444: return appInfo;
0445: }
0446:
0447: public EjbJarInfo configureApplication(EjbJar ejbJar)
0448: throws OpenEJBException {
0449: EjbModule ejbModule = new EjbModule(ejbJar);
0450: return configureApplication(ejbModule);
0451: }
0452:
0453: public EjbJarInfo configureApplication(EjbModule ejbModule)
0454: throws OpenEJBException {
0455: AppModule appModule = new AppModule(ejbModule.getClassLoader(),
0456: ejbModule.getJarLocation());
0457: appModule.getEjbModules().add(ejbModule);
0458: AppInfo appInfo = configureApplication(appModule);
0459: return appInfo.ejbJars.get(0);
0460: }
0461:
0462: public ClientInfo configureApplication(ClientModule clientModule)
0463: throws OpenEJBException {
0464: AppModule appModule = new AppModule(clientModule
0465: .getClassLoader(), clientModule.getJarLocation());
0466: appModule.getClientModules().add(clientModule);
0467: AppInfo appInfo = configureApplication(appModule);
0468: return appInfo.clients.get(0);
0469: }
0470:
0471: public ConnectorInfo configureApplication(
0472: ConnectorModule connectorModule) throws OpenEJBException {
0473: AppModule appModule = new AppModule(connectorModule
0474: .getClassLoader(), connectorModule.getJarLocation());
0475: appModule.getResourceModules().add(connectorModule);
0476: AppInfo appInfo = configureApplication(appModule);
0477: return appInfo.connectors.get(0);
0478: }
0479:
0480: public WebAppInfo configureApplication(WebModule webModule)
0481: throws OpenEJBException {
0482: AppModule appModule = new AppModule(webModule.getClassLoader(),
0483: webModule.getJarLocation());
0484: appModule.getWebModules().add(webModule);
0485: AppInfo appInfo = configureApplication(appModule);
0486: return appInfo.webApps.get(0);
0487: }
0488:
0489: public AppInfo configureApplication(AppModule appModule)
0490: throws OpenEJBException {
0491:
0492: logger.info("config.configApp", appModule.getJarLocation());
0493: deployer.deploy(appModule);
0494: AppInfoBuilder appInfoBuilder = new AppInfoBuilder(this );
0495:
0496: return appInfoBuilder.build(appModule);
0497: }
0498:
0499: private static class DefaultService {
0500: private final Class<? extends Service> type;
0501: private final String id;
0502:
0503: public DefaultService(String id, Class<? extends Service> type) {
0504: this .id = id;
0505: this .type = type;
0506: }
0507: }
0508:
0509: private static final Map<Class<? extends ServiceInfo>, DefaultService> defaultProviders = new HashMap<Class<? extends ServiceInfo>, DefaultService>();
0510:
0511: private static final Map<Class<? extends ServiceInfo>, Class<? extends Service>> types = new HashMap<Class<? extends ServiceInfo>, Class<? extends Service>>();
0512:
0513: static {
0514: defaultProviders.put(MdbContainerInfo.class,
0515: new DefaultService("MESSAGE", Container.class));
0516: defaultProviders.put(StatefulSessionContainerInfo.class,
0517: new DefaultService("STATEFUL", Container.class));
0518: defaultProviders.put(StatelessSessionContainerInfo.class,
0519: new DefaultService("STATELESS", Container.class));
0520: defaultProviders.put(CmpEntityContainerInfo.class,
0521: new DefaultService("CMP_ENTITY", Container.class));
0522: defaultProviders.put(BmpEntityContainerInfo.class,
0523: new DefaultService("BMP_ENTITY", Container.class));
0524: defaultProviders.put(SecurityServiceInfo.class,
0525: new DefaultService("SecurityService",
0526: SecurityService.class));
0527: defaultProviders.put(TransactionServiceInfo.class,
0528: new DefaultService("TransactionManager",
0529: TransactionManager.class));
0530: defaultProviders.put(ConnectionManagerInfo.class,
0531: new DefaultService("ConnectionManager",
0532: ConnectionManager.class));
0533: defaultProviders.put(ProxyFactoryInfo.class,
0534: new DefaultService("ProxyFactory", ProxyFactory.class));
0535:
0536: for (Map.Entry<Class<? extends ServiceInfo>, DefaultService> entry : defaultProviders
0537: .entrySet()) {
0538: types.put(entry.getKey(), entry.getValue().type);
0539: }
0540:
0541: types.put(ResourceInfo.class, Resource.class);
0542: }
0543:
0544: public <T extends ServiceInfo> T configureService(
0545: Class<? extends T> type) throws OpenEJBException {
0546: return configureService((Service) null, type);
0547: }
0548:
0549: private <T extends ServiceInfo> Service getDefaultService(
0550: Class<? extends T> type) throws OpenEJBException {
0551: DefaultService defaultService = defaultProviders.get(type);
0552:
0553: if (defaultService == null)
0554: return null;
0555:
0556: Service service;
0557: try {
0558: service = JaxbOpenejb.create(defaultService.type);
0559: service.setType(defaultService.id);
0560: } catch (Exception e) {
0561: String name = (defaultService == null || defaultService.type == null) ? "null"
0562: : defaultService.type.getName();
0563: throw new OpenEJBException("Cannot instantiate class "
0564: + name, e);
0565: }
0566: return service;
0567: }
0568:
0569: public <T extends ServiceInfo> T configureService(Service service,
0570: Class<? extends T> infoType) throws OpenEJBException {
0571: try {
0572: if (infoType == null)
0573: throw new NullPointerException("type");
0574:
0575: if (service == null) {
0576: service = getDefaultService(infoType);
0577: if (service == null) {
0578: throw new OpenEJBException(messages.format(
0579: "configureService.noDefaultService",
0580: infoType.getName()));
0581: }
0582: }
0583:
0584: String providerType = service.getClass().getSimpleName();
0585:
0586: ServiceProvider provider = resolveServiceProvider(service,
0587: infoType);
0588:
0589: if (provider == null) {
0590: List<ServiceProvider> providers = ServiceUtils
0591: .getServiceProvidersByServiceType(providerType);
0592: StringBuilder sb = new StringBuilder();
0593: // for (ServiceProvider p : providers) {
0594: // sb.append(System.getProperty("line.separator"));
0595: // sb.append(" <").append(p.getService());
0596: // sb.append(" id=\"").append(service.getId()).append('"');
0597: // sb.append(" provider=\"").append(p.getId()).append("\"/>");
0598: // }
0599:
0600: List<String> types = new ArrayList<String>();
0601: for (ServiceProvider p : providers) {
0602: for (String type : p.getTypes()) {
0603: if (types.contains(type))
0604: continue;
0605: types.add(type);
0606: sb.append(System.getProperty("line.separator"));
0607: sb.append(" <").append(p.getService());
0608: sb.append(" id=\"").append(service.getId())
0609: .append('"');
0610: sb.append(" type=\"").append(type).append(
0611: "\"/>");
0612: }
0613: }
0614: String noProviderMessage = messages.format(
0615: "configureService.noProviderForService",
0616: providerType, service.getId(), service
0617: .getType(), service.getProvider(), sb
0618: .toString());
0619: throw new NoSuchProviderException(noProviderMessage);
0620: }
0621:
0622: if (service.getId() == null)
0623: service.setId(provider.getId());
0624:
0625: logger.info("configureService.configuring",
0626: service.getId(), provider.getService(), provider
0627: .getId());
0628:
0629: Properties props = new SuperProperties();
0630: props.putAll(provider.getProperties());
0631: props.putAll(service.getProperties());
0632: props.putAll(getSystemProperties(service.getId(), provider
0633: .getService()));
0634:
0635: if (providerType != null
0636: && !provider.getService().equals(providerType)) {
0637: throw new OpenEJBException(messages.format(
0638: "configureService.wrongProviderType", service
0639: .getId(), providerType));
0640: }
0641:
0642: T info;
0643:
0644: try {
0645: info = infoType.newInstance();
0646: } catch (Exception e) {
0647: throw new OpenEJBException("Cannot instantiate class "
0648: + infoType.getName(), e);
0649: }
0650:
0651: info.service = provider.getService();
0652: info.types.addAll(provider.getTypes());
0653: info.description = provider.getDescription();
0654: info.displayName = provider.getDisplayName();
0655: info.className = provider.getClassName();
0656: info.factoryMethod = provider.getFactoryName();
0657: info.id = service.getId();
0658: info.properties = props;
0659: info.constructorArgs.addAll(parseConstructorArgs(provider));
0660:
0661: specialProcessing(info);
0662:
0663: return info;
0664: } catch (NoSuchProviderException e) {
0665: String message = logger.fatal("configureService.failed", e,
0666: service.getId());
0667: throw new OpenEJBException(message + ": " + e.getMessage());
0668: } catch (Throwable e) {
0669: String message = logger.fatal("configureService.failed", e,
0670: service.getId());
0671: throw new OpenEJBException(message, e);
0672: }
0673: }
0674:
0675: private <T extends ServiceInfo> void specialProcessing(T info) {
0676: ServiceInfo serviceInfo = info;
0677: TopicOrQueueDefaults.process(serviceInfo);
0678: }
0679:
0680: @SuppressWarnings({"unchecked"})
0681: private ServiceProvider resolveServiceProvider(Service service,
0682: Class infoType) throws OpenEJBException {
0683:
0684: if (service.getProvider() != null) {
0685: return ServiceUtils.getServiceProvider(service
0686: .getProvider());
0687: }
0688:
0689: if (service.getType() != null) {
0690: return ServiceUtils.getServiceProviderByType(service
0691: .getClass().getSimpleName(), service.getType());
0692: }
0693:
0694: if (service.getId() != null) {
0695: try {
0696: return ServiceUtils.getServiceProvider(service.getId());
0697: } catch (NoSuchProviderException e) {
0698: }
0699: }
0700:
0701: if (infoType != null) {
0702: Service defaultService = getDefaultService(infoType);
0703: if (defaultService != null) {
0704: return resolveServiceProvider(defaultService, null);
0705: }
0706: }
0707:
0708: return null;
0709: }
0710:
0711: public <T extends ServiceInfo> T configureService(String id,
0712: Class<? extends T> type) throws OpenEJBException {
0713: return configureService(type, id, null, id, null);
0714: }
0715:
0716: /**
0717: * Resolving the provider for a particular service follows this algorithm:
0718: *
0719: * 1. Attempt to load the provider specified by the 'providerId'.
0720: * 2. If this fails, throw NoSuchProviderException
0721: * 3. If providerId is null, attempt to load the specified provider using the 'serviceId' as the 'providerId'
0722: * 4. If this fails, check the hardcoded defaults for a default providerId using the supplied 'type'
0723: * 5. If this fails, throw NoSuchProviderException
0724: */
0725: public <T extends ServiceInfo> T configureService(
0726: Class<? extends T> type, String serviceId,
0727: Properties declaredProperties, String providerId,
0728: String serviceType) throws OpenEJBException {
0729: Class<? extends Service> serviceClass = types.get(type);
0730: Service service;
0731: try {
0732: service = serviceClass.newInstance();
0733: } catch (Exception e) {
0734: throw new OpenEJBException(
0735: "Cannot instantiate service class '"
0736: + serviceClass.getName() + "'", e);
0737: }
0738: service.setId(serviceId);
0739: service.setProvider(providerId);
0740:
0741: if (declaredProperties != null) {
0742: service.getProperties().putAll(declaredProperties);
0743: }
0744:
0745: return configureService(service, type);
0746: }
0747:
0748: protected static Properties getSystemProperties(String serviceId,
0749: String serviceType) {
0750: String fullPrefix = serviceType.toUpperCase() + "." + serviceId
0751: + ".";
0752: String fullPrefix2 = serviceType.toUpperCase() + "."
0753: + serviceId + "|";
0754: String shortPrefix = serviceId + ".";
0755: String shortPrefix2 = serviceId + "|";
0756:
0757: // Override with system properties
0758: Properties serviceProperties = new Properties();
0759: Properties sysProps = new Properties(System.getProperties());
0760: sysProps.putAll(SystemInstance.get().getProperties());
0761: for (Map.Entry<Object, Object> entry : sysProps.entrySet()) {
0762: String name = (String) entry.getKey();
0763: Object value = entry.getValue();
0764: if (value instanceof String) {
0765: if (name.startsWith(fullPrefix)) {
0766: name = name.substring(fullPrefix.length());
0767: serviceProperties.setProperty(name, (String) value);
0768: } else if (name.startsWith(fullPrefix2)) {
0769: name = name.substring(fullPrefix2.length());
0770: serviceProperties.setProperty(name, (String) value);
0771: } else if (name.startsWith(shortPrefix)) {
0772: name = name.substring(shortPrefix.length());
0773: serviceProperties.setProperty(name, (String) value);
0774: } else if (name.startsWith(shortPrefix2)) {
0775: name = name.substring(shortPrefix2.length());
0776: serviceProperties.setProperty(name, (String) value);
0777: }
0778: }
0779: }
0780: return serviceProperties;
0781: }
0782:
0783: static Map<String, Class<? extends ContainerInfo>> containerTypes = new HashMap<String, Class<? extends ContainerInfo>>();
0784:
0785: static {
0786: containerTypes.put(BeanTypes.STATELESS,
0787: StatelessSessionContainerInfo.class);
0788: containerTypes.put(BeanTypes.STATEFUL,
0789: StatefulSessionContainerInfo.class);
0790: containerTypes.put(BeanTypes.BMP_ENTITY,
0791: BmpEntityContainerInfo.class);
0792: containerTypes.put(BeanTypes.CMP_ENTITY,
0793: CmpEntityContainerInfo.class);
0794: containerTypes.put(BeanTypes.MESSAGE, MdbContainerInfo.class);
0795: }
0796:
0797: protected static Class<? extends ContainerInfo> getContainerInfoType(
0798: String ctype) {
0799: return containerTypes.get(ctype);
0800: }
0801:
0802: private List<String> parseConstructorArgs(ServiceProvider service) {
0803: String constructor = service.getConstructor();
0804: if (constructor == null) {
0805: return Collections.emptyList();
0806: }
0807: return Arrays.asList(constructor.split("[ ,]+"));
0808: }
0809:
0810: protected List<String> getResourceIds() {
0811: return getResourceIds(null);
0812: }
0813:
0814: protected List<String> getResourceIds(String type) {
0815: return getResourceIds(type, null);
0816: }
0817:
0818: protected List<String> getResourceIds(String type,
0819: Properties required) {
0820: List<String> resourceIds = new ArrayList<String>();
0821:
0822: if (required == null)
0823: required = new Properties();
0824:
0825: OpenEjbConfiguration runningConfig = getRunningConfig();
0826: if (runningConfig != null) {
0827: for (ResourceInfo resourceInfo : runningConfig.facilities.resources) {
0828: if (isResourceType(resourceInfo.service,
0829: resourceInfo.types, type)
0830: && implies(required, resourceInfo.properties)) {
0831: resourceIds.add(resourceInfo.id);
0832: }
0833: }
0834: }
0835:
0836: if (sys != null) {
0837: for (ResourceInfo resourceInfo : sys.facilities.resources) {
0838: if (isResourceType(resourceInfo.service,
0839: resourceInfo.types, type)
0840: && implies(required, resourceInfo.properties)) {
0841: resourceIds.add(resourceInfo.id);
0842: }
0843: }
0844:
0845: // The only time we'd have one of these is if we were building
0846: // the above sys instance
0847: if (openejb != null) {
0848: for (Resource resource : openejb.getResource()) {
0849: ArrayList<String> types = new ArrayList<String>();
0850: if (resource.getType() != null) {
0851: types.add(resource.getType());
0852: }
0853: if (isResourceType("Resource", types, type)
0854: && implies(required, resource
0855: .getProperties())) {
0856: resourceIds.add(resource.getId());
0857: }
0858: }
0859: }
0860: }
0861: return resourceIds;
0862: }
0863:
0864: protected ResourceInfo getResourceInfo(String id) {
0865: OpenEjbConfiguration runningConfig = getRunningConfig();
0866: if (runningConfig != null) {
0867: for (ResourceInfo resourceInfo : runningConfig.facilities.resources) {
0868: if (resourceInfo.id == id) {
0869: return resourceInfo;
0870: }
0871: }
0872: }
0873:
0874: if (sys != null) {
0875: for (ResourceInfo resourceInfo : sys.facilities.resources) {
0876: if (resourceInfo.id == id) {
0877: return resourceInfo;
0878: }
0879: }
0880: }
0881: return null;
0882: }
0883:
0884: @SuppressWarnings({"UnusedDeclaration","EmptyFinallyBlock"})
0885: private boolean isResourceType(String service, List<String> types,
0886: String type) {
0887: boolean b = false;
0888: try {
0889: if (type == null)
0890: return b = true;
0891: if (service == null)
0892: return b = false;
0893: return b = types.contains(type);
0894: } finally {
0895: // System.out.println("isResourceType: "+b+" ["+service +"] ["+type+"] ["+ Join.join(",", types)+"]");
0896: // Throwable throwable = new Exception().fillInStackTrace();
0897: // throwable.printStackTrace(System.out);
0898: }
0899: }
0900:
0901: protected List<String> getContainerIds() {
0902: List<String> containerIds = new ArrayList<String>();
0903:
0904: OpenEjbConfiguration runningConfig = getRunningConfig();
0905: if (runningConfig != null) {
0906: for (ContainerInfo containerInfo : runningConfig.containerSystem.containers) {
0907: containerIds.add(containerInfo.id);
0908: }
0909: }
0910:
0911: if (sys != null) {
0912: for (ContainerInfo containerInfo : sys.containerSystem.containers) {
0913: containerIds.add(containerInfo.id);
0914: }
0915:
0916: // The only time we'd have one of these is if we were building
0917: // the above sys instance
0918: if (openejb != null) {
0919: for (Container container : openejb.getContainer()) {
0920: containerIds.add(container.getId());
0921: }
0922: }
0923: }
0924:
0925: return containerIds;
0926: }
0927:
0928: protected List<ContainerInfo> getContainerInfos() {
0929: List<ContainerInfo> containers = new ArrayList<ContainerInfo>();
0930:
0931: OpenEjbConfiguration runningConfig = getRunningConfig();
0932: if (runningConfig != null) {
0933: for (ContainerInfo containerInfo : runningConfig.containerSystem.containers) {
0934: containers.add(containerInfo);
0935: }
0936: }
0937:
0938: if (sys != null) {
0939: for (ContainerInfo containerInfo : sys.containerSystem.containers) {
0940: containers.add(containerInfo);
0941: }
0942: }
0943: return containers;
0944: }
0945:
0946: private OpenEjbConfiguration getRunningConfig() {
0947: return SystemInstance.get().getComponent(
0948: OpenEjbConfiguration.class);
0949: }
0950:
0951: private static class TopicOrQueueDefaults {
0952: public static void process(ServiceInfo provider) {
0953: if (!provider.service.equals("Resource"))
0954: return;
0955: if (!provider.types.contains("Topic")
0956: && !provider.types.contains("Queue"))
0957: return;
0958: if (!provider.className
0959: .matches("org.apache.activemq.command.ActiveMQ(Topic|Queue)"))
0960: return;
0961:
0962: String dest = provider.properties
0963: .getProperty("destination");
0964: if (dest == null || dest.length() == 0) {
0965: provider.properties.setProperty("destination",
0966: provider.id);
0967: }
0968: }
0969: }
0970:
0971: public static class ResourceInfoComparator implements
0972: Comparator<ResourceInfo> {
0973: private final List<String> ids;
0974: private static final int EQUAL = 0;
0975: private static final int GREATER = 1;
0976: private static final int LESS = -1;
0977:
0978: public ResourceInfoComparator(List<ResourceInfo> resources) {
0979: ids = new ArrayList<String>();
0980: for (ResourceInfo info : resources) {
0981: ids.add(info.id);
0982: }
0983: }
0984:
0985: public int compare(ResourceInfo a, ResourceInfo b) {
0986: String refA = getReference(a);
0987: String refB = getReference(b);
0988:
0989: // both null or the same id
0990: if (refA == null && refB == null || refA != null
0991: && refA.equals(refB)) {
0992: return EQUAL;
0993: }
0994:
0995: // b is referencing a
0996: if (a.id.equals(refB)) {
0997: return LESS;
0998: }
0999:
1000: // a is referencing b
1001: if (b.id.equals(refA)) {
1002: return GREATER;
1003: }
1004:
1005: // a has a ref and b doesn't
1006: if (refA != null && refB == null) {
1007: return GREATER;
1008: }
1009:
1010: // b has a ref and a doesn't
1011: if (refB != null && refA == null) {
1012: return LESS;
1013: }
1014:
1015: return EQUAL;
1016: }
1017:
1018: public int hasReference(ResourceInfo info) {
1019: for (Object value : info.properties.values()) {
1020: if (ids.contains(value))
1021: return GREATER;
1022: }
1023: return EQUAL;
1024: }
1025:
1026: public String getReference(ResourceInfo info) {
1027: for (Object value : info.properties.values()) {
1028: value = ((String) value).trim();
1029: if (ids.contains(value))
1030: return (String) value;
1031: }
1032: return null;
1033: }
1034: }
1035: }
|