Package org.apache.tuscany.sca.contribution.service.impl

Source Code of org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl

/*
* 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.contribution.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;

import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Composite;
import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.ContributionFactory;
import org.apache.tuscany.sca.contribution.DeployedArtifact;
import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
import org.apache.tuscany.sca.contribution.processor.PackageProcessor;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
import org.apache.tuscany.sca.contribution.service.ContributionException;
import org.apache.tuscany.sca.contribution.service.ContributionRepository;
import org.apache.tuscany.sca.contribution.service.ContributionService;
import org.apache.tuscany.sca.contribution.service.ExtensibleContributionListener;
import org.apache.tuscany.sca.contribution.service.util.IOHelper;
import org.apache.tuscany.sca.definitions.SCADefinitions;

/**
* Service interface that manages artifacts contributed to a Tuscany runtime.
*
* @version $Rev: 608074 $ $Date: 2008-01-02 10:35:24 +0000 (Wed, 02 Jan 2008) $
*/
/**
*
*/
public class ContributionServiceImpl implements ContributionService {

    /**
     * Repository where contributions are stored. Usually set by injection.
     */
    private ContributionRepository contributionRepository;

    /**
     * Registry of available package processors.
     */
    private PackageProcessor packageProcessor;

    /**
     * Registry of available artifact processors
     */

    private URLArtifactProcessor artifactProcessor;

    /**
     * Registry of available stax processors,
     * used for loading contribution metadata in a extensible way
     */
    private StAXArtifactProcessor staxProcessor;

    /**
     * Event listener for contribution operations
     */
    private ExtensibleContributionListener contributionListener;

    /**
     * Registry of available model resolvers
     */

    private ModelResolverExtensionPoint modelResolvers;

    /**
     * Model factory extension point
     */

    private ModelFactoryExtensionPoint modelFactories;

    /**
     * xml factory used to create reader instance to load contribution metadata
     */
    private XMLInputFactory xmlFactory;

    /**
     * Assembly factory
     */
    private AssemblyFactory assemblyFactory;

    /**
     * Contribution model factory
     */
    private ContributionFactory contributionFactory;
   
   
    private List<SCADefinitions> contributionSCADefinitions = new ArrayList<SCADefinitions>();

    private ModelResolver domainResolver;

    public ContributionServiceImpl(ContributionRepository repository,
                                   PackageProcessor packageProcessor,
                                   URLArtifactProcessor documentProcessor,
                                   StAXArtifactProcessor staxProcessor,
                                   ExtensibleContributionListener contributionListener,
                                   ModelResolver domainResolver,
                                   ModelResolverExtensionPoint modelResolvers,
                                   ModelFactoryExtensionPoint modelFactories,
                                   AssemblyFactory assemblyFactory,
                                   ContributionFactory contributionFactory,
                                   XMLInputFactory xmlFactory) {
        super();
        this.contributionRepository = repository;
        this.packageProcessor = packageProcessor;
        this.artifactProcessor = documentProcessor;
        this.staxProcessor = staxProcessor;
        this.contributionListener = contributionListener;
        this.modelResolvers = modelResolvers;
        this.modelFactories = modelFactories;
        this.xmlFactory = xmlFactory;
        this.assemblyFactory = assemblyFactory;
        this.contributionFactory = contributionFactory;
        this.domainResolver = domainResolver;
    }

    public Contribution contribute(String contributionURI, URL sourceURL, boolean storeInRepository)
        throws ContributionException, IOException {
        if (contributionURI == null) {
            throw new IllegalArgumentException("URI for the contribution is null");
        }
        if (sourceURL == null) {
            throw new IllegalArgumentException("Source URL for the contribution is null");
        }

        return addContribution(contributionURI, sourceURL, null, null, storeInRepository);
    }

    public Contribution contribute(String contributionURI,
                                   URL sourceURL,
                                   ModelResolver modelResolver,
                                   boolean storeInRepository) throws ContributionException, IOException {
        if (contributionURI == null) {
            throw new IllegalArgumentException("URI for the contribution is null");
        }
        if (sourceURL == null) {
            throw new IllegalArgumentException("Source URL for the contribution is null");
        }

        return addContribution(contributionURI, sourceURL, null, modelResolver, storeInRepository);
    }

