/* * 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.tuscany.sca.host.embedded.impl; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import javax.xml.namespace.QName; import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentService; import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.CompositeService; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.assembly.SCABindingFactory; import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.contribution.Artifact; import org.apache.tuscany.sca.contribution.Contribution; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; import org.apache.tuscany.sca.contribution.service.ContributionException; import org.apache.tuscany.sca.contribution.service.ContributionService; import org.apache.tuscany.sca.contribution.service.util.FileHelper; import org.apache.tuscany.sca.core.assembly.ActivationException; import org.apache.tuscany.sca.core.assembly.CompositeActivator; import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl; import org.apache.tuscany.sca.core.context.ServiceReferenceImpl; import org.apache.tuscany.sca.host.embedded.SCADomain; import org.apache.tuscany.sca.host.embedded.management.ComponentListener; import org.apache.tuscany.sca.host.embedded.management.ComponentManager; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentContext; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; import org.osoa.sca.CallableReference; import org.osoa.sca.ServiceReference; import org.osoa.sca.ServiceRuntimeException; import android.content.Context; /** * A default SCA domain facade implementation. * * @version $Rev: 637139 $ $Date: 2008-03-14 09:02:49 -0700 (Fri, 14 Mar 2008) $ */ public class DefaultSCADomain extends SCADomain { private String uri; private String[] composites; private Composite domainComposite; private List contributions; private Map components; private ReallySmallRuntime runtime; private ComponentManager componentManager; private ClassLoader runtimeClassLoader; private ClassLoader applicationClassLoader; private String domainURI; private String contributionLocation; /** * Constructs a new domain facade. * * @param domainURI * @param contributionLocation * @param composites */ public DefaultSCADomain(ClassLoader runtimeClassLoader, ClassLoader applicationClassLoader, String domainURI, String contributionLocation, String... composites) { this.uri = domainURI; this.composites = composites; this.runtimeClassLoader = runtimeClassLoader; this.applicationClassLoader = applicationClassLoader; this.domainURI = domainURI; this.contributionLocation = contributionLocation; this.composites = composites; init(); } /** * Constructs a new domain facade. * * @param domainURI * @param contributionLocation * @param composites */ public DefaultSCADomain(Context context, ClassLoader runtimeClassLoader, ClassLoader applicationClassLoader, String domainURI, String contributionLocation, String... composites) { super(context); this.uri = domainURI; this.composites = composites; this.runtimeClassLoader = runtimeClassLoader; this.applicationClassLoader = applicationClassLoader; this.domainURI = domainURI; this.contributionLocation = contributionLocation; this.composites = composites; init(); } public void init() { contributions = new ArrayList(); components = new HashMap(); runtime = new ReallySmallRuntime(runtimeClassLoader); try { runtime.start(); } catch (ActivationException e) { throw new ServiceRuntimeException(e); } // Contribute the given contribution to an in-memory repository ContributionService contributionService = runtime.getContributionService(); URL contributionURL; try { contributionURL = getContributionLocation(applicationClassLoader, contributionLocation, this.composites); /* if (contributionURL != null) { // Make sure the URL is correctly encoded (for example, escape the space characters) contributionURL = contributionURL.toURI().toURL(); }*/ } catch (Exception e) { throw new ServiceRuntimeException(e); } try { addContribution(contributionService, contributionURL); } catch (IOException e) { throw new ServiceRuntimeException(e); } /* try { String scheme = contributionURL.toURI().getScheme(); if (scheme == null || scheme.equalsIgnoreCase("file")) { File contributionFile = new File(contributionURL.toURI()); if (contributionFile.isDirectory()) { String[] contributions = contributionFile.list(new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jar"); } }); if (contributions != null && contributions.length > 0 && contributions.length == contributionFile.list().length) { for (String contribution : contributions) { addContribution(contributionService, new File(contributionFile, contribution).toURI().toURL()); } } else { addContribution(contributionService, contributionURL); } } else { addContribution(contributionService, contributionURL); } } else { addContribution(contributionService, contributionURL); } } catch (IOException e) { throw new ServiceRuntimeException(e); } catch (URISyntaxException e) { throw new ServiceRuntimeException(e); }*/ // Create an in-memory domain level composite AssemblyFactory assemblyFactory = runtime.getAssemblyFactory(); domainComposite = assemblyFactory.createComposite(); domainComposite.setName(new QName(Constants.SCA10_NS, "domain")); domainComposite.setURI(domainURI); //when the deployable composites were specified when initializing the runtime if (composites != null && composites.length > 0 && composites[0].length() > 0) { // Include all specified deployable composites in the SCA domain Map compositeArtifacts = new HashMap(); for (Contribution contribution : contributions) { for (Artifact artifact : contribution.getArtifacts()) { if (artifact.getModel() instanceof Composite) { compositeArtifacts.put(artifact.getURI(), (Composite)artifact.getModel()); } } } for (String compositePath : composites) { Composite composite = compositeArtifacts.get(compositePath); if (composite == null) { throw new ServiceRuntimeException("Composite not found: " + compositePath); } domainComposite.getIncludes().add(composite); } } else { // in this case, a sca-contribution.xml should have been specified for (Contribution contribution : contributions) { for (Composite composite : contribution.getDeployables()) { domainComposite.getIncludes().add(composite); } } } //update the runtime for all SCA Definitions processed from the contribution.. //so that the policyset determination done during 'build' has the all the defined //intents and policysets //runtime.updateSCADefinitions(null); // Build the SCA composites for (Composite composite : domainComposite.getIncludes()) { try { runtime.buildComposite(composite); } catch (CompositeBuilderException e) { throw new ServiceRuntimeException(e); } } // Activate and start composites CompositeActivator compositeActivator = runtime.getCompositeActivator(); compositeActivator.setDomainComposite(domainComposite); for (Composite composite : domainComposite.getIncludes()) { try { compositeActivator.activate(composite); } catch (ActivationException e) { throw new ServiceRuntimeException(e); } } for (Composite composite : domainComposite.getIncludes()) { try { for (Component component : composite.getComponents()) { compositeActivator.start(component); } } catch (ActivationException e) { throw new ServiceRuntimeException(e); } } // Index the top level components for (Composite composite : domainComposite.getIncludes()) { for (Component component : composite.getComponents()) { components.put(component.getName(), component); } } this.componentManager = new DefaultSCADomainComponentManager(this); // For debugging purposes, print the composites // ExtensionPointRegistry extensionPoints = runtime.getExtensionPointRegistry(); // StAXArtifactProcessorExtensionPoint artifactProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); // StAXArtifactProcessor processor = artifactProcessors.getProcessor(Composite.class); // for (Composite composite : domainComposite.getIncludes()) { // try { // ByteArrayOutputStream bos = new ByteArrayOutputStream(); // XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); // outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); // processor.write(composite, outputFactory.createXMLStreamWriter(bos)); // Document document = // DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos // .toByteArray())); // OutputFormat format = new OutputFormat(); // format.setIndenting(true); // format.setIndent(2); // XMLSerializer serializer = new XMLSerializer(System.out, format); // serializer.serialize(document); // } catch (Exception e) { // e.printStackTrace(); // } // } } protected void addContribution(ContributionService contributionService, URL contributionURL) throws IOException { try { String contributionURI = FileHelper.getName(contributionURL.getPath()); if (contributionURI == null || contributionURI.length() == 0) { contributionURI = contributionURL.toString(); } contributions.add(contributionService.contribute(contributionURI, contributionURL, false)); } catch (ContributionException e) { throw new ServiceRuntimeException(e); } } @Override public void close() { super.close(); // Stop and deactivate composites CompositeActivator compositeActivator = runtime.getCompositeActivator(); for (Composite composite : domainComposite.getIncludes()) { try { for (Component component : composite.getComponents()) { compositeActivator.stop(component); } } catch (ActivationException e) { throw new ServiceRuntimeException(e); } } for (Composite composite : domainComposite.getIncludes()) { try { compositeActivator.deactivate(composite); } catch (ActivationException e) { throw new ServiceRuntimeException(e); } } // Remove the contribution from the in-memory repository ContributionService contributionService = runtime.getContributionService(); for (Contribution contribution : contributions) { try { contributionService.remove(contribution.getURI()); } catch (ContributionException e) { throw new ServiceRuntimeException(e); } } // Stop the runtime try { runtime.stop(); } catch (ActivationException e) { throw new ServiceRuntimeException(e); } } /** * Determine the location of a contribution, given a contribution path and a * list of composites. * * @param contributionPath * @param composites * @param classLoader * @return * @throws MalformedURLException */ protected URL getContributionLocation(ClassLoader classLoader, String contributionPath, String[] composites) throws MalformedURLException { return new URL(contributionPath); } @Override @SuppressWarnings("unchecked") public > R cast(B target) throws IllegalArgumentException { return (R)runtime.getProxyFactory().cast(target); } @Override public B getService(Class businessInterface, String serviceName) { ServiceReference serviceReference = getServiceReference(businessInterface, serviceName); if (serviceReference == null) { throw new ServiceRuntimeException("Service not found: " + serviceName); } return serviceReference.getService(); } private ServiceReference createServiceReference(Class businessInterface, String targetURI) { try { AssemblyFactory assemblyFactory = runtime.getAssemblyFactory(); Composite composite = assemblyFactory.createComposite(); composite.setName(new QName(Constants.SCA10_TUSCANY_NS, "default")); RuntimeComponent component = (RuntimeComponent)assemblyFactory.createComponent(); component.setName("default"); component.setURI("default"); runtime.getCompositeActivator().configureComponentContext(component); composite.getComponents().add(component); RuntimeComponentReference reference = (RuntimeComponentReference)assemblyFactory.createComponentReference(); reference.setName("default"); ModelFactoryExtensionPoint factories = runtime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class); JavaInterfaceFactory javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class); InterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract(); interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface)); reference.setInterfaceContract(interfaceContract); component.getReferences().add(reference); reference.setComponent(component); SCABindingFactory scaBindingFactory = factories.getFactory(SCABindingFactory.class); SCABinding binding = scaBindingFactory.createSCABinding(); binding.setURI(targetURI); reference.getBindings().add(binding); return new ServiceReferenceImpl(businessInterface, component, reference, binding, runtime .getProxyFactory(), runtime.getCompositeActivator()); } catch (Exception e) { throw new ServiceRuntimeException(e); } } @Override public ServiceReference getServiceReference(Class businessInterface, String name) { // Extract the component name String componentName; String serviceName; int i = name.indexOf('/'); if (i != -1) { componentName = name.substring(0, i); serviceName = name.substring(i + 1); } else { componentName = name; serviceName = null; } // Lookup the component in the domain Component component = components.get(componentName); if (component == null) { // The component is not local in the partition, try to create a remote service ref return createServiceReference(businessInterface, name); } RuntimeComponentContext componentContext = null; // If the component is a composite, then we need to find the // non-composite component that provides the requested service if (component.getImplementation() instanceof Composite) { for (ComponentService componentService : component.getServices()) { if (serviceName == null || serviceName.equals(componentService.getName())) { CompositeService compositeService = (CompositeService)componentService.getService(); if (compositeService != null) { if (serviceName != null) { serviceName = "$promoted$." + serviceName; } componentContext = ((RuntimeComponent)compositeService.getPromotedComponent()).getComponentContext(); return componentContext.createSelfReference(businessInterface, compositeService .getPromotedService()); } break; } } // No matching service is found throw new ServiceRuntimeException("Composite service not found: " + name); } else { componentContext = ((RuntimeComponent)component).getComponentContext(); if (serviceName != null) { return componentContext.createSelfReference(businessInterface, serviceName); } else { return componentContext.createSelfReference(businessInterface); } } } @Override public String getURI() { return uri; } @Override public ComponentManager getComponentManager() { return componentManager; } public Set getComponentNames() { Set componentNames = new HashSet(); for (Contribution contribution : contributions) { for (Artifact artifact : contribution.getArtifacts()) { if (artifact.getModel() instanceof Composite) { for (Component component : ((Composite)artifact.getModel()).getComponents()) { componentNames.add(component.getName()); } } } } return componentNames; } public Component getComponent(String componentName) { for (Contribution contribution : contributions) { for (Artifact artifact : contribution.getArtifacts()) { if (artifact.getModel() instanceof Composite) { for (Component component : ((Composite)artifact.getModel()).getComponents()) { if (component.getName().equals(componentName)) { return component; } } } } } return null; } public void startComponent(String componentName) throws ActivationException { Component component = getComponent(componentName); if (component == null) { throw new IllegalArgumentException("no component: " + componentName); } CompositeActivator compositeActivator = runtime.getCompositeActivator(); compositeActivator.start(component); } public void stopComponent(String componentName) throws ActivationException { Component component = getComponent(componentName); if (component == null) { throw new IllegalArgumentException("no component: " + componentName); } CompositeActivator compositeActivator = runtime.getCompositeActivator(); compositeActivator.stop(component); } } class DefaultSCADomainComponentManager implements ComponentManager { protected DefaultSCADomain scaDomain; protected List listeners = new CopyOnWriteArrayList(); public DefaultSCADomainComponentManager(DefaultSCADomain scaDomain) { this.scaDomain = scaDomain; } public void addComponentListener(ComponentListener listener) { this.listeners.add(listener); } public void removeComponentListener(ComponentListener listener) { this.listeners.remove(listener); } public Set getComponentNames() { return scaDomain.getComponentNames(); } public Component getComponent(String componentName) { return scaDomain.getComponent(componentName); } public void startComponent(String componentName) throws ActivationException { scaDomain.startComponent(componentName); } public void stopComponent(String componentName) throws ActivationException { scaDomain.stopComponent(componentName); } public void notifyComponentStarted(String componentName) { for (ComponentListener listener : listeners) { try { listener.componentStarted(componentName); } catch (Exception e) { e.printStackTrace(); // TODO: log } } } public void notifyComponentStopped(String componentName) { for (ComponentListener listener : listeners) { try { listener.componentStopped(componentName); } catch (Exception e) { e.printStackTrace(); // TODO: log } } } public boolean isComponentStarted(String componentName) { RuntimeComponentImpl runtimeComponent = (RuntimeComponentImpl)getComponent(componentName); return runtimeComponent.isStarted(); } }