diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2008-11-19 00:10:54 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2008-11-19 00:10:54 +0000 |
commit | 60744a36aae604ac3c4499ed54f1082ab8f5947d (patch) | |
tree | e31d312659c912cdf29ef7a677406795fe5b3726 /java/sca/modules/contribution/src | |
parent | ad1c9458ea08eb593be252b706a88568f17c494c (diff) |
Copying modules from Equinox branch, to start merging the delta changes from 1.x/original trunk
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@718815 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/contribution/src')
80 files changed, 6863 insertions, 0 deletions
diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java new file mode 100644 index 0000000000..7400501d85 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.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; + +import org.apache.tuscany.sca.assembly.Base; + + +/** + * Represents an artifact in an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public interface Artifact extends Base { + + /** + * Returns the URI that unique identifies the artifact inside the contribution. + * + * @return The artifact URI + */ + String getURI(); + + /** + * Sets the URI that uniquely identifies the artifact inside the contribution. + * + * @param uri The artifact URI + */ + void setURI(String uri); + + /** + * Returns the location of the artifact. + * + * @return The artifact location + */ + String getLocation(); + + /** + * Set the location of the artifact. + * + * @param location The artifact location + */ + void setLocation(String location); + + + /** + * Returns the in-memory model representing the artifact. + * + * @return The model object + */ + Object getModel(); + + /** + * Sets the in-memory model representing the artifact. + * + * @param model The model object + */ + void setModel(Object model); + + /** + * Returns the contents of the artifact cached here. + * @return the contents of the artifact + */ + byte[] getContents(); + + /** + * Sets the contents of the artifact. + * @param contents the contents of the artifact + */ + void setContents(byte[] contents); +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Constants.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Constants.java new file mode 100644 index 0000000000..4cf20125b9 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Constants.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Constants used in SCA contribution. + * + * @version $Rev$ $Date$ + */ +public interface Constants { + String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + String SCA10_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.0"; +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java new file mode 100644 index 0000000000..81b0b08b9d --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Constants for the main supported contribution package type. + * + * @version $Rev$ $Date$ + */ +@Deprecated +public interface ContentType { + + /** + * Java compressed contribution package + */ + String JAR = "application/x-compressed"; + + /** + * Filesystem folder contribution package + */ + String FOLDER = "application/vnd.tuscany.folder"; + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java new file mode 100644 index 0000000000..80dece4496 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java @@ -0,0 +1,123 @@ +/* + * 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 an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public interface Contribution extends Artifact { + + /** + * Default location of contribution metadata in an SCA contribution. + */ + String SCA_CONTRIBUTION_META = "META-INF/sca-contribution.xml"; + + /** + * Default location of a generated contribution metadata in an SCA contribution. + */ + String SCA_CONTRIBUTION_GENERATED_META = "META-INF/sca-contribution-generated.xml"; + + /** + * Default location of deployable composites in an SCA contribution. + */ + String SCA_CONTRIBUTION_DEPLOYABLES = "META-INF/sca-deployables/"; + + + /** + * Returns a list of exports based on the contribution metadata. + * + * @return The list of exports in this contribution + */ + List<Export> getExports(); + + /** + * Returns a list of imports based on the contribution metadata. + * + * @return The list of imports in this contribution + */ + List<Import> getImports(); + + /** + * Returns the list of deployable composites in the contribution. + * + * @return The list of deployable composites + */ + List<Composite> getDeployables(); + + /** + * Returns the list of artifacts in the contribution. + * + * @return The list of artifacts in the contribution + */ + List<Artifact> 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); + + /** + * Returns the list of contributions that this contribution depends on. + * + * @return + */ + List<Contribution> getDependencies(); + + /** + * Returns the ClassLoader used to load classes and resources from + * this contribution + * + * FIXME Remove this, the base contribution model should not depend + * on Java ClassLoaders. + * + * @return The contribution ClassLoader + */ + ClassLoader getClassLoader(); + + /** + * Sets the ClassLoader used to load classes and resources from + * this contribution + * + * FIXME Remove this, the base contribution model should not depend + * on Java ClassLoaders. + * + * @param classLoader the contribution class loader + */ + void setClassLoader(ClassLoader classLoader); + +}
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java new file mode 100644 index 0000000000..67c9a05a0b --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java @@ -0,0 +1,73 @@ +/* + * 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; + + +/** + * A factory for the contribution model. + * + * @version $Rev$ $Date$ + */ +public interface ContributionFactory { + + /** + * Create a contribution model object + * + * @return The new contribution model object + */ + Contribution createContribution(); + + /** + * Create a contribution metadata model object + * + * @return The new contribution metadata model object + */ + ContributionMetadata createContributionMetadata(); + + /** + * Create a deployedArtifact model object + * + * @return The new deployedArtifact model object + */ + @Deprecated + DeployedArtifact createDeployedArtifact(); + + /** + * Create an artifact model object + * + * @return The new artifact model object + */ + Artifact createArtifact(); + + /** + * Create a default import model object. + * + * @return the new default import model object + */ + DefaultImport createDefaultImport(); + + /** + * Create a default export model object. + * + * @return the new default export model object + */ + DefaultExport createDefaultExport(); + +}
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java new file mode 100644 index 0000000000..4043fb9eda --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java @@ -0,0 +1,55 @@ +/* + * 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.Base; +import org.apache.tuscany.sca.assembly.Composite; + +/** + * The representation of SCA contribution metadata. + * + * @version $Rev$ $Date$ + */ +public interface ContributionMetadata extends Base { + + /** + * Returns a list of exports based on the contribution metadata. + * + * @return The list of exports + */ + List<Export> getExports(); + + /** + * Returns a list of imports based on the contribution metadata. + * + * @return The list of imports + */ + List<Import> getImports(); + + /** + * Returns the list of deployable based on the contribution metadata. + * + * @return The list of deployable composites + */ + List<Composite> getDeployables(); + +}
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.java new file mode 100644 index 0000000000..98954c288a --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.java @@ -0,0 +1,32 @@ +/* + * 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.impl.ContributionFactoryImpl; + + +/** + * Default implementation of a contribution model factory. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionFactory extends ContributionFactoryImpl { + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java new file mode 100644 index 0000000000..b2eddb8336 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java @@ -0,0 +1,30 @@ +/* + * 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; + + +/** + * The representation of an export that exports all artifacts in + * a contribution. + * + * @version $Rev$ $Date$ + */ +public interface DefaultExport extends Export { +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java new file mode 100644 index 0000000000..20798dcd17 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java @@ -0,0 +1,30 @@ +/* + * 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; + + +/** + * The representation of a default import that imports artifacts from + * all contributions. + * + * @version $Rev$ $Date$ + */ +public interface DefaultImport extends Import { +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java new file mode 100644 index 0000000000..ffe190132c --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.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; + +/** + * Representation of a deployed artifact + * + * @version $Rev$ $Date$ + */ +@Deprecated +public interface DeployedArtifact extends Artifact { +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java new file mode 100644 index 0000000000..bfa16b1ce3 --- /dev/null +++ b/java/sca/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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java new file mode 100644 index 0000000000..35076f55a7 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.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; + +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 that a specific export actually exports 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.java new file mode 100644 index 0000000000..c0dd5431d7 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.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; + +/** + * Constants for the main supported contribution package types. + * + * @version $Rev$ $Date$ + */ +public interface PackageType { + + /** + * Java compressed contribution package + */ + String JAR = "application/x-compressed"; + + /** + * Filesystem folder contribution package + */ + String FOLDER = "application/vnd.tuscany.folder"; + + + String BUNDLE = "application/osgi.bundle"; + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java new file mode 100644 index 0000000000..881987f622 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.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.impl; + +import org.apache.tuscany.sca.contribution.Artifact; + + +/** + * The model representing an artifact in a contribution. + * + * @version $Rev$ $Date$ + */ +class ArtifactImpl implements Artifact { + private String uri; + private String location; + private Object model; + private boolean unresolved; + private byte[] contents; + + ArtifactImpl() { + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public Object getModel() { + return model; + } + + public void setModel(Object model) { + this.model = model; + } + + public byte[] getContents() { + return contents; + } + + public void setContents(byte[] contents) { + this.contents = contents; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof Artifact) { + return uri.equals(((Artifact)obj).getURI()); + } else { + return false; + } + } + } + + @Override + public String toString() { + return "Artifact:" + uri + "\n" + + "at: " + location; + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java new file mode 100644 index 0000000000..c678c2eaef --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.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.impl; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.DefaultImport; +import org.apache.tuscany.sca.contribution.DeployedArtifact; + + +/** + * Default implementation of a contribution model factory. + * + * @version $Rev$ $Date$ + */ +public class ContributionFactoryImpl implements ContributionFactory { + + protected ContributionFactoryImpl() { + } + + public Contribution createContribution() { + return new ContributionImpl(); + } + + public ContributionMetadata createContributionMetadata() { + return new ContributionMetadataImpl(); + } + + public Artifact createArtifact() { + return new ArtifactImpl(); + } + + public DefaultExport createDefaultExport() { + return new DefaultExportImpl(); + } + + public DefaultImport createDefaultImport() { + return new DefaultImportImpl(); + } + + @Deprecated + public DeployedArtifact createDeployedArtifact() { + class DeployedArtifactImpl extends ArtifactImpl implements DeployedArtifact { + } + return new DeployedArtifactImpl(); + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java new file mode 100644 index 0000000000..0b41016caa --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java @@ -0,0 +1,159 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +class ContributionImpl implements Contribution { + private String uri; + private String location; + private Object model; + private byte[] contents; + private boolean unresolved; + private List<Export> exports = new ArrayList<Export>(); + private List<Import> imports = new ArrayList<Import>(); + private List<Composite> deployables = new ArrayList<Composite>(); + private List<Artifact> artifacts = new ArrayList<Artifact>(); + private List<Contribution> dependencies = new ArrayList<Contribution>(); + private ModelResolver modelResolver; + + // FIXME remove this dependency on Java ClassLoaders + private ClassLoader classLoader; + + ContributionImpl() { + } + + public String getLocation() { + return this.location; + } + + public void setLocation(String location) { + this.location = location; + } + + //FIXME Remove dependency on Java ClassLoaders + public ClassLoader getClassLoader() { + return classLoader; + } + + //FIXME Remove dependency on Java ClassLoaders + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + + public String getURI() { + return this.uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public Object getModel() { + return model; + } + + public void setModel(Object model) { + this.model = model; + } + + public byte[] getContents() { + return contents; + } + + public void setContents(byte[] contents) { + this.contents = contents; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + public List<Contribution> getDependencies() { + return dependencies; + } + + public List<Export> getExports() { + return exports; + } + + public List<Import> getImports() { + return imports; + } + + public List<Composite> getDeployables() { + return deployables; + } + + public List<Artifact> getArtifacts() { + return artifacts; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof Artifact) { + return uri.equals(((Artifact)obj).getURI()); + } else { + return false; + } + } + } + + @Override + public String toString() { + return "Contribution : " + uri + " \n" + + "from: " + location; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.java new file mode 100644 index 0000000000..75b12b1260 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.java @@ -0,0 +1,64 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +class ContributionMetadataImpl implements ContributionMetadata { + private boolean unresolved; + private List<Export> exports = new ArrayList<Export>(); + private List<Import> imports = new ArrayList<Import>(); + private List<Composite> deployables = new ArrayList<Composite>(); + + ContributionMetadataImpl() { + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public List<Export> getExports() { + return exports; + } + + public List<Import> getImports() { + return imports; + } + + public List<Composite> getDeployables() { + return deployables; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java new file mode 100644 index 0000000000..e67395337a --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java @@ -0,0 +1,45 @@ +/* + * 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.impl; + +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an export for the contribution + * + * @version $Rev$ $Date$ + */ +public class DefaultExportImpl implements DefaultExport { + private ModelResolver modelResolver; + + protected DefaultExportImpl() { + super(); + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java new file mode 100644 index 0000000000..17c09f2cbc --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java @@ -0,0 +1,55 @@ +/* + * 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.impl; + +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.DefaultImport; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an import for the contribution + * + * @version $Rev$ $Date$ + */ +public class DefaultImportImpl implements DefaultImport { + private ModelResolver modelResolver; + + protected DefaultImportImpl() { + super(); + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + + public boolean match(Export export) { + if (export instanceof DefaultExport) { + return true; + } + return false; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java new file mode 100644 index 0000000000..5be0b188f4 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.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.processor; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * Base interface for artifact processors. + * + * @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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..029df61f0f --- /dev/null +++ b/java/sca/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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java new file mode 100644 index 0000000000..f23797a831 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java @@ -0,0 +1,539 @@ +/* + * 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 String writeElementPrefix(XMLStreamWriter writer, String uri) throws XMLStreamException { + if (uri == null) { + return null; + } + String prefix = writer.getPrefix(uri); + if (prefix != null) { + return null; + } 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); + return prefix; + } + + } + + /** + * Start an element. + * @param uri + * @param name + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException { + String prefix = writeElementPrefix(writer, uri); + writer.writeStartElement(uri, name); + if (prefix != null){ + writer.writeNamespace(prefix,uri); + } + writeAttributePrefixes(writer, attrs); + writeAttributes(writer, attrs); + } + + /** + * Start an element. + * @param qname + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException { + writeStart(writer, qname.getNamespaceURI(), qname.getLocalPart(), 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); + } + + /** + * Start a document. + * @param writer + * @param qname + * @param attrs + * @throws XMLStreamException + */ + protected void writeStartDocument(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException { + writeStartDocument(writer, qname.getNamespaceURI(), qname.getLocalPart(), attrs); + } + + /** + * 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, Integer value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, Integer value) { + this(null, name, value); + } + + public XAttr(String uri, String name, Double value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, Double 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) { + + // Use the prefix already bound to the given URI + if (prefix.length() > 0) { + return prefix + ":" + qname.getLocalPart(); + } else { + + // Empty prefix, just return the local part of the given qname + return 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); + writer.writeNamespace(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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java new file mode 100644 index 0000000000..3b99eba586 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java @@ -0,0 +1,45 @@ +/* + * 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; + +/** + * Base class for exceptions raised by contribution services. + * + * @version $Rev$ $Date$ + */ +public class ContributionException extends Exception { + + private static final long serialVersionUID = 4432880414927652578L; + + protected ContributionException() { + super(); + } + + protected ContributionException(String message) { + super(message); + } + + protected ContributionException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionException(Throwable cause) { + super(cause); + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java new file mode 100644 index 0000000000..6fd7d0c91e --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java @@ -0,0 +1,95 @@ +/* + * 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; + + +/** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java new file mode 100644 index 0000000000..fe1a09d398 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.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.processor; + + +/** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java new file mode 100644 index 0000000000..0039dd9f8b --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/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.processor; + +/** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java new file mode 100644 index 0000000000..286c9dc791 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java @@ -0,0 +1,62 @@ +/* + * 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; + + + +/** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..3c67a8c550 --- /dev/null +++ b/java/sca/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 extension point. + * + * @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. + */ + 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..d268c5b011 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java @@ -0,0 +1,384 @@ +/* + * 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.Map; +import java.util.Set; + +import javax.xml.namespace.QName; +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.assembly.AssemblyFactory; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +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 ExtensionPointRegistry extensionPoints; + private FactoryExtensionPoint modelFactories; + private MonitorFactory monitorFactory; + private boolean loaded; + private StAXArtifactProcessor<Object> extensibleStAXProcessor; + private StAXAttributeProcessor<Object> extensibleStAXAttributeProcessor; + private Monitor monitor = null; + + /** + * Constructs a new extension point. + */ + public DefaultStAXArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + UtilityExtensionPoint utilities = this.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) + this.monitor = monitorFactory.createMonitor(); + this.extensibleStAXProcessor = new ExtensibleStAXArtifactProcessor(this, inputFactory, outputFactory, this.monitor); + + StAXAttributeProcessorExtensionPoint attributeExtensionPoint = extensionPoints.getExtensionPoint(StAXAttributeProcessorExtensionPoint.class); + this.extensibleStAXAttributeProcessor = new ExtensibleStAXAttributeProcessor(attributeExtensionPoint ,inputFactory, outputFactory, this.monitor); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public void addArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + } + + public void removeArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + } + if (artifactProcessor.getModelType() != null) { + 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); + } + + /** + * Returns a QName object from a QName expressed as {ns}name + * or ns#name. + * + * @param qname + * @return + */ + private static QName getQName(String qname) { + if (qname == null) { + return null; + } + qname = qname.trim(); + if (qname.startsWith("{")) { + int h = qname.indexOf('}'); + if (h != -1) { + return new QName(qname.substring(1, h), qname.substring(h + 1)); + } + } else { + int h = qname.indexOf('#'); + if (h != -1) { + return new QName(qname.substring(0, h), qname.substring(h + 1)); + } + } + throw new IllegalArgumentException("Invalid qname: "+qname); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private void loadArtifactProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(StAXArtifactProcessor.class.getName()); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", extensibleStAXProcessor, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration : processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + + // Load a StAX artifact processor + + // Get the model QName + QName artifactType = getQName(attributes.get("qname")); + + // 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(artifactType, modelTypeName, factoryName, + processorDeclaration, extensionPoints, modelFactories, + extensibleStAXProcessor,extensibleStAXAttributeProcessor, monitor); + 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 ExtensionPointRegistry extensionPoints; + private QName artifactType; + private String modelTypeName; + private String factoryName; + private ServiceDeclaration processorDeclaration; + private StAXArtifactProcessor processor; + private Class<?> modelType; + private StAXArtifactProcessor<Object> extensionProcessor; + private StAXAttributeProcessor<Object> extensionAttributeProcessor; + private Monitor monitor; + + LazyStAXArtifactProcessor(QName artifactType, + String modelTypeName, + String factoryName, + ServiceDeclaration processorDeclaration, + ExtensionPointRegistry extensionPoints, + FactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> extensionProcessor, + StAXAttributeProcessor<Object> extensionAttributeProcessor, + Monitor monitor) { + + this.extensionPoints = extensionPoints; + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.factoryName = factoryName; + this.processorDeclaration = processorDeclaration; + this.extensionProcessor = extensionProcessor; + this.extensionAttributeProcessor = extensionAttributeProcessor; + this.monitor = monitor; + } + + public QName getArtifactType() { + return artifactType; + } + + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + private StAXArtifactProcessor getProcessor() { + if (processor == null) { + + if (processorDeclaration.getClassName() + .equals("org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor")) { + + // Specific initialization for the DefaultBeanModelProcessor + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + PolicyFactory policyFactory = modelFactories.getFactory(PolicyFactory.class); + try { + Class<StAXArtifactProcessor> processorClass = + (Class<StAXArtifactProcessor>)processorDeclaration.loadClass(); + Object modelFactory; + if (factoryName != null) { + Class<?> factoryClass = (Class<?>)processorDeclaration.loadClass(factoryName); + modelFactory = modelFactories.getFactory(factoryClass); + } else { + modelFactory = null; + } + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(AssemblyFactory.class, + PolicyFactory.class, + QName.class, + Class.class, + Object.class, + Monitor.class); + processor = + constructor.newInstance(assemblyFactory, + policyFactory, + artifactType, + getModelType(), + modelFactory, + monitor); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } else { + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + + // Load and instantiate the processor class + try { + Class<StAXArtifactProcessor> processorClass = + (Class<StAXArtifactProcessor>)processorDeclaration.loadClass(); + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, Monitor.class); + processor = constructor.newInstance(modelFactories, monitor); + } catch (NoSuchMethodException e) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, monitor); + } catch (NoSuchMethodException e1) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor, monitor); + } catch (NoSuchMethodException e2) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class, StAXAttributeProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor, extensionAttributeProcessor, monitor); + } catch (NoSuchMethodException e2a) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor, monitor); + } catch (NoSuchMethodException e3) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, StAXAttributeProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor, extensionAttributeProcessor, monitor); + } catch (NoSuchMethodException e3a) { + + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class); + processor = constructor.newInstance(modelFactories); + } catch (NoSuchMethodException e4) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class); + processor = constructor.newInstance(extensionPoints); + } catch (NoSuchMethodException e4a) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor); + } catch (NoSuchMethodException e5) { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor); + } + } + } + } + } + } + } + } + } + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } + } + 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 (modelTypeName != null && modelType == null) { + try { + modelType = processorDeclaration.loadClass(modelTypeName); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processorDeclaration, ie); + throw ie; + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java new file mode 100644 index 0000000000..bd38a609a6 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java @@ -0,0 +1,323 @@ +/* + * 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.Map; +import java.util.Set; + +import javax.xml.namespace.QName; +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.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * The default implementation of an extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public class DefaultStAXAttributeProcessorExtensionPoint extends + DefaultArtifactProcessorExtensionPoint<StAXAttributeProcessor> implements StAXAttributeProcessorExtensionPoint { + + private ExtensionPointRegistry extensionPoints; + private FactoryExtensionPoint modelFactories; + private StAXAttributeProcessor<Object> extensibleStAXAttributeProcessor; + private boolean loaded; + private Monitor monitor = null; + + /** + * Constructs a new extension point. + */ + public DefaultStAXAttributeProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + UtilityExtensionPoint utilities = this.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) { + this.monitor = monitorFactory.createMonitor(); + } + this.extensibleStAXAttributeProcessor = new ExtensibleStAXAttributeProcessor(this, inputFactory, outputFactory, this.monitor); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public void addArtifactProcessor(StAXAttributeProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + } + + public void removeArtifactProcessor(StAXAttributeProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.remove(artifactProcessor.getModelType()); + } + } + + @Override + public StAXAttributeProcessor getProcessor(Class<?> modelType) { + loadArtifactProcessors(); + return super.getProcessor(modelType); + } + + @Override + public StAXAttributeProcessor getProcessor(Object artifactType) { + loadArtifactProcessors(); + return super.getProcessor(artifactType); + } + + /** + * Returns a QName object from a QName expressed as {ns}name + * or ns#name. + * + * @param qname + * @return + */ + private static QName getQName(String qname) { + if (qname == null) { + return null; + } + qname = qname.trim(); + if (qname.startsWith("{")) { + int h = qname.indexOf('}'); + if (h != -1) { + return new QName(qname.substring(1, h), qname.substring(h + 1)); + } + } else { + int h = qname.indexOf('#'); + if (h != -1) { + return new QName(qname.substring(0, h), qname.substring(h + 1)); + } + } + throw new IllegalArgumentException("Invalid qname: "+qname); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private void loadArtifactProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(StAXAttributeProcessor.class.getName()); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", extensibleStAXAttributeProcessor, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration : processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + + // Load a StAX artifact processor + + // Get the model QName + QName artifactType = getQName(attributes.get("qname")); + + // 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 + StAXAttributeProcessor processor = + new LazyStAXAttributeProcessor(artifactType, modelTypeName, factoryName, + processorDeclaration, extensionPoints, modelFactories, + extensibleStAXAttributeProcessor, monitor); + addArtifactProcessor(processor); + } + + loaded = true; + } + + /** + * A wrapper around an Artifact processor class allowing lazy loading and + * initialization of artifact processors. + */ + private static class LazyStAXAttributeProcessor implements StAXAttributeProcessor { + + private ExtensionPointRegistry extensionPoints; + private QName artifactType; + private String modelTypeName; + private String factoryName; + private ServiceDeclaration processorDeclaration; + private StAXAttributeProcessor processor; + private Class<?> modelType; + private StAXAttributeProcessor<Object> extensionProcessor; + private Monitor monitor; + + LazyStAXAttributeProcessor(QName artifactType, + String modelTypeName, + String factoryName, + ServiceDeclaration processorDeclaration, + ExtensionPointRegistry extensionPoints, + FactoryExtensionPoint modelFactories, + StAXAttributeProcessor<Object> extensionProcessor, + Monitor monitor) { + + this.extensionPoints = extensionPoints; + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.factoryName = factoryName; + this.processorDeclaration = processorDeclaration; + this.extensionProcessor = extensionProcessor; + this.monitor = monitor; + } + + public QName getArtifactType() { + return artifactType; + } + + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + private StAXAttributeProcessor getProcessor() { + if (processor == null) { + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + + // Load and instantiate the processor class + try { + Class<StAXAttributeProcessor> processorClass = + (Class<StAXAttributeProcessor>)processorDeclaration.loadClass(); + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, Monitor.class); + processor = constructor.newInstance(modelFactories, monitor); + } catch (NoSuchMethodException e) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, monitor); + } catch (NoSuchMethodException e1) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor, monitor); + } catch (NoSuchMethodException e2) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor, monitor); + } catch (NoSuchMethodException e3) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class); + processor = constructor.newInstance(modelFactories); + } catch (NoSuchMethodException e4) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class); + processor = constructor.newInstance(extensionPoints); + } catch (NoSuchMethodException e4a) { + try { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor); + } catch (NoSuchMethodException e5) { + Constructor<StAXAttributeProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor); + } + } + } + } + } + } + } + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + + } + return processor; + } + + public Object read(QName attributeName, XMLStreamReader inputSource) throws ContributionReadException, XMLStreamException { + return getProcessor().read(attributeName, inputSource); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + getProcessor().write(model, outputSource); + } + + public Class<?> getModelType() { + if (modelTypeName != null && modelType == null) { + try { + modelType = processorDeclaration.loadClass(modelTypeName); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processorDeclaration, ie); + throw ie; + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..402d4aa151 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java @@ -0,0 +1,239 @@ +/* + * 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.Map; +import java.util.Set; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + + +/** + * The default implementation of a URL artifact processor extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultURLArtifactProcessorExtensionPoint + extends DefaultArtifactProcessorExtensionPoint<URLArtifactProcessor> + implements URLArtifactProcessorExtensionPoint { + + private ExtensionPointRegistry extensionPoints; + private StAXArtifactProcessor<?> staxProcessor; + private boolean loaded; + private Monitor monitor = null; + + /** + * Constructs a new extension point. + */ + public DefaultURLArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + FactoryExtensionPoint modelFactories = this.extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + UtilityExtensionPoint utilities = this.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) + this.monitor = monitorFactory.createMonitor(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, this.monitor); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public void addArtifactProcessor(URLArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + } + + public void removeArtifactProcessor(URLArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + } + if (artifactProcessor.getModelType() != null) { + 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); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private void loadProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(URLArtifactProcessor.class.getName()); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", staxProcessor, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration: processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + // 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(artifactType, modelTypeName, + processorDeclaration, extensionPoints, staxProcessor, monitor); + 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 ExtensionPointRegistry extensionPoints; + private String artifactType; + private String modelTypeName; + private ServiceDeclaration processorDeclaration; + private URLArtifactProcessor processor; + private Class<?> modelType; + private StAXArtifactProcessor<?> staxProcessor; + private Monitor monitor; + + LazyURLArtifactProcessor(String artifactType, + String modelTypeName, + ServiceDeclaration processorDeclaration, + ExtensionPointRegistry extensionPoints, + StAXArtifactProcessor<?> staxProcessor, + Monitor monitor) { + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.processorDeclaration = processorDeclaration; + this.extensionPoints = extensionPoints; + this.staxProcessor = staxProcessor; + this.monitor = monitor; + } + + public String getArtifactType() { + return artifactType; + } + + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + private URLArtifactProcessor getProcessor() { + if (processor == null) { + try { + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + Class<URLArtifactProcessor> processorClass = (Class<URLArtifactProcessor>)processorDeclaration.loadClass(); + try { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(FactoryExtensionPoint.class, Monitor.class); + processor = constructor.newInstance(modelFactories, monitor); + } catch (NoSuchMethodException e) { + try { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(FactoryExtensionPoint.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, staxProcessor, monitor); + } catch (NoSuchMethodException e2) { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, staxProcessor, monitor); + } + } + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } + return processor; + } + + public Object read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException { + return getProcessor().read(contributionURL, artifactURI, artifactURL); + } + + public Class<?> getModelType() { + if (modelTypeName != null && modelType == null) { + try { + modelType = processorDeclaration.loadClass(modelTypeName); + } catch (ClassNotFoundException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processorDeclaration, ie); + throw ie; + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java new file mode 100644 index 0000000000..9258a837d8 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java @@ -0,0 +1,325 @@ +/* + * 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.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.List; + +import javax.xml.XMLConstants; +import javax.xml.stream.EventFilter; +import javax.xml.stream.StreamFilter; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLReporter; +import javax.xml.stream.XMLResolver; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.XMLEventAllocator; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Default implementation of an XMLInputFactory that creates validating + * XMLStreamReaders. + * + * @version $Rev$ $Date$ + */ +public class DefaultValidatingXMLInputFactory extends ValidatingXMLInputFactory { + + private XMLInputFactory inputFactory; + private ValidationSchemaExtensionPoint schemas; + private Monitor monitor; + private boolean initialized; + private boolean hasSchemas; + private Schema aggregatedSchema; + + public DefaultValidatingXMLInputFactory(ExtensionPointRegistry registry) { + FactoryExtensionPoint factoryExtensionPoint = registry.getExtensionPoint(FactoryExtensionPoint.class); + XMLInputFactory factory = factoryExtensionPoint.getFactory(XMLInputFactory.class); + this.inputFactory = factory; + this.schemas = registry.getExtensionPoint(ValidationSchemaExtensionPoint.class); + this.monitor = + registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(MonitorFactory.class).createMonitor(); + } + + /** + * Constructs a new XMLInputFactory. + * + * @param inputFactory + * @param schemas + */ + public DefaultValidatingXMLInputFactory(XMLInputFactory inputFactory, ValidationSchemaExtensionPoint schemas, Monitor monitor) { + this.inputFactory = inputFactory; + this.schemas = schemas; + this.monitor = monitor; + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + /** + * Initialize the registered schemas and create an aggregated schema for + * validation. + */ + private void initializeSchemas() { + if (initialized) { + return; + } + initialized = true; + + // Load the XSDs registered in the validation schema extension point + try { + List<String> uris = schemas.getSchemas(); + int n = uris.size(); + if (n ==0) { + return; + } else { + hasSchemas = true; + } + final Source[] sources = new Source[n]; + for (int i =0; i < n; i++) { + final String uri = uris.get(i); + // Allow privileged access to open URL stream. Requires FilePermission in security policy. + final URL url = new URL( uri ); + InputStream urlStream; + try { + urlStream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() { + public InputStream run() throws IOException { + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", url, (IOException)e.getException()); + throw (IOException)e.getException(); + } + sources[i] = new StreamSource(urlStream, uri); + } + + // Create an aggregated validation schemas from all the XSDs + final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + // Allow privileged access to check files. Requires FilePermission + // in security policy. + try { + aggregatedSchema = AccessController.doPrivileged(new PrivilegedExceptionAction<Schema>() { + public Schema run() throws SAXException { + return schemaFactory.newSchema(sources); + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", schemaFactory, (SAXException)e.getException()); + throw (SAXException)e.getException(); + } + + } catch (Error e) { + // FIXME Log this, some old JDKs don't support XMLSchema validation + //e.printStackTrace(); + } catch (SAXParseException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", schemas, ie); + throw ie; + } catch (Exception e) { + //FIXME Log this, some old JDKs don't support XMLSchema validation + e.printStackTrace(); + } + } + + @Override + public XMLEventReader createFilteredReader(XMLEventReader arg0, EventFilter arg1) throws XMLStreamException { + return inputFactory.createFilteredReader(arg0, arg1); + } + + @Override + public XMLStreamReader createFilteredReader(XMLStreamReader arg0, StreamFilter arg1) throws XMLStreamException { + return inputFactory.createFilteredReader(arg0, arg1); + } + + @Override + public XMLEventReader createXMLEventReader(InputStream arg0, String arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + @Override + public XMLEventReader createXMLEventReader(InputStream arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + @Override + public XMLEventReader createXMLEventReader(Reader arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + @Override + public XMLEventReader createXMLEventReader(Source arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + @Override + public XMLEventReader createXMLEventReader(String arg0, InputStream arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + @Override + public XMLEventReader createXMLEventReader(String arg0, Reader arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + @Override + public XMLEventReader createXMLEventReader(XMLStreamReader arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + @Override + public XMLStreamReader createXMLStreamReader(InputStream arg0, String arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + }else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + @Override + public XMLStreamReader createXMLStreamReader(InputStream arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + @Override + public XMLStreamReader createXMLStreamReader(Reader arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + @Override + public XMLStreamReader createXMLStreamReader(Source arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + @Override + public XMLStreamReader createXMLStreamReader(String arg0, InputStream arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + @Override + public XMLStreamReader createXMLStreamReader(String arg0, Reader arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + @Override + public XMLEventAllocator getEventAllocator() { + return inputFactory.getEventAllocator(); + } + + @Override + public Object getProperty(String arg0) throws IllegalArgumentException { + return inputFactory.getProperty(arg0); + } + + @Override + public XMLReporter getXMLReporter() { + return inputFactory.getXMLReporter(); + } + + @Override + public XMLResolver getXMLResolver() { + return inputFactory.getXMLResolver(); + } + + @Override + public boolean isPropertySupported(String arg0) { + return inputFactory.isPropertySupported(arg0); + } + + @Override + public void setEventAllocator(XMLEventAllocator arg0) { + inputFactory.setEventAllocator(arg0); + } + + @Override + public void setProperty(String arg0, Object arg1) throws IllegalArgumentException { + inputFactory.setProperty(arg0, arg1); + } + + @Override + public void setXMLReporter(XMLReporter arg0) { + inputFactory.setXMLReporter(arg0); + } + + @Override + public void setXMLResolver(XMLResolver arg0) { + inputFactory.setXMLResolver(arg0); + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java new file mode 100644 index 0000000000..a6631f498e --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java @@ -0,0 +1,95 @@ +/* + * 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.FileNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of an extension point for XML schemas. + * + * @version $Rev$ $Date$ + */ +public class DefaultValidationSchemaExtensionPoint implements ValidationSchemaExtensionPoint { + + private List<String> schemas = new ArrayList<String>(); + private boolean loaded; + + public void addSchema(String uri) { + schemas.add(uri); + } + + public void removeSchema(String uri) { + schemas.remove(uri); + } + + /** + * Load schema declarations from META-INF/services/ + * org.apache.tuscany.sca.contribution.processor.ValidationSchema files + */ + private void loadSchemas() { + if (loaded) + return; + + // Get the schema declarations + Set<ServiceDeclaration> schemaDeclarations; + try { + schemaDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations("org.apache.tuscany.sca.contribution.processor.ValidationSchema"); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // TODO - temp fix to ensure that the schema tuscany-sca.xsd always comes first + String tuscanyScaXsd = null; + + // Find each schema + for (ServiceDeclaration schemaDeclaration: schemaDeclarations) { + URL url = schemaDeclaration.getResource(schemaDeclaration.getClassName()); + if (url == null) { + throw new IllegalArgumentException(new FileNotFoundException(schemaDeclaration.getClassName())); + } + + if (url.toString().contains("tuscany-sca.xsd")){ + tuscanyScaXsd = url.toString(); + } else { + schemas.add(url.toString()); + } + } + + if (tuscanyScaXsd != null){ + schemas.add(0, tuscanyScaXsd); + } + + loaded = true; + } + + public List<String> getSchemas() { + loadSchemas(); + return schemas; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java new file mode 100644 index 0000000000..947fdb330d --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java @@ -0,0 +1,266 @@ +/* + * 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 java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible StAX artifact processor. + * + * Takes a StAXArtifactProcessorExtensionPoint and delegates to the proper + * StAXArtifactProcessor by element QName + * + * @version $Rev$ $Date$ + */ +public class ExtensibleStAXArtifactProcessor implements StAXArtifactProcessor<Object> { + private static final Logger logger = Logger.getLogger(ExtensibleStAXArtifactProcessor.class.getName()); + + private static final QName ANY_ELEMENT = new QName("http://www.w3.org/2001/XMLSchema", "anyElement"); + + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private StAXArtifactProcessorExtensionPoint processors; + private Monitor monitor; + + /** + * Constructs a new ExtensibleStAXArtifactProcessor. + * @param processors + * @param inputFactory + * @param outputFactory + */ + public ExtensibleStAXArtifactProcessor(StAXArtifactProcessorExtensionPoint processors, + XMLInputFactory inputFactory, + XMLOutputFactory outputFactory, + Monitor monitor) { + super(); + this.processors = processors; + this.inputFactory = inputFactory; + this.outputFactory = outputFactory; + if (this.outputFactory != null) { + this.outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE); + } + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void warning(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + + public Object read(XMLStreamReader source) throws ContributionReadException, XMLStreamException { + + // Delegate to the processor associated with the element QName + int event = source.getEventType(); + if (event == XMLStreamConstants.START_DOCUMENT) { + source.nextTag(); + } + QName name = source.getName(); + StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name); + if (processor == null) { + Location location = source.getLocation(); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Element " + name + " cannot be processed. (" + location + ")"); + } + warning("ElementCannotBeProcessed", processors, name, location); + + return null; + + //FIXME Re-enable feature after complete merge is done + /* + StAXArtifactProcessor<?> anyElementProcessor = processors.getProcessor(ANY_ELEMENT); + if (anyElementProcessor != null) { + return anyElementProcessor.read(source); + } else { + 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); + } else { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("No StAX processor is configured to handle " + model.getClass()); + } + warning("NoStaxProcessor", processors, model.getClass()); + + //FIXME Re-enable feature after complete merge is done + /* + StAXArtifactProcessor anyElementProcessor = processors.getProcessor(ANY_ELEMENT); + if (anyElementProcessor != null) { + anyElementProcessor.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 InputStream. + * @param is The artifact InputStream + * @param type Model type + * @return The model + * @throws ContributionReadException + */ + public <M> M read(InputStream is, Class<M> 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 { + error("UnrecognizedElementException", reader, name); + UnrecognizedElementException e = new UnrecognizedElementException(name); + throw e; + } + } catch (ContributionReadException e) { + Location location = reader.getLocation(); + e.setLine(location.getLineNumber()); + e.setColumn(location.getColumnNumber()); + error("ContributionReadException", reader, e); + 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); + error("ContributionReadException", inputFactory, ce); + throw ce; + } + } + + /** + * Write a model to an OutputStream. + * @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) { + ContributionWriteException cw = new ContributionWriteException(e); + error("ContributionWriteException", outputFactory, cw); + throw cw; + } + } + + public QName getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java new file mode 100644 index 0000000000..48e80a073a --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java @@ -0,0 +1,243 @@ +/* + * 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.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.contribution.Constants; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible StAX attribute processor. + * + * Takes a StAXAttributeProcessorExtensionPoint and delegates to the proper + * StAXAttributeProcessor by attribute QName + * + * @version $Rev$ $Date$ + */ +public class ExtensibleStAXAttributeProcessor + implements StAXAttributeProcessor<Object> { + + private static final Logger logger = Logger.getLogger(ExtensibleStAXAttributeProcessor.class.getName()); + + private static final QName UNKNOWN_ATTRIBUTE = new QName(Constants.SCA10_TUSCANY_NS, "unknown"); + + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private StAXAttributeProcessorExtensionPoint processors; + private Monitor monitor; + + /** + * Constructs a new ExtensibleStAXArtifactProcessor. + * @param processors + * @param inputFactory + * @param outputFactory + */ + public ExtensibleStAXAttributeProcessor(StAXAttributeProcessorExtensionPoint processors, + XMLInputFactory inputFactory, + XMLOutputFactory outputFactory, + Monitor monitor) { + super(); + this.processors = processors; + this.inputFactory = inputFactory; + this.outputFactory = outputFactory; + if (this.outputFactory != null) { + this.outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE); + } + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void warning(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + + public Object read(QName attributeName, XMLStreamReader source) throws ContributionReadException, XMLStreamException { + + // Delegate to the processor associated with the attribute QName + int event = source.getEventType(); + if (event == XMLStreamConstants.START_DOCUMENT) { + source.nextTag(); + } + + StAXAttributeProcessor<?> processor = null; + + //lookup for registered attribute processors + processor = (StAXAttributeProcessor<?>)processors.getProcessor(attributeName); + if (processor == null) { + Location location = source.getLocation(); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Attribute " + attributeName + " cannot be processed. (" + location + ")"); + } + warning("AttributeCannotBeProcessed", processors, attributeName, location); + } else { + return processor.read(attributeName, source); + } + + + //handle extension attributes without processors + processor = (StAXAttributeProcessor<?>)processors.getProcessor(UNKNOWN_ATTRIBUTE); + if (processor == null) { + Location location = source.getLocation(); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Could not find Default Attribute processor !"); + } + warning("DefaultAttributeProcessorNotAvailable", processors, UNKNOWN_ATTRIBUTE, location); + } + + return processor == null ? null : processor.read(attributeName, source); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + + if(model == null) { + return; + } + + // Delegate to the processor associated with the model type + StAXAttributeProcessor processor = processors.getProcessor(model.getClass()); + if(processor == null) { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("No StAX processor is configured to handle " + model.getClass()); + } + warning("NoStaxProcessor", processors, model.getClass()); + } else { + processor.write(model, outputSource); + return; + } + + //handle extension attributes without processors + processor = (StAXAttributeProcessor<?>)processors.getProcessor(UNKNOWN_ATTRIBUTE); + if(processor == null) { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("No Default StAX processor is configured to handle " + model.getClass()); + } + warning("NoDefaultStaxProcessor", processors, model.getClass()); + } else { + processor.write(model, outputSource); + return; + } + } + + + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + + // Delegate to the processor associated with the model type + if (model != null) { + StAXAttributeProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.resolve(model, resolver); + } + } + } + + /** + * Read a model from an InputStream. + * @param is The artifact InputStream + * @param type Model type + * @return The model + * @throws ContributionReadException + */ + public <M> M read(InputStream is, Class<M> type) throws ContributionReadException { + return null; + } + + /** + * Write a model to an OutputStream. + * @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) { + ContributionWriteException cw = new ContributionWriteException(e); + error("ContributionWriteException", outputFactory, cw); + throw cw; + } + } + + public QName getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java new file mode 100644 index 0000000000..cc31d2e073 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java @@ -0,0 +1,139 @@ +/* + * 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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible URL artifact processor. + * + * Takes a URLArtifactProcessorExtensionPoint and delegates to the proper URLArtifactProcessor + * by either fileName or fileExtention + * + * @version $Rev$ $Date$ + */ +public class ExtensibleURLArtifactProcessor + implements URLArtifactProcessor<Object> { + + private URLArtifactProcessorExtensionPoint processors; + private Monitor monitor; + + /** + * Constructs a new ExtensibleURLArtifactProcessor. + * + * @param processors + */ + public ExtensibleURLArtifactProcessor(URLArtifactProcessorExtensionPoint processors, Monitor monitor) { + this.processors = processors; + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + @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 <M> M read(URL contributionURL, URI artifactURI, URL artifactUrl, Class<M> 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()); + error("UnrecognizedElementException", processors, artifactURI.toString()); + throw e; + } + } + + public String getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } + + /** + * Returns the file name from a URL. + * @param url + * @return + */ + private static String getFileName(URL url){ + String fileName = url.getPath(); + int pos = fileName.lastIndexOf("/"); + + return fileName.substring(pos +1); + } +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java new file mode 100644 index 0000000000..1bf9b4d494 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java @@ -0,0 +1,59 @@ +/* + * 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; + + +/** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..9700e2bc60 --- /dev/null +++ b/java/sca/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; + +/** + * An extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface StAXArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<StAXArtifactProcessor> { + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.java new file mode 100644 index 0000000000..b25bf0d669 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.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; + + + +/** + * An artifact processor that can read attributes from a StAX XMLStreamReader. + * + * @version $Rev$ $Date$ + */ +public interface StAXAttributeProcessor<M> extends ArtifactProcessor<M>{ + + /** + * Reads a model from an XMLStreamReader. + * + * @param reader The XMLStreamReader + * @return A model representation of the input. + */ + M read(QName attributeName, 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java new file mode 100644 index 0000000000..ebad243c1c --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.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; + +/** + * An extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface StAXAttributeProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<StAXAttributeProcessor> { + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java new file mode 100644 index 0000000000..c44ca0c66a --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.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; + +import java.net.URI; +import java.net.URL; + + +/** + * An artifact processor that can read models from a URL. + * + * @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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..7714586951 --- /dev/null +++ b/java/sca/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; + +/** + * An extension point for URL artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface URLArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<URLArtifactProcessor> { + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java new file mode 100644 index 0000000000..4c6f0b7282 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/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.processor; + +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); + 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java new file mode 100644 index 0000000000..8a166e42f0 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.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.processor; + + +/** + * 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. + * + * FIXME Don't use as it's deprecated and replaced by UnsupportedPackageTypeException. + * + * @version $Rev$ $Date$ + */ +@Deprecated +public class UnsupportedContentTypeException extends ContributionException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructs a new UnsupportedContentTypeException. + * + * @param message + */ + public UnsupportedContentTypeException(String message) { + super(message); + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java new file mode 100644 index 0000000000..ce94cef6a0 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java @@ -0,0 +1,40 @@ +/* + * 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; + + +/** + * 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 UnsupportedPackageTypeException extends ContributionException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructs a new UnsupportedPackageTypeException. + * + * @param message + */ + public UnsupportedPackageTypeException(String message) { + super(message); + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java new file mode 100644 index 0000000000..c0eef5a7a8 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java @@ -0,0 +1,30 @@ +/* + * 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.stream.XMLInputFactory; + +/** + * Base marker class for validating XML input factories. + * + * @version $Rev$ $Date$ + */ +public abstract class ValidatingXMLInputFactory extends XMLInputFactory { +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java new file mode 100644 index 0000000000..ee8fbba5a5 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java @@ -0,0 +1,387 @@ +/* + * 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.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +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$ + */ +class ValidatingXMLStreamReader extends StreamReaderDelegate implements XMLStreamReader { + private static final Logger logger = Logger.getLogger(ValidatingXMLStreamReader.class.getName()); + + private int level; + private ValidatorHandler handler; + private final Monitor monitor; + + /** + * Constructs a new ValidatingXMLStreamReader. + * + * @param reader + * @param schema + * @throws XMLStreamException + */ + ValidatingXMLStreamReader(XMLStreamReader reader, Schema schema, Monitor monitor) throws XMLStreamException { + super(reader); + this.monitor = monitor; + if (schema == null) { + return; + } + + handler = schema.newValidatorHandler(); + handler.setDocumentLocator(new LocatorAdapter()); + try { + handler.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + } catch (SAXException e) { + XMLStreamException xse = new XMLStreamException(e); + error("XMLStreamException", handler, xse); + throw xse; + } + + // 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 { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.error("SchemaError", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + + public void fatalError(SAXParseException exception) throws SAXException { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.error("SchemaFatalError", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + + public void warning(SAXParseException exception) throws SAXException { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.warning("SchemaWarning", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + }); + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void warning(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + @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) { + XMLStreamException xse = new XMLStreamException(e.getMessage(), e); + error("XMLStreamException", handler, xse); + throw xse; + } + 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) { + XMLStreamException xse = new XMLStreamException(e); + error("XMLStreamException", handler, xse); + throw xse; + } + 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; + } + } + } + + /** + * Handle a start element event. + * + * @throws SAXException + */ + 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); + } + + /** + * Handle an endElement event. + * + * @throws SAXException + */ + 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; + } + + /** + * Adapter for mapping Locator information. + */ + private final class LocatorAdapter implements Locator { + + private LocatorAdapter() { + } + + 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java new file mode 100644 index 0000000000..cc3bb59a5b --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.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.processor; + +import java.util.List; + + +/** + * An extension point for XML schemas used for validation. + * + * @version $Rev$ $Date$ + */ +public interface ValidationSchemaExtensionPoint { + + /** + * Add a schema. + * + * @param uri the URI of the schema + */ + void addSchema(String uri); + + /** + * Remove a schema. + * + * @param uri the URI of the schema + */ + void removeSchema(String uri); + + /** + * Returns the list of schemas registered in the extension point. + * @return the list of schemas + */ + List<String> getSchemas(); + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java new file mode 100644 index 0000000000..f3555ee71e --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java @@ -0,0 +1,107 @@ +/* + * 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; + +import org.apache.tuscany.sca.assembly.Base; + +/** + * A weak reference to a class, which should be used to register classes + * with an ArtifactResolver and resolve these classes later. + * + * FIXME The core contribution model should not have dependencies on classes + * and ClassLoaders. This should move to the Java import support module. + * + * @version $Rev$ $Date$ + */ +public class ClassReference implements Base { + + 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; + } + + public boolean isUnresolved() { + return clazz == null; + } + + public void setUnresolved(boolean unresolved) { + throw new IllegalStateException(); + } + + @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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java new file mode 100644 index 0000000000..13c622adf0 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java @@ -0,0 +1,68 @@ +/* + * 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; + +/** + * A model resolver implementation that delegates to a list of model resolvers. + * + * @version $Rev$ $Date$ + */ +public class DefaultDelegatingModelResolver implements ModelResolver { + + private List<ModelResolver> resolvers; + + public DefaultDelegatingModelResolver(List<ModelResolver> resolvers) { + this.resolvers = resolvers; + } + + 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 resolvers + for (ModelResolver resolver: resolvers) { + + Object resolved = resolver.resolveModel(modelClass, unresolved); + + // Return the resolved model object + if (resolved instanceof Base) { + if (!((Base)resolved).isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + + // Model object was not resolved + return unresolved; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java new file mode 100644 index 0000000000..c6facd2b02 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java @@ -0,0 +1,80 @@ +/*
+ * 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 a list of contributions.
+ *
+ * @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 the export, try to 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);
+ }
+ }
+ }
+ }
+ }
+
+ // Model object was not resolved
+ return unresolved;
+ }
+
+}
diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.java new file mode 100644 index 0000000000..9ae57c41d0 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.java @@ -0,0 +1,69 @@ +/* + * 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.Export; + +/** + * A model resolver implementation that delegates to a list of exports. + * + * @version $Rev$ $Date$ + */ +public class DefaultImportModelResolver implements ModelResolver { + + private List<Export> exports; + + public DefaultImportModelResolver(List<Export> exports) { + this.exports = exports; + } + + 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 exports + for (Export export: exports) { + + Object resolved = export.getModelResolver().resolveModel(modelClass, unresolved); + + // Return the resolved model object + if (resolved instanceof Base) { + if (!((Base)resolved).isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + + // Model object was not resolved + return unresolved; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.java new file mode 100644 index 0000000000..bf175813f3 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.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; + +import java.util.HashMap; +import java.util.Map; + + +/** + * A default implementation of a model resolver based on a map. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolver implements ModelResolver { + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + public DefaultModelResolver() { + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + + // Return the resolved object + return modelClass.cast(resolved); + + } else { + + // Return the unresolved object + return unresolved; + } + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + + // FIXME: TUSCANY-2499: temporarily give access to the models to get the jms binding + // use of definitions.xml working while the definitions.xml processing is being refactored + public Map getModels() { + return map; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java new file mode 100644 index 0000000000..878a2efdab --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java @@ -0,0 +1,114 @@ +/* + * 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.Map; +import java.util.Set; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + + +/** + * The default implementation of a model resolver extension point. + * + * @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, ServiceDeclaration> loadedResolvers; + + /** + * Constructs a new DefaultModelResolverExtensionPoint. + */ + public DefaultModelResolverExtensionPoint() { + } + + public void addResolver(Class<?> modelType, Class<? extends ModelResolver> resolver) { + resolvers.put(modelType, resolver); + } + + public void removeResolver(Class<?> modelType) { + resolvers.remove(modelType); + } + + @SuppressWarnings("unchecked") + 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) { + ServiceDeclaration resolverClass = loadedResolvers.get(c.getName()); + if (resolverClass != null) { + try { + return (Class<? extends ModelResolver>)resolverClass.loadClass(); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + } else { + return resolver; + } + } + + Class<? extends ModelResolver > resolver = resolvers.get(modelType); + if (resolver == null) { + ServiceDeclaration resolverClass = loadedResolvers.get(modelType.getName()); + if (resolverClass != null) { + try { + return (Class<? extends ModelResolver>)resolverClass.loadClass(); + } 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, ServiceDeclaration>(); + + // Get the model resolver service declarations + Set<ServiceDeclaration> modelResolverDeclarations; + try { + modelResolverDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ModelResolver.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Load model resolvers + for (ServiceDeclaration modelResolverDeclaration: modelResolverDeclarations) { + Map<String, String> attributes = modelResolverDeclaration.getAttributes(); + String model = attributes.get("model"); + + loadedResolvers.put(model, modelResolverDeclaration); + } + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java new file mode 100644 index 0000000000..b48742bcae --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java @@ -0,0 +1,200 @@ +/* + * 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.core.FactoryExtensionPoint; + +/** + * 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 resolverExtensions; + private final FactoryExtensionPoint modelFactories; + private final Contribution contribution; + private ModelResolver defaultResolver; + private final Map<Class<?>, ModelResolver> resolversByModelType = new HashMap<Class<?>, ModelResolver>(); + private final Map<Class<?>, ModelResolver> resolversByImplementationClass = new HashMap<Class<?>, ModelResolver>(); + private Map<Object, Object> map = new HashMap<Object, Object>(); + private Object lastUnresolved; + + /** + * Constructs an extensible model resolver + * + * @param contribution + * @param resolverExtensions + * @param modelFactories + * @param defaultResolver + */ + @Deprecated + public ExtensibleModelResolver(Contribution contribution, + ModelResolverExtensionPoint resolverExtensions, + FactoryExtensionPoint modelFactories, + ModelResolver defaultResolver) { + this.contribution = contribution; + this.resolverExtensions = resolverExtensions; + this.modelFactories = modelFactories; + //FIXME Remove this default resolver, this is currently used to resolve policy declarations + // but they should be handled by the contribution import/export mechanism instead of this + // defaultResolver hack. + this.defaultResolver = defaultResolver; + } + + /** + * Constructs an extensible model resolver + * + * @param resolverExtensions + * @param contribution + * @param modelFactories + */ + public ExtensibleModelResolver(Contribution contribution, + ModelResolverExtensionPoint resolverExtensions, + FactoryExtensionPoint modelFactories) { + this.contribution = contribution; + this.resolverExtensions = resolverExtensions; + this.modelFactories = modelFactories; + } + + /** + * 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 = resolversByModelType.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 = resolverExtensions.getResolver(c); + if (resolverClass != null) { + + // Construct the model resolver instance and cache it + resolverInstance = resolversByImplementationClass.get(resolverClass); + if (resolverInstance != null) { + resolversByModelType.put(c, resolverInstance); + return resolverInstance; + } + try { + Constructor<? extends ModelResolver> constructor = + resolverClass + .getConstructor(new Class[] {Contribution.class, FactoryExtensionPoint.class}); + if (constructor != null) { + + resolverInstance = constructor.newInstance(contribution, modelFactories); + resolversByImplementationClass.put(resolverClass, resolverInstance); + resolversByModelType.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) { + // Protect against dependency cycles causing infinite recursion + // Save the current unresolved object and check later if we are trying + // to resolve the same object again + if (unresolved == lastUnresolved) { + return unresolved; + } + lastUnresolved = unresolved; + + ModelResolver resolver = getModelResolverInstance(unresolved.getClass()); + if (resolver != null) { + Object resolved = resolver.resolveModel(modelClass, unresolved); + if (resolved != null && resolved != unresolved) { + lastUnresolved = null; + return modelClass.cast(resolved); + } + } else { + //FIXME Remove this default resolver, this is currently used to resolve policy declarations + // but they should be handled by the contribution import/export mechanism instead of this + // defaultResolver hack. + if (defaultResolver != null) { + Object resolved = defaultResolver.resolveModel(modelClass, unresolved); + if (resolved != null && resolved != unresolved) { + lastUnresolved = null; + return modelClass.cast(resolved); + } + } + + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + lastUnresolved = null; + return modelClass.cast(resolved); + } + } + + return unresolved; + } + + // FIXME: TUSCANY-2499: temporarily give access to the defaultResolver to get the jms binding + // use of definitions.xml working while the definitions.xml processing is being refactored + public ModelResolver getDefaultModelResolver() { + return defaultResolver; + } + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java new file mode 100644 index 0000000000..2831bebbc4 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java @@ -0,0 +1,69 @@ +/* + * 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; + +/** + * A model resolver, responsible for resolving models in the scope of an + * SCA contribution. + * + * SCA Assemblies reference 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 logical URIs. Model resolvers are used to resolve these references + * and get the in-memory models representing the referenced artifacts. + * + * @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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java new file mode 100644 index 0000000000..4a25059792 --- /dev/null +++ b/java/sca/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 model type as the key + * + * @param modelType The model type + * @param resolver The model resolver Class + */ + void addResolver(Class<?> modelType, Class <? extends ModelResolver> resolver); + + /** + * Remove the model resolver class for a specific model type + * + * @param modelType The model type + */ + void removeResolver(Class<?> modelType); + + /** + * Retrieve a model resolver class for a specific model type + * + * @param modelType The model artifact type + * @return The model resolver Class + */ + Class <? extends ModelResolver> getResolver(Class<?> modelType); +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java new file mode 100644 index 0000000000..74f0f2d71d --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java @@ -0,0 +1,45 @@ +/* + * 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; + +/** + * Extension to assembly model implementations to provide a model resolver. + * + * @version $Rev$ $Date$ + */ +public interface ResolverExtension { + + /** + * 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/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.java new file mode 100644 index 0000000000..2394f4510b --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.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.net.URL;
+
+/**
+ * A resource URL, which should be used to register resources
+ * with an ArtifactResolver and resolve these resources later.
+ *
+ * FIXME Don't use as its deprecated, use Artifact instead.
+ *
+ * @version $Rev$ $Date$
+ */
+@Deprecated
+public class ResourceReference {
+
+ private URL resourceURL;
+ private String resourceName;
+
+ /**
+ * Constructs a new ResourceReference.
+ *
+ * @param resourceName Name of resource
+ * @param resourceURL The resource URL
+ */
+ public ResourceReference(String resourceName, URL resourceURL) {
+ this.resourceURL = resourceURL;
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Constructs a new ResourceReference.
+ *
+ * @param resourceName Name of resource
+ */
+ public ResourceReference(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Get the resource URL.
+ *
+ * @return The resource URL
+ */
+ public URL getResource() {
+ return resourceURL;
+ }
+
+ /**
+ * Get the resource name.
+ *
+ * @return The resource name
+ */
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ /**
+ * Returns true if the resource reference is unresolved.
+ *
+ * @return Whether or not the resource has been resolved
+ */
+ public boolean isUnresolved() {
+ return resourceURL == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else {
+ if (obj instanceof ResourceReference) {
+ return resourceName.equals(((ResourceReference)obj).resourceName);
+ } else {
+ return false;
+ }
+ }
+ }
+
+}
diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.java new file mode 100644 index 0000000000..4e71e1ac30 --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.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.scanner; + +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.processor.ContributionException; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; + +/** + * Interface for contribution package scanners + * + * Contribution scanners understand the format of the contribution and how to get the + * artifacts in the contribution. + * + * @version $Rev$ $Date$ + */ +public interface ContributionScanner { + + /** + * Returns the type of package supported by this package scanner. + * + * @return the package type + */ + String getContributionType(); + + /** + * Returns a list of artifacts in the contribution. + * + * @param contributionURL Contribution URL + * @return List of artifact URIs + * @throws ContributionException + * @throws IOException + */ + List<String> getArtifacts(URL contributionURL) throws ContributionReadException; + + /** + * Return the URL for an artifact in the contribution. + * + * This is needed for archives such as jar files that have specific URL schemes + * for the artifacts they contain. + * + * @param contributionURL Contribution URL + * @param artifact The relative URI for the artifact + * @return The artifact URL + */ + URL getArtifactURL(URL contributionURL, String artifact) throws ContributionReadException; + +} diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.java new file mode 100644 index 0000000000..1ca9def4ea --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.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.scanner; + +/** + * An extension point for contribution scanners + * + * @version $Rev$ $Date$ + */ +public interface ContributionScannerExtensionPoint { + + /** + * Add a ContributionScanner using the contribution type as the key. + * + * @param scanner The contribution scanner + */ + void addContributionScanner(ContributionScanner scanner); + + /** + * Remove a ContributionScanner. + * + * @param scanner The contribution scanner + */ + void removeContributionScanner(ContributionScanner scanner); + + /** + * Returns the ContributionScanner for the given contribution type. + * + * @param contributionType The contribution type + * @return The contribution scanner + */ + ContributionScanner getContributionScanner(String contributionType); + +}
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java new file mode 100644 index 0000000000..cf3c77d5eb --- /dev/null +++ b/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java @@ -0,0 +1,125 @@ +/* + * 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.scanner; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of a contribution scanner extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionScannerExtensionPoint implements ContributionScannerExtensionPoint { + + private Map<String, ContributionScanner> scanners = new HashMap<String, ContributionScanner>(); + private boolean loaded; + + public DefaultContributionScannerExtensionPoint() { + } + + public void addContributionScanner(ContributionScanner scanner) { + scanners.put(scanner.getContributionType(), scanner); + } + + public void removeContributionScanner(ContributionScanner scanner) { + scanners.remove(scanner.getContributionType()); + } + + public ContributionScanner getContributionScanner(String contentType) { + loadScanners(); + return scanners.get(contentType); + } + + private void loadScanners() { + if (loaded) + return; + + // Get the scanner service declarations + Set<ServiceDeclaration> scannerDeclarations; + try { + scannerDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ContributionScanner.class.getName()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (ServiceDeclaration scannerDeclaration: scannerDeclarations) { + Map<String, String> attributes = scannerDeclaration.getAttributes(); + + // Load a URL artifact scanner + String contributionType = attributes.get("type"); + + // Create a scanner wrapper and register it + ContributionScanner scanner = new LazyContributionScanner(contributionType, scannerDeclaration); + addContributionScanner(scanner); + } + + loaded = true; + } + + /** + * A facade for contribution scanners. + */ + private static class LazyContributionScanner implements ContributionScanner { + + private ServiceDeclaration scannerDeclaration; + private String contributionType; + private ContributionScanner scanner; + + private LazyContributionScanner(String contributionType, ServiceDeclaration scannerDeclaration) { + this.scannerDeclaration = scannerDeclaration; + this.contributionType = contributionType; + } + + public URL getArtifactURL(URL contributionSourceURL, String artifact) throws ContributionReadException { + return getScanner().getArtifactURL(contributionSourceURL, artifact); + } + + public List<String> getArtifacts(URL contributionSourceURL) throws ContributionReadException { + return getScanner().getArtifacts(contributionSourceURL); + } + + public String getContributionType() { + return contributionType; + } + + private ContributionScanner getScanner() { + if (scanner == null) { + try { + Class<ContributionScanner> scannerClass = (Class<ContributionScanner>)scannerDeclaration.loadClass(); + Constructor<ContributionScanner> constructor = scannerClass.getConstructor(); + scanner = constructor.newInstance(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return scanner; + } + } +} diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory new file mode 100644 index 0000000000..bcc346d9f8 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.DefaultContributionFactory
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint new file mode 100644 index 0000000000..9e6433ba6c --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultContributionPostProcessorExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint new file mode 100644 index 0000000000..8ea5fc0a7e --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessorExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessorExtensionPoint new file mode 100644 index 0000000000..607725bcfe --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultStAXAttributeProcessorExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint new file mode 100644 index 0000000000..9d78ca93d0 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultURLArtifactProcessorExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory new file mode 100644 index 0000000000..f2856cb259 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory @@ -0,0 +1,17 @@ +# 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.
+org.apache.tuscany.sca.contribution.processor.DefaultValidatingXMLInputFactory
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint new file mode 100644 index 0000000000..ae6e876df6 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultValidationSchemaExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint new file mode 100644 index 0000000000..4bb65e55e7 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.resolver.DefaultModelResolverExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint new file mode 100644 index 0000000000..727f8f6ce7 --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.scanner.DefaultContributionScannerExtensionPoint
diff --git a/java/sca/modules/contribution/src/main/resources/contribution-validation-messages.properties b/java/sca/modules/contribution/src/main/resources/contribution-validation-messages.properties new file mode 100644 index 0000000000..4f9f85048e --- /dev/null +++ b/java/sca/modules/contribution/src/main/resources/contribution-validation-messages.properties @@ -0,0 +1,34 @@ +# +# +# 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. +# +# +SchemaError = XMLSchema validation error occured in: {0} ,line = {1}, column = {2}, Message = {3} +SchemaFatalError = XMLSchema validation fatal error occured in: {0} ,line = {1}, column = {2}, Message = {3} +SchemaWarning = XMLSchema validation warning occured in: {0} ,line = {1}, column = {2}, Message = {3} +UnsupportedPackageTypeException = Unsupported contribution package type: {0} +ElementCannotBeProcessed = Element {0} cannot be processed. ({1}) +AttributeCannotBeProcessed = Attribute {0} cannot be processed. ({1}) +NoStaxProcessor = No StAX processor is configured to handle {0} +ContributionWriteException = ContributionWriteException occured due to : +ContributionReadException = ContributionReadException occured due to : +UnrecognizedElementException = Unrecognized Element : {0} +IllegalArgumentException = Invalid qname: {0} +PrivilegedActionException = PrivilegedActionException occured due to : +AttributeCannotBeProcessed = Attribute {0} cannot be processed. ({1}) + diff --git a/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java new file mode 100644 index 0000000000..14b6b956da --- /dev/null +++ b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.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.processor; + +import static junit.framework.Assert.assertNotNull; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * URL Artifact Processor Extension Point test case + * Verifies the right registration and lookup for processors that handle filename and file types + * + * @version $Rev$ $Date$ + */ +public class URLartifactProcessorExtensionPointTestCase { + + private static URLArtifactProcessorExtensionPoint artifactProcessors; + + @BeforeClass + public static void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + artifactProcessors = new DefaultURLArtifactProcessorExtensionPoint(extensionPoints); + artifactProcessors.addArtifactProcessor(new FileTypeArtifactProcessor()); + artifactProcessors.addArtifactProcessor(new FileNameArtifactProcessor()); + } + + @Test + public final void testFileTypeProcessor() { + assertNotNull(artifactProcessors.getProcessor(".m1")); + } + + @Test + public final void testFileNameProcessor() { + assertNotNull(artifactProcessors.getProcessor("file.m2")); + + } + + /** + * Internal mock classes + * + */ + + private class M1 { + } + + private class M2 { + } + + private static class FileTypeArtifactProcessor implements URLArtifactProcessor<M1> { + public FileTypeArtifactProcessor() { + } + + public M1 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M1 m1, ModelResolver resolver) throws ContributionResolveException { + } + + public String getArtifactType() { + return ".m1"; + } + + public Class<M1> getModelType() { + return M1.class; + } + } + + private static class FileNameArtifactProcessor implements URLArtifactProcessor<M2> { + public FileNameArtifactProcessor() { + } + + public M2 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M2 m2, ModelResolver resolver) throws ContributionResolveException { + } + + public String getArtifactType() { + return "file.m2"; + } + + public Class<M2> getModelType() { + return M2.class; + } + } + +} diff --git a/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.java b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.java new file mode 100644 index 0000000000..f5b04f503c --- /dev/null +++ b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.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.resolver; + +import static junit.framework.Assert.assertTrue; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultContributionFactory; +import org.junit.Before; +import org.junit.Test; + +/** + * Test the default model resolver implementation. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolverTestCase { + + private ModelResolver resolver; + private ContributionFactory factory; + + @Before + public void setUp() throws Exception { + resolver = new DefaultModelResolver(); + factory = new DefaultContributionFactory(); + } + + @Test + public void testResolved() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + @Test + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + @Test + public void testResolvedArtifact() { + Artifact artifact = factory.createArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + Artifact x = factory.createArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(Artifact.class, x); + assertTrue(x == artifact); + } + + class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + +} diff --git a/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.java b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.java new file mode 100644 index 0000000000..e4082b3b85 --- /dev/null +++ b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.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.resolver; + +import static junit.framework.Assert.assertTrue; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultContributionFactory; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.DefaultFactoryExtensionPoint; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.junit.Before; +import org.junit.Test; + +/** + * Test DefaultArtifactResolver. + * + * @version $Rev$ $Date$ + */ +public class ExtensibleModelResolverTestCase { + private ExtensibleModelResolver resolver; + + private ContributionFactory factory; + + @Before + public void setUp() throws Exception { + + ModelResolverExtensionPoint resolvers = new DefaultModelResolverExtensionPoint(); + resolvers.addResolver(Model.class, TestModelResolver.class); + + FactoryExtensionPoint factories = new DefaultFactoryExtensionPoint(new DefaultExtensionPointRegistry()); + + resolver = new ExtensibleModelResolver(null, resolvers, factories, null); + + factory = new DefaultContributionFactory(); + } + + @Test + public void testResolvedDefault() { + OtherModel a = new OtherModel("a"); + resolver.addModel(a); + OtherModel x = new OtherModel("a"); + x = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == a); + } + + @Test + public void testResolvedRegisteredClass() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + @Test + public void testUnresolvedDefault() { + OtherModel x = new OtherModel("a"); + OtherModel y = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == y); + } + + @Test + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + @Test + public void testResolvedArtifact() { + Artifact artifact = factory.createArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + Artifact x = factory.createArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(Artifact.class, x); + assertTrue(x == artifact); + } + + private class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + + private class OtherModel { + private String name; + + OtherModel(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((OtherModel)obj).name); + } + } +} diff --git a/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java new file mode 100644 index 0000000000..cd586d3b2c --- /dev/null +++ b/java/sca/modules/contribution/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.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.resolver; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; + +/** + * A test implementation of a model resolver, based on a map. + * + * @version $Rev$ $Date$ + */ +public class TestModelResolver implements ModelResolver { + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + public TestModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) { + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + return modelClass.cast(resolved); + } + // Return the unresolved object + return unresolved; + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + +} diff --git a/java/sca/modules/contribution/src/test/resources/deployables/sample-calculator.jar b/java/sca/modules/contribution/src/test/resources/deployables/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/java/sca/modules/contribution/src/test/resources/deployables/sample-calculator.jar diff --git a/java/sca/modules/contribution/src/test/resources/repository/sample-calculator.jar b/java/sca/modules/contribution/src/test/resources/repository/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..9c46c679d2 --- /dev/null +++ b/java/sca/modules/contribution/src/test/resources/repository/sample-calculator.jar diff --git a/java/sca/modules/contribution/src/test/resources/test.composite b/java/sca/modules/contribution/src/test/resources/test.composite new file mode 100644 index 0000000000..1e09549194 --- /dev/null +++ b/java/sca/modules/contribution/src/test/resources/test.composite @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite>
+ This file just needs to exist
+</composite>
\ No newline at end of file diff --git a/java/sca/modules/contribution/src/test/resources/test.ext b/java/sca/modules/contribution/src/test/resources/test.ext new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/java/sca/modules/contribution/src/test/resources/test.ext |