    public Contribution contribute(String contributionURI, URL sourceURL, InputStream input)
        throws ContributionException, IOException {

        return addContribution(contributionURI, sourceURL, input, null, true);
    }

    public Contribution contribute(String contributionURI, URL sourceURL, InputStream input, ModelResolver modelResolver)
        throws ContributionException, IOException {

        return addContribution(contributionURI, sourceURL, input, modelResolver, true);
    }

    public Contribution getContribution(String uri) {
        return this.contributionRepository.getContribution(uri);
    }

    /**
     * Remove a contribution and notify listener that contribution was removed
     */
    public void remove(String uri) throws ContributionException {
        Contribution contribution = contributionRepository.getContribution(uri);
        this.contributionRepository.removeContribution(contribution);
        this.contributionListener.contributionRemoved(this.contributionRepository, contribution);
    }

    /**
     * Add a composite model to the contribution
     */
    public void addDeploymentComposite(Contribution contribution, Composite composite) throws ContributionException {
        DeployedArtifact artifact = this.contributionFactory.createDeployedArtifact();
        artifact.setURI(composite.getURI());
        artifact.setModel(composite);

        contribution.getArtifacts().add(artifact);

        contribution.getDeployables().add(composite);
    }

    /**
     * Utility/Helper methods for contribution service
     */

    /**
     * Perform read of the contribution metada loader (sca-contribution.xml and sca-contribution-generated.xml)
     * When the two metadata files are available, the information provided are merged, and the sca-contribution has priorities
     *
     * @param sourceURL
     * @return Contribution
     * @throws ContributionException
     */
    private Contribution readContributionMetadata(URL sourceURL) throws ContributionException {
        Contribution contributionMetadata = null;

        URL[] clUrls = {sourceURL};
        URLClassLoader cl = new URLClassLoader(clUrls, null);

        ContributionMetadataDocumentProcessor metadataDocumentProcessor =
            new ContributionMetadataDocumentProcessor(cl, staxProcessor, assemblyFactory, contributionFactory,
                                                      xmlFactory);
        contributionMetadata = contributionFactory.createContribution();
        try {
            metadataDocumentProcessor.read(contributionMetadata);
        } catch (XMLStreamException e) {
            throw new InvalidContributionMetadataException("Invalid contribution metadata for contribution.");
        }

        // For debugging purposes, write it back to XML
        //        if (contributionMetadata != null) {
        //            try {
        //                ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //                XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        //                outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
        //                staxProcessor.write(contributionMetadata, 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();
        //            }
        //        }

        return contributionMetadata;
    }

