diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-1.0/modules/contribution/src/main/java |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-1.0/modules/contribution/src/main/java')
49 files changed, 4522 insertions, 0 deletions
diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java new file mode 100644 index 0000000000..1b4a61234b --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java @@ -0,0 +1,57 @@ +/* + * 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; + + +/** + * Base Artifact interface to accomodate common properties between Contribution and Deployed Artifact + * + * @version $Rev$ $Date$ + */ +public interface Artifact { + /** + * Get the URI that unique identifies the artifact + * + * @return The artifact uri + */ + String getURI(); + + /** + * Set the URI that unique identifies the artifact + * + * @param uri The artifact uri + */ + void setURI(String uri); + + /** + * Get the URL location for the artifact + * + * @return The artifact location + */ + String getLocation(); + + /** + * Set the URL location for the artifact + * + * @param location The artifact location + */ + void setLocation(String location); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java new file mode 100644 index 0000000000..51e5b586be --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java @@ -0,0 +1,56 @@ +/* + * 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; + +/** + * Identifies internal content types for contribution package and artifacts + * + * @version $Rev$ $Date$ + */ +public interface ContentType { + /** + * Java compressed contribution package + */ + String JAR = "application/x-compressed"; + /** + * Filesystem folder contribution package + */ + String FOLDER = "application/vnd.tuscany.folder"; + /** + * Contribution metadata file + */ + String CONTRIBUTION_METADATA = "application/vnd.tuscany.contribution.metadata"; + /** + * SCA Composite description file + */ + String COMPOSITE = "application/vnd.tuscany.composite"; + /** + * WSDL file + */ + String WSDL = "application/vnd.tuscany.wsdl"; + /** + * Java source/binary file + */ + String JAVA = "application/java-vm"; + /** + * Unkown contentType + */ + String UNKNOWN = "content/unknown"; +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java new file mode 100644 index 0000000000..e31805bf9a --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java @@ -0,0 +1,91 @@ +/* + * 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; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +public interface Contribution extends Artifact { + /** + * Default location of contribution metadata in a contribution package + */ + String SCA_CONTRIBUTION_META = "META-INF/sca-contribution.xml"; + /** + * default location of a generated contribution metadata in a contribution package + */ + String SCA_CONTRIBUTION_GENERATED_META = "META-INF/sca-contribution-generated.xml"; + /** + * Default location of deployables in a contribution + */ + String SCA_CONTRIBUTION_DEPLOYABLES = "META-INF/sca-deployables/"; + + + /** + * Get a list of exports based on the Contribution metadata sidefile + * + * @return The list of exported artifacts from this contribution + */ + List<Export> getExports(); + + /** + * Get a list of imports based on the Contribution metadata sidefile + * + * @return The list of imported artifacts on this contribution + */ + List<Import> getImports(); + + /** + * Get a list of deployables for the contribution based on the contribution metadata sidefile + * + * @return The list of deployable composites + */ + List<Composite> getDeployables(); + + /** + * Get a list of artifacts from the contribution + * + * @return The list of deployed artifacts for the contribution + */ + List<DeployedArtifact> getArtifacts(); + + /** + * Returns the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @param modelResolver The model resolver + */ + void setModelResolver(ModelResolver modelResolver); + +}
\ No newline at end of file diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java new file mode 100644 index 0000000000..e21ae3999b --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java @@ -0,0 +1,42 @@ +/* + * 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; + + +/** + * Contribution model object factory + * + * @version $Rev$ $Date$ + */ +public interface ContributionFactory { + /** + * Create a contribution model object + * + * @return The new contribution model object + */ + Contribution createContribution(); + + /** + * Create a deployedArtifact model object + * + * @return The new deployedArtifact model object + */ + DeployedArtifact createDeployedArtifact(); +}
\ No newline at end of file diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.java new file mode 100644 index 0000000000..ac3cd010d1 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.java @@ -0,0 +1,134 @@ +/* + * 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; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; + +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; + + +/** + * Default implementation of a model factory extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelFactoryExtensionPoint implements ModelFactoryExtensionPoint { + + private HashMap<Class<?>, Object> factories = new HashMap<Class<?>, Object>(); + + public DefaultModelFactoryExtensionPoint() { + } + + /** + * Add a model factory extension. + * + * @param factory The factory to add + */ + public void addFactory(Object factory) { + Class[] interfaces = factory.getClass().getInterfaces(); + if (interfaces.length == 0) { + Class<?> sc = factory.getClass().getSuperclass(); + if (sc != Object.class) { + factories.put(sc, factory); + } + } else { + for (int i = 0; i<interfaces.length; i++) { + factories.put(interfaces[i], factory); + } + } + } + + /** + * Remove a model factory extension. + * + * @param factory The factory to remove + */ + public void removeFactory(Object factory) { + Class[] interfaces = factory.getClass().getInterfaces(); + if (interfaces.length == 0) { + Class<?> sc = factory.getClass().getSuperclass(); + if (sc != Object.class) { + factories.remove(sc); + } + } else { + for (int i = 0; i<interfaces.length; i++) { + factories.remove(interfaces[i]); + } + } + } + + /** + * Get a factory implementing the given interface. + * @param factoryInterface The lookup key (factory interface) + * @return The factory + */ + public <T> T getFactory(Class<T> factoryInterface) { + Object factory = factories.get(factoryInterface); + if (factory == null) { + + if (factoryInterface.isInterface()) { + + // Dynamically load a factory class declared under META-INF/services + ClassLoader classLoader = factoryInterface.getClassLoader(); + if (classLoader == null) + classLoader = ClassLoader.getSystemClassLoader(); + try { + List<String> classNames = ServiceConfigurationUtil.getServiceClassNames(classLoader, factoryInterface.getName()); + if (!classNames.isEmpty()) { + Class<?> factoryClass = Class.forName(classNames.iterator().next(), true, classLoader); + + try { + // Default empty constructor + Constructor<?> constructor = factoryClass.getConstructor(); + factory = constructor.newInstance(); + } catch (NoSuchMethodException e) { + + // Constructor taking the model factory extension point + Constructor<?> constructor = factoryClass.getConstructor(ModelFactoryExtensionPoint.class); + factory = constructor.newInstance(this); + } + + // Cache the loaded factory + addFactory(factory); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else { + + // Call the newInstance static method on the factory abstract class + try { + Method newInstanceMethod = factoryInterface.getMethod("newInstance"); + factory = newInstanceMethod.invoke(null); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + + // Cache the factory + addFactory(factory); + } + } + return factoryInterface.cast(factory); + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java new file mode 100644 index 0000000000..4b0fb1cc08 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java @@ -0,0 +1,43 @@ +/* + * 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; + +/** + * Representation of a deployed artifact + * + * @version $Rev$ $Date$ + */ +public interface DeployedArtifact extends Artifact { + + /** + * Get the assembly model associated with this artifact + * + * @return The assembly model + */ + Object getModel(); + + /** + * Set the assembly model associated with this artifact + * + * @param modelObject The assembly model + */ + void setModel(Object modelObject); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java new file mode 100644 index 0000000000..bfa16b1ce3 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java @@ -0,0 +1,47 @@ +/* + * 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; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an export. + * + * @version $Rev$ $Date$ + */ +public interface Export { + + /** + * Returns the model resolver for the models representing artifacts + * made available by this export. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing artifacts + * made available by this export. + * + * @param modelResolver + */ + void setModelResolver(ModelResolver modelResolver); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java new file mode 100644 index 0000000000..4a4b63805b --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java @@ -0,0 +1,54 @@ +/* + * 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; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + + +/** + * The representation of an import. + * + * @version $Rev$ $Date$ + */ +public interface Import { + + /** + * Returns the model resolver for the models representing artifacts + * made available by this import. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing artifacts + * made available by this import. + * + * @param modelResolver The model resolver + */ + void setModelResolver(ModelResolver modelResolver); + + /** + * Verify is a specific export is provider of what is being imported + * @param export The Exported being verified + * @return true/false + */ + boolean match(Export export); +}
\ No newline at end of file diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java new file mode 100644 index 0000000000..0ada4ebec3 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java @@ -0,0 +1,54 @@ +/* + * 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; + +/** + * An extension point for model factories. Model factories are provided to + * abstract the classes that represent artifacts in the assembly model away + * from their creation mechanism. When the runtime needs to extend the model + * as it reads in contributed artifacts it looks up the factory for the + * artifact required in this registry + * + * @version $Rev$ $Date$ + */ +public interface ModelFactoryExtensionPoint { + + /** + * Add a model factory extension. + * + * @param factory The factory to add + */ + void addFactory(Object factory); + + /** + * Remove a model factory extension. + * + * @param factory The factory to remove + */ + void removeFactory(Object factory); + + /** + * Get a factory implementing the given interface. + * @param factoryInterface the lookup key (factory interface) + * @return The factory + */ + <T> T getFactory(Class<T> factoryInterface); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java new file mode 100644 index 0000000000..014c187733 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java @@ -0,0 +1,48 @@ +/* + * 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.processor; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; + +/** + * Interface for extensions that can process contributions. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactProcessor<M> { + + /** + * Resolve references from this model to other models. For example references + * from a composite to another one, or references from a composite to a WSDL + * model. + * + * @param model The model to resolve + * @param resolver The resolver to use to resolve referenced models + */ + void resolve(M model, ModelResolver resolver) throws ContributionResolveException; + + /** + * Returns the type of model handled by this artifact processor. + * + * @return The type of model handled by this artifact processor + */ + Class<M> getModelType(); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..029df61f0f --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java @@ -0,0 +1,58 @@ +/* + * 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.processor; + +/** + * An extension point for artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactProcessorExtensionPoint<P extends ArtifactProcessor> { + + /** + * Add an artifact processor. + * + * @param artifactProcessor The artifact processor to add + */ + void addArtifactProcessor(P artifactProcessor); + + /** + * Remove an artifact processor. + * + * @param artifactProcessor The artifact processor to remove + */ + void removeArtifactProcessor(P artifactProcessor); + + /** + * Returns the processor associated with the given artifact type. + * + * @param artifactType An artifact type + * @return The processor associated with the given artifact type + */ + P getProcessor(Object artifactType); + + /** + * Returns the processor associated with the given model type. + * + * @param modelType A model type + * @return The processor associated with the given model type + */ + P getProcessor(Class<?> modelType); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java new file mode 100644 index 0000000000..ed41b9ae6e --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java @@ -0,0 +1,486 @@ +/* + * 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.processor; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + + +/** + * A base class with utility methods for the other artifact processors in this module. + * + * @version $Rev$ $Date$ + */ +public abstract class BaseStAXArtifactProcessor { + + /** + * Returns a qname from a string. + * @param reader + * @param value + * @return + */ + protected QName getQNameValue(XMLStreamReader reader, String value) { + if (value != null) { + int index = value.indexOf(':'); + String prefix = index == -1 ? "" : value.substring(0, index); + String localName = index == -1 ? value : value.substring(index + 1); + String ns = reader.getNamespaceContext().getNamespaceURI(prefix); + if (ns == null) { + ns = ""; + } + return new QName(ns, localName, prefix); + } else { + return null; + } + } + + /** + * Returns the boolean value of an attribute. + * @param reader + * @param name + * @return + */ + protected boolean getBoolean(XMLStreamReader reader, String name) { + String value = reader.getAttributeValue(null, name); + if (value == null) { + return false; + } + return Boolean.valueOf(value); + } + + /** + * Returns the qname value of an attribute. + * @param reader + * @param name + * @return + */ + protected QName getQName(XMLStreamReader reader, String name) { + String qname = reader.getAttributeValue(null, name); + return getQNameValue(reader, qname); + } + + /** + * Returns the value of an attribute as a list of qnames. + * @param reader + * @param name + * @return + */ + protected List<QName> getQNames(XMLStreamReader reader, String name) { + String value = reader.getAttributeValue(null, name); + if (value != null) { + List<QName> qnames = new ArrayList<QName>(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + qnames.add(getQName(reader, tokens.nextToken())); + } + return qnames; + } else { + return Collections.emptyList(); + } + } + + /** + * Returns the string value of an attribute. + * @param reader + * @param name + * @return + */ + protected String getString(XMLStreamReader reader, String name) { + return reader.getAttributeValue(null, name); + } + + /** + * Test if an attribute is explicitly set + * @param reader + * @param name + * @return + */ + protected boolean isSet(XMLStreamReader reader, String name) { + return reader.getAttributeValue(null, name) != null; + } + + /** + * Returns the value of xsi:type attribute + * @param reader The XML stream reader + * @return The QName of the type, if the attribute is not present, null is + * returned. + */ + protected QName getXSIType(XMLStreamReader reader) { + String qname = reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); + return getQNameValue(reader, qname); + } + + /** + * Parse the next child element. + * @param reader + * @return + * @throws XMLStreamException + */ + protected boolean nextChildElement(XMLStreamReader reader) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); + if (event == END_ELEMENT) { + return false; + } + if (event == START_ELEMENT) { + return true; + } + } + return false; + } + + /** + * Advance the stream to the next END_ELEMENT event skipping any nested + * content. + * @param reader the reader to advance + * @throws XMLStreamException if there was a problem reading the stream + */ + protected void skipToEndElement(XMLStreamReader reader) throws XMLStreamException { + int depth = 0; + while (reader.hasNext()) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + depth++; + } else if (event == XMLStreamConstants.END_ELEMENT) { + if (depth == 0) { + return; + } + depth--; + } + } + } + + /** + * + * @param writer + * @param uri + * @throws XMLStreamException + */ + private void writeElementPrefix(XMLStreamWriter writer, String uri) throws XMLStreamException { + if (uri == null) { + return; + } + String prefix = writer.getPrefix(uri); + if (prefix != null) { + return; + } else { + + // Find an available prefix and bind it to the given uri + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + } + + } + + /** + * Start an element. + * @param uri + * @param name + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException { + writeElementPrefix(writer, uri); + writeAttributePrefixes(writer, attrs); + writer.writeStartElement(uri, name); + writeAttributes(writer, attrs); + } + + /** + * End an element. + * @param writer + * @throws XMLStreamException + */ + protected void writeEnd(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndElement(); + } + + /** + * Start a document. + * @param writer + * @throws XMLStreamException + */ + protected void writeStartDocument(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException { + writer.writeStartDocument(); + writer.setDefaultNamespace(uri); + writeStart(writer, uri, name, attrs); + writer.writeDefaultNamespace(uri); + } + + /** + * End a document. + * @param writer + * @throws XMLStreamException + */ + protected void writeEndDocument(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndDocument(); + } + + /** + * Write attributes to the current element. + * @param writer + * @param attrs + * @throws XMLStreamException + */ + protected void writeAttributes(XMLStreamWriter writer, XAttr... attrs) throws XMLStreamException { + for (XAttr attr : attrs) { + if (attr != null) + attr.write(writer); + } + } + + /** + * Write attribute prefixes to the current element. + * @param writer + * @param attrs + * @throws XMLStreamException + */ + protected void writeAttributePrefixes(XMLStreamWriter writer, XAttr... attrs) throws XMLStreamException { + for (XAttr attr : attrs) { + if (attr != null) + attr.writePrefix(writer); + } + } + + /** + * Represents an XML attribute that needs to be written to a document. + */ + public static class XAttr { + + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private String uri = SCA10_NS; + private String name; + private Object value; + + public XAttr(String uri, String name, String value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, String value) { + this(null, name, value); + } + + public XAttr(String uri, String name, List values) { + this.uri = uri; + this.name = name; + this.value = values; + } + + public XAttr(String name, List values) { + this(null, name, values); + } + + public XAttr(String uri, String name, Boolean value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, Boolean value) { + this(null, name, value); + } + + public XAttr(String uri, String name, QName value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, QName value) { + this(null, name, value); + } + + /** + * Writes a string from a qname and registers a prefix for its namespace. + * @param reader + * @param value + * @return + */ + private String writeQNameValue(XMLStreamWriter writer, QName qname) throws XMLStreamException { + if (qname != null) { + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + prefix = writer.getPrefix(uri); + if (prefix != null && prefix.length() > 0) { + + // Use the prefix already bound to the given uri + return prefix + ":" + qname.getLocalPart(); + } else { + + // Find an available prefix and bind it to the given uri + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + writer.writeNamespace(prefix, uri); + return prefix + ":" + qname.getLocalPart(); + } + } else { + return null; + } + } + + /** + * Registers a prefix for the namespace of a QName. + * @param reader + * @param value + * @return + */ + private void writeQNamePrefix(XMLStreamWriter writer, QName qname) throws XMLStreamException { + if (qname != null) { + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + prefix = writer.getPrefix(uri); + if (prefix != null) { + return; + } else { + + // Find an available prefix and bind it to the given uri + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + } + } + } + + /** + * Write to document + * @param writer + * @throws XMLStreamException + */ + public void write(XMLStreamWriter writer) throws XMLStreamException { + String str; + if (value instanceof QName) { + + // Write a QName + str = writeQNameValue(writer, (QName)value); + + } else if (value instanceof List) { + + // Write a list of values + List values = (List)value; + if (values.isEmpty()) { + return; + } + StringBuffer buffer = new StringBuffer(); + for (Object v: values) { + if (v == null) { + // Skip null values + continue; + } + + if (v instanceof XAttr) { + // Write an XAttr value + ((XAttr)v).write(writer); + continue; + } + + if (buffer.length() != 0) { + buffer.append(' '); + } + if (v instanceof QName) { + // Write a qname value + buffer.append(writeQNameValue(writer, (QName)v)); + } else { + // Write value as a string + buffer.append(String.valueOf(v)); + } + } + str = buffer.toString(); + + } else { + + // Write a string + if (value == null) { + return; + } + str = String.valueOf(value); + } + if (str.length() == 0) { + return; + } + + // Write the attribute + if (uri != null && !uri.equals(SCA10_NS)) { + writer.writeAttribute(uri, name, str); + } else { + writer.writeAttribute(name,str); + } + } + + /** + * Registers a prefix for the namespace of a QName or list of QNames + * @param writer + * @throws XMLStreamException + */ + public void writePrefix(XMLStreamWriter writer) throws XMLStreamException { + if (value instanceof QName) { + + // Write prefix for a single QName value + writeQNamePrefix(writer, (QName)value); + + } else if (value instanceof List) { + + // Write prefixes for a list of values + for (Object v: (List)value) { + if (v instanceof QName) { + // Write prefix for a QName value + writeQNamePrefix(writer, (QName)v); + + } else if (v instanceof XAttr) { + // Write prefix for an XAttr value + ((XAttr)v).writePrefix(writer); + } + } + } + } + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..1c2faf9503 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java @@ -0,0 +1,66 @@ +/* + * 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.processor; + +import java.util.HashMap; +import java.util.Map; + +/** + * The default implementation of an artifact processor registry. + * + * @version $Rev$ $Date$ + */ +abstract class DefaultArtifactProcessorExtensionPoint<P> { + protected final Map<Object, P> processorsByArtifactType = new HashMap<Object, P>(); + protected final Map<Class<?>, P> processorsByModelType = new HashMap<Class<?>, P>(); + + /** + * Constructs a new loader registry. + */ + public DefaultArtifactProcessorExtensionPoint() { + } + + /** + * Returns the processor associated with the given artifact type. + * + * @param artifactType An artifact type + * @return The processor associated with the given artifact type + */ + public P getProcessor(Object artifactType) { + return processorsByArtifactType.get(artifactType); + } + + /** + * Returns the processor associated with the given model type. + * + * @param modelType A model type + * @return The processor associated with the given model type + */ + public P getProcessor(Class<?> modelType) { + Class<?>[] classes = modelType.getInterfaces(); + for (Class<?> c : classes) { + P processor = processorsByModelType.get(c); + if (processor != null) { + return processor; + } + } + return processorsByModelType.get(modelType); + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java new file mode 100644 index 0000000000..5a794498d9 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java @@ -0,0 +1,130 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; + +/** + * Default implementation of ContributionProcessorRegistry + * + * @version $Rev$ $Date$ + */ +public class DefaultPackageProcessorExtensionPoint implements PackageProcessorExtensionPoint { + + private Map<String, PackageProcessor> processors = new HashMap<String, PackageProcessor>(); + private boolean loaded; + + public DefaultPackageProcessorExtensionPoint() { + } + + public void addPackageProcessor(PackageProcessor processor) { + processors.put(processor.getPackageType(), processor); + } + + public void removePackageProcessor(PackageProcessor processor) { + processors.remove(processor.getPackageType()); + } + + public PackageProcessor getPackageProcessor(String contentType) { + loadProcessors(); + return processors.get(contentType); + } + + private void loadProcessors() { + if (loaded) + return; + + // Get the processor service declarations + ClassLoader classLoader = PackageProcessor.class.getClassLoader(); + List<String> processorDeclarations; + try { + processorDeclarations = ServiceConfigurationUtil.getServiceClassNames(classLoader, PackageProcessor.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (String processorDeclaration: processorDeclarations) { + Map<String, String> attributes = ServiceConfigurationUtil.parseServiceDeclaration(processorDeclaration); + String className = attributes.get("class"); + + // Load a URL artifact processor + String packageType = attributes.get("type"); + + // Create a processor wrapper and register it + PackageProcessor processor = new LazyPackageProcessor(packageType, className); + addPackageProcessor(processor); + } + + loaded = true; + } + + /** + * A facade for package processors. + */ + private static class LazyPackageProcessor implements PackageProcessor { + + private String className; + private String packageType; + private PackageProcessor processor; + + private LazyPackageProcessor(String packageType, String className) { + this.className = className; + this.packageType = packageType; + } + + public URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException { + return getProcessor().getArtifactURL(packageSourceURL, artifact); + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, IOException { + return getProcessor().getArtifacts(packageSourceURL, inputStream); + } + + public String getPackageType() { + return packageType; + } + + @SuppressWarnings("unchecked") + private PackageProcessor getProcessor() { + if (processor == null) { + try { + ClassLoader classLoader = PackageProcessor.class.getClassLoader(); + Class<PackageProcessor> processorClass = (Class<PackageProcessor>)Class.forName(className, true, classLoader); + Constructor<PackageProcessor> constructor = processorClass.getConstructor(); + processor = constructor.newInstance(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return processor; + } + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..9ebf49554c --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java @@ -0,0 +1,215 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * The default implementation of an extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public class DefaultStAXArtifactProcessorExtensionPoint + extends DefaultArtifactProcessorExtensionPoint<StAXArtifactProcessor> + implements StAXArtifactProcessorExtensionPoint { + + private ModelFactoryExtensionPoint modelFactories; + private boolean loaded; + + /** + * Constructs a new extension point. + */ + public DefaultStAXArtifactProcessorExtensionPoint(ModelFactoryExtensionPoint modelFactories) { + this.modelFactories = modelFactories; + } + + public void addArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + + public void removeArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + processorsByModelType.remove(artifactProcessor.getModelType()); + } + + @Override + public StAXArtifactProcessor getProcessor(Class<?> modelType) { + loadArtifactProcessors(); + return super.getProcessor(modelType); + } + + @Override + public StAXArtifactProcessor getProcessor(Object artifactType) { + loadArtifactProcessors(); + return super.getProcessor(artifactType); + } + + private void loadArtifactProcessors() { + if (loaded) + return; + + // Get the processor service declarations + ClassLoader classLoader = StAXArtifactProcessor.class.getClassLoader(); + List<String> processorDeclarations; + try { + processorDeclarations = ServiceConfigurationUtil.getServiceClassNames(classLoader, StAXArtifactProcessor.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (String processorDeclaration: processorDeclarations) { + Map<String, String> attributes = ServiceConfigurationUtil.parseServiceDeclaration(processorDeclaration); + String className = attributes.get("class"); + + // Load a StAX artifact processor + + // Get the model qname + QName artifactType = null; + String qname = attributes.get("qname"); + if (qname != null) { + int h = qname.indexOf('#'); + artifactType = new QName(qname.substring(0, h), qname.substring(h+1)); + } + + // Get the model class name + String modelTypeName = attributes.get("model"); + + // Get the model factory class name + String factoryName = attributes.get("factory"); + + // Create a processor wrapper and register it + StAXArtifactProcessor processor = new LazyStAXArtifactProcessor(modelFactories, artifactType, modelTypeName, factoryName, className); + addArtifactProcessor(processor); + } + + loaded = true; + } + + /** + * A wrapper around an Artifact processor class allowing lazy loading and + * initialization of artifact processors. + */ + private static class LazyStAXArtifactProcessor implements StAXArtifactProcessor { + + private ModelFactoryExtensionPoint modelFactories; + private QName artifactType; + private String modelTypeName; + private String factoryName; + private String className; + private StAXArtifactProcessor processor; + private Class modelType; + + LazyStAXArtifactProcessor(ModelFactoryExtensionPoint modelFactories, QName artifactType, String modelTypeName, String factoryName, String className) { + this.modelFactories = modelFactories; + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.factoryName = factoryName; + this.className = className; + } + + public QName getArtifactType() { + return artifactType; + } + + @SuppressWarnings("unchecked") + private StAXArtifactProcessor getProcessor() { + if (processor == null) { + + if (className.equals("org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor")) { + + // Specific initialization for the DefaultBeanModelProcessor + AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + PolicyFactory policyFactory = modelFactories.getFactory(PolicyFactory.class); + try { + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + Class<StAXArtifactProcessor> processorClass = (Class<StAXArtifactProcessor>)Class.forName(className, true, classLoader); + Object modelFactory; + if (factoryName != null) { + Class<?> factoryClass = (Class<?>)Class.forName(factoryName, true, classLoader); + modelFactory = modelFactories.getFactory(factoryClass); + } else { + modelFactory = null; + } + Constructor<StAXArtifactProcessor> constructor = processorClass.getConstructor(AssemblyFactory.class, PolicyFactory.class, QName.class, Class.class, Object.class); + processor = constructor.newInstance(assemblyFactory, policyFactory, artifactType, getModelType(), modelFactory); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } else { + + // Load and instanciate the processor class + try { + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + Class<StAXArtifactProcessor> processorClass = (Class<StAXArtifactProcessor>)Class.forName(className, true, classLoader); + Constructor<StAXArtifactProcessor> constructor = processorClass.getConstructor(ModelFactoryExtensionPoint.class); + processor = constructor.newInstance(modelFactories); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + return processor; + } + + public Object read(XMLStreamReader inputSource) throws ContributionReadException, XMLStreamException { + return getProcessor().read(inputSource); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + getProcessor().write(model, outputSource); + } + + public Class getModelType() { + if (modelType == null) { + try { + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + modelType = Class.forName(modelTypeName, true, classLoader); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..acc611c101 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java @@ -0,0 +1,165 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; + +/** + * The default implementation of a StAX artifact processor registry. + * + * @version $Rev$ $Date$ + */ +public class DefaultURLArtifactProcessorExtensionPoint + extends DefaultArtifactProcessorExtensionPoint<URLArtifactProcessor> + implements URLArtifactProcessorExtensionPoint { + + private ModelFactoryExtensionPoint modelFactories; + private boolean loaded; + + /** + * Constructs a new extension point. + */ + public DefaultURLArtifactProcessorExtensionPoint(ModelFactoryExtensionPoint modelFactories) { + this.modelFactories = modelFactories; + } + + public void addArtifactProcessor(URLArtifactProcessor artifactProcessor) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + + public void removeArtifactProcessor(URLArtifactProcessor artifactProcessor) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + processorsByModelType.remove(artifactProcessor.getModelType()); + } + + @Override + public URLArtifactProcessor getProcessor(Class<?> modelType) { + loadProcessors(); + return super.getProcessor(modelType); + } + + @Override + public URLArtifactProcessor getProcessor(Object artifactType) { + loadProcessors(); + return super.getProcessor(artifactType); + } + + private void loadProcessors() { + if (loaded) + return; + + // Get the processor service declarations + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + List<String> processorDeclarations; + try { + processorDeclarations = ServiceConfigurationUtil.getServiceClassNames(classLoader, URLArtifactProcessor.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (String processorDeclaration: processorDeclarations) { + Map<String, String> attributes = ServiceConfigurationUtil.parseServiceDeclaration(processorDeclaration); + String className = attributes.get("class"); + + // Load a URL artifact processor + String artifactType = attributes.get("type"); + String modelTypeName = attributes.get("model"); + + // Create a processor wrapper and register it + URLArtifactProcessor processor = new LazyURLArtifactProcessor(modelFactories, artifactType, modelTypeName, className); + addArtifactProcessor(processor); + } + + loaded = true; + } + + /** + * A wrapper around an Artifact processor class allowing lazy loading and + * initialization of artifact processors. + */ + private static class LazyURLArtifactProcessor implements URLArtifactProcessor { + + private ModelFactoryExtensionPoint modelFactories; + private String artifactType; + private String modelTypeName; + private String className; + private URLArtifactProcessor processor; + private Class modelType; + + LazyURLArtifactProcessor(ModelFactoryExtensionPoint modelFactories, String artifactType, String modelTypeName, String className) { + this.modelFactories = modelFactories; + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.className = className; + } + + public String getArtifactType() { + return artifactType; + } + + @SuppressWarnings("unchecked") + private URLArtifactProcessor getProcessor() { + if (processor == null) { + try { + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + Class<URLArtifactProcessor> processorClass = (Class<URLArtifactProcessor>)Class.forName(className, true, classLoader); + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(ModelFactoryExtensionPoint.class); + processor = constructor.newInstance(modelFactories); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return processor; + } + + public Object read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException { + return getProcessor().read(contributionURL, artifactURI, artifactURL); + } + + public Class getModelType() { + if (modelType == null) { + try { + ClassLoader classLoader = URLArtifactProcessor.class.getClassLoader(); + modelType = Class.forName(modelTypeName, true, classLoader); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.java new file mode 100644 index 0000000000..fb6e1b29ce --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.java @@ -0,0 +1,79 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.TypeDescriber; +import org.apache.tuscany.sca.contribution.service.UnsupportedContentTypeException; + +/** + * Default implementation of PackageProcessor. + * + * This implementation has a packageProcessorExtensionPoint + * and it delegates to the proper package processor based on content type + * + * @version $Rev$ $Date$ + */ +public class ExtensiblePackageProcessor implements PackageProcessor { + + private PackageProcessorExtensionPoint processors; + + /** + * Helper method to describe contentType for each artifact + */ + private TypeDescriber packageTypeDescriber; + + public ExtensiblePackageProcessor(PackageProcessorExtensionPoint processors, TypeDescriber packageTypeDescriber) { + this.processors = processors; + this.packageTypeDescriber = packageTypeDescriber; + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) + throws ContributionException, IOException { + String contentType = this.packageTypeDescriber.getType(packageSourceURL, null); + if (contentType == null) { + throw new UnsupportedContentTypeException("Unsupported contribution package", packageSourceURL.toString()); + } + + PackageProcessor packageProcessor = this.processors.getPackageProcessor(contentType); + if (packageProcessor == null) { + throw new UnsupportedContentTypeException(contentType, packageSourceURL.getPath()); + } + + return packageProcessor.getArtifacts(packageSourceURL, inputStream); + } + + public URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException { + String contentType = this.packageTypeDescriber.getType(packageSourceURL, null); + PackageProcessor packageProcessor = this.processors.getPackageProcessor(contentType); + return packageProcessor.getArtifactURL(packageSourceURL, artifact); + } + + public String getPackageType() { + return null; + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java new file mode 100644 index 0000000000..8034a45d79 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java @@ -0,0 +1,173 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.contribution.service.UnrecognizedElementException; + +/** + * The default implementation of a StAX artifact processor registry. + * + * This implementation has a StAXArtifactProcessorExtensionPoint and + * it delegates to the proper StAXArtifactProcessor by element QName + * + * @version $Rev$ $Date$ + */ +public class ExtensibleStAXArtifactProcessor + implements StAXArtifactProcessor<Object> { + + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private StAXArtifactProcessorExtensionPoint processors; + + /** + * Constructs a new loader registry. + * @param inputFactory + * @param outputFactory + */ + public ExtensibleStAXArtifactProcessor(StAXArtifactProcessorExtensionPoint processors, XMLInputFactory inputFactory, XMLOutputFactory outputFactory) { + super(); + this.processors = processors; + this.inputFactory = inputFactory; + this.outputFactory = outputFactory; + this.outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE); + } + + public Object read(XMLStreamReader source) throws ContributionReadException, XMLStreamException { + + // Delegate to the processor associated with the element qname + QName name = source.getName(); + StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name); + if (processor == null) { + return null; + } + return processor.read(source); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + + // Delegate to the processor associated with the model type + if (model != null) { + StAXArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.write(model, outputSource); + } + } + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + + // Delegate to the processor associated with the model type + if (model != null) { + StAXArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.resolve(model, resolver); + } + } + } + + /** + * Read a model from an input stream. + * @param is The artifact inputstream + * @param type Model type + * @return The model + * @throws ContributionReadException + */ + public <MO> MO read(InputStream is, Class<MO> type) throws ContributionReadException { + try { + XMLStreamReader reader; + try { + reader = inputFactory.createXMLStreamReader(is); + try { + reader.nextTag(); + QName name = reader.getName(); + Object mo = read(reader); + if (type.isInstance(mo)) { + return type.cast(mo); + } else { + UnrecognizedElementException e = new UnrecognizedElementException(name); + throw e; + } + } catch (ContributionReadException e) { + Location location = reader.getLocation(); + e.setLine(location.getLineNumber()); + e.setColumn(location.getColumnNumber()); + throw e; + } finally { + try { + reader.close(); + } catch (XMLStreamException e) { + // ignore + } + } + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException(e); + throw ce; + } + } + + /** + * Write a model to an ouput stream. + * @param model + * @param os + * @throws ContributionWriteException + */ + public void write(Object model, OutputStream os) throws ContributionWriteException { + try { + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os); + write(model, writer); + writer.flush(); + writer.close(); + } catch (XMLStreamException e) { + throw new ContributionWriteException(e); + } + } + + public QName getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java new file mode 100644 index 0000000000..3c7c886d80 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java @@ -0,0 +1,121 @@ +/* + * 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.processor; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.UnrecognizedElementException; + +/** + * The default implementation of a URL artifact processor. + * + * This implementation has a URLArtifactProcessorExtensionPoint and + * it delegate to the proper URLArtifactProcessor by either fileName or fileExtention + * + * @version $Rev$ $Date$ + */ +public class ExtensibleURLArtifactProcessor + implements URLArtifactProcessor<Object> { + + private URLArtifactProcessorExtensionPoint processors; + + /** + * Constructs a new URL artifact processor. + * + * @param processors + */ + public ExtensibleURLArtifactProcessor(URLArtifactProcessorExtensionPoint processors) { + this.processors = processors; + } + + @SuppressWarnings("unchecked") + public Object read(URL contributionURL, URI sourceURI, URL sourceURL) throws ContributionReadException { + URLArtifactProcessor<Object> processor = null; + + // Delegate to the processor associated with file extension + String fileName = getFileName(sourceURL); + + //try to retrieve a processor for the specific filename + processor = (URLArtifactProcessor<Object>)processors.getProcessor(fileName); + + if (processor == null) { + //try to find my file type (extension) + String extension = sourceURL.getPath(); + + int extensionStart = extension.lastIndexOf('.'); + //handle files without extension (e.g NOTICE) + if (extensionStart > 0) { + extension = extension.substring(extensionStart); + processor = (URLArtifactProcessor<Object>)processors.getProcessor(extension); + } + } + + if (processor == null) { + return null; + } + return processor.read(contributionURL, sourceURI, sourceURL); + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + + // Delegate to the processor associated with the model type + if (model != null) { + URLArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.resolve(model, resolver); + } + } + } + + public <MO> MO read(URL contributionURL, URI artifactURI, URL artifactUrl, Class<MO> type) + throws ContributionReadException { + Object mo = read(contributionURL, artifactURI, artifactUrl); + if (type.isInstance(mo)) { + return type.cast(mo); + } else { + UnrecognizedElementException e = new UnrecognizedElementException(null); + e.setResourceURI(artifactURI.toString()); + throw e; + } + } + + public String getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } + + /** + * Utility functions + */ + + private String getFileName(URL url){ + String fileName = url.getPath(); + int pos = fileName.lastIndexOf("/"); + + return fileName.substring(pos +1); + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.java new file mode 100644 index 0000000000..28b268301f --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.java @@ -0,0 +1,67 @@ +/* + * 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.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Contribution package processors + * These processors understand the internal format of the contribution and how to process the artifacts + * + * @version $Rev$ $Date$ + */ +public interface PackageProcessor { + + /** + * Returns the type of package supported by this package processor. + * + * @return the package type + */ + String getPackageType(); + + /** + * Retrieve a list of artifacts for the specific package type + * + * @param packageSourceURL Contribution package location URL + * @param inputStream Optional content of the package + * @return List of artifact URIs + * @throws ContributionException + * @throws IOException + */ + List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, IOException; + + /** + * Return the URL for an artifact in the package. + * This is needed in the case of special archives such as jar files that have special + * URL structure for internal artifacts + * + * @param packageSourceURL Contribution package location URL + * @param artifact The relative URI for the artifact + * @return The artifact URL + */ + URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException; + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java new file mode 100644 index 0000000000..27499b5847 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java @@ -0,0 +1,50 @@ +/* + * 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.processor; + +/** + * An extension point for package processors + * + * @version $Rev$ $Date$ + */ +public interface PackageProcessorExtensionPoint { + + /** + * Register a PackageProcessor using the package type as the key + * + * @param processor The package processor + */ + void addPackageProcessor(PackageProcessor processor); + + /** + * Unregister a PackageProcessor + * + * @param processor The package processor + */ + void removePackageProcessor(PackageProcessor processor); + + /** + * Returns the PackageProcessor for the given package type. + * + * @param packageType The package type + * @return The package processor + */ + PackageProcessor getPackageProcessor(String packageType); + +}
\ No newline at end of file diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java new file mode 100644 index 0000000000..fcf9347564 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java @@ -0,0 +1,61 @@ +/* + * 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.processor; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; + +/** + * An artifact processor that can read models from a StAX XMLStreamReader. + * + * @version $Rev$ $Date$ + */ +public interface StAXArtifactProcessor<M> extends ArtifactProcessor<M> { + + /** + * Reads a model from an XMLStreamReader. + * + * @param reader The XMLStreamReader + * @return A model representation of the input. + */ + M read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException; + + /** + * Writes a model to an XMLStreamWriter. + * + * @param model A model representing the source + * @param writer The XML stream writer + * @throws ContributionWriteException + * @throws XMLStreamException + */ + void write(M model, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException; + + /** + * Returns the type of artifact handled by this artifact processor. + * + * @return The type of artifact handled by this artifact processor + */ + QName getArtifactType(); +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..fb272d05bc --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java @@ -0,0 +1,29 @@ +/* + * 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.processor; + +/** + * A registry for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface StAXArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<StAXArtifactProcessor> { + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java new file mode 100644 index 0000000000..eb6201c856 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java @@ -0,0 +1,51 @@ +/* + * 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.processor; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.contribution.service.ContributionReadException; + +/** + * An artifact processor that can read models from an InputStream. + * + * @version $Rev$ $Date$ + */ +public interface URLArtifactProcessor<M> extends ArtifactProcessor<M> { + + /** + * Reads a model from a URL. + * + * @param contributionURL Contribution location URL + * @param artifactURI Artifact URI + * @param artifactURL Artifact location URL + * @return A model representation of the input. + */ + M read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException; + + /** + * Returns the type of artifact handled by this artifact processor. + * + * @return The type of artifact handled by this artifact processor + */ + String getArtifactType(); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..0b02c12830 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java @@ -0,0 +1,29 @@ +/* + * 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.processor; + +/** + * A registry for Document artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface URLArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<URLArtifactProcessor> { + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java new file mode 100644 index 0000000000..bd1687fafd --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java @@ -0,0 +1,319 @@ +/* + * 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.processor; + +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.StreamReaderDelegate; +import javax.xml.validation.Schema; +import javax.xml.validation.ValidatorHandler; + +import org.xml.sax.Attributes; +import org.xml.sax.ErrorHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * + * A validating XMLStreamReader that reports XMLSchema validation errors. + * + * @version $Rev$ $Date$ + */ +public class ValidatingXMLStreamReader extends StreamReaderDelegate implements XMLStreamReader { + private static final Logger logger = Logger.getLogger(ValidatingXMLStreamReader.class.getName()); + + private int level; + private ValidatorHandler handler; + + public ValidatingXMLStreamReader(XMLStreamReader reader, Schema schema) throws XMLStreamException { + super(reader); + if (schema == null) { + return; + } + + handler = schema.newValidatorHandler(); + handler.setDocumentLocator(new LocatorAdaptor()); + try { + handler.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + } catch (SAXException e) { + throw new XMLStreamException(e); + } + + // These validation errors are just warnings for us as we want to support + // running from an XML document with XSD validation errors, as long as we can + // get the metadata we need from the document + handler.setErrorHandler(new ErrorHandler() { + private String getMessage(SAXParseException e) { + return "XMLSchema validation problem in: " + e.getSystemId() + ", line: " + e.getLineNumber() + ", column: " + e.getColumnNumber() + "\n" + e.getMessage(); + } + + public void error(SAXParseException exception) throws SAXException { + logger.warning(getMessage(exception)); + } + + public void fatalError(SAXParseException exception) throws SAXException { + logger.warning(getMessage(exception)); + } + + public void warning(SAXParseException exception) throws SAXException { + logger.warning(getMessage(exception)); + } + }); + } + + @Override + public int next() throws XMLStreamException { + if (handler == null) { + return super.next(); + } + + int event = super.next(); + try { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(); + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(super.getPITarget(), super.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + case XMLStreamConstants.SPACE: + case XMLStreamConstants.ENTITY_REFERENCE: + handler.characters(super.getTextCharacters(), super.getTextStart(), super.getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(); + level--; + break; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + break; + } + } catch (SAXException e) { + throw new XMLStreamException(e.getMessage(), e); + } + return event; + } + + @Override + public int nextTag() throws XMLStreamException { + if (handler == null) { + return super.nextTag(); + } + + for (;;) { + int event = super.getEventType(); + try { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(); + return event; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(super.getPITarget(), super.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + case XMLStreamConstants.SPACE: + case XMLStreamConstants.ENTITY_REFERENCE: + handler.characters(super.getTextCharacters(), super.getTextStart(), super.getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(); + level--; + return event; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + return event; + } + } catch (SAXException e) { + throw new XMLStreamException(e); + } + super.next(); + } + } + + @Override + public String getElementText() throws XMLStreamException { + if (handler == null) { + return super.getElementText(); + } + + if (getEventType() != XMLStreamConstants.START_ELEMENT) { + return super.getElementText(); + } + StringBuffer text = new StringBuffer(); + + for (;;) { + int event = next(); + switch (event) { + case XMLStreamConstants.END_ELEMENT: + return text.toString(); + + case XMLStreamConstants.COMMENT: + case XMLStreamConstants.PROCESSING_INSTRUCTION: + continue; + + case CHARACTERS: + case CDATA: + case SPACE: + case ENTITY_REFERENCE: + text.append(getText()); + break; + + default: + break; + } + } + } + + private void handleStartElement() throws SAXException { + + // send startPrefixMapping events immediately before startElement event + int nsCount = super.getNamespaceCount(); + for (int i = 0; i < nsCount; i++) { + String prefix = super.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.startPrefixMapping(prefix, super.getNamespaceURI(i)); + } + + // fire startElement + QName qname = super.getName(); + String prefix = qname.getPrefix(); + String rawname; + if (prefix == null || prefix.length() == 0) { + rawname = qname.getLocalPart(); + } else { + rawname = prefix + ':' + qname.getLocalPart(); + } + Attributes attrs = getAttributes(); + handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs); + } + + private void handleEndElement() throws SAXException { + + // fire endElement + QName qname = super.getName(); + handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString()); + + // send endPrefixMapping events immediately after endElement event + // we send them in the opposite order to that returned but this is not + // actually required by SAX + int nsCount = super.getNamespaceCount(); + for (int i = nsCount - 1; i >= 0; i--) { + String prefix = super.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.endPrefixMapping(prefix); + } + } + + /** + * Get the attributes associated with the current START_ELEMENT event. + * + * @return the StAX attributes converted to org.xml.sax.Attributes + */ + private Attributes getAttributes() { + AttributesImpl attrs = new AttributesImpl(); + + // add namespace declarations + for (int i = 0; i < super.getNamespaceCount(); i++) { + String prefix = super.getNamespacePrefix(i); + String uri = super.getNamespaceURI(i); + if (prefix == null) { + attrs.addAttribute("", "", "xmlns", "CDATA", uri); + } else { + attrs.addAttribute("", "", "xmlns:" + prefix, "CDATA", uri); + } + } + + // Regular attributes + for (int i = 0; i < super.getAttributeCount(); i++) { + String uri = super.getAttributeNamespace(i); + if (uri == null) { + uri = ""; + } + String localName = super.getAttributeLocalName(i); + String prefix = super.getAttributePrefix(i); + String qname; + if (prefix == null || prefix.length() == 0) { + qname = localName; + } else { + qname = prefix + ':' + localName; + } + String type = super.getAttributeType(i); + String value = super.getAttributeValue(i); + + attrs.addAttribute(uri, localName, qname, type, value); + } + + return attrs; + } + + /** + * Adaptor for mapping Locator information. + */ + private final class LocatorAdaptor implements Locator { + + private LocatorAdaptor() { + } + + public int getColumnNumber() { + Location location = getLocation(); + return location == null ? 0 : location.getColumnNumber(); + } + + public int getLineNumber() { + Location location = getLocation(); + return location == null ? 0 : location.getLineNumber(); + } + + public String getPublicId() { + Location location = getLocation(); + return location == null ? "" : location.getPublicId(); + } + + public String getSystemId() { + Location location = getLocation(); + return location == null ? "" : location.getSystemId(); + } + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java new file mode 100644 index 0000000000..6715341ca9 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java @@ -0,0 +1,103 @@ +/* + * 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.resolver; + +import java.lang.ref.WeakReference; + +/** + * A weak reference to a class, which should be used to register classes + * with an ArtifactResolver and resolve these classes later. + * + * @version $Rev$ $Date$ + */ +public class ClassReference { + + private WeakReference<Class> clazz; + private String className; + + /** + * Constructs a new ClassReference. + * + * @param clazz The class reference + */ + public ClassReference(Class clazz) { + this.clazz = new WeakReference<Class>(clazz); + this.className = clazz.getName(); + } + + /** + * Constructs a new ClassReference. + * + * @param className The class name + */ + public ClassReference(String className) { + this.className = className; + } + + /** + * Get the referenced class. + * + * @return The referenced class + */ + public Class getJavaClass() { + if (clazz != null) { + return clazz.get(); + } else { + return null; + } + } + + /** + * Get the referenced class name. + * + * @return The class name + */ + public String getClassName() { + return className; + } + + /** + * Returns true if the class reference is unresolved. + * + * @return Wether or not the class has been resolved + */ + public boolean isUnresolved() { + return clazz == null; + } + + @Override + public int hashCode() { + return className.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof ClassReference) { + return className.equals(((ClassReference)obj).className); + } else { + return false; + } + } + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java new file mode 100644 index 0000000000..ce6305814a --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java @@ -0,0 +1,84 @@ +/*
+ * 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.resolver;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Base;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+
+/**
+ * A model resolver implementation that considers Exports in any available contribution
+ *
+ * @version $Rev: 560435 $ $Date: 2007-07-27 18:26:55 -0700 (Fri, 27 Jul 2007) $
+ */
+public class DefaultImportAllModelResolver implements ModelResolver {
+
+ private Import import_;
+ private List<Contribution> contributions;
+
+ public DefaultImportAllModelResolver(Import import_, List<Contribution> contributions) {
+ this.import_ = import_;
+ this.contributions = contributions;
+ }
+
+ public void addModel(Object resolved) {
+ throw new IllegalStateException();
+ }
+
+ public Object removeModel(Object resolved) {
+ throw new IllegalStateException();
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ //TODO optimize and cache results of the resolution later
+
+ // Go over all available contributions
+ for (Contribution contribution : contributions) {
+
+ // Go over all exports in the contribution
+ for (Export export : contribution.getExports()) {
+ // If the export matches our namespace, try to the resolve the model object
+ if (import_.match(export)) {
+ Object resolved = export.getModelResolver().resolveModel(modelClass, unresolved);
+
+ // Return the resolved model object
+ if (resolved instanceof Base) {
+ if (!((Base)resolved).isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ else if (resolved instanceof org.apache.tuscany.sca.assembly.Base) {
+ if (!((org.apache.tuscany.sca.assembly.Base)resolved).isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ }
+ }
+ }
+
+ // Model object was not resolved
+ return unresolved;
+ }
+
+}
diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java new file mode 100644 index 0000000000..bde0f24341 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java @@ -0,0 +1,113 @@ +/* + * 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.resolver; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; + +/** + * The default implementation of a model resolver Class registry. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolverExtensionPoint implements ModelResolverExtensionPoint { + + private final Map<Class<?>, Class<? extends ModelResolver>> resolvers = new HashMap<Class<?>, Class<? extends ModelResolver>>(); + private Map<String, String> loadedResolvers; + + /** + * Constructs a new model resolver registry. + */ + public DefaultModelResolverExtensionPoint() { + } + + public void addResolver(Class<?> modelType, Class<? extends ModelResolver> resolver) { + resolvers.put(modelType, resolver); + } + + public void removeResolver(Class<?> modelType) { + resolvers.remove(modelType); + } + + public Class<? extends ModelResolver> getResolver(Class<?> modelType) { + loadModelResolvers(); + + Class<?>[] classes = modelType.getInterfaces(); + for (Class<?> c : classes) { + Class<? extends ModelResolver> resolver = resolvers.get(c); + if (resolver == null) { + String className = loadedResolvers.get(c.getName()); + if (className != null) { + try { + return (Class<? extends ModelResolver>)Class.forName(className, true, modelType.getClassLoader()); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + } else { + return resolver; + } + } + + Class<? extends ModelResolver > resolver = resolvers.get(modelType); + if (resolver == null) { + String className = loadedResolvers.get(modelType.getName()); + if (className != null) { + try { + return (Class<? extends ModelResolver>)Class.forName(className, true, modelType.getClassLoader()); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + } + return resolver; + } + + /** + * Dynamically load model resolvers declared under META-INF/services + */ + private void loadModelResolvers() { + if (loadedResolvers != null) + return; + loadedResolvers = new HashMap<String, String>(); + + // Get the model resolver service declarations + ClassLoader classLoader = ModelResolver.class.getClassLoader(); + List<String> modelResolverDeclarations; + try { + modelResolverDeclarations = ServiceConfigurationUtil.getServiceClassNames(classLoader, ModelResolver.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Load model resolvers + for (String dataBindingDeclaration: modelResolverDeclarations) { + Map<String, String> attributes = ServiceConfigurationUtil.parseServiceDeclaration(dataBindingDeclaration); + String className = attributes.get("class"); + String model = attributes.get("model"); + + loadedResolvers.put(model, className); + } + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java new file mode 100644 index 0000000000..e6899e3174 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java @@ -0,0 +1,152 @@ +/* + * 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.resolver; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; + +/** + * An implementation of an extensible model resolver which delegates to the + * proper resolver extension based on the class of the model to resolve. + * + * @version $Rev$ $Date$ + */ +public class ExtensibleModelResolver implements ModelResolver { + private final ModelResolverExtensionPoint resolvers; + private final ModelFactoryExtensionPoint factories; + private final Contribution contribution; + private final Map<Class<?>, ModelResolver> resolverInstances = new HashMap<Class<?>, ModelResolver>(); + private Map<Object, Object> map = new HashMap<Object, Object>(); + private ModelResolver domainResolver = null; + + /** + * Constructs an extensible model resolver + * + * @param resolvers + * @param contribution + */ + public ExtensibleModelResolver(Contribution contribution, + ModelResolverExtensionPoint resolvers, + ModelFactoryExtensionPoint factories) { + this.contribution = contribution; + this.resolvers = resolvers; + this.factories = factories; + } + + /** + * Returns the proper resolver instance based on the interfaces of the model + * If one is not available on the registry, instantiate on demand + * + * @param modelType + * @return + */ + private ModelResolver getModelResolverInstance(Class<?> modelType) { + + // Look up a model resolver instance for the model class or + // each implemented interface + Class<?>[] interfaces = modelType.getInterfaces(); + Class<?>[] classes = new Class<?>[interfaces.length + 1]; + classes[0] = modelType; + if (interfaces.length != 0) { + System.arraycopy(interfaces, 0, classes, 1, interfaces.length); + } + for (Class<?> c : classes) { + + // Look up an existing model resolver instance + ModelResolver resolverInstance = resolverInstances.get(c); + if (resolverInstance != null) { + return resolverInstance; + } + + // We don't have an instance, lookup a model resolver class + // and instantiate it + Class<? extends ModelResolver> resolverClass = resolvers.getResolver(c); + if (resolverClass != null) { + try { + Constructor<? extends ModelResolver> constructor = + resolverClass + .getConstructor(new Class[] {Contribution.class, ModelFactoryExtensionPoint.class}); + if (constructor != null) { + + // Construct the model resolver instance and cache it + resolverInstance = constructor.newInstance(contribution, factories); + resolverInstances.put(c, resolverInstance); + return resolverInstance; + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + + return null; + } + + public void addModel(Object resolved) { + ModelResolver resolver = getModelResolverInstance(resolved.getClass()); + if (resolver != null) { + resolver.addModel(resolved); + } else { + map.put(resolved, resolved); + } + } + + public Object removeModel(Object resolved) { + ModelResolver resolver = getModelResolverInstance(resolved.getClass()); + if (resolver != null) { + return resolver.removeModel(resolved); + } else { + return map.remove(resolved); + } + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + ModelResolver resolver = getModelResolverInstance(unresolved.getClass()); + if (resolver != null) { + return resolver.resolveModel(modelClass, unresolved); + } else { + if (domainResolver != null) { + Object resolved = domainResolver.resolveModel(modelClass, unresolved); + if (resolved != null && resolved != unresolved) { + return modelClass.cast(resolved); + } + } + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + return modelClass.cast(resolved); + } + } + + return unresolved; + } + + public ModelResolver getDomainResolver() { + return domainResolver; + } + + public void setDomainResolver(ModelResolver domainResolver) { + this.domainResolver = domainResolver; + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java new file mode 100644 index 0000000000..850f79fdea --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java @@ -0,0 +1,66 @@ +/* + * 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.resolver; + +/** + * SCA Assemblies reference many artifacts of a wide variety of types. These + * include: + * <ul> + * <li> Reference from one SCA composite to another SCA composite + * <li> Reference to PolicySet files + * <li> Reference to interface definition files, either WSDL or Java interfaces + * <li> Reference to XSD files + * <li> Reference to any of a wide variety of implementation artifact files, + * including Java classes, BPEL scripts, C++ DLLs and classes, PHP scripts + * </ul> + * In the SCA assemblies, these various artifacts are referenced using either + * QNames or URIs that do not point to a specific entity. Resolution of these + * references to concrete artifacts is necessary as part of the operation of the + * SCA domain. + * + * @version $Rev$ $Date$ + */ +public interface ModelResolver { + + /** + * Resolve the model representing an artifact. + * + * @param modelClass the type of artifact + * @param unresolved the unresolved model + * @return the resolved model + */ + <T> T resolveModel(Class<T> modelClass, T unresolved); + + /** + * Add a resolved model. + * + * @param resolved The model + */ + void addModel(Object resolved); + + /** + * Remove a resolved model. + * + * @param resolved + * @return The removed model, or null if the model was not removed + */ + Object removeModel(Object resolved); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java new file mode 100644 index 0000000000..0b14b7f3c3 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java @@ -0,0 +1,52 @@ +/* + * 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.resolver; + + +/** + * An extension point for Model Resolvers + * + * @version $Rev$ $Date$ + */ +public interface ModelResolverExtensionPoint { + + /** + * Register a Model Resolver Class using the Artifact Type as the key + * + * @param modelType The model artifact type + * @param resolver The model resolver Class + */ + void addResolver(Class<?> modelType, Class <? extends ModelResolver> resolver); + + /** + * Remove the Model Resolver Class for a specific Artifact Type + * + * @param modelType The model artifact type + */ + void removeResolver(Class<?> modelType); + + /** + * Retrieve a Model Resolver Class for a specific Artifact Type + * + * @param modelType The model artifact type + * @return The model resolver Class + */ + Class <? extends ModelResolver> getResolver(Class<?> modelType); +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/AbstractContributionException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/AbstractContributionException.java new file mode 100644 index 0000000000..e5b18b4738 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/AbstractContributionException.java @@ -0,0 +1,124 @@ +/* + * 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; + +import java.io.PrintWriter; + +/** + * The root checked exception for the Contribution Service. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractContributionException extends Exception { + private static final long serialVersionUID = -7847121698339635268L; + private final String identifier; + + /** + * Override constructor from Exception. + * + * @see Exception + */ + public AbstractContributionException() { + super(); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @see Exception + */ + public AbstractContributionException(String message) { + super(message); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @see Exception + */ + public AbstractContributionException(String message, String identifier) { + super(message); + this.identifier = identifier; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param cause passed to Exception + * @see Exception + */ + public AbstractContributionException(String message, Throwable cause) { + super(message, cause); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @param cause passed to Exception + * @see Exception + */ + public AbstractContributionException(String message, String identifier, Throwable cause) { + super(message, cause); + this.identifier = identifier; + } + + /** + * Override constructor from Exception. + * + * @param cause passed to Exception + * @see Exception + */ + public AbstractContributionException(Throwable cause) { + super(cause); + this.identifier = null; + } + + /** + * Returns a string representing additional error information referred to in the error message. + * + * @return additional error information + */ + public String getIdentifier() { + return identifier; + } + + public PrintWriter appendBaseMessage(PrintWriter writer) { + if (identifier == null) { + if (super.getMessage() == null) { + return writer; + } + return writer.append(super.getMessage()); + } + if (super.getMessage() != null) { + writer.append(super.getMessage()); + } + writer.append(" [").append(identifier).append(']'); + return writer; + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java new file mode 100644 index 0000000000..484200286b --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java @@ -0,0 +1,53 @@ +/* + * 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; + +/** + * Base class for exceptions raised by contribution services. + * + * @version $Rev$ $Date$ + */ +public class ContributionException extends AbstractContributionException { + + private static final long serialVersionUID = 4432880414927652578L; + + protected ContributionException() { + super(); + } + + protected ContributionException(String message) { + super(message); + } + + protected ContributionException(String message, String identifier) { + super(message, identifier); + } + + protected ContributionException(String message, Throwable cause) { + super(message, cause); + } + + protected ContributionException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ContributionException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.java new file mode 100644 index 0000000000..5158eaf85c --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.java @@ -0,0 +1,58 @@ +/* + * 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; + +import java.util.EventListener; + +import org.apache.tuscany.sca.contribution.Contribution; + +/** + * A listener interface used to listen to contribution repository events. + * + * @version $Rev$ $Date$ + */ +public interface ContributionListener extends EventListener { + + /** + * Notifies the listener that a contribution has been added. + * + * @param repository The contribution repository + * @param contribution The new contribution + */ + void contributionAdded(ContributionRepository repository, Contribution contribution); + + /** + * Notifies the listener that a contribution has been removed. + * + * @param repository The contribution repository + * @param contribution The removed contribution. + */ + void contributionRemoved(ContributionRepository repository, Contribution contribution); + + /** + * Notifies the listener that a contribution has been updated. + * + * @param repository The contribution repository + * @param oldContribution The old contribution + * @param contribution The new contribution + */ + void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java new file mode 100644 index 0000000000..ce2b4b13c3 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java @@ -0,0 +1,44 @@ +/* + * 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; + +import java.util.List; + +public interface ContributionListenerExtensionPoint { + + /** + * Adds a contribution repository listener extension. + * @param listener The listener to add + */ + void addContributionListener(ContributionListener listener); + + /** + * Removes a contribution repository listener extension. + * @param listener The listener to remove + */ + void removeContributionListener(ContributionListener listener); + + /** + * Returns the contribution repository listeners. + * @return + */ + List<ContributionListener> getContributionListeners(); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java new file mode 100644 index 0000000000..33399dcc2f --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java @@ -0,0 +1,94 @@ +/* + * 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; + +/** + * Denotes an exception while reading artifacts inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionReadException extends ContributionException { + public static final int UNDEFINED = -1; + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + private int line = UNDEFINED; + private int column = UNDEFINED; + + public ContributionReadException(String message) { + super(message); + } + + public ContributionReadException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionReadException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being read. + * + * @return the location of the resource that was being read + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being read. + * + * @param resourceURI the location of the resource that was being read + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + + /** + * Returns the line inside the resource that was being read. + * @return the line inside the resource that was being read + */ + public int getLine() { + return line; + } + + /** + * Sets the line inside the resource that was being read. + * @param line the line inside the resource that was being read + */ + public void setLine(int line) { + this.line = line; + } + + /** + * Returns the column inside the resource that was being read. + * @return the column inside the resource that was being read + */ + public int getColumn() { + return column; + } + + /** + * Sets the column inside the resource that was being read. + * @param column the column inside the resource that was being read + */ + public void setColumn(int column) { + this.column = column; + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java new file mode 100644 index 0000000000..838359be5f --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java @@ -0,0 +1,128 @@ +/* + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.Contribution; + +/** + * Contribution repository + * + * @version $Rev$ $Date$ + */ +public interface ContributionRepository { + + /** + * Get the URI of the SCA domain + * + * @return The domain URI + */ + URI getDomain(); + + /** + * Copies a contribution to the repository. + * + * @param contribution A URl pointing to the contribution being copied to + * the repository + * @param sourceURL url of the source. this would be used to calculate the right + * filename to be stored on the repository when a inputStream is being + * provided + * @param contributionStream InputStream with the content of the + * distribution + * @return A URL pointing to the content of the contribution in the + * repository + * @throws IOException + */ + URL store(String contribution, URL sourceURL, InputStream contributionStream) throws IOException; + /** + * Copy a contribution from the source URL to the repository + * + * @param contribution A URl pointing to the contribution being copied to + * the repository + * @param sourceURL url of the source. this would be used to calculate the right + * filename to be stored on the repository when a inputStream is being + * provided + * @return A URL pointing to the content of the contribution in the + * repository + * @throws IOException + */ + URL store(String contribution, URL sourceURL) throws IOException; + + /** + * Look up the contribution by URI + * + * @param contribution The URI of the contribution + * @return A URL pointing to the content of the contribution in the + * repository, it will be null if the contribution cannot be found + * in the repository + */ + URL find(String contribution); + + /** + * Remove a contribution from the repository + * + * @param contribution The URI of the contribution to be removed + */ + void remove(String contribution); + + /** + * Get list of URIs for all the contributions in the repository + * + * @return A list of contribution URIs + */ + List<String> list(); + + /** + * Returns the contributions available in the repository. + * @return The list of contributions. + */ + List<Contribution> getContributions(); + + /** + * Adds a contribution to the repository. + * @param contribution The new contribution. + */ + void addContribution(Contribution contribution); + + /** + * Removes a contribution from the repository. + * @param contribution The contribution to remove + */ + void removeContribution(Contribution contribution); + + /** + * Updates a contribution in the repository + * @param contribution The contribution to update + */ + void updateContribution(Contribution contribution); + + /** + * Returns the contribution with the given URI. + * @param uri the URI of the contribution + * @return The contribution + */ + Contribution getContribution(String uri); + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java new file mode 100644 index 0000000000..ecb774ac0c --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java @@ -0,0 +1,41 @@ +/* + * 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; + +/** + * Denotes a problem while resolving models inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionResolveException extends ContributionException { + private static final long serialVersionUID = -7459051598906813461L; + + public ContributionResolveException(String message) { + super(message); + } + + public ContributionResolveException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionResolveException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java new file mode 100644 index 0000000000..4bf29a3993 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Base class for runtime exceptions raised by contribution services. + * + * @version $Rev$ $Date$ + */ +public class ContributionRuntimeException extends RuntimeException { + private static final long serialVersionUID = 7711215366287498896L; + + protected ContributionRuntimeException() { + super(); + } + + protected ContributionRuntimeException(String message) { + super(message); + } + + protected ContributionRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java new file mode 100644 index 0000000000..d82f89b79e --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java @@ -0,0 +1,142 @@ +/* + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * Service interface that manages artifacts contributed to a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public interface ContributionService { + /** + * Contribute an artifact to the SCA Domain. The type of the contribution is + * determined by the Content-Type of the resource or, if that is undefined, + * by some implementation-specific means (such as mapping an extension in + * the URL's path). + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param storeInRepository Flag that identifies if you want to copy the + * contribution to the repository + * @return The contribution model representing the contribution + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the resource + */ + Contribution contribute(String contributionURI, URL sourceURL, boolean storeInRepository) throws ContributionException, + IOException; + + /** + * Contribute an artifact to the SCA Domain. The type of the contribution is + * determined by the Content-Type of the resource or, if that is undefined, + * by some implementation-specific means (such as mapping an extension in + * the URL's path). + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param storeInRepository Flag that identifies if you want to copy the + * contribution to the repository + * @return The contribution model representing the contribution + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the resource + */ + Contribution contribute(String contributionURI, URL sourceURL, ModelResolver modelResolver, boolean storeInRepository) throws ContributionException, + IOException; + + /** + * Contribute an artifact to the SCA Domain. + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact. + * This is used to identify what name should be used when storing + * the contribution on the repository + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param contributionContent A stream containing the resource being + * contributed; the stream will not be closed but the read + * position after the call is undefined + * @return The contribution model representing the contribution + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + Contribution contribute(String contributionURI, URL sourceURL, InputStream contributionContent) + throws ContributionException, IOException; + + /** + * Contribute an artifact to the SCA Domain. + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact. + * This is used to identify what name should be used when storing + * the contribution on the repository + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param contributionContent A stream containing the resource being + * contributed; the stream will not be closed but the read + * position after the call is undefined + * @return The contribution model representing the contribution + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + Contribution contribute(String contributionURI, URL sourceURL, InputStream contributionContent, ModelResolver modelResolver) + throws ContributionException, IOException; + + /** + * Get the model for an installed contribution + * + * @param contribution The URI of an installed contribution + * @return The model for the contribution or null if there is no such + * contribution + */ + Contribution getContribution(String contribution); + + /** + * Adds or updates a deployment composite using a supplied composite + * ("composite by value" - a data structure, not an existing resource in the + * domain) to the contribution identified by a supplied contribution URI. + * The added or updated deployment composite is given a relative URI that + * matches the "name" attribute of the composite, with a ".composite" + * suffix. + * + * @param contribution The contribution to where + * @param composite + * @throws ContributionException + */ + void addDeploymentComposite(Contribution contribution, Composite composite) throws ContributionException; + + /** + * Remove a contribution from the SCA domain + * + * @param contribution The URI of the contribution + * @throws DeploymentException + */ + void remove(String contribution) throws ContributionException; + +}
\ No newline at end of file diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWireException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWireException.java new file mode 100644 index 0000000000..f67b2a1e51 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWireException.java @@ -0,0 +1,42 @@ +/* + * 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; + + +/** + * Denotes a problem while wiring models inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionWireException extends ContributionException { + private static final long serialVersionUID = -7459051598906813461L; + + public ContributionWireException(String message) { + super(message); + } + + public ContributionWireException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionWireException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java new file mode 100644 index 0000000000..8bfdedf180 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java @@ -0,0 +1,61 @@ +/* + * 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; + + +/** + * Denotes an exception while writing artifacts inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionWriteException extends ContributionException { + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + + public ContributionWriteException(String message) { + super(message); + } + + public ContributionWriteException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionWriteException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being written. + * + * @return the location of the resource that was being written + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being written. + * + * @param resourceURI the location of the resource that was being written + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java new file mode 100644 index 0000000000..9e77705ed3 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java @@ -0,0 +1,86 @@ +/* + * 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; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil; + +/** + * Default implementation of a contribution listener extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionListenerExtensionPoint implements ContributionListenerExtensionPoint { + + private List<ContributionListener> listeners = new ArrayList<ContributionListener>(); + private boolean loadedListeners; + + public void addContributionListener(ContributionListener listener) { + listeners.add(listener); + } + + public List<ContributionListener> getContributionListeners() { + loadListeners(); + return listeners; + } + + public void removeContributionListener(ContributionListener listener) { + listeners.remove(listener); + } + + /** + * Dynamically load listeners declared under META-INF/services + */ + private void loadListeners() { + if (loadedListeners) + return; + + // Get the databinding service declarations + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + List<String> listenerDeclarations; + try { + listenerDeclarations = ServiceConfigurationUtil.getServiceClassNames(classLoader, ContributionListener.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Load data bindings + for (String listenerDeclaration: listenerDeclarations) { + ContributionListener listener; + try { + Class<ContributionListener> listenerClass = (Class<ContributionListener>)Class.forName(listenerDeclaration, true, classLoader); + listener = listenerClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + addContributionListener(listener); + } + + loadedListeners = true; + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java new file mode 100644 index 0000000000..0b9aca70cf --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java @@ -0,0 +1,77 @@ +/* + * 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; + +import org.apache.tuscany.sca.contribution.Contribution; + +public class ExtensibleContributionListener implements ContributionListener { + private final ContributionListenerExtensionPoint listeners; + + /** + * Default constructor receiving the listener extension point + * + * @param listeners + */ + public ExtensibleContributionListener(ContributionListenerExtensionPoint listeners) { + this.listeners = listeners; + } + + /** + * Process "contributionAdded" event to all resigtered listeners + */ + public void contributionAdded(ContributionRepository repository, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionAdded(repository, contribution); + } catch (Exception e) { + // ignore, contiue to the next listener + } + } + } + + /** + * Process "contributionRemoved" event to all registered listeners + */ + public void contributionRemoved(ContributionRepository repository, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionRemoved(repository, contribution); + } catch (Exception e) { + // ignore, contiue to the next listener + } + + } + } + + /** + * Process "contributionUpdated" event to all registered listeners + */ + public void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionUpdated(repository, oldContribution, contribution); + } catch (Exception e) { + // ignore, contiue to the next listener + } + + } + } + +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java new file mode 100644 index 0000000000..b0e02f06fa --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java @@ -0,0 +1,38 @@ +/* + * 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; + +import java.net.URL; + +/** + * Provide content type for a given resource + * + * @version $Rev$ $Date$ + */ +public interface TypeDescriber { + /** + * Get the content type for the specified resource + * + * @param resourceURL The resource url + * @param defaultType The default content type + * @return The content type + */ + String getType(URL resourceURL, String defaultType); +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java new file mode 100644 index 0000000000..5079db4904 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java @@ -0,0 +1,48 @@ +/* + * 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; + +import javax.xml.namespace.QName; + +/** + * Exception that indicates an element was encountered that could not be handled. + * + * @version $Rev$ $Date$ + */ +public class UnrecognizedElementException extends ContributionReadException { + private static final long serialVersionUID = 2549543622209829032L; + private final QName element; + + /** + * Constructor that indicates which element could not be handled. + * @param element the element that could not be handled + */ + public UnrecognizedElementException(QName element) { + super("Unrecognized element: " + element.toString()); + this.element = element; + } + + /** + * Returns the element that could not be handled. + * @return the element that could not be handled. + */ + public QName getElement() { + return element; + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java new file mode 100644 index 0000000000..764fe251f2 --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java @@ -0,0 +1,49 @@ +/* + * 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; + +/** + * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain. + * The Content-Type value supplied will be returned as the message text for this exception. + * + * @version $Rev$ $Date$ + */ +public class UnsupportedContentTypeException extends ContributionException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructor specifying the Content-Type value that is not supported. + * + * @param contentType the type that is not supported + */ + public UnsupportedContentTypeException(String contentType) { + super(contentType); + } + + /** + * Constructor specifying the Content-Type value that is not supported + * and an identifier to use with this exception (typically the resource being processed). + * + * @param contentType the type that is not supported + * @param identifier an identifier for this exception + */ + public UnsupportedContentTypeException(String contentType, String identifier) { + super(contentType, identifier); + } +} diff --git a/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceConfigurationUtil.java b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceConfigurationUtil.java new file mode 100644 index 0000000000..88d960994c --- /dev/null +++ b/branches/sca-java-1.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/util/ServiceConfigurationUtil.java @@ -0,0 +1,98 @@ +/* + * 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.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +public class ServiceConfigurationUtil { + + /** + * Read the service name from a configuration file + * + * @param classLoader + * @param name The name of the service class + * @return A class name which extends/implements the service class + * @throws IOException + */ + public static List<String> getServiceClassNames(ClassLoader classLoader, String name) throws IOException { + List<String> classNames = new ArrayList<String>(); + for (URL url: Collections.list(classLoader.getResources("META-INF/services/" + name))) { + InputStream is = url.openStream(); + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + while (true) { + String line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (!line.startsWith("#") && !"".equals(line)) { + classNames.add(line.trim()); + } + } + } finally { + if (reader != null) + reader.close(); + if (is != null) { + try { + is.close(); + } catch (IOException ioe) {} + } + } + } + return classNames; + } + + /** + * Parse a service declaration in the form class;attr=value,attr=value and + * return a map of attributes + * + * @param declaration + * @return a map of attributes + */ + public static Map<String, String> parseServiceDeclaration(String declaration) { + Map<String, String> attributes = new HashMap<String, String>(); + StringTokenizer tokens = new StringTokenizer(declaration); + String className = tokens.nextToken(";"); + if (className != null) + attributes.put("class", className); + for (; tokens.hasMoreTokens(); ) { + String key = tokens.nextToken("=").substring(1); + if (key == null) + break; + String value = tokens.nextToken(",").substring(1); + if (value == null) + break; + attributes.put(key, value); + } + return attributes; + } + +} |