    /**
     * Note:
     *
     * @param contributionURI ContributionID
     * @param sourceURL contribution location
     * @param contributionStream contribution content
     * @param storeInRepository flag if we store the contribution into the
     *            repository or not
     * @return the contribution model representing the contribution
     * @throws IOException
     * @throws DeploymentException
     */
    private Contribution addContribution(String contributionURI,
                                         URL sourceURL,
                                         InputStream contributionStream,
                                         ModelResolver modelResolver,
                                         boolean storeInRepository) throws IOException, ContributionException {

        if (contributionStream == null && sourceURL == null) {
            throw new IllegalArgumentException("The content of the contribution is null.");
        }

        // store the contribution in the contribution repository
        URL locationURL = sourceURL;
        if (contributionRepository != null && storeInRepository) {
            if (contributionStream == null) {
                locationURL = contributionRepository.store(contributionURI, sourceURL);
            } else {
                locationURL = contributionRepository.store(contributionURI, sourceURL, contributionStream);
            }
        }

        //initialize contribution based on it's metadata if available
        Contribution contribution = readContributionMetadata(locationURL);

        // Create contribution model resolver
        if (modelResolver == null) {
            modelResolver = new ExtensibleModelResolver(contribution, modelResolvers, modelFactories);
        }

        if (modelResolver instanceof ExtensibleModelResolver) {
            ((ExtensibleModelResolver)modelResolver).setDomainResolver(domainResolver);
        }

        //set contribution initial information
        contribution.setURI(contributionURI.toString());
        contribution.setLocation(locationURL.toString());
        contribution.setModelResolver(modelResolver);

        List<URI> contributionArtifacts = null;

        //NOTE: if a contribution is stored on the repository
        //the stream would be consumed at this point
        if (storeInRepository || contributionStream == null) {
            contributionStream = sourceURL.openStream();
            try {
                // process the contribution
                contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream);
            } finally {
                IOHelper.closeQuietly(contributionStream);
                contributionStream = null;
            }
        } else {
            // process the contribution
            contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream);
        }

        // Read all artifacts in the contribution
        processReadPhase(contribution, contributionArtifacts);

        //
        this.contributionListener.contributionAdded(this.contributionRepository, contribution);

        // Resolve them
        processResolvePhase(contribution);

        // Add all composites under META-INF/sca-deployables to the
        // list of deployables
        String prefix = Contribution.SCA_CONTRIBUTION_DEPLOYABLES;
        for (DeployedArtifact artifact : contribution.getArtifacts()) {
            if (artifact.getModel() instanceof Composite) {
                if (artifact.getURI().startsWith(prefix)) {
                    Composite composite = (Composite)artifact.getModel();
                    if (!contribution.getDeployables().contains(composite)) {
                        contribution.getDeployables().add(composite);
                    }
                }
            }
        }

        // store the contribution on the registry
        this.contributionRepository.addContribution(contribution);

        return contribution;
    }

    /**
     * This utility method process each artifact and delegates to proper
     * artifactProcessor to read the model and generate the in-memory representation
     * 
     * @param contribution
     * @param artifacts
     * @throws ContributionException
     * @throws MalformedURLException
     */
    private void processReadPhase(Contribution contribution, List<URI> artifacts) throws ContributionException,
        MalformedURLException {

        ModelResolver modelResolver = contribution.getModelResolver();
        URL contributionURL = new URL(contribution.getLocation());
        for (URI a : artifacts) {
            URL artifactURL = packageProcessor.getArtifactURL(new URL(contribution.getLocation()), a);

            // Add the deployed artifact model to the resolver
            DeployedArtifact artifact = this.contributionFactory.createDeployedArtifact();
            artifact.setURI(a.toString());
            artifact.setLocation(artifactURL.toString());
            contribution.getArtifacts().add(artifact);
            modelResolver.addModel(artifact);

            // Let the artifact processor read the artifact into a model
            Object model = this.artifactProcessor.read(contributionURL, a, artifactURL);
            if (model != null) {
                artifact.setModel(model);

                // Add the loaded model to the model resolver
                modelResolver.addModel(model);
               
                if ( model instanceof SCADefinitions ) {
                    contributionSCADefinitions.add((SCADefinitions)model);
                }
            }
        }
    }

    /**
     * This utility method process each artifact and delegates to proper
     * artifactProcessor to resolve the model references
     *
     * @param contribution
     * @throws ContributionException
     */
    @SuppressWarnings("unchecked")
    private void processResolvePhase(Contribution contribution) throws ContributionException {
        List<DeployedArtifact> composites = new ArrayList<DeployedArtifact>();

        // for each artifact that was processed on the contribution
        for (DeployedArtifact artifact : contribution.getArtifacts()) {
            //leave the composites to be resolved at the end
            if (artifact.getURI().endsWith(".composite")) {
                composites.add(artifact);
            } else {
                // resolve the model object
                if (artifact.getModel() != null) {
                    this.artifactProcessor.resolve(artifact.getModel(), contribution.getModelResolver());
                }
            }
        }

        //process each composite file
        for (DeployedArtifact artifact : composites) {
            // resolve the model object
            if (artifact.getModel() != null) {
                // System.out.println("Processing Resolve Phase : " + artifact.getURI());
                this.artifactProcessor.resolve(artifact.getModel(), contribution.getModelResolver());
            }
        }

        //resolve deployables from contribution metadata
        List<Composite> resolvedDeployables = new ArrayList<Composite>();
        for (Composite deployableComposite : contribution.getDeployables()) {
            Composite resolvedDeployable =
                contribution.getModelResolver().resolveModel(Composite.class, deployableComposite);

            resolvedDeployables.add(resolvedDeployable);
        }
        contribution.getDeployables().clear();
        contribution.getDeployables().addAll(resolvedDeployables);
    }

    public List<SCADefinitions> getContributionSCADefinitions() {
        return contributionSCADefinitions;
    }
}
TOP

Related Classes of org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.