diff options
Diffstat (limited to '')
181 files changed, 13536 insertions, 0 deletions
diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.java new file mode 100644 index 0000000000..e8597a55fc --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi; + +/** + * Base class providing a simple implementation of Lifecycle. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractLifecycle implements Lifecycle { + protected volatile int lifecycleState = UNINITIALIZED; + + public int getLifecycleState() { + return lifecycleState; + } + + /** + * Set the current state of the Lifecycle. + * + * @param lifecycleState the new state + */ + protected void setLifecycleState(int lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public void start() { + setLifecycleState(RUNNING); + } + + public void stop() { + setLifecycleState(STOPPED); + } + + /** + * Returns the current lifecycle as a String (for example, "RUNNING"). + * + * @return the current lifecycle as a String + */ + public String toString() { + switch (lifecycleState) { + case Lifecycle.CONFIG_ERROR: + return "CONFIG_ERROR"; + case Lifecycle.ERROR: + return "ERROR"; + case Lifecycle.INITIALIZING: + return "INITIALIZING"; + case Lifecycle.INITIALIZED: + return "INITIALIZED"; + case Lifecycle.RUNNING: + return "RUNNING"; + case Lifecycle.STOPPING: + return "STOPPING"; + case Lifecycle.STOPPED: + return "STOPPED"; + case Lifecycle.UNINITIALIZED: + return "UNINITIALIZED"; + default: + return "UNKNOWN"; + } + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.java new file mode 100644 index 0000000000..74a076778e --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.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.spi; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * The root exception for the runtime package. Exceptions occurring in the runtime are generally non-recoverable + * + * @version $Rev$ $Date$ + */ +public abstract class CoreRuntimeException extends TuscanyRuntimeException { + + public CoreRuntimeException() { + super(); + } + + public CoreRuntimeException(String message) { + super(message); + } + + public CoreRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public CoreRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.java new file mode 100644 index 0000000000..28bc8652b2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.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.spi; + +/** + * Denotes an invalid name + * + * @version $Rev$ $Date$ + */ +public class InvalidNameException extends CoreRuntimeException { + + public InvalidNameException() { + super(); + } + + public InvalidNameException(String message) { + super(message); + } + + public InvalidNameException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidNameException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.java new file mode 100644 index 0000000000..94e7d2027f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.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.spi; + +/** + * Implementations adhere to runtime lifecycle semantics + * + * @version $Rev$ $Date$ + */ +public interface Lifecycle { + /* A configuration error state */ + int CONFIG_ERROR = -1; + /* Has not been initialized */ + int UNINITIALIZED = 0; + /* In the process of being configured and initialized */ + int INITIALIZING = 1; + /* Instantiated and configured */ + int INITIALIZED = 2; + /* Configured and initialized */ + int RUNNING = 4; + /* In the process of being shutdown */ + int STOPPING = 5; + /* Has been shutdown and removed from the module */ + int STOPPED = 6; + /* In an error state */ + int ERROR = 7; + + /** + * Returns the lifecycle state + * + * @see #UNINITIALIZED + * @see #INITIALIZING + * @see #INITIALIZED + * @see #RUNNING + * @see #STOPPING + * @see #STOPPED + */ + int getLifecycleState(); + + /** + * Starts the Lifecycle. + * + * @throws CoreRuntimeException + */ + void start() throws CoreRuntimeException; + + /** + * Stops the Lifecycle. + * + * @throws CoreRuntimeException + */ + void stop() throws CoreRuntimeException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.java new file mode 100644 index 0000000000..635a5f9090 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.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.spi; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Denotes an error creating a new object instance + * + * @version $Rev$ $Date$ + */ +public class ObjectCreationException extends TuscanyRuntimeException { + private static final long serialVersionUID = -6423113430265944499L; + + public ObjectCreationException() { + super(); + } + + public ObjectCreationException(String message) { + super(message); + } + + public ObjectCreationException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectCreationException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java new file mode 100644 index 0000000000..d505e14f61 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java @@ -0,0 +1,35 @@ +/* + * 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.spi; + +/** + * Implementations create new instances of a particular type + * + * @version $Rev$ $Date$ + */ +public interface ObjectFactory<T> { + + /** + * Return a instance of the type that this factory creates. + * + * @return a instance from this factory + */ + T getInstance() throws ObjectCreationException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java new file mode 100644 index 0000000000..ec1c181afc --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi; + +/** + * An evaluated name consisting of a part/port pair. In the runtime, a part generally 'contains' or 'provides' ports + * such as a component/service point or a component/reference pair. + * + * @version $Rev$ $Date$ + */ +public class QualifiedName { + public static final String NAME_SEPARATOR = "/"; + + private String qName; + private String partName; + private String portName; + + /** + * Constructs a new qualified name in the form of part/port where part is the parent context and port represents a + * child, which is either a service in the case of an atomic context or a contained context in the case of a + * composite. + * + * @throws InvalidNameException if the name is in an invalid format + */ + public QualifiedName(String qualifiedName) throws InvalidNameException { + if (qualifiedName == null) { + return; + } + int pos = qualifiedName.indexOf(QualifiedName.NAME_SEPARATOR); + switch (pos) { + case -1: + partName = qualifiedName; + break; + case 0: + throw new InvalidNameException(qualifiedName); + default: + partName = qualifiedName.substring(0, pos); + portName = qualifiedName.substring(pos + 1); + break; + } + qName = qualifiedName; + } + + /** + * Returns the parsed part name + */ + public String getPartName() { + return partName; + } + + /** + * Returns the parsed port name if the original is of the compound for part/port + */ + public String getPortName() { + return portName; + } + + /** + * Returns the full part/port name pair + */ + public String getQualifiedName() { + return qName; + } + + public String toString() { + return qName; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/annotation/Autowire.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/annotation/Autowire.java new file mode 100644 index 0000000000..0e48f1bc1b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/annotation/Autowire.java @@ -0,0 +1,46 @@ +/* + * 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.spi.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * A system annotation to inject an autowired instance + * + * @version $Rev$ $Date$ + */ +@Target({METHOD, FIELD, PARAMETER}) +@Retention(RUNTIME) +public @interface Autowire { + /** + * The name of the autowire. If not specified then the name will be derived from the annotated field. + */ + String name() default ""; + + /** + * Indicates if a reference must be specified. + */ + boolean required() default true; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.java new file mode 100644 index 0000000000..5fd9be89b6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.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.spi.bootstrap; + +/** + * Class that defines the names of well known component + * + * @version $Rev$ $Date$ + */ +public final class ComponentNames { + /** + * The name of the component that forms the root of the runtime tree. + */ + public static final String TUSCANY_RUNTIME = "tuscany.runtime"; + + /** + * The name of the component that forms the root of the application context tree. + */ + public static final String TUSCANY_ROOT = "tuscany.root"; + + /** + * The name of the component that form the root of the system context tree. + */ + public static final String TUSCANY_SYSTEM = "tuscany.system"; + + /** + * The name of the component that contains the deployer. + */ + public static final String TUSCANY_DEPLOYER = "tuscany.deployer"; + + private ComponentNames() { + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/RuntimeComponent.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/RuntimeComponent.java new file mode 100644 index 0000000000..380abb474b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/bootstrap/RuntimeComponent.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.bootstrap; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.Deployer; + +/** + * Interface that represents the Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public interface RuntimeComponent extends CompositeComponent { + /** + * Returns the component that forms the root of the user component tree. All user components will be managed by + * composites that are children of this root. + * + * @return the root of the user component tree + */ + CompositeComponent getRootComponent(); + + /** + * Returns the component that forms the root of the system component tree. All system components, components that + * provide system services needed by the Tuscany runtime itself, will be managed by composites that are children of + * this root. + * + * @return the root of the system component tree + */ + CompositeComponent getSystemComponent(); + + /** + * Returns the deployer for this runtime. This interface can be used to deploy new SCA bundles to the runtime. + * + * @return the deployer for this runtime + */ + Deployer getDeployer(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.java new file mode 100644 index 0000000000..9586cdb6fd --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.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.spi.builder; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; + +/** + * Responsible for processing a service or reference in an assembly configured with a particular binding. The builder + * will create and return corresponding {@link org.apache.tuscany.spi.component.Service} or {@link + * org.apache.tuscany.spi.component.Reference} + * + * @version $Rev$ $Date$ + */ +public interface BindingBuilder<B extends Binding> { + Service build(CompositeComponent parent, + BoundServiceDefinition<B> boundServiceDefinition, + DeploymentContext deploymentContext); + + Reference build(CompositeComponent parent, + BoundReferenceDefinition<B> boundReferenceDefinition, + DeploymentContext deploymentContext); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindlessBuilder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindlessBuilder.java new file mode 100644 index 0000000000..94ddb39a59 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BindlessBuilder.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.spi.builder; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.BindlessServiceDefinition; +import org.apache.tuscany.spi.model.ReferenceDefinition; + +/** + * Responsible for processing a service or reference in an assembly configured without any binding. The builder + * will create and return corresponding {@link org.apache.tuscany.spi.component.Service} or {@link + * org.apache.tuscany.spi.component.Reference} + * + * @version $Rev$ $Date$ + */ +public interface BindlessBuilder { + + Service build(CompositeComponent parent, + BindlessServiceDefinition serviceDefinition, + DeploymentContext deploymentContext); + + Reference build(CompositeComponent parent, + ReferenceDefinition referenceDefinition, + DeploymentContext deploymentContext); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java new file mode 100644 index 0000000000..c1d314297e --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java @@ -0,0 +1,82 @@ +/* + * 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.spi.builder; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.BindlessServiceDefinition; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; + +/** + * Implementations build <code>SCAObject</code> types from model objects. + * + * @version $Rev$ $Date$ + */ +public interface Builder { + /** + * Builds a <code>Component</code> context from a <code>ComponentDefinition</code> + * + * @param parent the composite that will be the parent of the newly built component + * @param componentDefinition the component definition as parsed from an SCA assembly + * @param deploymentContext the current deployment context + * @return a newly created component + */ + <I extends Implementation<?>> Component build(CompositeComponent parent, + ComponentDefinition<I> componentDefinition, + DeploymentContext deploymentContext); + + /** + * TODO: JavaDoc this when we know if we will still register Services as contexts + */ + <B extends Binding> SCAObject build(CompositeComponent parent, + BoundServiceDefinition<B> boundServiceDefinition, + DeploymentContext deploymentContext); + + /** + * TODO: JavaDoc this when we know if we will still register References as contexts + */ + <B extends Binding> SCAObject build(CompositeComponent parent, + BoundReferenceDefinition<B> boundReferenceDefinition, + DeploymentContext deploymentContext); + + /** + * TODO: Make sure that this method belongs here + * Allow a builder registry to provide building of bindless services via + * appropriate registered builder + */ + SCAObject build(CompositeComponent parent, + BindlessServiceDefinition serviceDefinition, + DeploymentContext deploymentContext); + + /** + * TODO: Make sure that this method belongs here + * Allow a builder registry to provide building of targetless references via + * appropriate registered builder + */ + SCAObject build(CompositeComponent parent, + ReferenceDefinition referenceDefinition, + DeploymentContext deploymentContext); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.java new file mode 100644 index 0000000000..e4c07e53f9 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.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.spi.builder; + +/** + * Represents an error processing an assembly model + * + * @version $Rev$ $Date$ + */ +public class BuilderConfigException extends BuilderException { + + public BuilderConfigException() { + super(); + } + + public BuilderConfigException(String message) { + super(message); + } + + public BuilderConfigException(String message, Throwable cause) { + super(message, cause); + } + + public BuilderConfigException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.java new file mode 100644 index 0000000000..6e5e6ab124 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.builder; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * The root exception for the builder package. Builder exceptions denote a non-recoverable failure. + * + * @version $Rev$ $Date$ + */ +public abstract class BuilderException extends CoreRuntimeException { + + public BuilderException() { + super(); + } + + public BuilderException(String message) { + super(message); + } + + public BuilderException(String message, Throwable cause) { + super(message, cause); + } + + public BuilderException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.java new file mode 100644 index 0000000000..9d75f360d4 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.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.spi.builder; + +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Maintains a registry of builders in the runtime, dispatching to the appropriate one as an assembly model is processed + * into runtime artifacts + * + * @version $Rev$ $Date$ + */ +public interface BuilderRegistry extends Builder { + + /** + * Register a builder for an implementation type. + * + * @param implClass the type of implementation that this builder can handle + * @param builder the builder to be registered + */ + <I extends Implementation<?>> void register(Class<I> implClass, ComponentBuilder<I> builder); + + /** + * Unregister a builder for an implementation type. + * + * @param implClass the implementation whose builder should be unregistered + */ + <I extends Implementation<?>> void unregister(Class<I> implClass); + + /** + * TODO: JavaDoc this once we know if we will be building contexts for bindings + */ + <B extends Binding> void register(BindingBuilder<B> builder); + + /** + * TODO: JavaDoc this once we know if we will be building contexts for bindings + */ + <B extends Binding> void register(Class<B> implClass, BindingBuilder<B> builder); + + /** + * TODO: Make sure this belongs here + */ + void register(BindlessBuilder builder); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.java new file mode 100644 index 0000000000..ca1e25e8b1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.java @@ -0,0 +1,36 @@ +/* + * 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.spi.builder; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Responsible for building a {@link Component} from an atomic or composite component configured in an assembly + * + * @version $Rev$ $Date$ + */ +public interface ComponentBuilder<I extends Implementation<?>> { + Component build(CompositeComponent parent, + ComponentDefinition<I> componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.java new file mode 100644 index 0000000000..07ea5352ff --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; + +/** + * Implementations are responsible for bridging invocation chains as an assembly is converted to runtime artifacts + * + * @version $$Rev$$ $$Date$$ + */ +public interface Connector { + + /** + * Connects the given source's wires to corresponding wires to a target. Wires are connected by bridging invocation + * chains. + * + * @param source the source, i.e. a <code>Service</code>, <code>Component</code>, or <code>Reference</code> + */ + void connect(SCAObject source); + + /** + * Bridges the invocation chains associated with an inbound and outbound wire. + * + * @param inbound the wire to bridge from + * @param outbound the target wire + * @param optimizable if the bridge may be optimized + * @throws BuilderConfigException + */ + void connect(InboundWire inbound, OutboundWire outbound, boolean optimizable) + throws BuilderConfigException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java new file mode 100644 index 0000000000..78bb5a5cc8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java @@ -0,0 +1,35 @@ +/* + * 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.spi.builder; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidServiceInterfaceException extends BuilderConfigException { + private final Class<?> interfaceClass; + + public InvalidServiceInterfaceException(String message, Class<?> interfaceClass) { + super(message); + this.interfaceClass = interfaceClass; + } + + public Class<?> getInterfaceClass() { + return interfaceClass; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/PostProcessingException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/PostProcessingException.java new file mode 100644 index 0000000000..6868a7b2d5 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/PostProcessingException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +/** + * Denotes an error during post-processing of a wire + * + * @version $Rev$ $Date$ + */ +public class PostProcessingException extends BuilderException { + public PostProcessingException() { + } + + public PostProcessingException(String message) { + super(message); + } + + public PostProcessingException(String message, Throwable cause) { + super(message, cause); + } + + public PostProcessingException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessor.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessor.java new file mode 100644 index 0000000000..26de89a9f1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessor.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.spi.builder; + +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; + +/** + * Implementations are called after inbound and outbound wires are decorated with policy and before they are connected. + * + * @version $Rev$ $Date$ + */ +public interface WirePostProcessor { + + /** + * @param source + * @param target + */ + void process(OutboundWire source, InboundWire target); + + /** + * @param source + * @param target + */ + void process(InboundWire source, OutboundWire target); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorExtension.java new file mode 100644 index 0000000000..0795c5783a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorExtension.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.spi.builder; + +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.annotation.Autowire; + +@Scope("MODULE") +/** + * @version $Rev$ $Date$ + */ +public abstract class WirePostProcessorExtension implements WirePostProcessor { + + protected WirePostProcessorRegistry registry; + + @Autowire + public void setRegistry(WirePostProcessorRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void init() { + registry.register(this); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorRegistry.java new file mode 100644 index 0000000000..a1750943eb --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/builder/WirePostProcessorRegistry.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.spi.builder; + +/** + * Acts as a delegating <code>WirePostProcessor</code>, delegating post-processing of wires after policies have been + * applied and source an targets have been matched but before they are connected. + * + * @version $Rev$ $Date$ + */ +public interface WirePostProcessorRegistry extends WirePostProcessor { + + + /** + * Registers a post-processor in the runtime + * + * @param processor the processor to register + */ + void register(WirePostProcessor processor); + + /** + * De-registers a post-processor in the runtime + * + * @param processor the processor to de-register + */ + void unregister(WirePostProcessor processor); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.java new file mode 100644 index 0000000000..d7de7c0d6b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.java @@ -0,0 +1,122 @@ +/* + * 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.spi.component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.tuscany.spi.AbstractLifecycle; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.event.TrueFilter; + +/** + * Functionality common to all <code>SCAObject<code> implementations + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractSCAObject extends AbstractLifecycle implements SCAObject { + protected static final EventFilter TRUE_FILTER = new TrueFilter(); + + protected Map<EventFilter, List<RuntimeEventListener>> listeners; + protected final CompositeComponent parent; + private final String name; + private final Map<Object, Object> extensions = new HashMap<Object, Object>(); + + public AbstractSCAObject(String name, CompositeComponent parent) { + this.name = name; + this.parent = parent; + } + + public String getName() { + return name; + } + + public CompositeComponent getParent() { + return parent; + } + + public void addListener(RuntimeEventListener listener) { + addListener(TRUE_FILTER, listener); + } + + public void removeListener(RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + for (List<RuntimeEventListener> currentList : getListeners().values()) { + for (RuntimeEventListener current : currentList) { + if (current == listener) { + currentList.remove(current); + return; + } + } + } + } + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + List<RuntimeEventListener> list = getListeners().get(filter); + if (list == null) { + list = new CopyOnWriteArrayList<RuntimeEventListener>(); + listeners.put(filter, list); + } + list.add(listener); + } + } + + public void publish(Event event) { + assert event != null : "Event object was null"; + for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) { + if (entry.getKey().match(event)) { + for (RuntimeEventListener listener : entry.getValue()) { + listener.onEvent(event); + } + } + } + } + + protected Map<EventFilter, List<RuntimeEventListener>> getListeners() { + if (listeners == null) { + listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>(); + } + return listeners; + } + + public void prepare() { + + } + + public String toString() { + return "[" + name + "] in state [" + super.toString() + ']'; + } + + public Map<Object, Object> getExtensions() { + return extensions; + } + + public boolean isSystem() { + return false; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.java new file mode 100644 index 0000000000..532debddeb --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.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.spi.component; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * The runtime instantiation of an SCA atomic, or leaf-type, component + * + * @version $Rev$ $Date$ + */ +public interface AtomicComponent extends Component { + + /** + * Returns whether component instances should be eagerly initialized + */ + boolean isEagerInit(); + + /** + * Returns the initialization level for this component. + * + * @return the initialization level for this component + * @see org.apache.tuscany.spi.model.ComponentDefinition#getInitLevel() + */ + int getInitLevel(); + + /** + * Notifies the given instance of an initialization event + * + * @throws TargetException + */ + void init(Object instance) throws TargetException; + + /** + * Notifies the given instance of a destroy event + * + * @throws TargetException + */ + void destroy(Object instance) throws TargetException; + + /** + * Creates a new implementation instance, generally used as a callback by a {@link + * org.apache.tuscany.spi.component.ScopeContainer} + * + * @throws ObjectCreationException + */ + Object createInstance() throws ObjectCreationException; + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AutowireResolutionException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AutowireResolutionException.java new file mode 100644 index 0000000000..00e1392a9c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/AutowireResolutionException.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.spi.component; + +/** + * Denotes an exception while resolving an automatic wire + * + * @version $Rev$ $Date$ + */ +public class AutowireResolutionException extends TargetException { + + public AutowireResolutionException() { + super(); + } + + public AutowireResolutionException(String message) { + super(message); + } + + public AutowireResolutionException(String message, Throwable cause) { + super(message, cause); + } + + public AutowireResolutionException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Component.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Component.java new file mode 100644 index 0000000000..2f4453eb41 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Component.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * The runtime instantiation of an SCA component + * + * @version $$Rev$$ $$Date$$ + */ +public interface Component extends SCAObject { + + /** + * Returns a service associated with the given name + * + * @throws TargetException if an error occurs retrieving the service instance + */ + Object getServiceInstance(String name) throws TargetException; + + /** + * Returns the service interfaces implemented by the component + */ + List<Class<?>> getServiceInterfaces(); + + /** + * Adds a target-side wire. Target-side wire factories contain the invocation chains associated with the destination + * service of a wire + */ + void addInboundWire(InboundWire wire); + + /** + * Returns the target-side wire associated with the given service name + */ + InboundWire getInboundWire(String serviceName); + + /** + * Returns a map of inbound wires for a service. + */ + Map<String, InboundWire> getInboundWires(); + + /** + * Adds a source-side wire for the given reference. Source-side wires contain the invocation chains for a reference + * in the implementation associated with the instance wrapper created by this configuration. + */ + void addOutboundWire(OutboundWire wire); + + /** + * Adds a set of source-side multiplicity wires for the given reference. Source-side wires contain the invocation + * chains for a reference in the implementation associated with the instance wrapper created by this configuration. + */ + void addOutboundWires(Class<?> multiplicityClass, List<OutboundWire> wires); + + /** + * Returns a map of source-side wires for references. There may be 1..n wires per reference. + */ + Map<String, List<OutboundWire>> getOutboundWires(); + + /** + * Callback to create a {@link org.apache.tuscany.spi.wire.TargetInvoker} which dispatches to a service offered by + * the component + * + * @param targetName + * @param operation the operation to invoke + */ + TargetInvoker createTargetInvoker(String targetName, Operation operation); + + /** + * Callback to create a {@link org.apache.tuscany.spi.wire.TargetInvoker} which dispatches to a service offered by + * the component + * + * @param operation the operation to invoke + */ + TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentNotFoundException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentNotFoundException.java new file mode 100644 index 0000000000..a71fe5aeba --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentNotFoundException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when a component cannot be found + * + * @version $$Rev$$ $$Date$$ + */ +public class ComponentNotFoundException extends ComponentRuntimeException { + public ComponentNotFoundException() { + } + + public ComponentNotFoundException(String message) { + super(message); + } + + public ComponentNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ComponentNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.java new file mode 100644 index 0000000000..3b17229bed --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * An unchecked exception encountered by an {@link SCAObject} + * + * @version $Rev$ $Date$ + */ +public class ComponentRuntimeException extends CoreRuntimeException { + + public ComponentRuntimeException() { + super(); + } + + public ComponentRuntimeException(String message) { + super(message); + } + + public ComponentRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ComponentRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/CompositeComponent.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/CompositeComponent.java new file mode 100644 index 0000000000..1f847b319a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/CompositeComponent.java @@ -0,0 +1,184 @@ +/* + * 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.spi.component; + +import java.util.List; + +import org.w3c.dom.Document; + +import org.apache.tuscany.spi.event.RuntimeEventListener; + +/** + * The runtime instantiation of an SCA composite component. Composites may contain child components, offer services, and + * have references. Children are contained in two namespaces, an application namespace for end-user components deployed + * to a runtime, and a system namespace for components that provide system services. + * + * @version $Rev$ $Date$ + */ +public interface CompositeComponent extends Component, RuntimeEventListener { + + /** + * Registers a child of this composite. + * + * @param context the context to add as a child + * @throws InvalidComponentTypeException + */ + void register(SCAObject context) throws InvalidComponentTypeException; + + /** + * Register a simple Java Object as a system component. This is primarily intended for use by bootstrap code to + * create the initial configuration components. + * + * @param name the name of the resulting component + * @param service the service interface the component should expose + * @param instance the Object that will become the component's implementation + * @throws ObjectRegistrationException + */ + <S, I extends S> void registerJavaObject(String name, Class<S> service, I instance) + throws ObjectRegistrationException; + + /** + * Returns the child associated with a given name + */ + SCAObject getChild(String name); + + /** + * Returns the system child associated with a given name + */ + SCAObject getSystemChild(String name); + + /** + * Returns the children contained by the composite + */ + List<SCAObject> getChildren(); + + /** + * Returns the system children contained by the composite + */ + List<SCAObject> getSystemChildren(); + + /** + * Returns the services contained by the composite + */ + List<Service> getServices(); + + /** + * Returns the system services contained by the composite + */ + List<Service> getSystemServices(); + + /** + * Returns the service associated with the given name + * + * @throws ComponentNotFoundException + */ + Service getService(String name) throws ComponentNotFoundException; + + /** + * Returns the system service associated with the given name + * + * @throws ComponentNotFoundException + */ + Service getSystemService(String name) throws ComponentNotFoundException; + + /** + * Returns a system service associated with the given name + * + * @throws TargetException if an error occurs retrieving the service instance + */ + Object getSystemServiceInstance(String name) throws TargetException; + + /** + * Returns the references contained by the composite + */ + List<Reference> getReferences(); + + /** + * Returns the system references contained by the composite + */ + List<Reference> getSystemReferences(); + + /** + * Returns the service instance for associated with the child registered for the given name + */ + <T> T locateService(Class<T> serviceInterface, String serviceName); + + /** + * Returns the system service instance for associated with the child registered for the given name + */ + <T> T locateSystemService(Class<T> serviceInterface, String serviceName); + + /** + * @param scopeContainer + */ + void setScopeContainer(ScopeContainer scopeContainer); + + /** + * Returns the value of a Property of this composite. + * + * @param name the name of the Property + * @return its value, or null if there is not such property or if it has no defined value + */ + Document getPropertyValue(String name); + + /** + * Invoked by child components to return an an autowire target. Resolved targets may be services or components in + * the parent or its ancestors, or references in a sibling component + * + * @param instanceInterface the type of service being requested + * @return a reference to the requested service or null if none can be found + * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire + */ + <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException; + + /** + * Invoked by system child components to return an an autowire target. Resolved targets may be system services or + * components in the parent or its ancestors, or references in a sibling component + * + * @param instanceInterface the type of service being requested + * @return a reference to the requested service or null if none can be found + * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire + */ + <T> T resolveSystemInstance(Class<T> instanceInterface) throws AutowireResolutionException; + + /** + * Invoked by a parent component to return an autowire target in a child. Resolved targets must be services. For + * example, given a parent P and two siblings, A and B, A would request an autowire by invoking {@link + * #resolveInstance(Class<T>)} on P, which in turn could invoke the present method on B in order to resolve a + * target. + * + * @param instanceInterface the type of service being requested + * @return a reference to the requested service or null if none can be found + * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire + */ + <T> T resolveExternalInstance(Class<T> instanceInterface) throws AutowireResolutionException; + + /** + * Invoked by a parent component to return a system autowire target in a child. Resolved targets must be system + * services. For example, given a parent P and two siblings, A and B, A would request an autowire by invoking {@link + * #resolveInstance(Class<T>)} on P, which in turn could invoke the present method on B in order to resolve a + * target. + * + * @param instanceInterface the type of service being requested + * @return a reference to the requested service or null if none can be found + * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire + */ + <T> T resolveSystemExternalInstance(Class<T> instanceInterface) throws AutowireResolutionException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.java new file mode 100644 index 0000000000..f6c71b078b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.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.spi.component; + +/** + * Denotes an attempt to add an child to a composite component with a name equal to an existing child + * + * @version $Rev$ $Date$ + */ +public class DuplicateNameException extends ComponentRuntimeException { + + public DuplicateNameException() { + super(); + } + + public DuplicateNameException(String message) { + super(message); + } + + public DuplicateNameException(String message, Throwable cause) { + super(message, cause); + } + + public DuplicateNameException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java new file mode 100644 index 0000000000..8ed3f68e1f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when a target for an operation is not of the required type + * + * @version $$Rev$$ $$Date$$ + */ +public class IllegalTargetException extends TargetException { + public IllegalTargetException() { + } + + public IllegalTargetException(String message) { + super(message); + } + + public IllegalTargetException(String message, Throwable cause) { + super(message, cause); + } + + public IllegalTargetException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/InvalidComponentTypeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/InvalidComponentTypeException.java new file mode 100644 index 0000000000..6ad53f08b0 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/InvalidComponentTypeException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when an operation is attempted using the wrong context type + * + * @version $$Rev$$ $$Date$$ + */ +public class InvalidComponentTypeException extends ComponentRuntimeException { + public InvalidComponentTypeException() { + } + + public InvalidComponentTypeException(String message) { + super(message); + } + + public InvalidComponentTypeException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidComponentTypeException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ObjectRegistrationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ObjectRegistrationException.java new file mode 100644 index 0000000000..66547e3143 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ObjectRegistrationException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when an error is encountered registering an object + * + * @version $$Rev$$ $$Date$$ + */ +public class ObjectRegistrationException extends ComponentRuntimeException { + public ObjectRegistrationException() { + } + + public ObjectRegistrationException(String message) { + super(message); + } + + public ObjectRegistrationException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectRegistrationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Reference.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Reference.java new file mode 100644 index 0000000000..44eb112d56 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Reference.java @@ -0,0 +1,104 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireInvocationHandler; + +/** + * Manages an SCA reference configured with a binding + * + * @version $Rev$ $Date$ + */ +public interface Reference extends SCAObject { + + /** + * Returns the service interface configured for the reference + */ + Class<?> getInterface(); + + /** + * Returns the handler responsible for flowing a request through the reference + * + * @throws TargetException + */ + WireInvocationHandler getHandler() throws TargetException; + + /** + * Returns the inbound wire for flowing a request through the reference + */ + InboundWire getInboundWire(); + + /** + * Sets the inbound wire for flowing a request through the reference + */ + void setInboundWire(InboundWire wire); + + /** + * Returns the outbound wire used by the reference to connect to a target + */ + OutboundWire getOutboundWire(); + + /** + * Sets the outbound wire used by the reference to connect to a target + */ + void setOutboundWire(OutboundWire wire); + + /** + * Callback to create a {@link org.apache.tuscany.spi.wire.TargetInvoker} which dispatches to the target service of + * the reference + * + * @param contract the service contract to invoke on + * @param operation the operation to invoke + */ + TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation); + + /** + * Creates a target invoker for callbacks + */ + TargetInvoker createCallbackTargetInvoker(ServiceContract contract, Operation operation); + + /** + * Callback to create a {@link org.apache.tuscany.spi.wire.TargetInvoker} which issues a non-blocking dispatch + * + * @param wire the outbound wire of the invocation source, used for callbacks + * @param operation the operation to invoke + */ + TargetInvoker createAsyncTargetInvoker(OutboundWire wire, Operation operation); + + /** + * Get the ServiceContract for the binding + * @return + */ + ServiceContract<?> getBindingServiceContract(); + + + /** + * Set the ServiceContract for the binding. This contract will be used for the outbound wire. + * If not set, it will be the same as the ServideContract from the interface. + * + * @param serviceContract + */ + void setBindingServiceContract(ServiceContract<?> serviceContract); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceNotFoundException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceNotFoundException.java new file mode 100644 index 0000000000..7020ede3a5 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceNotFoundException.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.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Thrown when a component reference is not defined in the compoenent type + * + * @version $$Rev$$ $$Date$$ + */ +public class ReferenceNotFoundException extends CoreRuntimeException { + private static final long serialVersionUID = 737170534780079573L; + + public ReferenceNotFoundException() { + } + + public ReferenceNotFoundException(String message) { + super(message); + } + + public ReferenceNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ReferenceNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java new file mode 100644 index 0000000000..3a335a3200 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java @@ -0,0 +1,76 @@ +/* + * 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.spi.component; + +import java.util.Map; + +import org.apache.tuscany.spi.Lifecycle; +import org.apache.tuscany.spi.event.EventPublisher; +import org.apache.tuscany.spi.model.Scope; + +/** + * Represents the base SCA artifact type in an assembly + * + * @version $Rev$ $Date$ + */ +public interface SCAObject extends EventPublisher, Lifecycle { + + /** + * Returns the artifact name + */ + String getName(); + + /** + * Returns the parent composite, or null if the artifact does not have one + */ + CompositeComponent getParent(); + + /** + * Returns the artifact scope + */ + Scope getScope(); + + /** + * Returns an instance associated with the default service + * + * @throws TargetException if an error occurs retrieving the instance + */ + Object getServiceInstance() throws TargetException; + + /** + * Called to signal that the composite should perform and required steps prior to registration with its parent such + * as wiring of its children + */ + void prepare(); + + /** + * The extensions map contains other runtime context such as type systems for various databindings + * + * @return A live map of extended context + */ + Map<Object, Object> getExtensions(); + + /** + * Returns true if the artifact is a system artifact + * + * @return true if the artifact is a system artifact + */ + boolean isSystem(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.java new file mode 100644 index 0000000000..58ac3c6502 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.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.spi.component; + +import org.apache.tuscany.spi.Lifecycle; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; + + +/** + * Manages the lifecycle and visibility of instances associated with a set of {@link AtomicComponent}s. + * + * @version $Rev$ $Date$ + * @see SCAObject + */ +public interface ScopeContainer extends Lifecycle, RuntimeEventListener { + + /** + * Returns the scope value representing the scope context + */ + Scope getScope(); + + /** + * Sets the work context used by the scope container + */ + void setWorkContext(WorkContext workContext); + + /** + * Registers a component with the scope component + */ + void register(AtomicComponent component); + + /** + * Returns an instance associated with the current component + * + * @throws TargetException + */ + Object getInstance(AtomicComponent component) throws TargetException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeNotFoundException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeNotFoundException.java new file mode 100644 index 0000000000..b42e6afaeb --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeNotFoundException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Throw when a scope context cannot be found for a given scope + * + * @version $$Rev$$ $$Date$$ + */ +public class ScopeNotFoundException extends ScopeRuntimeException { + public ScopeNotFoundException() { + } + + public ScopeNotFoundException(String message) { + super(message); + } + + public ScopeNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ScopeNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.java new file mode 100644 index 0000000000..2f3fe47b72 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.java @@ -0,0 +1,37 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Scope; + +/** + * Manages {@link ScopeContainer}s in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface ScopeRegistry { + + ScopeContainer getScopeContainer(Scope scope) throws ScopeNotFoundException; + + <T extends ScopeContainer> void registerFactory(Scope scope, ObjectFactory<T> factory); + + void deregisterFactory(Scope scope); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRuntimeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRuntimeException.java new file mode 100644 index 0000000000..2724c34ffe --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRuntimeException.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.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Denotes a general runtime exception encountered by a scope context + * + * @version $Rev$ $Date$ + */ +public class ScopeRuntimeException extends CoreRuntimeException { + + public ScopeRuntimeException() { + super(); + } + + public ScopeRuntimeException(String message) { + super(message); + } + + public ScopeRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ScopeRuntimeException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Service.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Service.java new file mode 100644 index 0000000000..b165931ac0 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/Service.java @@ -0,0 +1,97 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireInvocationHandler; + +/** + * The runtime instantiation of an SCA service configured with a binding. + * + * @version $Rev$ $Date$ + */ +public interface Service extends SCAObject { + + /** + * Returns the handler responsible for flowing a request through the service + * + * @throws TargetException + */ + WireInvocationHandler getHandler() throws TargetException; + + /** + * Returns the service interface configured for the service + */ + Class<?> getInterface(); + + /** + * Returns the inbound wire for flowing a request through the service + * + * @return the inbound wire for flowing a request through the service + */ + InboundWire getInboundWire(); + + /** + * Sets the inbound wire for flowing a request through the service + * + * @param wire the inbound wire for flowing a request through the service + */ + void setInboundWire(InboundWire wire); + + /** + * Returns the outbound wire for flowing a request out of the service + * + * @return the outbound wire for flowing a request out of the service + */ + OutboundWire getOutboundWire(); + + /** + * Sets the outbound wire for flowing a request out of the service + * + * @param wire the outbound wire for flowing a request out of the service + */ + void setOutboundWire(OutboundWire wire); + + /** + * Returns the target invoker for dispatching callback invocations + * + * @param contract the callback contract + * @param operation the callback operation the target invoker dispatches to + */ + TargetInvoker createCallbackTargetInvoker(ServiceContract contract, Operation operation); + + /** + * Get the ServiceContract for the binding + * @return + */ + ServiceContract<?> getBindingServiceContract(); + + + /** + * Set the ServiceContract for the binding. This contract will be used for the inbound wire. + * If not set, it will be the same as the ServideContract from the interface. + + * @param serviceContract + */ + void setBindingServiceContract(ServiceContract<?> serviceContract); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SystemAtomicComponent.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SystemAtomicComponent.java new file mode 100644 index 0000000000..2c7376f5fb --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/SystemAtomicComponent.java @@ -0,0 +1,37 @@ +/* + * 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.spi.component; + +/** + * Implementations are specialized atomic components used to provide system services by the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface SystemAtomicComponent extends AtomicComponent { + + /** + * Returns the target instance associated with the component. A target instance is the actual object a request is + * dispatched to sans wire chain. + * + * @throws org.apache.tuscany.spi.component.TargetException + * + */ + Object getTargetInstance() throws TargetException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.java new file mode 100644 index 0000000000..3c0bf22dd0 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Denotes an error while performing an operation on a target component implementation instance or proxy + * + * @version $Rev$ $Date$ + */ +public class TargetException extends CoreRuntimeException { + + public TargetException() { + super(); + } + + public TargetException(String message) { + super(message); + } + + public TargetException(String message, Throwable cause) { + super(message, cause); + } + + public TargetException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java new file mode 100644 index 0000000000..1dc67f046d --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when a target of an operation cannot be found + * + * @version $$Rev$$ $$Date$$ + */ +public class TargetNotFoundException extends TargetException { + public TargetNotFoundException() { + } + + public TargetNotFoundException(String message) { + super(message); + } + + public TargetNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public TargetNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.java new file mode 100644 index 0000000000..fed65a039b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.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.spi.component; + +/** + * Implementations track information associated with a request as it is processed by the runtime + * + * @version $Rev$ $Date$ + */ +public interface WorkContext { + + Object getCurrentMessageId(); + + void setCurrentMessageId(Object messageId); + + Object getCurrentCorrelationId(); + + void setCurrentCorrelationId(Object correlationId); + + /** + * Returns the composite where a remote request came in + */ + CompositeComponent getRemoteComponent(); + + /** + * Sets the composite where a remote request came in + */ + void setRemoteComponent(CompositeComponent component); + + /** + * Returns the unique key for the given identifier associated with the current request + */ + Object getIdentifier(Object type); + + /** + * Sets the unique key for the given identifier associated with the current request + */ + void setIdentifier(Object type, Object identifier); + + /** + * Clears the unique key for the given identifier associated with the current request + */ + void clearIdentifier(Object type); + + /** + * Clears all identifiers associated with the current request + */ + void clearIdentifiers(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.java new file mode 100644 index 0000000000..2f48aa2292 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.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.spi.databinding; + +import org.apache.tuscany.spi.model.DataType; + +/** + * DataBinding represents a data representation, for example, SDO, JAXB and AXIOM + */ +public interface DataBinding { + /** + * The name of a databinding should be case-insensitive and unique + * + * @return The name of the databinding + */ + String getName(); + + /** + * Introspect a java class or interface to create a DataType model + * + * @param javaType The java class or interface to be introspected + * @return The DataType or null if the java type is not supported by this databinding + */ + DataType introspect(Class<?> javaType); + + /** + * Introspect the data to figure out the corresponding data type + * + * @param value The object to be checked + * @return The DataType or null if the java type is not supported by this databinding + */ + DataType introspect(Object value); + + /** + * Provide a WrapperHandler for this databinding + * @return A wrapper handler which can handle wrapping/wrapping for this databinding + */ + WrapperHandler getWrapperHandler(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.java new file mode 100644 index 0000000000..ba47401cc2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.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.spi.databinding; + +import org.apache.tuscany.spi.model.DataType; + +/** + * The registry for data bindings + */ +public interface DataBindingRegistry { + /** + * Register a data binding + * + * @param dataBinding + */ + void register(DataBinding dataBinding); + + /** + * Look up a data binding by id + * + * @param id The name of the databinding + * @return The databinding + */ + DataBinding getDataBinding(String id); + + /** + * Unregister a data binding + * + * @param id + * @return The unregistered databinding + */ + DataBinding unregister(String id); + + /** + * Introspect the java class to figure out what DataType supports it + * + * @param javaType The java class or interface + * @return A DataType representing the java type or null if no databinding + * recognizes the java type + */ + DataType introspectType(Class<?> javaType); + + /** + * Introspect the value to figure out the corresponding DataType + * + * @param value The object value + * @return A DataType representing the value or null if no databinding + * recognizes the value + */ + DataType introspectType(Object value); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.java new file mode 100755 index 0000000000..a0eb7ac10d --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.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.spi.databinding; + +/** + * Data pipe allows a data source pushes data into its sink and pipe the data into its result + * + * @param <S> The data binding type of the sink + * @param <R> The data binding type of the result + */ +public interface DataPipe<S, R> extends Transformer { + + /** + * Returns a sink (for example, java.io.OutputStream, java.io.Writer or org.xml.sax.ContentHandler) to receive data + * pushed by the source + * + * @return The sink to consume data + */ + S getSink(); + + /** + * Returns the data populated by the sink + * + * @return + */ + R getResult(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.java new file mode 100755 index 0000000000..ba936b46db --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.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.spi.databinding; + +import java.util.Map; + +import org.apache.tuscany.spi.model.DataType; + +/** + * This interface will be used as a Tuscany system service to perform data mediations + * + * Mediate the data from one type to the other one + * + */ +public interface Mediator { + + /** + * Mediate the data from the source type to the target type + * @param source The data to be mediated + * @param sourceDataType Data type for the source data + * @param targetDataType Data type for the target data + * @param context + * @return + */ + Object mediate(Object source, DataType sourceDataType, DataType targetDataType, Map<Class<?>, Object> context); + /** + * Mediate the source data into the target which is a sink to receive the data + * @param source The data to be mediated + * @param target The sink to receive data + * @param sourceDataType Data type for the source data + * @param targetDataType Data type for the target data + */ + void mediate( + Object source, + Object target, + DataType sourceDataType, + DataType targetDataType, + Map<Class<?>, Object> context); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java new file mode 100644 index 0000000000..21e8cc2750 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java @@ -0,0 +1,36 @@ +/* + * 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.spi.databinding; + +/** + * PullTransformer transforms data from one binding format to the other one which can be directly consumed + * + * @param <S> The source data type + * @param <R> the target data type + */ +public interface PullTransformer<S, R> extends Transformer { + /** + * Transform source data into the result type. + * + * @param source The source data + * @param context The context for the transformation + * @return The transformed result + */ + R transform(S source, TransformationContext context); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.java new file mode 100644 index 0000000000..d68b6aa772 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.java @@ -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. + */ +package org.apache.tuscany.spi.databinding; + +/** + * A transformer that pushes data from its source into the sink + * + * @param <S> + * @param <R> + */ +public interface PushTransformer<S, R> extends Transformer { + /** + * @param source The source data + * @param sink The sink to receive the data + * @param context + */ + void transform(S source, R sink, TransformationContext context); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.java new file mode 100644 index 0000000000..7c0bf4d01a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.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.spi.databinding; + +import org.apache.tuscany.spi.idl.TypeInfo; + +/** + * Type Mapper between XML schema simple data types and java objects + */ +public interface SimpleTypeMapper { + /** + * Parse the XML lexical representation into a java object + * @param simpleType The XSD simple type + * @param value the XML lexical representation + * @param context The context of the transformation + * @return A java object for the XML value + */ + Object toJavaObject(TypeInfo simpleType, String value, TransformationContext context); + /** + * Create the XML lexical representation for a java object + * @param simpleType The XSD simple type + * @param obj The java object + * @param context The context of the transformation + * @return The XML lexical representation + */ + String toXMLLiteral(TypeInfo simpleType, Object obj, TransformationContext context); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.java new file mode 100755 index 0000000000..8287de1707 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.java @@ -0,0 +1,72 @@ +/* + * 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.spi.databinding; + +import java.util.Map; + +import org.apache.tuscany.spi.model.DataType; + +/** + * Context for data transformation + * + */ +public interface TransformationContext { + /** + * Get the source data type + * + * @return + */ + DataType getSourceDataType(); + + /** + * Get the target data type + * + * @return + */ + DataType getTargetDataType(); + + /** + * Set the source data type + * + * @param sourceDataType + */ + void setSourceDataType(DataType sourceDataType); + + /** + * Set the target data type + * + * @param targetDataType + */ + void setTargetDataType(DataType targetDataType); + + /** + * Get the classloader + * + * @return + */ + ClassLoader getClassLoader(); + + /** + * Get a map of metadata + * + * @return + */ + Map<Class<?>, Object> getMetadata(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java new file mode 100755 index 0000000000..9b57e1cf70 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.databinding; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Reports problems during data transformation + */ +public class TransformationException extends TuscanyRuntimeException { + + private static final long serialVersionUID = 7662385613693006428L; + + public TransformationException() { + super(); + } + + public TransformationException(String message, Throwable cause) { + super(message, cause); + } + + public TransformationException(String message) { + super(message); + } + + public TransformationException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java new file mode 100755 index 0000000000..2f969e979d --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.databinding; + +/** + * A transformer provides the data transformation from source type to target type. The cost of the transformation is + * modeled as weight. + */ +public interface Transformer { + /** + * Get the source type that this transformer transforms data from. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @return A key indentifying the source type + */ + String getSourceDataBinding(); + + /** + * Get the target type that this transformer transforms data into. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @return A key indentifying the target type + */ + String getTargetDataBinding(); + + /** + * Get the cost of the transformation. The weight can be used to choose the most efficient path if there are more + * than one available from the source to the target. + * + * @return An integer representing the cost of the transformation + */ + int getWeight(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java new file mode 100755 index 0000000000..5381dfa081 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java @@ -0,0 +1,75 @@ +/* + * 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.spi.databinding; + +import java.util.List; + +/** + * Registry for data transformers + */ +public interface TransformerRegistry { + /** + * Register a transformer + * + * @param sourceDataBinding + * @param targetDataBinding + * @param weight + * @param transformer + */ + void registerTransformer(String sourceDataBinding, + String targetDataBinding, + int weight, + Transformer transformer); + + /** + * Register a transformer + * + * @param transformer + */ + void registerTransformer(Transformer transformer); + + /** + * Unregister a transformer + * + * @param sourceDataBinding + * @param targetDataBinding + * @return + */ + boolean unregisterTransformer(String sourceDataBinding, String targetDataBinding); + + /** + * Get the direct Transformer which can transform data from source type to + * result type + * + * @param sourceDataBinding + * @param targetDataBinding + * @return + */ + Transformer getTransformer(String sourceDataBinding, String targetDataBinding); + + /** + * Get the a chain of Transformers which can transform data from source type + * to result type + * + * @param sourceDataBinding + * @param targetDataBinding + * @return + */ + List<Transformer> getTransformerChain(String sourceDataBinding, String targetDataBinding); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.java new file mode 100644 index 0000000000..e60cb2af92 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.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.spi.databinding; + +import org.apache.tuscany.spi.idl.ElementInfo; + +/** + * A contract for transformers to deal with wrapping/unwrapping for WSDL wrapper style operations + */ +public interface WrapperHandler<T> { + /** + * Create a wrapper element + * + * @param element The XSD element + * @param context The transformation context + * @return An object representing the wrapper element + */ + T create(ElementInfo element, TransformationContext context); + + /** + * Set child element for the wrapper + * + * @param wrapper The wrapper + * @param i The index + * @param childElement The XSD element + * @param value The value of the child + */ + void setChild(T wrapper, int i, ElementInfo childElement, Object value); + + /** + * Get child element from the wrapper + * + * @param wrapper The wrapper + * @param i The index + * @param element The XSD element + * @return The value of the child + */ + Object getChild(T wrapper, int i, ElementInfo element); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.java new file mode 100644 index 0000000000..2b927b8e55 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.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.spi.databinding.extension; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Helper for DOM + */ +public final class DOMHelper { + private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance(); + static { + FACTORY.setNamespaceAware(true); + } + + private DOMHelper() { + } + + public static Document newDocument() throws ParserConfigurationException { + return newDocumentBuilder().newDocument(); + } + + public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { + return FACTORY.newDocumentBuilder(); + } + + public static QName getQName(Node node) { + String ns = node.getNamespaceURI(); + if (ns == null) { + ns = ""; + } + // node.getLocalName() will return null if it is created using DOM Level + // 1 method + // such as createElement() + return new QName(ns, node.getNodeName()); + } + + public static Element createElement(Document document, QName name) { + String prefix = name.getPrefix(); + String qname = + (prefix != null && prefix.length() > 0) ? prefix + ":" + name.getLocalPart() : name + .getLocalPart(); + return document.createElementNS(name.getNamespaceURI(), qname); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java new file mode 100644 index 0000000000..e40b75de55 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java @@ -0,0 +1,104 @@ +/* + * 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.spi.databinding.extension; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.model.DataType; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Base Implementation of DataBinding + */ +@Scope("MODULE") +@Service(DataBinding.class) +public abstract class DataBindingExtension implements DataBinding { + protected DataBindingRegistry registry; + + protected Class<?> baseType; + + protected String name; + + /** + * Create a databinding with the base java type whose name will be used as + * the name of the databinding + * + * @param baseType The base java class or interface representing the + * databinding, for example, org.w3c.dom.Node + */ + protected DataBindingExtension(Class<?> baseType) { + this(baseType.getName(), baseType); + } + + /** + * Create a databinding with the name and base java type + * + * @param name The name of the databinding + * @param baseType The base java class or interface representing the + * databinding, for example, org.w3c.dom.Node + */ + protected DataBindingExtension(String name, Class<?> baseType) { + this.name = name; + this.baseType = baseType; + } + + @Autowire + public void setDataBindingRegistry(DataBindingRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void init() { + registry.register(this); + } + + public DataType introspect(Class<?> javaType) { + if (baseType == null || javaType == null) { + return null; + } + if (baseType.isAssignableFrom(javaType)) { + return new DataType<Class>(name, javaType, baseType); + } else { + return null; + } + } + + public DataType introspect(Object value) { + if (value == null) { + return null; + } else { + return introspect(value.getClass()); + } + } + + public final String getName() { + return name; + } + + /** + * @see org.apache.tuscany.spi.databinding.DataBinding#getWrapperHandler() + */ + public WrapperHandler getWrapperHandler() { + return null; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.java new file mode 100644 index 0000000000..4605f945e2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.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.spi.databinding.extension; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.idl.ElementInfo; +import org.apache.tuscany.spi.idl.TypeInfo; + +/** + * Transformer to convert data from a simple java object to a databinding's representation + */ +public abstract class Java2SimpleTypeTransformer<T> extends TransformerExtension<Object, T> implements + PullTransformer<Object, T> { + + protected SimpleTypeMapper mapper; + + public Java2SimpleTypeTransformer() { + this.mapper = new SimpleTypeMapperExtension(); + } + + public Java2SimpleTypeTransformer(SimpleTypeMapper mapper) { + this.mapper = (mapper != null) ? mapper : new SimpleTypeMapperExtension(); + } + + public T transform(Object source, TransformationContext context) { + ElementInfo element = + (ElementInfo) context.getTargetDataType().getMetadata(ElementInfo.class.getName()); + TypeInfo simpleType = (TypeInfo) element.getType(); + String text = mapper.toXMLLiteral(simpleType, source, context); + return createElement(element, text, context); + } + + public Class getSourceType() { + return Object.class; + } + + public int getWeight() { + return 10000; + } + + protected abstract T createElement(ElementInfo element, String literal, TransformationContext context); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.java new file mode 100644 index 0000000000..d861bdce92 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.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.spi.databinding.extension; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.idl.ElementInfo; +import org.apache.tuscany.spi.idl.TypeInfo; + +/** + * Transformer to convert data from a databinding's representation of simple + * types to Java Objects + */ +public abstract class SimpleType2JavaTransformer<T> extends TransformerExtension<T, Object> implements + PullTransformer<T, Object> { + + protected SimpleTypeMapper mapper; + + public SimpleType2JavaTransformer() { + this.mapper = new SimpleTypeMapperExtension(); + } + + public SimpleType2JavaTransformer(SimpleTypeMapper mapper) { + this.mapper = (mapper != null) ? mapper : new SimpleTypeMapperExtension(); + } + + public Object transform(T source, TransformationContext context) { + TypeInfo simpleType = (TypeInfo)context.getSourceDataType().getMetadata(TypeInfo.class.getName()); + if (simpleType == null) { + ElementInfo element = + (ElementInfo)context.getSourceDataType().getMetadata(ElementInfo.class.getName()); + simpleType = (TypeInfo)element.getType(); + } + return mapper.toJavaObject(simpleType, getText(source), context); + } + + public Class getTargetType() { + return Object.class; + } + + public int getWeight() { + // Cannot be used for imtermediate + return 10000; + } + + /** + * Get the string value from the source + * @param source + * @return A string + */ + protected abstract String getText(T source); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java new file mode 100644 index 0000000000..40dca934d5 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java @@ -0,0 +1,391 @@ +/* + * 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.spi.databinding.extension; + +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.idl.TypeInfo; + +public class SimpleTypeMapperExtension extends XSDDataTypeConverter implements SimpleTypeMapper { + public static final Map<Class, String> JAVA2XML = new HashMap<Class, String>(); + + public static final String URI_2001_SCHEMA_XSD = "http://www.w3.org/2001/XMLSchema"; + + public static final Map<String, Class> XML2JAVA = new HashMap<String, Class>(); + + public static final QName XSD_ANY = new QName(URI_2001_SCHEMA_XSD, "any"); + + public static final QName XSD_ANYSIMPLETYPE = new QName(URI_2001_SCHEMA_XSD, "anySimpleType"); + + public static final QName XSD_ANYTYPE = new QName(URI_2001_SCHEMA_XSD, "anyType"); + + public static final QName XSD_ANYURI = new QName(URI_2001_SCHEMA_XSD, "anyURI"); + + public static final QName XSD_BASE64 = new QName(URI_2001_SCHEMA_XSD, "base64Binary"); + + public static final QName XSD_BOOLEAN = new QName(URI_2001_SCHEMA_XSD, "boolean"); + + public static final QName XSD_BYTE = new QName(URI_2001_SCHEMA_XSD, "byte"); + + public static final QName XSD_DATE = new QName(URI_2001_SCHEMA_XSD, "date"); + + public static final QName XSD_DATETIME = new QName(URI_2001_SCHEMA_XSD, "dateTime"); + + public static final QName XSD_DAY = new QName(URI_2001_SCHEMA_XSD, "gDay"); + + public static final QName XSD_DECIMAL = new QName(URI_2001_SCHEMA_XSD, "decimal"); + + public static final QName XSD_DOUBLE = new QName(URI_2001_SCHEMA_XSD, "double"); + + public static final QName XSD_DURATION = new QName(URI_2001_SCHEMA_XSD, "duration"); + + public static final QName XSD_ENTITIES = new QName(URI_2001_SCHEMA_XSD, "ENTITIES"); + + public static final QName XSD_ENTITY = new QName(URI_2001_SCHEMA_XSD, "ENTITY"); + + public static final QName XSD_FLOAT = new QName(URI_2001_SCHEMA_XSD, "float"); + + public static final QName XSD_HEXBIN = new QName(URI_2001_SCHEMA_XSD, "hexBinary"); + + public static final QName XSD_IDREF = new QName(URI_2001_SCHEMA_XSD, "IDREF"); + + public static final QName XSD_IDREFS = new QName(URI_2001_SCHEMA_XSD, "IDREFS"); + + public static final QName XSD_INT = new QName(URI_2001_SCHEMA_XSD, "int"); + + public static final QName XSD_INTEGER = new QName(URI_2001_SCHEMA_XSD, "integer"); + + public static final QName XSD_LONG = new QName(URI_2001_SCHEMA_XSD, "long"); + + public static final QName XSD_MONTH = new QName(URI_2001_SCHEMA_XSD, "gMonth"); + + public static final QName XSD_MONTHDAY = new QName(URI_2001_SCHEMA_XSD, "gMonthDay"); + + public static final QName XSD_NAME = new QName(URI_2001_SCHEMA_XSD, "Name"); + + public static final QName XSD_NCNAME = new QName(URI_2001_SCHEMA_XSD, "NCName"); + + public static final QName XSD_NEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "negativeInteger"); + + public static final QName XSD_NMTOKEN = new QName(URI_2001_SCHEMA_XSD, "NMTOKEN"); + + public static final QName XSD_NMTOKENS = new QName(URI_2001_SCHEMA_XSD, "NMTOKENS"); + + public static final QName XSD_NONNEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonNegativeInteger"); + + public static final QName XSD_NONPOSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonPositiveInteger"); + + public static final QName XSD_NORMALIZEDSTRING = new QName(URI_2001_SCHEMA_XSD, "normalizedString"); + + public static final QName XSD_NOTATION = new QName(URI_2001_SCHEMA_XSD, "NOTATION"); + + public static final QName XSD_POSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "positiveInteger"); + + public static final QName XSD_QNAME = new QName(URI_2001_SCHEMA_XSD, "QName"); + + public static final QName XSD_SHORT = new QName(URI_2001_SCHEMA_XSD, "short"); + + public static final Map<String, TypeInfo> XSD_SIMPLE_TYPES = new HashMap<String, TypeInfo>(); + + public static final QName XSD_STRING = new QName(URI_2001_SCHEMA_XSD, "string"); + + public static final QName XSD_TIME = new QName(URI_2001_SCHEMA_XSD, "time"); + + public static final QName XSD_TOKEN = new QName(URI_2001_SCHEMA_XSD, "token"); + + public static final QName XSD_UNSIGNEDBYTE = new QName(URI_2001_SCHEMA_XSD, "unsignedByte"); + + public static final QName XSD_UNSIGNEDINT = new QName(URI_2001_SCHEMA_XSD, "unsignedInt"); + + public static final QName XSD_UNSIGNEDLONG = new QName(URI_2001_SCHEMA_XSD, "unsignedLong"); + + public static final QName XSD_UNSIGNEDSHORT = new QName(URI_2001_SCHEMA_XSD, "unsignedShort"); + + public static final QName XSD_YEAR = new QName(URI_2001_SCHEMA_XSD, "gYear"); + + public static final QName XSD_YEARMONTH = new QName(URI_2001_SCHEMA_XSD, "gYearMonth"); + + private static final String[] XSD_TYPE_NAMES = + {"string", "boolean", "double", "float", "int", "integer", "long", "short", "byte", "decimal", + "base64Binary", "hexBinary", "anySimpleType", "anyType", "any", "QName", "dateTime", "date", "time", + "normalizedString", "token", "unsignedLong", "unsignedInt", "unsignedShort", "unsignedByte", + "positiveInteger", "negativeInteger", "nonNegativeInteger", "nonPositiveInteger", "gYearMonth", + "gMonthDay", "gYear", "gMonth", "gDay", "duration", "Name", "NCName", "NMTOKEN", "NMTOKENS", + "NOTATION", "ENTITY", "ENTITIES", "IDREF", "IDREFS", "anyURI", "language", "ID"}; + + static { + for (String type : XSD_TYPE_NAMES) { + TypeInfo simpleType = new TypeInfo(new QName(URI_2001_SCHEMA_XSD, type), true, null); + XSD_SIMPLE_TYPES.put(type, simpleType); + } + } + + static { + JAVA2XML.put(boolean.class, "boolean"); + JAVA2XML.put(byte.class, "byte"); + JAVA2XML.put(short.class, "short"); + JAVA2XML.put(int.class, "int"); + JAVA2XML.put(long.class, "long"); + JAVA2XML.put(float.class, "float"); + JAVA2XML.put(double.class, "double"); + JAVA2XML.put(Boolean.class, "boolean"); + JAVA2XML.put(Byte.class, "byte"); + JAVA2XML.put(Short.class, "short"); + JAVA2XML.put(Integer.class, "int"); + JAVA2XML.put(Long.class, "long"); + JAVA2XML.put(Float.class, "float"); + JAVA2XML.put(Double.class, "double"); + JAVA2XML.put(java.lang.String.class, "string"); + JAVA2XML.put(java.math.BigInteger.class, "integer"); + JAVA2XML.put(java.math.BigDecimal.class, "decimal"); + JAVA2XML.put(java.util.Calendar.class, "dateTime"); + JAVA2XML.put(java.util.Date.class, "dateTime"); + JAVA2XML.put(javax.xml.namespace.QName.class, "QName"); + JAVA2XML.put(java.net.URI.class, "string"); + JAVA2XML.put(javax.xml.datatype.XMLGregorianCalendar.class, "anySimpleType"); + JAVA2XML.put(javax.xml.datatype.Duration.class, "duration"); + JAVA2XML.put(java.lang.Object.class, "anyType"); + JAVA2XML.put(java.awt.Image.class, "base64Binary"); + JAVA2XML.put(byte[].class, "base64Binary"); + // java2XSD.put(javax.activation.DataHandler.class, "base64Binary"); + JAVA2XML.put(javax.xml.transform.Source.class, "base64Binary"); + JAVA2XML.put(java.util.UUID.class, "string"); + } + + static { + XML2JAVA.put("string", java.lang.String.class); + XML2JAVA.put("integer", java.math.BigInteger.class); + XML2JAVA.put("int", int.class); + XML2JAVA.put("long", long.class); + XML2JAVA.put("short", short.class); + XML2JAVA.put("decimal", java.math.BigDecimal.class); + XML2JAVA.put("float", float.class); + XML2JAVA.put("double", double.class); + XML2JAVA.put("boolean", boolean.class); + XML2JAVA.put("byte", byte.class); + XML2JAVA.put("QName", javax.xml.namespace.QName.class); + XML2JAVA.put("dateTime", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("base64Binary", byte[].class); + XML2JAVA.put("hexBinary", byte[].class); + XML2JAVA.put("unsignedInt", long.class); + XML2JAVA.put("unsignedShort", int.class); + XML2JAVA.put("unsignedByte", short.class); + XML2JAVA.put("time", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("date", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gDay", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gMonth", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gYear", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gYearMonth", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gMonthDay", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("anySimpleType", java.lang.Object.class); // For elements + // XML2JAVA.put("anySimpleType", java.lang.String.class); // For + // attributes + XML2JAVA.put("duration", javax.xml.datatype.Duration.class); + XML2JAVA.put("NOTATION", javax.xml.namespace.QName.class); + } + + private DatatypeFactory factory; + + public SimpleTypeMapperExtension() { + super(); + try { + this.factory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public Class getJavaType(TypeInfo xmlType) { + TypeInfo baseType = xmlType; + while (baseType.getBaseType() != null) { + baseType = baseType.getBaseType(); + } + return XML2JAVA.get(baseType.getQName().getLocalPart()); + } + + public TypeInfo getXMLType(Class javaType) { + return XSD_SIMPLE_TYPES.get(JAVA2XML.get(javaType)); + } + + public Object toJavaObject(TypeInfo simpleType, String literal, TransformationContext context) { + /** + * <ul> + * <li>xsd:string --- java.lang.String + * <li>xsd:integer --- java.math.BigInteger + * <li>xsd:int --- int + * <li>xsd:long --- long + * <li>xsd:short --- short + * <li>xsd:decimal --- java.math.BigDecimal + * <li>xsd:float --- float + * <li>xsd:double --- double + * <li>xsd:boolean --- boolean + * <li>xsd:byte --- byte + * <li>xsd:QName --- javax.xml.namespace.QName + * <li>xsd:dateTime --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:base64Binary --- byte[] + * <li>xsd:hexBinary --- byte[] + * <li>xsd:unsignedInt --- long + * <li>xsd:unsignedShort --- int + * <li>xsd:unsignedByte --- short + * <li>xsd:time --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:date --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:g* --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:anySimpleType (for xsd:element of this type)a + * java.lang.Object + * <li>xsd:anySimpleType (for xsd:attribute of this type) + * java.lang.String + * <li>xsd:duration javax.xml.datatype.Duration + * <li>xsd:NOTATION javax.xml.namespace.QName + * </ul> + */ + + if (literal == null) { + return null; + } + String value = literal.trim(); + if (!simpleType.isSimpleType()) { + throw new IllegalArgumentException("Complex type is not supported for simple java databinding."); + } + TypeInfo baseType = simpleType; + while (baseType.getBaseType() != null) { + baseType = (TypeInfo)baseType.getBaseType(); + } + + QName type = baseType.getQName(); + if (type.equals(XSD_STRING)) { + return parseString(value); + } else if (type.equals(XSD_INT)) { + return parseInt(value); + } else if (type.equals(XSD_INTEGER)) { + return parseInteger(value); + } else if (type.equals(XSD_INT)) { + return parseInt(value); + } else if (type.equals(XSD_FLOAT)) { + return parseFloat(value); + } else if (type.equals(XSD_DOUBLE)) { + return parseDouble(value); + } else if (type.equals(XSD_SHORT)) { + return parseShort(value); + } else if (type.equals(XSD_DECIMAL)) { + return parseDecimal(value); + } else if (type.equals(XSD_BOOLEAN)) { + return parseBoolean(value); + } else if (type.equals(XSD_BYTE)) { + return parseByte(value); + } else if (type.equals(XSD_LONG)) { + return parseLong(value); + } else if (type.equals(XSD_UNSIGNEDBYTE)) { + return parseUnsignedShort(value); + } else if (type.equals(XSD_UNSIGNEDSHORT)) { + return parseUnsignedShort(value); + } else if (type.equals(XSD_UNSIGNEDINT)) { + return parseUnsignedInt(value); + } else if (type.equals(XSD_UNSIGNEDLONG)) { + return parseUnsignedInt(value); + } else if (type.equals(XSD_DATETIME)) { + return parseDateTime(value); + } else if (type.equals(XSD_DATE)) { + return parseDate(value); + } else if (type.equals(XSD_TIME)) { + return parseTime(value); + } else if (type.equals(XSD_DURATION)) { + return parseDuration(value); + } else if (type.equals(XSD_HEXBIN)) { + return parseHexBinary(value); + } else if (type.equals(XSD_BASE64)) { + return parseBase64Binary(value); + } else if (type.equals(XSD_QNAME)) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) + : null); + return parseQName(value, namespaceContext); + } else if (type.equals(XSD_NOTATION)) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) + : null); + return parseQName(value, namespaceContext); + } else if (type.equals(XSD_YEAR)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_MONTH)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_DAY)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_YEARMONTH)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_MONTHDAY)) { + return factory.newXMLGregorianCalendar(value); + } else { + return value; + } + } + + @SuppressWarnings("deprecation") + private XMLGregorianCalendar toXMLGregorianCalendar(Date date) { + GregorianCalendar c = + new GregorianCalendar(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date + .getMinutes(), date.getSeconds()); + return factory.newXMLGregorianCalendar(c); + } + + private XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) { + return factory.newXMLGregorianCalendar(calendar); + } + + public String toXMLLiteral(TypeInfo simpleType, Object obj, TransformationContext context) { + if (obj instanceof Float || obj instanceof Double) { + if (obj instanceof Float) { + return printDouble(((Float)obj).floatValue()); + } else { + return printDouble(((Double)obj).doubleValue()); + } + } else if (obj instanceof GregorianCalendar) { + GregorianCalendar calendar = (GregorianCalendar)obj; + return toXMLGregorianCalendar(calendar).toXMLFormat(); + } else if (obj instanceof Date) { + return toXMLGregorianCalendar((Date)obj).toXMLFormat(); + } else if (obj instanceof XMLGregorianCalendar) { + return ((XMLGregorianCalendar)obj).toXMLFormat(); + } else if (obj instanceof byte[]) { + if (simpleType.getQName().equals(XSD_BASE64)) { + return printBase64Binary((byte[])obj); + } else if (simpleType.getQName().equals(XSD_HEXBIN)) { + return printHexBinary((byte[])obj); + } + } else if (obj instanceof QName) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) + : null); + return printQName((QName)obj, namespaceContext); + } + return obj.toString(); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.java new file mode 100644 index 0000000000..d4f2cef9a2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.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.spi.databinding.extension; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Service; + +/** + * Base Implementation of Transformer which provides the registration to the transformer registry + */ +@org.osoa.sca.annotations.Scope("MODULE") +@Service(Transformer.class) +public abstract class TransformerExtension<S, T> implements Transformer { + + protected TransformerRegistry registry; + + protected TransformerExtension() { + super(); + } + + @Autowire + public void setTransformerRegistry(TransformerRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void init() { + registry.registerTransformer(this); + } + + protected abstract Class getSourceType(); + protected abstract Class getTargetType(); + + public String getSourceDataBinding() { + return getSourceType().getName(); + } + + public String getTargetDataBinding() { + return getTargetType().getName(); + } + + public int getWeight() { + // default to 50 + return 50; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java new file mode 100644 index 0000000000..6e7cc8808f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java @@ -0,0 +1,940 @@ +/* + * 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.spi.databinding.extension; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParsePosition; +import java.util.Calendar; +import java.util.TimeZone; +import javax.xml.XMLConstants; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +/** + * Utility class for XSD data type conversions + */ +public class XSDDataTypeConverter { + public static final class Base64Binary { + private static final char[] S_BASE64CHAR = + {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '+', '/'}; + + private static final char S_BASE64PAD = '='; + + private static final byte[] S_DECODETABLE = new byte[128]; + + static { + for (int i = 0; i < S_DECODETABLE.length; i++) { + S_DECODETABLE[i] = Byte.MAX_VALUE; // 127 + } + for (int i = 0; i < S_BASE64CHAR.length; i++) { + // 0 to 63 + S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i; + } + } + + private Base64Binary() { + } + + /** + * + */ + public static byte[] decode(char[] data, int off, int len) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[len / 4 * 3 + 3]; + int obufcount = 0; + for (int i = off; i < off + len; i++) { + char ch = data[i]; + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + if (obufcount == obuf.length) { + return obuf; + } + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + + /** + * + */ + public static void decode(char[] data, int off, int len, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + for (int i = off; i < off + len; i++) { + char ch = data[i]; + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + int obufcount = decode0(ibuf, obuf, 0); + ostream.write(obuf, 0, obufcount); + } + } + } + } + + /** + * + */ + public static byte[] decode(String data) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[data.length() / 4 * 3 + 3]; + int obufcount = 0; + for (int i = 0; i < data.length(); i++) { + char ch = data.charAt(i); + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + if (obufcount == obuf.length) { + return obuf; + } + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + + /** + * + */ + public static void decode(String data, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + for (int i = 0; i < data.length(); i++) { + char ch = data.charAt(i); + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + int obufcount = decode0(ibuf, obuf, 0); + ostream.write(obuf, 0, obufcount); + } + } + } + } + + private static int decode0(char[] ibuf, byte[] obuf, int index) { + int wp = index; + int outlen = 3; + if (ibuf[3] == S_BASE64PAD) { + outlen = 2; + } + if (ibuf[2] == S_BASE64PAD) { + outlen = 1; + } + int b0 = S_DECODETABLE[ibuf[0]]; + int b1 = S_DECODETABLE[ibuf[1]]; + int b2 = S_DECODETABLE[ibuf[2]]; + int b3 = S_DECODETABLE[ibuf[3]]; + switch (outlen) { + case 1: + obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + return 1; + case 2: + obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); + return 2; + case 3: + obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); + obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f); + return 3; + default: + throw new IllegalArgumentException("The character sequence is not base64 encoded."); + } + } + + /** + * Returns base64 representation of specified byte array. + */ + public static String encode(byte[] data) { + return encode(data, 0, data.length); + } + + /** + * Returns base64 representation of specified byte array. + */ + public static String encode(byte[] data, int off, int len) { + if (len <= 0) { + return ""; + } + char[] out = new char[len / 3 * 4 + 4]; + int rindex = off; + int windex = 0; + int rest = len - off; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[windex++] = S_BASE64CHAR[i >> 18]; + out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f]; + out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f]; + out[windex++] = S_BASE64CHAR[i & 0x3f]; + rindex += 3; + rest -= 3; + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[windex++] = S_BASE64CHAR[i >> 2]; + out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f]; + out[windex++] = S_BASE64PAD; + out[windex++] = S_BASE64PAD; + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[windex++] = S_BASE64CHAR[i >> 10]; + out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f]; + out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f]; + out[windex++] = S_BASE64PAD; + } + return new String(out, 0, windex); + } + + /** + * Outputs base64 representation of the specified byte array to a byte stream. + */ + public static void encode(byte[] data, int off, int len, OutputStream ostream) throws IOException { + if (len <= 0) { + return; + } + byte[] out = new byte[4]; + int rindex = off; + int rest = len - off; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[0] = (byte) S_BASE64CHAR[i >> 18]; + out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f]; + out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f]; + out[3] = (byte) S_BASE64CHAR[i & 0x3f]; + ostream.write(out, 0, 4); + rindex += 3; + rest -= 3; + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[0] = (byte) S_BASE64CHAR[i >> 2]; + out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f]; + out[2] = (byte) S_BASE64PAD; + out[3] = (byte) S_BASE64PAD; + ostream.write(out, 0, 4); + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[0] = (byte) S_BASE64CHAR[i >> 10]; + out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f]; + out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f]; + out[3] = (byte) S_BASE64PAD; + ostream.write(out, 0, 4); + } + } + + /** + * Outputs base64 representation of the specified byte array to a character stream. + */ + public static void encode(byte[] data, int off, int len, Writer writer) throws IOException { + if (len <= 0) { + return; + } + char[] out = new char[4]; + int rindex = off; + int rest = len - off; + int output = 0; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[0] = S_BASE64CHAR[i >> 18]; + out[1] = S_BASE64CHAR[(i >> 12) & 0x3f]; + out[2] = S_BASE64CHAR[(i >> 6) & 0x3f]; + out[3] = S_BASE64CHAR[i & 0x3f]; + writer.write(out, 0, 4); + rindex += 3; + rest -= 3; + output += 4; + if (output % 76 == 0) { + writer.write("\n"); + } + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[0] = S_BASE64CHAR[i >> 2]; + out[1] = S_BASE64CHAR[(i << 4) & 0x3f]; + out[2] = S_BASE64PAD; + out[3] = S_BASE64PAD; + writer.write(out, 0, 4); + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[0] = S_BASE64CHAR[i >> 10]; + out[1] = S_BASE64CHAR[(i >> 4) & 0x3f]; + out[2] = S_BASE64CHAR[(i << 2) & 0x3f]; + out[3] = S_BASE64PAD; + writer.write(out, 0, 4); + } + } + } + + /** + * <p/> + * Utility class for xs:hexbinary. </p> + */ + public static final class HexBinary { + private HexBinary() { + } + + /** + * Converts the string <code>pValue</code> into an array of hex bytes. + */ + public static byte[] decode(String pValue) { + if ((pValue.length() % 2) != 0) { + throw new IllegalArgumentException("A HexBinary string must have even length."); + } + byte[] result = new byte[pValue.length() / 2]; + int j = 0; + int i = 0; + while (i < pValue.length()) { + byte b; + char c = pValue.charAt(i++); + char d = pValue.charAt(i++); + if (c >= '0' && c <= '9') { + b = (byte) ((c - '0') << 4); + } else if (c >= 'A' && c <= 'F') { + b = (byte) ((c - 'A' + 10) << 4); + } else if (c >= 'a' && c <= 'f') { + b = (byte) ((c - 'a' + 10) << 4); + } else { + throw new IllegalArgumentException("Invalid hex digit: " + c); + } + if (d >= '0' && d <= '9') { + b += (byte) (d - '0'); + } else if (d >= 'A' && d <= 'F') { + b += (byte) (d - 'A' + 10); + } else if (d >= 'a' && d <= 'f') { + b += (byte) (d - 'a' + 10); + } else { + throw new IllegalArgumentException("Invalid hex digit: " + d); + } + result[j++] = b; + } + return result; + } + + /** + * Converts the byte array <code>pHexBinary</code> into a string. + */ + public static String encode(byte[] pHexBinary) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < pHexBinary.length; i++) { + byte b = pHexBinary[i]; + byte c = (byte) ((b & 0xf0) >> 4); + if (c <= 9) { + result.append((char) ('0' + c)); + } else { + result.append((char) ('A' + c - 10)); + } + c = (byte) (b & 0x0f); + if (c <= 9) { + result.append((char) ('0' + c)); + } else { + result.append((char) ('A' + c - 10)); + } + } + return result.toString(); + } + + /** + * Creates a clone of the given byte array. + */ + public static byte[] getClone(byte[] pHexBinary) { + byte[] result = new byte[pHexBinary.length]; + System.arraycopy(pHexBinary, 0, result, 0, pHexBinary.length); + return result; + } + } + + public class XSDDateFormat extends XSDDateTimeFormat { + private static final long serialVersionUID = -1629412916827246627L; + + /** + * Creates a new instance. + */ + public XSDDateFormat() { + super(true, false); + } + } + + /** + * <p/> + * An instance of {@link java.text.Format}, which may be used to parse and format <code>xs:dateTime</code> values. + * </p> + */ + public static class XSDDateTimeFormat extends Format { + private static final long serialVersionUID = -1148332471737068969L; + + final boolean parseDate; + + final boolean parseTime; + + /** + * Creates a new instance. + */ + public XSDDateTimeFormat() { + this(true, true); + } + + XSDDateTimeFormat(boolean pParseDate, boolean pParseTime) { + parseDate = pParseDate; + parseTime = pParseTime; + } + + private void append(StringBuffer pBuffer, int pNum, int pMinLen) { + String s = Integer.toString(pNum); + for (int i = s.length(); i < pMinLen; i++) { + pBuffer.append('0'); + } + pBuffer.append(s); + } + + public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) { + assert pCalendar != null : "The Calendar argument must not be null."; + assert pBuffer != null : "The StringBuffer argument must not be null."; + assert pPos != null : "The FieldPosition argument must not be null."; + + Calendar cal = (Calendar) pCalendar; + if (parseDate) { + int year = cal.get(Calendar.YEAR); + if (year < 0) { + pBuffer.append('-'); + year = -year; + } + append(pBuffer, year, 4); + pBuffer.append('-'); + append(pBuffer, cal.get(Calendar.MONTH) + 1, 2); + pBuffer.append('-'); + append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2); + if (parseTime) { + pBuffer.append('T'); + } + } + if (parseTime) { + append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2); + pBuffer.append(':'); + append(pBuffer, cal.get(Calendar.MINUTE), 2); + pBuffer.append(':'); + append(pBuffer, cal.get(Calendar.SECOND), 2); + int millis = cal.get(Calendar.MILLISECOND); + if (millis > 0) { + pBuffer.append('.'); + append(pBuffer, millis, 3); + } + } + TimeZone tz = cal.getTimeZone(); + // JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis()); + int offset = cal.get(Calendar.ZONE_OFFSET); + if (tz.inDaylightTime(cal.getTime())) { + offset += cal.get(Calendar.DST_OFFSET); + } + if (offset == 0) { + pBuffer.append('Z'); + } else { + if (offset < 0) { + pBuffer.append('-'); + offset = -offset; + } else { + pBuffer.append('+'); + } + int minutes = offset / (60 * 1000); + int hours = minutes / 60; + minutes -= hours * 60; + append(pBuffer, hours, 2); + pBuffer.append(':'); + append(pBuffer, minutes, 2); + } + return pBuffer; + } + + private int parseInt(String pString, int offset, StringBuffer pDigits) { + int length = pString.length(); + int pOffset = offset; + pDigits.setLength(0); + while (pOffset < length) { + char c = pString.charAt(pOffset); + if (Character.isDigit(c)) { + pDigits.append(c); + ++pOffset; + } else { + break; + } + } + return pOffset; + } + + public Object parseObject(String pString, ParsePosition pParsePosition) { + assert pString != null : "The String argument must not be null."; + assert pParsePosition != null : "The ParsePosition argument must not be null."; + int offset = pParsePosition.getIndex(); + int length = pString.length(); + + boolean isMinus = false; + StringBuffer digits = new StringBuffer(); + int year = 0; + int month = 0; + int mday = 0; + if (parseDate) { + // Sign + if (offset < length) { + char c = pString.charAt(offset); + if (c == '+') { + ++offset; + } else if (c == '-') { + ++offset; + isMinus = true; + } + } + + offset = parseInt(pString, offset, digits); + if (digits.length() < 4) { + pParsePosition.setErrorIndex(offset); + return null; + } + year = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '-') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + month = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '-') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + mday = Integer.parseInt(digits.toString()); + + if (parseTime) { + if (offset < length && pString.charAt(offset) == 'T') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + } + } else { + year = month = mday = 0; + } + + int hour = 0; + int minute = 0; + int second = 0; + int millis = 0; + if (parseTime) { + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + hour = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == ':') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + minute = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == ':') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + second = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '.') { + ++offset; + offset = parseInt(pString, offset, digits); + if (digits.length() > 0) { + millis = Integer.parseInt(digits.toString()); + } else { + millis = 0; + } + } else { + millis = 0; + } + } else { + hour = minute = second = millis = 0; + } + + digits.setLength(0); + digits.append("GMT"); + if (offset < length) { + char c = pString.charAt(offset); + if (c == 'Z') { + // Ignore UTC, it is the default + ++offset; + } else if (c == '+' || c == '-') { + digits.append(c); + ++offset; + for (int i = 0; i < 5; i++) { + if (offset >= length) { + pParsePosition.setErrorIndex(offset); + return null; + } + c = pString.charAt(offset); + if ((i != 2 && Character.isDigit(c)) || (i == 2 && c == ':')) { + digits.append(c); + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + ++offset; + } + } + } + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(digits.toString())); + cal.set(isMinus ? -year : year, parseDate ? month - 1 : month, mday, hour, minute, second); + cal.set(Calendar.MILLISECOND, millis); + pParsePosition.setIndex(offset); + return cal; + } + } + + public static class XSDTimeFormat extends XSDDateTimeFormat { + private static final long serialVersionUID = 1346506860724640517L; + + /** + * Creates a new instance. + */ + public XSDTimeFormat() { + super(false, true); + } + } + + private static final long MAX_UNSIGNED_INT = (((long) Integer.MAX_VALUE) * 2) + 1; + + private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1; + + public String parseAnySimpleType(String value) { + return value; + } + + public byte[] parseBase64Binary(String value) { + return Base64Binary.decode(value); + } + + public boolean parseBoolean(String value) { + return Boolean.valueOf(value).booleanValue(); + } + + public byte parseByte(String value) { + return Byte.parseByte(value); + } + + public Calendar parseDate(String value) { + XSDDateFormat format = new XSDDateFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse date " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public Calendar parseDateTime(String value) { + XSDDateTimeFormat format = new XSDDateTimeFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse dateTime " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public BigDecimal parseDecimal(String value) { + return new BigDecimal(value); + } + + public double parseDouble(String value) { + if ("INF".equals(value)) { + return Double.POSITIVE_INFINITY; + } else if ("-INF".equals(value)) { + return Double.NEGATIVE_INFINITY; + } else if ("NaN".equals(value)) { + return Double.NaN; + } else { + return Double.parseDouble(value); + } + } + + public Duration parseDuration(String pDuration) { + try { + return DatatypeFactory.newInstance().newDuration(pDuration); + } catch (DatatypeConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public float parseFloat(String value) { + if ("INF".equals(value)) { + return Float.POSITIVE_INFINITY; + } else if ("-INF".equals(value)) { + return Float.NEGATIVE_INFINITY; + } else if ("NaN".equals(value)) { + return Float.NaN; + } else { + return Float.parseFloat(value); + } + } + + public byte[] parseHexBinary(String value) { + return HexBinary.decode(value); + } + + public int parseInt(String value) { + return Integer.parseInt(value); + } + + public BigInteger parseInteger(String value) { + return new BigInteger(value); + } + + public long parseLong(String value) { + return Long.parseLong(value); + } + + public QName parseQName(String value, NamespaceContext context) { + int offset = value.indexOf(':'); + String uri; + String localName; + switch (offset) { + case -1: + localName = value; + uri = context.getNamespaceURI(""); + if (uri == null) { + // Should not happen, indicates an error in the + // NamespaceContext + // implementation + throw new IllegalArgumentException("The default prefix is not bound."); + } + break; + case 0: + throw new IllegalArgumentException("Default prefix must be indicated by not using a colon: " + + value); + default: + String prefix = value.substring(0, offset); + localName = value.substring(offset + 1); + uri = context.getNamespaceURI(prefix); + if (uri == null) { + throw new IllegalArgumentException("The prefix " + prefix + " is not bound."); + } + } + return new QName(uri, localName); + } + + public short parseShort(String value) { + return Short.parseShort(value); + } + + public String parseString(String value) { + return value; + } + + public Calendar parseTime(String value) { + XSDTimeFormat format = new XSDTimeFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse time " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public long parseUnsignedInt(String value) { + long l = Long.parseLong(value); + if (l < 0) { + throw new IllegalArgumentException("Failed to parse UnsignedInt " + value + + ": result is negative"); + } + if (l > MAX_UNSIGNED_INT) { + throw new IllegalArgumentException("Failed to parse UnsignedInt " + value + + ": result exceeds maximum value " + MAX_UNSIGNED_INT); + } + return l; + } + + public int parseUnsignedShort(String value) { + int i = Integer.parseInt(value); + if (i < 0) { + throw new IllegalArgumentException("Failed to parse UnsignedShort " + value + + ": result is negative"); + } + if (i > MAX_UNSIGNED_SHORT) { + throw new IllegalArgumentException("Failed to parse UnsignedShort " + value + + ": result exceeds maximum value " + MAX_UNSIGNED_SHORT); + } + return i; + } + + public String printAnySimpleType(String value) { + return value; + } + + public String printBase64Binary(byte[] value) { + return Base64Binary.encode(value); + } + + public String printBoolean(boolean value) { + return (value ? Boolean.TRUE : Boolean.FALSE).toString(); + } + + public String printByte(byte value) { + return Byte.toString(value); + } + + public String printDate(Calendar value) { + return new XSDDateFormat().format(value); + } + + public String printDateTime(Calendar value) { + return new XSDDateTimeFormat().format(value); + } + + public String printDecimal(BigDecimal value) { + return value.toString(); + } + + public String printDouble(double value) { + return Double.toString(value); + } + + public String printDuration(Duration pDuration) { + return pDuration.toString(); + } + + public String printFloat(float value) { + return Float.toString(value); + } + + public String printHexBinary(byte[] value) { + return HexBinary.encode(value); + } + + public String printInt(int value) { + return Integer.toString(value); + } + + public String printInteger(BigInteger value) { + return value.toString(); + } + + public String printLong(long value) { + return Long.toString(value); + } + + public String printQName(QName value, NamespaceContext context) { + String prefix = context.getPrefix(value.getNamespaceURI()); + if (prefix == null) { + throw new IllegalArgumentException("The namespace URI " + value.getNamespaceURI() + + " is not bound."); + } else if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + return value.getLocalPart(); + } else { + return prefix + ":" + value.getLocalPart(); + } + } + + public String printShort(short value) { + return Short.toString(value); + } + + public String printString(String value) { + return value; + } + + public String printTime(Calendar value) { + return new XSDTimeFormat().format(value); + } + + public String printUnsignedInt(long value) { + return Long.toString(value); + } + + public String printUnsignedShort(int value) { + return Integer.toString(value); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.java new file mode 100644 index 0000000000..63db5b9e24 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.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.spi.deployer; + +import java.net.URLClassLoader; +import java.net.URL; +import java.net.URLStreamHandlerFactory; + +/** + * ClassLoader associated with a composite. + * + * @version $Rev$ $Date$ + */ +public class CompositeClassLoader extends URLClassLoader { + private static final URL[] NOURLS = {}; + + public CompositeClassLoader(ClassLoader classLoader) { + super(NOURLS, classLoader); + } + + public CompositeClassLoader(URL[] urls, ClassLoader classLoader) { + super(urls, classLoader); + } + + public CompositeClassLoader(URL[] urls) { + super(urls); + } + + public CompositeClassLoader(URL[] urls, ClassLoader classLoader, URLStreamHandlerFactory urlStreamHandlerFactory) { + super(urls, classLoader, urlStreamHandlerFactory); + } + + public void addURL(URL url) { + super.addURL(url); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.java new file mode 100644 index 0000000000..4e53a5d0ea --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.java @@ -0,0 +1,46 @@ +/* + * 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.spi.deployer; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Interface that can be used to deploy SCA bundles to a runtime. + * + * @version $Rev$ $Date$ + */ +public interface Deployer { + /** + * Deploy a component as a child of the supplied parent. This operation creates a new component in the runtime to + * represent the supplied component definition. The type of component created will depend on the component + * definition implementation; for example, if the implementation of the component definition is a composite then + * typically a CompositeComponent would be returned. + * + * @param parent the parent context + * @param componentDefinition the component definition as parsed from an assembly + * @return the newly deployed component + */ + <I extends Implementation<?>> Component deploy(CompositeComponent parent, + ComponentDefinition<I> componentDefinition) + throws LoaderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.java new file mode 100644 index 0000000000..1a3a2ffb75 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.deployer; + +import java.net.URL; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.spi.component.ScopeContainer; + +/** + * A holder that can be used during the load process to store information that is not part of the logical assembly + * model. This should be regarded as transient and references to this context should not be stored inside the model. + * + * $Rev$ $Date$ + */ +public interface DeploymentContext { + /** + * Returns the parent of this deployment context. + * Will be null for the context created at the root of a deployment. + * + * @return the parent of this deployment context; may be null + */ + DeploymentContext getParent(); + + /** + * Returns a class loader that can be used to load application resources. + * + * @return a class loader that can be used to load application resources + */ + ClassLoader getClassLoader(); + + /** + * Returns a factory that can be used to obtain an StAX XMLStreamReader. + * + * @return a factory that can be used to obtain an StAX XMLStreamReader + */ + XMLInputFactory getXmlFactory(); + + /** + * Returns the ScopeContainer for the MODULE scope that will be associated with this deployment unit. + * + * @return the ScopeContainer for the MODULE scope that will be associated with this deployment unit + */ + ScopeContainer getModuleScope(); + + /** + * Returns the location of the SCDL definition being deployed. + * + * @return the location of the SCDL definition being deployed + */ + URL getScdlLocation(); + + /** + * Return the extension property with the supplied name. + * + * @param name the name of the property + * @return the property value; if null indicates that no property is present + */ + Object getExtension(String name); + + /** + * Set the value of an extension property. + * + * @param name the name of the property + * @param value the property value; if null then the extension property is removed + */ + void putExtension(String name, Object value); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/Event.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/Event.java new file mode 100644 index 0000000000..b874ca43c9 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/Event.java @@ -0,0 +1,33 @@ +/* + * 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.spi.event; + +/** + * Represents an event that is propagated in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface Event { + + /** + * Returns the source of the event + */ + Object getSource(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java new file mode 100644 index 0000000000..d61d04cdc8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java @@ -0,0 +1,33 @@ +/* + * 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.spi.event; + +/** + * Evaluates whether a {@link RuntimeEventListener} is applicable to a given runtime event + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventFilter { + + /** + * Performs the actual evaluation on an event + */ + boolean match(Event event); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.java new file mode 100644 index 0000000000..35df22fb9c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.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.spi.event; + +/** + * Publishes events in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventPublisher { + + /** + * Publish an event + */ + void publish(Event object); + + /** + * Registers a listener to receive notifications for the context + */ + void addListener(RuntimeEventListener listener); + + /** + * Registers a listener to receive notifications for the context + */ + void addListener(EventFilter filter, RuntimeEventListener listener); + + + /** + * Removes a previously registered listener + */ + void removeListener(RuntimeEventListener listener); + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.java new file mode 100644 index 0000000000..5146559098 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.java @@ -0,0 +1,31 @@ +/* + * 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.spi.event; + +import java.util.EventListener; + +/** + * Listeners observe events fired in the SCA runtime. + * + * @version $Rev$ $Date$ + */ +public interface RuntimeEventListener extends EventListener { + + void onEvent(Event event); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.java new file mode 100644 index 0000000000..81382b86ac --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.java @@ -0,0 +1,31 @@ +/* + * 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.spi.event; + +/** + * An event filter that always returns a true condition + * + * @version $$Rev$$ $$Date$$ + */ +public class TrueFilter implements EventFilter { + + public boolean match(Event event) { + return true; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java new file mode 100644 index 0000000000..2a74409088 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java @@ -0,0 +1,149 @@ +/* + * 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.spi.extension; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireService; + +/** + * An extension point for atomic component type, which new implementation types may extend + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AtomicComponentExtension extends AbstractSCAObject implements AtomicComponent { + + protected ScopeContainer scopeContainer; + protected Scope scope; + protected Map<String, InboundWire> serviceWires = new HashMap<String, InboundWire>(); + protected Map<String, List<OutboundWire>> referenceWires = new HashMap<String, List<OutboundWire>>(); + protected WireService wireService; + protected WorkContext workContext; + protected WorkScheduler workScheduler; + private final int initLevel; + + protected AtomicComponentExtension(String name, + CompositeComponent parent, + ScopeContainer scopeContainer, + WireService wireService, + WorkContext workContext, + WorkScheduler workScheduler, + int initLevel) { + super(name, parent); + this.scopeContainer = scopeContainer; + this.wireService = wireService; + this.workContext = workContext; + this.workScheduler = workScheduler; + this.initLevel = initLevel; + } + + public Scope getScope() { + return scope; + } + + public int getInitLevel() { + return initLevel; + } + + public boolean isEagerInit() { + return initLevel > 0; + } + + public void start() throws CoreRuntimeException { + super.start(); + scopeContainer.register(this); + } + + public void init(Object instance) throws TargetException { + + } + + public void destroy(Object instance) throws TargetException { + + } + + public void addInboundWire(InboundWire wire) { + serviceWires.put(wire.getServiceName(), wire); + onServiceWire(wire); + } + + public InboundWire getInboundWire(String serviceName) { + if (serviceName == null) { + if (serviceWires.size() < 1) { + return null; + } + return serviceWires.values().iterator().next(); + } else { + return serviceWires.get(serviceName); + } + } + + public Map<String, InboundWire> getInboundWires() { + return Collections.unmodifiableMap(serviceWires); + } + + public void addOutboundWire(OutboundWire wire) { + List<OutboundWire> list = new ArrayList<OutboundWire>(); + list.add(wire); + referenceWires.put(wire.getReferenceName(), list); + onReferenceWire(wire); + } + + public Map<String, List<OutboundWire>> getOutboundWires() { + return Collections.unmodifiableMap(referenceWires); + } + + public void addOutboundWires(Class<?> multiplicityClass, List<OutboundWire> wires) { + assert wires != null && wires.size() > 0; + referenceWires.put(wires.get(0).getReferenceName(), wires); + onReferenceWires(multiplicityClass, wires); + } + + public TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation) { + throw new UnsupportedOperationException(); + } + + protected void onReferenceWire(OutboundWire wire) { + } + + protected void onReferenceWires(Class<?> multiplicityClass, List<OutboundWire> wires) { + } + + protected void onServiceWire(InboundWire wire) { + } + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java new file mode 100644 index 0000000000..170840ac32 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java @@ -0,0 +1,76 @@ +/* + * 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.spi.extension; + +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.builder.BindingBuilder; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Binding; +import org.apache.tuscany.spi.model.BoundReferenceDefinition; +import org.apache.tuscany.spi.model.BoundServiceDefinition; +import org.apache.tuscany.spi.wire.WireService; + +/** + * An extension point for binding builders. When adding support for new bindings, implementations may extend this class + * as a convenience. + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public abstract class BindingBuilderExtension<B extends Binding> implements BindingBuilder<B> { + + protected BuilderRegistry builderRegistry; + protected WireService wireService; + + @Autowire + public void setBuilderRegistry(BuilderRegistry registry) { + this.builderRegistry = registry; + } + + @Autowire + public void setWireService(WireService wireService) { + this.wireService = wireService; + } + + @Init(eager = true) + public void init() { + builderRegistry.register(getBindingType(), this); + } + + public Service build(CompositeComponent parent, + BoundServiceDefinition<B> boundServiceDefinition, + DeploymentContext deploymentContext) { + return null; + } + + public Reference build(CompositeComponent parent, + BoundReferenceDefinition<B> boundReferenceDefinition, + DeploymentContext deploymentContext) { + return null; + } + + protected abstract Class<B> getBindingType(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java new file mode 100644 index 0000000000..1f5466dfcd --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java @@ -0,0 +1,93 @@ +/* + * 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.spi.extension; + +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.ComponentBuilder; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.wire.WireService; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.policy.PolicyBuilderRegistry; + +/** + * An extension point for component builders. When adding support for new component types, implementations may extend + * this class as a convenience. + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public abstract class ComponentBuilderExtension<I extends Implementation<?>> implements ComponentBuilder<I> { + + protected BuilderRegistry builderRegistry; + protected ScopeRegistry scopeRegistry; + protected WireService wireService; + protected WorkScheduler workScheduler; + protected WorkContext workContext; + protected PolicyBuilderRegistry policyBuilderRegistry; + protected Connector connector; + + @Autowire + public void setBuilderRegistry(BuilderRegistry registry) { + this.builderRegistry = registry; + } + + @Autowire + public void setScopeRegistry(ScopeRegistry scopeRegistry) { + this.scopeRegistry = scopeRegistry; + } + + @Autowire + public void setWireService(WireService wireService) { + this.wireService = wireService; + } + + @Autowire + public void setWorkScheduler(WorkScheduler workScheduler) { + this.workScheduler = workScheduler; + } + + @Autowire + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + + @Autowire + public void setPolicyBuilderRegistry(PolicyBuilderRegistry registry) { + policyBuilderRegistry = registry; + } + + @Autowire + public void setConnector(Connector connector) { + this.connector = connector; + } + + @Init(eager = true) + public void init() { + builderRegistry.register(getImplementationType(), this); + } + + protected abstract Class<I> getImplementationType(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.java new file mode 100644 index 0000000000..6c5086aec4 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.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.spi.extension; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.loader.ComponentTypeLoader; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.Implementation; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public abstract class ComponentTypeLoaderExtension<I extends Implementation> implements ComponentTypeLoader<I> { + protected LoaderRegistry loaderRegistry; + + protected ComponentTypeLoaderExtension() { + } + + protected ComponentTypeLoaderExtension(LoaderRegistry loaderRegistry) { + this.loaderRegistry = loaderRegistry; + } + + @Autowire + public void setLoaderRegistry(LoaderRegistry loaderRegistry) { + this.loaderRegistry = loaderRegistry; + } + + @Init(eager = true) + public void start() { + loaderRegistry.registerLoader(getImplementationClass(), this); + } + + @Destroy + public void stop() { + loaderRegistry.unregisterLoader(getImplementationClass()); + } + + protected abstract Class<I> getImplementationClass(); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.java new file mode 100644 index 0000000000..93aec79bfd --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.java @@ -0,0 +1,524 @@ +/* + * 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.spi.extension; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.w3c.dom.Document; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.AutowireResolutionException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ComponentNotFoundException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.DuplicateNameException; +import org.apache.tuscany.spi.component.IllegalTargetException; +import org.apache.tuscany.spi.component.ObjectRegistrationException; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * An extension point for composite components, which new types may extend + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class CompositeComponentExtension extends AbstractSCAObject implements CompositeComponent { + + protected final Map<String, SCAObject> children = new ConcurrentHashMap<String, SCAObject>(); + protected final List<Service> services = new ArrayList<Service>(); + protected final List<Reference> references = new ArrayList<Reference>(); + + protected final Map<String, Document> propertyValues; + protected final Connector connector; + + protected final Map<String, SCAObject> systemChildren = new ConcurrentHashMap<String, SCAObject>(); + protected final List<Service> systemServices = new ArrayList<Service>(); + protected final List<Reference> systemReferences = new ArrayList<Reference>(); + + // autowire mappings + protected final Map<Class, SCAObject> autowireInternal = new ConcurrentHashMap<Class, SCAObject>(); + protected final Map<Class, Service> autowireExternal = new ConcurrentHashMap<Class, Service>(); + protected final Map<Class, SCAObject> systemAutowireInternal = new ConcurrentHashMap<Class, SCAObject>(); + protected final Map<Class, Service> systemAutowireExternal = new ConcurrentHashMap<Class, Service>(); + + protected CompositeComponentExtension(String name, + CompositeComponent parent, + Connector connector, + Map<String, Document> propertyValues) { + super(name, parent); + this.propertyValues = propertyValues; + this.connector = connector; + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + + public void onEvent(Event event) { + publish(event); + } + + public <S, I extends S> void registerJavaObject(String name, Class<S> service, I instance) + throws ObjectRegistrationException { + throw new UnsupportedOperationException(); + } + + public Document getPropertyValue(String name) { + return propertyValues.get(name); + } + + public SCAObject getChild(String name) { + assert name != null : "Name was null"; + return children.get(name); + } + + public SCAObject getSystemChild(String name) { + assert name != null : "Name was null"; + return systemChildren.get(name); + } + + public List<SCAObject> getSystemChildren() { + return Collections.unmodifiableList(new ArrayList<SCAObject>(systemChildren.values())); + } + + public List<Service> getSystemServices() { + return Collections.unmodifiableList(systemServices); + } + + public List<Reference> getSystemReferences() { + return Collections.unmodifiableList(systemReferences); + } + + public List<SCAObject> getChildren() { + return Collections.unmodifiableList(new ArrayList<SCAObject>(children.values())); + } + + public List<Service> getServices() { + return Collections.unmodifiableList(services); + } + + public List<Reference> getReferences() { + return Collections.unmodifiableList(references); + } + + public void register(SCAObject child) { + if (child.isSystem()) { + if (systemChildren.get(child.getName()) != null) { + DuplicateNameException e = + new DuplicateNameException("A system child is already registered with the name"); + e.setIdentifier(child.getName()); + e.addContextName(getName()); + throw e; + } + systemChildren.put(child.getName(), child); + } else { + if (children.get(child.getName()) != null) { + DuplicateNameException e = new DuplicateNameException("A child is already registered with the name"); + e.setIdentifier(child.getName()); + e.addContextName(getName()); + throw e; + } + children.put(child.getName(), child); + } + if (child instanceof Service) { + Service service = (Service) child; + synchronized (services) { + if (service.isSystem()) { + systemServices.add(service); + } else { + services.add(service); + } + } + registerAutowire(service); + } else if (child instanceof Reference) { + Reference reference = (Reference) child; + synchronized (references) { + if (reference.isSystem()) { + systemReferences.add(reference); + } else { + references.add(reference); + } + } + registerAutowire(reference); + } else if (child instanceof AtomicComponent) { + AtomicComponent atomic = (AtomicComponent) child; + registerAutowire(atomic); + } else if (child instanceof CompositeComponent) { + CompositeComponent component = (CompositeComponent) child; + if (lifecycleState == RUNNING && component.getLifecycleState() == UNINITIALIZED) { + component.start(); + } + registerAutowire(component); + addListener(component); + } + } + + + public void addOutboundWire(OutboundWire wire) { + + } + + public void addOutboundWires(Class<?> multiplicityClass, List<OutboundWire> wires) { + + } + + public Map<String, List<OutboundWire>> getOutboundWires() { + return null; + } + + public void addInboundWire(InboundWire wire) { + //TODO implement + } + + public InboundWire getInboundWire(String serviceName) { + SCAObject object = children.get(serviceName); + if (!(object instanceof Service)) { + throw new ComponentNotFoundException(serviceName); + } + return ((Service) object).getInboundWire(); + } + + public Map<String, InboundWire> getInboundWires() { + synchronized (services) { + Map<String, InboundWire> map = new HashMap<String, InboundWire>(); + for (Service service : services) { + map.put(service.getName(), service.getInboundWire()); + } + return map; + } + } + + public TargetInvoker createAsyncTargetInvoker(InboundWire wire, Operation operation) { + throw new UnsupportedOperationException(); + } + + public Service getService(String name) { + SCAObject ctx = children.get(name); + if (ctx == null) { + ComponentNotFoundException e = new ComponentNotFoundException("Service not found"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } else if (!(ctx instanceof Service)) { + ComponentNotFoundException e = new ComponentNotFoundException("SCAObject not a service"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } + return (Service) ctx; + } + + public Object getServiceInstance() throws TargetException { + Service service = services.get(0); + if (service == null) { + throw new TargetException("Component has no services"); + } + return service.getServiceInstance(); + } + + public Service getSystemService(String name) { + SCAObject ctx = systemChildren.get(name); + if (ctx == null) { + ComponentNotFoundException e = new ComponentNotFoundException("Service not found"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } else if (!(ctx instanceof Service)) { + ComponentNotFoundException e = new ComponentNotFoundException("SCAObject not a service"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } + return (Service) ctx; + } + + public <T> T locateService(Class<T> serviceInterface, String name) { + SCAObject target = children.get(name); + if (target == null) { + TargetNotFoundException e = new TargetNotFoundException(name); + e.addContextName(getName()); + throw e; + } + return serviceInterface.cast(target.getServiceInstance()); + } + + public <T> T locateSystemService(Class<T> serviceInterface, String name) { + SCAObject object = systemChildren.get(name); + if (object == null) { + TargetNotFoundException e = new TargetNotFoundException(name); + e.addContextName(getName()); + throw e; + } + return serviceInterface.cast(object.getServiceInstance()); + } + + public Object getServiceInstance(String name) throws TargetException { + SCAObject context = children.get(name); + if (context == null) { + TargetNotFoundException e = new TargetNotFoundException(name); + e.addContextName(getName()); + throw e; + } else if (context instanceof Service) { + return context.getServiceInstance(); + } else { + IllegalTargetException e = new IllegalTargetException("Target must be a service"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } + } + + public Object getSystemServiceInstance(String name) throws TargetException { + SCAObject target = systemChildren.get(name); + if (target == null) { + TargetNotFoundException e = new TargetNotFoundException(name); + e.addContextName(getName()); + throw e; + } else if (target instanceof Service) { + return target.getServiceInstance(); + } else { + IllegalTargetException e = new IllegalTargetException("Target must be a service"); + e.setIdentifier(name); + e.addContextName(getName()); + throw e; + } + } + + public List<Class<?>> getServiceInterfaces() { + List<Class<?>> serviceInterfaces = new ArrayList<Class<?>>(services.size()); + synchronized (services) { + for (Service service : services) { + serviceInterfaces.add(service.getInterface()); + } + } + return serviceInterfaces; + } + + public <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException { + if (CompositeComponent.class.equals(instanceInterface)) { + return instanceInterface.cast(this); + } + SCAObject context = autowireInternal.get(instanceInterface); + if (context != null) { + try { + if (context instanceof AtomicComponent || context instanceof Reference || context instanceof Service) { + return instanceInterface.cast(context.getServiceInstance()); + } else { + IllegalTargetException e = new IllegalTargetException("Autowire target must be a system " + + "service, atomic component, or reference"); + e.setIdentifier(instanceInterface.getName()); + e.addContextName(getName()); + throw e; + } + } catch (CoreRuntimeException e) { + e.addContextName(getName()); + throw e; + } + } else { + try { + if (CompositeComponent.class.isAssignableFrom(instanceInterface)) { + return instanceInterface.cast(this); + } + // resolve to parent + if (getParent() == null) { + return null; + } + return getParent().resolveInstance(instanceInterface); + } catch (AutowireResolutionException e) { + e.addContextName(getName()); + throw e; + } + } + } + + public <T> T resolveSystemInstance(Class<T> instanceInterface) throws AutowireResolutionException { + if (CompositeComponent.class.equals(instanceInterface)) { + return instanceInterface.cast(this); + } + SCAObject context = systemAutowireInternal.get(instanceInterface); + if (context != null) { + try { + if (context instanceof AtomicComponent || context instanceof Reference || context instanceof Service) { + return instanceInterface.cast(context.getServiceInstance()); + } else { + IllegalTargetException e = new IllegalTargetException("Autowire target must be a system " + + "service, atomic component, or reference"); + e.setIdentifier(instanceInterface.getName()); + e.addContextName(getName()); + throw e; + } + } catch (CoreRuntimeException e) { + e.addContextName(getName()); + throw e; + } + } else { + try { + // resolve to parent + if (getParent() != null) { + return getParent().resolveSystemInstance(instanceInterface); + } else { + return null; + } + } catch (AutowireResolutionException e) { + e.addContextName(getName()); + throw e; + } + } + } + + public <T> T resolveExternalInstance(Class<T> instanceInterface) throws AutowireResolutionException { + Service service = autowireExternal.get(instanceInterface); + if (service != null) { + try { + return instanceInterface.cast(service.getServiceInstance()); + } catch (CoreRuntimeException e) { + e.addContextName(getName()); + throw e; + } + } else { + return null; + } + } + + public <T> T resolveSystemExternalInstance(Class<T> instanceInterface) throws AutowireResolutionException { + Service service = systemAutowireExternal.get(instanceInterface); + if (service != null) { + try { + return instanceInterface.cast(service.getServiceInstance()); + } catch (CoreRuntimeException e) { + e.addContextName(getName()); + throw e; + } + } else { + return null; + } + } + + public void prepare() { + // Connect services and references first so that their wires are linked first + List<SCAObject> childList = new ArrayList<SCAObject>(); + for (SCAObject child : systemChildren.values()) { + if (child instanceof Component) { + childList.add(child); + } else { + childList.add(0, child); + } + } + // connect system artifacts + for (SCAObject child : childList) { + // connect all children + // TODO for composite wires, should delegate down + connector.connect(child); + child.prepare(); + } + + // connect application artifacts + childList.clear(); + for (SCAObject child : children.values()) { + if (child instanceof Component) { + childList.add(child); + } else { + childList.add(0, child); + } + } + for (SCAObject child : childList) { + // connect all children + // TODO for composite wires, should delegate down + connector.connect(child); + child.prepare(); + } + } + + protected void registerAutowireExternal(Class<?> interfaze, Service service) { + if (interfaze == null) { + // The ServiceContract is not from Java + return; + } + if (service.isSystem()) { + if (systemAutowireExternal.containsKey(interfaze)) { + return; + } + systemAutowireExternal.put(interfaze, service); + } else { + if (autowireExternal.containsKey(interfaze)) { + return; + } + autowireExternal.put(interfaze, service); + } + } + + protected void registerAutowireInternal(Class<?> interfaze, SCAObject object) { + if (interfaze == null) { + // The ServiceContract is not from Java + return; + } + if (object.isSystem()) { + if (systemAutowireInternal.containsKey(interfaze)) { + return; + } + systemAutowireInternal.put(interfaze, object); + } else { + if (autowireInternal.containsKey(interfaze)) { + return; + } + autowireInternal.put(interfaze, object); + } + } + + protected void registerAutowire(CompositeComponent component) { + List<Service> services = component.getServices(); + for (Service service : services) { + registerAutowireInternal(service.getInterface(), service); + } + } + + protected void registerAutowire(AtomicComponent component) { + List<Class<?>> services = component.getServiceInterfaces(); + for (Class<?> service : services) { + registerAutowireInternal(service, component); + } + } + + protected void registerAutowire(Reference reference) { + registerAutowireInternal(reference.getInterface(), reference); + } + + protected void registerAutowire(Service service) { + registerAutowireExternal(service.getInterface(), service); + } + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.java new file mode 100644 index 0000000000..cc42247c33 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.extension; + +import javax.xml.namespace.QName; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.StAXElementLoader; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Support class for extending the Loader mechanism. + * + * @version $Rev$ $Date$ + */ +public abstract class LoaderExtension<T extends ModelObject> implements StAXElementLoader<T> { + /** + * The LoaderRegistry that this loader should register with; usually set by injection. This registry may also be + * used to load sub-elements. + */ + protected LoaderRegistry registry; + + /** + * Constructor specifies the registry to register with. + * + * @param registry the LoaderRegistry this loader should register with + */ + protected LoaderExtension(@Autowire LoaderRegistry registry) { + this.registry = registry; + } + + /** + * Initialize the loader. The base implementation registers this loader with the registry as a handler for the XML + * type returned by {@link #getXMLType()}. Implementations may override this to register the loader as a handler for + * multiple XML types. + */ + @Init(eager = true) + public void start() { + registry.registerLoader(getXMLType(), this); + } + + /** + * Destroy the loader. The base implementation unregisters the loader from the regsitry based on the type returned + * by {@link #getXMLType()}. + */ + @Destroy + public void stop() { + registry.unregisterLoader(getXMLType(), this); + } + + /** + * Returns the QName of the element that this implementation handles. + * + * @return the QName of the element that this implementation handles + */ + public abstract QName getXMLType(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceExtension.java new file mode 100644 index 0000000000..d6c3222c38 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceExtension.java @@ -0,0 +1,104 @@ +/* + * 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.spi.extension; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireInvocationHandler; +import org.apache.tuscany.spi.wire.WireService; + +/** + * The default implementation of an SCA reference + * + * @version $Rev$ $Date$ + */ +public abstract class ReferenceExtension extends AbstractSCAObject implements Reference { + + protected InboundWire inboundWire; + protected OutboundWire outboundWire; + protected Class<?> referenceInterface; + protected WireService wireService; + protected ServiceContract<?> bindingServiceContract; + + protected ReferenceExtension(String name, + Class<?> referenceInterface, + CompositeComponent parent, + WireService wireService) { + super(name, parent); + this.referenceInterface = referenceInterface; + this.wireService = wireService; + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + + public void setInboundWire(InboundWire wire) { + this.inboundWire = wire; + } + + public InboundWire getInboundWire() { + return inboundWire; + } + + public OutboundWire getOutboundWire() { + return outboundWire; + } + + public void setOutboundWire(OutboundWire outboundWire) { + this.outboundWire = outboundWire; + } + + public Class<?> getInterface() { + return referenceInterface; + } + + public Object getServiceInstance() throws TargetException { + return wireService.createProxy(inboundWire); + } + + public WireInvocationHandler getHandler() throws TargetException { + return wireService.createHandler(inboundWire); + } + + public TargetInvoker createCallbackTargetInvoker(ServiceContract contract, Operation operation) { + throw new UnsupportedOperationException(); + } + + public TargetInvoker createAsyncTargetInvoker(OutboundWire wire, Operation operation) { + throw new UnsupportedOperationException(); + } + + public ServiceContract<?> getBindingServiceContract() { + return bindingServiceContract; + } + + public void setBindingServiceContract(ServiceContract<?> serviceContract) { + this.bindingServiceContract = serviceContract; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceExtension.java new file mode 100644 index 0000000000..2eeddf7727 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceExtension.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.extension; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.WireInvocationHandler; +import org.apache.tuscany.spi.wire.WireService; + +/** + * The default implementation of an SCA service + * + * @version $Rev$ $Date$ + */ +public class ServiceExtension extends AbstractSCAObject implements Service { + + protected Class<?> interfaze; + protected InboundWire inboundWire; + protected OutboundWire outboundWire; + protected WireService wireService; + protected ServiceContract<?> bindingServiceContract; + + public ServiceExtension(String name, Class<?> interfaze, CompositeComponent parent, WireService wireService) + throws CoreRuntimeException { + super(name, parent); + this.interfaze = interfaze; + this.wireService = wireService; + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + + public InboundWire getInboundWire() { + return inboundWire; + } + + public void setInboundWire(InboundWire wire) { + inboundWire = wire; + } + + public OutboundWire getOutboundWire() { + return outboundWire; + } + + public void setOutboundWire(OutboundWire outboundWire) { + this.outboundWire = outboundWire; + } + + public TargetInvoker createCallbackTargetInvoker(ServiceContract contract, Operation operation) { + throw new UnsupportedOperationException(); + } + + public Object getServiceInstance() throws TargetException { + return wireService.createProxy(inboundWire); + } + + public WireInvocationHandler getHandler() { + return wireService.createHandler(inboundWire); + } + + public Class<?> getInterface() { + return interfaze; + } + + public ServiceContract<?> getBindingServiceContract() { + return bindingServiceContract; + } + + public void setBindingServiceContract(ServiceContract<?> serviceContract) { + this.bindingServiceContract = serviceContract; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/SystemAtomicComponentExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/SystemAtomicComponentExtension.java new file mode 100644 index 0000000000..8a65a91f3a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/SystemAtomicComponentExtension.java @@ -0,0 +1,72 @@ +/* + * 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.spi.extension; + +import java.util.List; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.SystemAtomicComponent; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * @version $Rev$ $Date$ + */ +public abstract class SystemAtomicComponentExtension extends AtomicComponentExtension implements SystemAtomicComponent { + protected List<Class<?>> interfazes; + + public SystemAtomicComponentExtension(String name, + CompositeComponent parent, + ScopeContainer scopeContainer, + int initLevel) { + this(name, null, parent, scopeContainer, initLevel); + } + + public SystemAtomicComponentExtension(String name, + List<Class<?>> serviceInterfaces, + CompositeComponent parent, + ScopeContainer scopeContainer, + int initLevel) { + super(name, parent, scopeContainer, null, null, null, initLevel); + this.interfazes = serviceInterfaces; + } + + public Object getServiceInstance() throws TargetException { + return getTargetInstance(); + } + + public Object getServiceInstance(String name) throws TargetException { + throw new UnsupportedOperationException(); + } + + public List<Class<?>> getServiceInterfaces() { + return interfazes; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + throw new UnsupportedOperationException(); + } + + public boolean isSystem() { + return true; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.java new file mode 100644 index 0000000000..faa13360c7 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.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.spi.extension; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * The default implementation of a TargetInvoker + */ +public abstract class TargetInvokerExtension implements TargetInvoker { + + private boolean cacheable; + + public TargetInvokerExtension() { + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } + return msg; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return isCacheable(); + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + // TargetInvoker extends Cloneable so this should not have been thrown + throw new AssertionError(e); + } + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.java new file mode 100644 index 0000000000..0e7922f0f1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.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.spi.host; + +import javax.servlet.Servlet; + +/** + * ServiceDefinition interface implemented by host environments that allow Servlets to be registered. + * <p/> + * This interface allows an SCA system component to register a servlet to handle inbound requests. + * + * @version $Rev$ $Date$ + */ +public interface ServletHost { + /** + * Register a mapping for an instance of a Servlet. This requests that the servlet container direct all requests to + * the designated mapping to the supplied Servlet instance. + * + * @param mapping the uri-mapping for the Servlet + * @param servlet the Servlet that should be invoked + */ + void registerMapping(String mapping, Servlet servlet); + + /** + * Unregister a servlet mapping. This directs the servlet contain not to direct any more requests to a previously + * registered Servlet. + * + * @param mapping the uri-mapping for the Servlet + */ + void unregisterMapping(String mapping); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/ElementInfo.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/ElementInfo.java new file mode 100644 index 0000000000..5a0bd3bb5f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/ElementInfo.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.idl; + +import javax.xml.namespace.QName; + +/** + * An abstraction of XML schema elements + */ +public class ElementInfo { + private QName name; + private TypeInfo type; + + /** + * @param name + * @param type + */ + public ElementInfo(QName name, TypeInfo type) { + super(); + this.name = name; + this.type = type; + } + + /** + * @return the name + */ + public QName getQName() { + return name; + } + + /** + * @return the type + */ + public TypeInfo getType() { + return type; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.java new file mode 100644 index 0000000000..5709524573 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.idl; + +import org.apache.tuscany.api.TuscanyException; + +/** + * @version $Rev$ $Date$ + */ +public abstract class InvalidServiceContractException extends TuscanyException { + public InvalidServiceContractException() { + } + + public InvalidServiceContractException(String message) { + super(message); + } + + public InvalidServiceContractException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidServiceContractException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.java new file mode 100644 index 0000000000..0b435e9eb9 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.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.spi.idl; + +/** + * Exception thrown to indicate that a service contract specification contains an overloaded method. + * + * @version $Rev$ $Date$ + */ +public class OverloadedOperationException extends InvalidServiceContractException { + private static final long serialVersionUID = -4658711318608885638L; + + public OverloadedOperationException() { + } + + public OverloadedOperationException(String message) { + super(message); + } + + public OverloadedOperationException(String message, Throwable cause) { + super(message, cause); + } + + public OverloadedOperationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/TypeInfo.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/TypeInfo.java new file mode 100644 index 0000000000..9bb107812c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/TypeInfo.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.spi.idl; + +import javax.xml.namespace.QName; + +/** + * An abstraction of XML schema types + */ +public class TypeInfo { + private QName name; + + private boolean isSimpleType; + + private TypeInfo baseType; + + /** + * @param name + * @param isSimpleType + */ + public TypeInfo(QName name, boolean isSimpleType, TypeInfo baseType) { + super(); + this.name = name; + this.isSimpleType = isSimpleType; + this.baseType = baseType; + } + + /** + * @return the isSimpleType + */ + public boolean isSimpleType() { + return isSimpleType; + } + + /** + * @return the name + */ + public QName getQName() { + return name; + } + + /** + * @return the baseType + */ + public TypeInfo getBaseType() { + return baseType; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/WrapperInfo.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/WrapperInfo.java new file mode 100644 index 0000000000..1125da744c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/WrapperInfo.java @@ -0,0 +1,117 @@ +/* + * 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.spi.idl; + +import java.util.List; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.DataType; + +/** + * The "Wrapper Style" WSDL operation is defined by The Java API for XML-Based Web Services (JAX-WS) 2.0 specification, + * section 2.3.1.2 Wrapper Style. + * <p/> + * A WSDL operation qualifies for wrapper style mapping only if the following criteria are met: <ul> <li>(i) The + * operation’s input and output messages (if present) each contain only a single part <li>(ii) The input message part + * refers to a global element declaration whose localname is equal to the operation name <li>(iii) The output message + * part refers to a global element declaration <li>(iv) The elements referred to by the input and output message parts + * (henceforth referred to as wrapper elements) are both complex types defined using the xsd:sequence compositor <li>(v) + * The wrapper elements only contain child elements, they must not contain other structures such as wildcards (element + * or attribute), xsd:choice, substitution groups (element references are not permitted) or attributes; furthermore, + * they must not be nillable. </ul> + */ +public class WrapperInfo { + private ElementInfo inputWrapperElement; + + private ElementInfo outputWrapperElement; + + private List<ElementInfo> inputChildElements; + + private List<ElementInfo> outputChildElements; + + private DataType<List<DataType<QName>>> unwrappedInputType; + + private DataType<QName> unwrappedOutputType; + + /** + * @param inputWrapperElement + * @param outputWrapperElement + * @param inputElements + * @param outputElements + * @param unwrappedInputType + * @param unwrappedOutputType + */ + public WrapperInfo(ElementInfo inputWrapperElement, + ElementInfo outputWrapperElement, + List<ElementInfo> inputElements, + List<ElementInfo> outputElements, + DataType<List<DataType<QName>>> unwrappedInputType, + DataType<QName> unwrappedOutputType) { + super(); + this.inputWrapperElement = inputWrapperElement; + this.outputWrapperElement = outputWrapperElement; + this.inputChildElements = inputElements; + this.outputChildElements = outputElements; + this.unwrappedInputType = unwrappedInputType; + this.unwrappedOutputType = unwrappedOutputType; + } + + /** + * @return the inputElements + */ + public List<ElementInfo> getInputChildElements() { + return inputChildElements; + } + + /** + * @return the inputWrapperElement + */ + public ElementInfo getInputWrapperElement() { + return inputWrapperElement; + } + + /** + * @return the outputElements + */ + public List<ElementInfo> getOutputChildElements() { + return outputChildElements; + } + + /** + * @return the outputWrapperElement + */ + public ElementInfo getOutputWrapperElement() { + return outputWrapperElement; + } + + /** + * @return the unwrappedInputType + */ + public DataType<List<DataType<QName>>> getUnwrappedInputType() { + return unwrappedInputType; + } + + /** + * @return the unwrappedOutputType + */ + public DataType<QName> getUnwrappedOutputType() { + return unwrappedOutputType; + } +}
\ No newline at end of file diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java new file mode 100644 index 0000000000..08f22147b5 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java @@ -0,0 +1,46 @@ +/* + * 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.spi.idl.java; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; + +/** + * Processor for creating JavaServiceContract definitions from Java Classes. + * + * @version $Rev$ $Date$ + */ +public interface InterfaceJavaIntrospector { + + /** + * Introspect a Java interface and return a service contract definition. + * + * @param type the interface to inspect + * @return a JavaServiceContract corresponding to the Java interface + */ + <I> JavaServiceContract introspect(Class<I> type) throws InvalidServiceContractException; + + /** + * Introspect a Java interface and return a service contract definition. + * + * @param type the interface to inspect + * @param callback the callback interface to inspec + * @return a JavaServiceContract corresponding to the Java interface + */ + <I, C> JavaServiceContract introspect(Class<I> type, Class<C> callback) throws InvalidServiceContractException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java new file mode 100644 index 0000000000..c7c7cb2aa8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java @@ -0,0 +1,96 @@ +/* + * 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.spi.idl.java; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; + +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; + +/** + * Contains methods for mapping between an operation in a {@link org.apache.tuscany.spi.model.ServiceContract} and a + * method defined by a Java interface + * + * @version $Rev$ $Date$ + */ +public final class JavaIDLUtils { + + private JavaIDLUtils() { + } + + /** + * Searches an array of methods for a match against the given operation + * + * @param operation the operation to match + * @param methods the methods to match against + * @return a matching method or null + */ + public static Method findMethod(Operation<?> operation, Method[] methods) { + for (Method method : methods) { + if (match(operation, method)) { + return method; + } + } + return null; + } + + /** + * Searches a collection of operations for a match against the given method + * + * @param method the method to match + * @param operations the operations to match against + * @return a matching operation or null + */ + public static Operation findOperation(Method method, Collection<Operation<?>> operations) { + for (Operation<?> operation : operations) { + if (match(operation, method)) { + return operation; + } + } + return null; + } + + /** + * Determines if the given operation matches the given method + * + * @return true if the operation matches, false if does not + */ + private static <T> boolean match(Operation<T> operation, Method method) { + Class<?>[] params = method.getParameterTypes(); + DataType<List<DataType<T>>> inputType = operation.getInputType(); + List<DataType<T>> types = inputType.getLogical(); + boolean found = true; + if (types.size() == params.length && method.getName().equals(operation.getName())) { + for (int i = 0; i < params.length; i++) { + Class<?> clazz = params[i]; + if (!clazz.equals(operation.getInputType().getLogical().get(i).getPhysical())) { + found = false; + } + } + } else { + found = false; + } + return found; + + } + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.java new file mode 100644 index 0000000000..afe98f0773 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.java @@ -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. + */ +package org.apache.tuscany.spi.idl.java; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; + +/** + * Implementations introspect metadata on a Java interface, populating the + * corresponding {@link JavaServiceContract} + * + * @version $Rev$ $Date$ + */ +public interface JavaInterfaceProcessor { + + void visitInterface(Class<?> clazz, Class<?> callbackClass, JavaServiceContract contract) + throws InvalidServiceContractException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.java new file mode 100644 index 0000000000..d0333b0c3d --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.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.spi.idl.java; + +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.annotation.Autowire; + +/** + * A convenience class for <code>JavaInterfaceProcessor</code> extensions that performs autowiring + * + * @version $Rev$ $Date$ + */ +public abstract class JavaInterfaceProcessorExtension implements JavaInterfaceProcessor { + + protected JavaInterfaceProcessorRegistry registry; + + @Autowire + public void setRegistry(JavaInterfaceProcessorRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void init() { + registry.registerProcessor(this); + } + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java new file mode 100644 index 0000000000..38c64e6f88 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java @@ -0,0 +1,39 @@ +/* + * 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.spi.idl.java; + +/** + * A registry of {@link JavaInterfaceProcessor}s. Interface processors update a service contract definition based on a + * Java interface + * + * @version $Rev$ $Date$ + */ +public interface JavaInterfaceProcessorRegistry extends InterfaceJavaIntrospector { + + /** + * Registers the given processor + */ + void registerProcessor(JavaInterfaceProcessor processor); + + /** + * Deregisters the given processor + */ + void unregisterProcessor(JavaInterfaceProcessor processor); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java new file mode 100644 index 0000000000..ee29846e26 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java @@ -0,0 +1,39 @@ +/* + * 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.spi.idl.java; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Represents a service contract specified using a Java interface + * + * @version $Rev$ $Date$ + */ +public class JavaServiceContract extends ServiceContract<Type> { + + public JavaServiceContract() { + } + + public JavaServiceContract(Class<?> interfaceClass) { + super(interfaceClass); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java new file mode 100644 index 0000000000..8014453f0b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java @@ -0,0 +1,163 @@ +/* + * 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.spi.implementation.java; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.Map; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Base class for ImplementationProcessors that handle annotations that add Properties. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractPropertyProcessor<A extends Annotation> extends ImplementationProcessorExtension { + private final Class<A> annotationClass; + private ImplementationProcessorService service; + + protected AbstractPropertyProcessor(Class<A> annotationClass, ImplementationProcessorService service) { + this.annotationClass = annotationClass; + this.service = service; + } + + public void visitMethod(CompositeComponent parent, + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + A annotation = method.getAnnotation(annotationClass); + if (annotation == null) { + return; + } + + if (!Void.TYPE.equals(method.getReturnType())) { + IllegalPropertyException ipe = new IllegalPropertyException("Method does not have void return type"); + ipe.setIdentifier(method.toString()); + throw ipe; + } + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length != 1) { + IllegalPropertyException ipe = new IllegalPropertyException("Method must have 1 parameter"); + ipe.setIdentifier(method.toString()); + throw ipe; + } + Class<?> javaType = paramTypes[0]; + + String name = getName(annotation); + if (name == null || name.length() == 0) { + name = method.getName(); + if (name.startsWith("set")) { + name = toPropertyName(method.getName()); + } + } + + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + if (properties.containsKey(name)) { + throw new DuplicatePropertyException(name); + } + + JavaMappedProperty<?> property = createProperty(name, javaType, method); + initProperty(property, annotation, parent, context); + properties.put(name, property); + } + + public void visitField(CompositeComponent parent, + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + A annotation = field.getAnnotation(annotationClass); + if (annotation == null) { + return; + } + + Class<?> javaType = field.getType(); + + String name = getName(annotation); + if (name == null || name.length() == 0) { + name = field.getName(); + } + + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + if (properties.containsKey(name)) { + throw new DuplicatePropertyException(name); + } + + JavaMappedProperty<?> property = createProperty(name, javaType, field); + initProperty(property, annotation, parent, context); + properties.put(name, property); + } + + public <T> void visitConstructor(CompositeComponent parent, Constructor<T> constructor, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + ConstructorDefinition<?> definition = type.getConstructorDefinition(); + Class[] params = constructor.getParameterTypes(); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + Annotation[][] annotations = constructor.getParameterAnnotations(); + for (int i = 0; i < params.length; i++) { + Class<?> param = params[i]; + Annotation[] paramAnnotations = annotations[i]; + for (Annotation annotation : paramAnnotations) { + if (annotation.annotationType().equals(annotationClass)) { + if (definition == null) { + definition = new ConstructorDefinition<T>(constructor); + type.setConstructorDefinition(definition); + } + A monitorAnnot = annotationClass.cast(annotation); + String name = getName(monitorAnnot); + if (name == null || name.length() == 0) { + name = param.getName(); + } + JavaMappedProperty<?> property = createProperty(name, param, constructor); + initProperty(property, monitorAnnot, parent, context); + properties.put(name, property); + service.addName(definition.getInjectionNames(), i, name); + } + } + } + } + + protected abstract String getName(A annotation); + + protected <T> void initProperty(JavaMappedProperty<T> property, + A annotation, + CompositeComponent parent, + DeploymentContext context) throws ProcessingException { + } + + protected <T> JavaMappedProperty<T> createProperty(String name, Class<T> javaType, Member member) + throws ProcessingException { + return new JavaMappedProperty<T>(name, null, javaType, member); + } + + + public static String toPropertyName(String name) { + if (!name.startsWith("set")) { + return name; + } + return Character.toLowerCase(name.charAt(3)) + name.substring(4); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java new file mode 100644 index 0000000000..94c185966f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +/** + * Hold injection information for the constructor used to instantiate a component implementation instance + * + * @version $Rev$ $Date$ + */ +public class ConstructorDefinition<T> { + + private Constructor<T> constructor; + private List<String> injectionNames; + + public ConstructorDefinition(Constructor<T> constructor) { + this.constructor = constructor; + injectionNames = new ArrayList<String>(); + } + + public Constructor<T> getConstructor() { + return constructor; + } + + public List<String> getInjectionNames() { + return injectionNames; + } + + public void setInjectionNames(List<String> injectionNames) { + this.injectionNames = injectionNames; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java new file mode 100644 index 0000000000..3582beff7f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +/** + * Thrown when an implementation has more than one property injection site with the same name + * + * @version $Rev$ $Date$ + */ +public class DuplicatePropertyException extends ProcessingException { + public DuplicatePropertyException() { + } + + public DuplicatePropertyException(String message) { + super(message); + } + + public DuplicatePropertyException(String message, Throwable cause) { + super(message, cause); + } + + public DuplicatePropertyException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java new file mode 100644 index 0000000000..40f7eeadb8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +/** + * Denotes an illegal property definition in a component type + * + * @version $Rev$ $Date$ + */ +public class IllegalPropertyException extends ProcessingException { + public IllegalPropertyException() { + } + + public IllegalPropertyException(String message) { + super(message); + } + + public IllegalPropertyException(String message, Throwable cause) { + super(message, cause); + } + + public IllegalPropertyException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.java new file mode 100644 index 0000000000..fb9beca53c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Implementations process class-level metadata, typically parsing annotations and updating the corresponding + * <code>ComponentType</code>. A processor may, for example, create a {@link JavaMappedProperty} which is responsible + * for injecting a complex type on a component implementation instance when it is instantiated. + * <p/> + * Processors will receive callbacks as the implementation class is walked while evalauting an assembly. It is the + * responsibility of the parser to determine whether to perform an action during the callback. + * + * @version $Rev$ $Date$ + */ +public interface ImplementationProcessor { + + /** + * A callback received when the component implementation class is first loaded + * + * @param parent the parent composite + * @param clazz the component implementation class + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitClass(CompositeComponent parent, + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation class hierarchy is evaluated + * + * @param parent the parent composite + * @param clazz the superclass in the component implmentation's class hierarchy + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitSuperClass(CompositeComponent parent, + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation's public and protected methods are evaluated + * + * @param parent the parent composite + * @param method the current public or protected method being evaluated + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + void visitMethod(CompositeComponent parent, + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation's constructor used for instantiation by the runtime is + * evaluated. If an implementation contains more than one constructor, the constructor passed to the callback will + * be chosen according to the algorithm described in the SCA Java Client and Implementation Model Specification. + * + * @param parent the parent composite + * @param constructor the constructor used for instantiating component implementation instances + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitConstructor(CompositeComponent parent, + Constructor<T> constructor, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException; + + /** + * A callback received as the component implementation's public and protected fields are evaluated + * + * @param parent the parent composite + * @param field the current public or protected field being evaluated + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + void visitField(CompositeComponent parent, + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * The final callback received when all other callbacks during evaluation of the component implementation have been + * issued + * + * @param parent the parent composite + * @param clazz the component implementation class + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitEnd(CompositeComponent parent, + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.java new file mode 100644 index 0000000000..79a715ca70 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.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.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * A convenience class for annotation processors which alleviates the need to implement unused callbacks + * + * @version $Rev$ $Date$ + */ +public abstract class ImplementationProcessorExtension implements ImplementationProcessor { + private IntrospectionRegistry registry; + + @Autowire + public void setRegistry(IntrospectionRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void init() { + registry.registerProcessor(this); + } + + @Destroy + public void destroy() { + registry.unregisterProcessor(this); + } + + public <T> void visitClass(CompositeComponent parent, Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public <T> void visitSuperClass(CompositeComponent parent, Class<T> clazz, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public void visitMethod(CompositeComponent parent, Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public <T> void visitConstructor(CompositeComponent parent, Constructor<T> constructor, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public void visitField(CompositeComponent parent, Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + } + + public <T> void visitEnd(CompositeComponent parent, Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.java new file mode 100644 index 0000000000..c1b0dc07af --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.java @@ -0,0 +1,90 @@ +/* + * 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.spi.implementation.java; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Member; +import java.util.List; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Provides utility methods for Java implementation processing + * + * @version $Rev$ $Date$ + */ +public interface ImplementationProcessorService { + + /** + * Introspects the given interface to produce a mapped service + */ + JavaMappedService createService(Class<?> interfaze) throws InvalidServiceContractException, + InvalidServiceContractException; + + JavaMappedReference createReference(String name, Member member, Class<?> paramType) throws ProcessingException; + + /** + * Processes the callback contract for a given interface type + * + * @param interfaze the interface type to examine + * @param contract the service contract the callback is associated wth + * @throws InvalidServiceContractException + * + */ + void processCallback(Class<?> interfaze, ServiceContract<?> contract) throws InvalidServiceContractException; + + /** + * Determines if all the members of a collection have unique types + * + * @param collection the collection to analyze + * @return true if the types are unique + */ + boolean areUnique(Class[] collection); + + /** + * Inserts a name at the specified position, paddiling the list if its size is less than the position + */ + void addName(List<String> names, int pos, String name); + + /** + * Processes a constructor parameter by introspecting its annotations + * + * @param param the parameter to process + * @param paramAnnotations the parameter annotations + * @param constructorNames the array of constructorNames specified by + * @param pos the declaration position of the constructor parameter + * @param type the component type associated with implementation being reflected + * @param injectionNames the list of parameter constructorNames specified on parameter annotations + * @throws ProcessingException + */ + boolean processParam( + Class<?> param, + Annotation[] paramAnnotations, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + List<String> injectionNames) throws ProcessingException; + + /** + * Returns true if {@link @Autowire}, {@link @Property}, or {@link @Reference} are present in the given array + */ + boolean injectionAnnotationsPresent(Annotation[][] annots); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.java new file mode 100644 index 0000000000..a6122a6ff1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +/** + * A system service which tracks {@link ImplementationProcessor}s + * + * @version $Rev$ $Date$ + */ +public interface IntrospectionRegistry extends Introspector { + + /** + * Registers the given processor and makes it available during assembly evaluation (i.e. build) + */ + void registerProcessor(ImplementationProcessor processor); + + /** + * Deregisters the given processor + */ + void unregisterProcessor(ImplementationProcessor processor); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.java new file mode 100644 index 0000000000..66abc1f686 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.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.spi.implementation.java; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Implementations are responsible for walking a component implementation class, adding additional component type + * information as appropriate + * + * @version $Rev$ $Date$ + */ +public interface Introspector { + + /** + * Walks the given component implementation class + * + * @param parent the parent composite + * @param clazz the component implementation class + * @param type the component type associated with the implementation class + * @return the updated component type + * @throws ProcessingException if an error is encountered evaluating the implementation class + */ + PojoComponentType introspect(CompositeComponent parent, + Class<?> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.java new file mode 100644 index 0000000000..34ac8f53f9 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.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.spi.implementation.java; + +import org.apache.tuscany.spi.model.ComponentType; + +/** + * A specialized component type definition whose services, references and properties can be mapped to the Java + * programming model. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedComponentType< + S extends JavaMappedService, + R extends JavaMappedReference, + P extends JavaMappedProperty<?> + > extends ComponentType<S, R, P> { + + private Class<?> implClass; + + public JavaMappedComponentType() { + } + + public JavaMappedComponentType(Class<?> implClass) { + this.implClass = implClass; + } + + /** + * Returns the implementation class associated with this component type. + * + * @return the implementation class associated with this component type + */ + public Class<?> getImplClass() { + return implClass; + } + + /** + * Sets the implementation class associated with this component type. + * + * @param implClass the implementation class associated with this component type + */ + public void setImplClass(Class<?> implClass) { + this.implClass = implClass; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.java new file mode 100644 index 0000000000..6d1715a035 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.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.spi.implementation.java; + +import java.lang.reflect.Member; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Property; + +/** + * A Property definition that is mapped to a specific location in the implementation class. This location will typically + * be used to inject property values. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedProperty<T> extends Property<T> { + private Member member; + + public JavaMappedProperty() { + } + + public JavaMappedProperty(String name, QName xmlType, Class<T> javaType) { + super(name, xmlType, javaType); + } + + public JavaMappedProperty(String name, QName xmlType, Class<T> javaType, Member member) { + super(name, xmlType, javaType); + this.member = member; + } + + /** + * Returns the Member that this property is mapped to. + * + * @return the Member that this property is mapped to + */ + public Member getMember() { + return member; + } + + /** + * Sets the Member that this property is mapped to + * + * @param member the Member that this property is mapped to + */ + public void setMember(Member member) { + this.member = member; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.java new file mode 100644 index 0000000000..8c718a831b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.java @@ -0,0 +1,60 @@ +/* + * 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.spi.implementation.java; + +import java.lang.reflect.Member; + +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * A ReferenceDefinition definition that is mapped to a specific location in the implementation class. This location + * will typically be used to inject reference values. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedReference extends ReferenceDefinition { + private Member member; + + public JavaMappedReference() { + } + + public JavaMappedReference(String name, ServiceContract serviceContract, Member member) { + super(name, serviceContract); + this.member = member; + } + + /** + * Returns the Member that this reference is mapped to. + * + * @return the Member that this reference is mapped to + */ + public Member getMember() { + return member; + } + + /** + * Sets the Member that this reference is mapped to + * + * @param member the Member that this reference is mapped to + */ + public void setMember(Member member) { + this.member = member; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.java new file mode 100644 index 0000000000..ee5e0bb2a7 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.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.spi.implementation.java; + +import java.lang.reflect.Member; + +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * A ServiceDefinition definition that is mapped to a Java interface. The mapped interface is not required to be the + * same as the interface specified in the service contract. This is to allow the service contract to be specified using + * different interface definition languages or, in the case were the IDL is Java, to allow the service definition to be + * loaded from a different classloader. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedService extends ServiceDefinition { + private Class<?> serviceInterface; + private Member callbackMember; + + public JavaMappedService() { + } + + public JavaMappedService(Class<?> serviceInterface) { + this.serviceInterface = serviceInterface; + } + + public JavaMappedService(String name, ServiceContract contract, boolean remotable) { + super(name, contract, remotable); + } + + public JavaMappedService(String name, + ServiceContract contract, + boolean remotable, + String callbackRefName, + Member callbackMember) { + super(name, contract, remotable, callbackRefName); + this.callbackMember = callbackMember; + } + + public JavaMappedService(String name, ServiceContract contract, Class<?> serviceInterface, boolean remotable) { + super(name, contract, remotable); + this.serviceInterface = serviceInterface; + } + + /** + * Returns the Java interface for this service. This may be different from the interface that defines the service + * contract. + * + * @return the Java interface for this service + */ + public Class<?> getServiceInterface() { + return serviceInterface; + } + + /** + * Sets the Java interface for this service. This may be different from the interface used to define the service + * contract. + * + * @param serviceInterface the Java interface for this service + */ + public void setServiceInterface(Class<?> serviceInterface) { + this.serviceInterface = serviceInterface; + } + + public Member getCallbackMember() { + return callbackMember; + } + + public void setCallbackMember(Member callbackMember) { + this.callbackMember = callbackMember; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java new file mode 100644 index 0000000000..edf3db5538 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * A component type specialization for POJO implementations + * + * @version $$Rev$$ $$Date$$ + */ +public class PojoComponentType<S extends ServiceDefinition, R extends ReferenceDefinition, P extends Property<?>> + extends ComponentType<S, R, P> { + + private Scope implementationScope = Scope.UNDEFINED; + private ConstructorDefinition<?> constructorDefinition; + private Method initMethod; + private Method destroyMethod; + + /** + * Returns the component implementation scope + */ + public Scope getImplementationScope() { + return implementationScope; + } + + /** + * Sets the component implementation scope + */ + public void setImplementationScope(Scope implementationScope) { + this.implementationScope = implementationScope; + } + + /** + * Returns the constructor used to instantiate implementation instances + */ + public ConstructorDefinition<?> getConstructorDefinition() { + return constructorDefinition; + } + + /** + * Sets the constructor used to instantiate implementation instances + */ + public void setConstructorDefinition(ConstructorDefinition<?> definition) { + this.constructorDefinition = definition; + } + + /** + * Returns the component initializer method + */ + public Method getInitMethod() { + return initMethod; + } + + /** + * Sets the component initializer method + */ + public void setInitMethod(Method initMethod) { + this.initMethod = initMethod; + } + + /** + * Returns the component destructor method + */ + public Method getDestroyMethod() { + return destroyMethod; + } + + /** + * Sets the component destructor method + */ + public void setDestroyMethod(Method destroyMethod) { + this.destroyMethod = destroyMethod; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.java new file mode 100644 index 0000000000..126526d082 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.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.spi.implementation.java; + +import org.apache.tuscany.spi.loader.LoaderException; + +/** + * Denotes a problem processing annotations on a POJO implementation + * + * @version $Rev$ $Date$ + */ +public class ProcessingException extends LoaderException { + public ProcessingException() { + } + + public ProcessingException(String message) { + super(message); + } + + public ProcessingException(String message, Throwable cause) { + super(message, cause); + } + + public ProcessingException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.java new file mode 100644 index 0000000000..8ad01d8197 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.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.spi.loader; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Loader that will load the ComponentType definition for the supplied implementation. The actual mechanism used to load + * that definition is determined by the Client and Implementation Specification for the implementaion type. In some + * cases the definition may be contained in a XML file related to the implementation artifact in some well defined + * manner; other implementations may obtain this information from introspection of the artifact itself (for example, by + * examining Java annotations). + * + * @version $Rev$ $Date$ + */ +public interface ComponentTypeLoader<I extends Implementation> { + /** + * Load the component type definition for the supplied implementation. + * + * @param parent the parent composite + * @param implementation the implementation whose component type information should be loaded + * @param deploymentContext the current deployment context + * @throws LoaderException if there was a problem loading the configuration type + */ + void load(CompositeComponent parent, I implementation, DeploymentContext deploymentContext) + throws LoaderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.java new file mode 100644 index 0000000000..59db6195d8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidReferenceException extends LoaderException { + private static final long serialVersionUID = -4346666572527197558L; + + public InvalidReferenceException() { + } + + public InvalidReferenceException(String message) { + super(message); + } + + public InvalidReferenceException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidReferenceException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.java new file mode 100644 index 0000000000..194a5cc7c7 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.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.spi.loader; + +/** + * Exception that indicates the loader encountered an invalid value. + * The message should be set to the invalid value. + * + * @version $Rev$ $Date$ + */ +public class InvalidValueException extends LoaderException { + + public InvalidValueException() { + } + + public InvalidValueException(String message) { + super(message); + } + + public InvalidValueException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidValueException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java new file mode 100644 index 0000000000..e6364fe02b --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java @@ -0,0 +1,81 @@ +/* + * 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.spi.loader; + +import java.net.URL; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * System service for loading physical artifacts that represent SCDL configurations and creating the model objects that + * represent them. + * + * @version $Rev$ $Date$ + */ +public interface Loader { + /** + * Parse the supplied XML stream, dispatching to the appropriate registered loader for each element encountered in + * the stream. + * <p/> + * This method must be called with the XML cursor positioned on a START_ELEMENT event. When this method returns, the + * stream will be positioned on the corresponding END_ELEMENT event. + * + * @param parent + * @param reader the XML stream to parse + * @param deploymentContext the current deployment context + * @return the model object obtained by parsing the current element on the stream + * @throws XMLStreamException if there was a problem reading the stream + */ + ModelObject load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException; + + /** + * Load a model object from a specified location. + * + * @param parent + * @param url the location of an XML document to be loaded + * @param type the type of ModelObject that is expected to be in the document + * @param deploymentContext the current deployment context + * @return the model ojbect loaded from the document + * @throws LoaderException if there was a problem loading the document + */ + <MO extends ModelObject> MO load(CompositeComponent parent, URL url, Class<MO> type, + DeploymentContext deploymentContext) + throws LoaderException; + + /** + * Load the component type definition for a given implementation. How the component type information is located is + * defined by the implementation specification. It may include loading from an XML sidefile, introspection of some + * artifact related to the implementation, some combination of those techniques or any other implementation-defined + * mechanism. + * + * @param parent the parent composite + * @param implementation the implementation whose component type should be loaded + * @param deploymentContext the current deployment context + * @throws LoaderException if there was a problem loading the component type definition + */ + <I extends Implementation<?>> void loadComponentType(CompositeComponent parent, I implementation, + DeploymentContext deploymentContext) + throws LoaderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.java new file mode 100644 index 0000000000..7b22fbbe94 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.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.spi.loader; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Base class for Exceptions raised during the loading process. Loader implementations should throw a subclass of this + * to indicate the actual problem. + * + * @version $Rev$ $Date$ + */ +public class LoaderException extends TuscanyException { + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + + public LoaderException() { + } + + public LoaderException(String message) { + super(message); + } + + public LoaderException(String message, Throwable cause) { + super(message, cause); + } + + public LoaderException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being loaded. + * + * @return the location of the resource that was being loaded + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being loaded. + * + * @param resourceURI the location of the resource that was being loaded + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.java new file mode 100644 index 0000000000..ea88b99b22 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.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.spi.loader; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Registry for XML loaders that can parse a StAX input stream and return model objects. + * <p/> + * Loaders will typically be contributed to the system by any extension that needs to handle extension specific + * information contained in some XML configuration file. The loader can be contributed as a system component with an + * autowire reference to this builderRegistry which is used during initialization to actually register. </p> This + * builderRegistry can also be used to parse an input stream, dispatching to the appropriate loader for each element + * accepted. Loaders can call back to the builderRegistry to load sub-elements that they are not able to handle + * directly. + * + * @version $Rev$ $Date$ + */ +public interface LoaderRegistry extends Loader { + /** + * Register a loader. This operation will typically be called by a loader during its initialization. + * + * @param element the element that should be delegated to the contibuted loader + * @param loader a loader that is being contributed to the system + */ + <T extends ModelObject> void registerLoader(QName element, StAXElementLoader<T> loader); + + /** + * Unregister a loader. This will typically be called by a loader as it is being destroyed. + * + * @param element the element that was being delegated to the contibuted loader + * @param loader a loader that should no longer be used + */ + <T extends ModelObject> void unregisterLoader(QName element, StAXElementLoader<T> loader); + + /** + * Regsiter a component type loader. + * + * @param key a type of implementation this loader can load component types for + * @param loader the loader that is being contributed to the system + */ + <I extends Implementation<?>> void registerLoader(Class<I> key, ComponentTypeLoader<I> loader); + + /** + * Unregister a component type loader form the system. + * + * @param key a type of implementation whose loader should be unregistered + */ + <I extends Implementation<?>> void unregisterLoader(Class<I> key); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java new file mode 100644 index 0000000000..bf48f91a74 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java @@ -0,0 +1,78 @@ +/* + * 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.spi.loader; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamConstants; + +/** + * Utility functions to support loader implementations. + * + * @version $Rev$ $Date$ + */ +public final class LoaderUtil { + private LoaderUtil() { + } + + /** + * 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 + */ + public static void skipToEndElement(XMLStreamReader reader) throws XMLStreamException { + int depth = 0; + while (true) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + depth++; + } else if (event == XMLStreamConstants.END_ELEMENT) { + if (depth == 0) { + return; + } + depth--; + } + } + } + + /** + * Load the class using the supplied ClassLoader. + * The class will be defined so any initializers present will be fired. + * As the class is being loaded, the Thread context ClassLoader will be + * set to the supplied classloader. + * + * @param name the name of the class to load + * @param cl the classloader to use to load it + * @return the class + * @throws MissingResourceException if the class could not be found + */ + public static Class<?> loadClass(String name, ClassLoader cl) throws MissingResourceException { + final Thread thread = Thread.currentThread(); + final ClassLoader oldCL = thread.getContextClassLoader(); + try { + thread.setContextClassLoader(cl); + return Class.forName(name, true, cl); + } catch (ClassNotFoundException e) { + throw new MissingResourceException(name, e); + } finally { + thread.setContextClassLoader(oldCL); + } + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java new file mode 100644 index 0000000000..89a44083cc --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java @@ -0,0 +1,35 @@ +/* + * 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.spi.loader; + +/** + * Exception that indicates that an implementation was not provided. + * + * @version $Rev$ $Date$ + */ +public class MissingImplementationException extends LoaderException { + private static final long serialVersionUID = -2917278473974880124L; + + /** + * Default constructor. + */ + public MissingImplementationException() { + super(); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java new file mode 100644 index 0000000000..4b44332de6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java @@ -0,0 +1,35 @@ +/* + * 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.spi.loader; + +/** + * Exception that indicates that an include was not provided. + * + * @version $Rev$ $Date$ + */ +public class MissingIncludeException extends LoaderException { + private static final long serialVersionUID = -2917278473974880124L; + + /** + * Default constructor. + */ + public MissingIncludeException() { + super(); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingMustOverridePropertyException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingMustOverridePropertyException.java new file mode 100644 index 0000000000..22042d46ac --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingMustOverridePropertyException.java @@ -0,0 +1,28 @@ +/* + * 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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class MissingMustOverridePropertyException extends LoaderException { + public MissingMustOverridePropertyException(String name) { + super(name); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java new file mode 100644 index 0000000000..b24806543c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Exception that indicates an expected resource could not be found. The message should be set to the name of the + * resource. + * + * @version $Rev$ $Date$ + */ +public class MissingResourceException extends LoaderException { + private static final long serialVersionUID = 3775013318397916445L; + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param resource the resource that could not be found + */ + public MissingResourceException(String resource) { + super(resource); + } + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param resource the resource that could not be found + */ + public MissingResourceException(String resource, Throwable cause) { + super(resource, cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/NotOverridablePropertyException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/NotOverridablePropertyException.java new file mode 100644 index 0000000000..4672f22a6a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/NotOverridablePropertyException.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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class NotOverridablePropertyException extends LoaderException { + private static final long serialVersionUID = 1483304023970967982L; + + public NotOverridablePropertyException(String name) { + super(name); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.java new file mode 100644 index 0000000000..8b569d76fb --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.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.spi.loader; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +/** + * A factory that will create an ObjectFactory for a property + * + * @version $Rev$ $Date$ + */ +public interface PropertyObjectFactory { + /** + * Return an ObjectFactory for instances of a property defined in an XML. The ObjectFactory must return instances + * that can safely be supplied to component implementations. If the instance is mutable and isolation between + * components is required, then the factory must clone or otherwise protect the implementation from unexpected + * modifications by other implementation instances. + * + * @param property the Property definition that the resulting ObjectFactory must be able to assign to + * @param propertyValue The component configuration of the property + * @return an ObjectFactory that can produce instances that can be assigned to the supplied Property + * @throws LoaderException if there is a problem creating the ObjectFactory + */ + <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> propertyValue) + throws LoaderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.java new file mode 100644 index 0000000000..08e873d86e --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.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.spi.loader; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * A loader that creates a model object from a StAX input stream. + * + * @version $Rev$ $Date$ + */ +public interface StAXElementLoader<T extends ModelObject> { + /** + * Create the model object for an element in an XML stream. When this method returns the stream will be positioned + * on the corresponding END_ELEMENT. + * + * @param parent + * @param reader the XML stream reader positioned on the applicable START_ELEMENT + * @param deploymentContext the context for the load operation + * @return the model object for that element + */ + T load(CompositeComponent parent, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.java new file mode 100644 index 0000000000..c2521071e1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.java @@ -0,0 +1,28 @@ +/* + * 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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class UndefinedPropertyException extends LoaderException { + public UndefinedPropertyException(String name) { + super(name); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnexpectedElementException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnexpectedElementException.java new file mode 100644 index 0000000000..cd5542f901 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnexpectedElementException.java @@ -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. + */ +package org.apache.tuscany.spi.loader; + +import javax.xml.namespace.QName; + +/** + * Exception that indicates that an element was found during loading that when loaded resulted in an unexpected type. + * This should not occur if the document being parsed conforms to its schema. The messages set to the name of the + * element + * + * @version $Rev$ $Date$ + */ +public class UnexpectedElementException extends LoaderException { + public UnexpectedElementException(QName element) { + super(element.toString()); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.java new file mode 100644 index 0000000000..b103c50f79 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.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.spi.loader; + +import javax.xml.namespace.QName; + +/** + * Exception that indicates an element was encountered that could not be handled. + * + * @version $Rev$ $Date$ + */ +public class UnrecognizedElementException extends LoaderException { + private static final long serialVersionUID = 2549543622209829032L; + private final QName element; + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param element the element that could not be handled + */ + public UnrecognizedElementException(QName element) { + super(element.toString()); + setIdentifier(getMessage()); + this.element = element; + } + + public QName getElement() { + return element; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java new file mode 100644 index 0000000000..8e12e970ae --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java @@ -0,0 +1,33 @@ +/* + * 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.spi.model; + +/** + * The base representation of an atomic component implementation + * + * @version $Rev$ $Date$ + */ +public abstract class AtomicImplementation<T extends ComponentType> extends Implementation<T> { + protected AtomicImplementation() { + } + + protected AtomicImplementation(T componentType) { + super(componentType); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Binding.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Binding.java new file mode 100644 index 0000000000..3b9a20c38e --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Binding.java @@ -0,0 +1,27 @@ +/* + * 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.spi.model; + +/** + * The base representation of a binding specified in an assembly + * + * @version $Rev$ $Date$ + */ +public abstract class Binding extends ModelObject { +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BindlessServiceDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BindlessServiceDefinition.java new file mode 100644 index 0000000000..e17269ddff --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BindlessServiceDefinition.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.spi.model; + +import java.net.URI; + +/** + * Represents a service in a composite, with an interface and a reference target. + * + * @version $Rev$ $Date$ + */ +public class BindlessServiceDefinition extends ServiceDefinition { + private URI target; + + public BindlessServiceDefinition(String name, ServiceContract contract, boolean remotable, URI target) { + super(name, contract, remotable); + this.target = target; + } + + public BindlessServiceDefinition() { + } + + public URI getTarget() { + return target; + } + + public void setTarget(URI target) { + this.target = target; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundReferenceDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundReferenceDefinition.java new file mode 100644 index 0000000000..bb973419b6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundReferenceDefinition.java @@ -0,0 +1,36 @@ +/* + * 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.spi.model; + +/** + * Represents a reference configured with a binding in a composite + * + * @version $Rev$ $Date$ + */ +public class BoundReferenceDefinition<B extends Binding> extends ReferenceDefinition { + private B binding; + + public B getBinding() { + return binding; + } + + public void setBinding(B binding) { + this.binding = binding; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundServiceDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundServiceDefinition.java new file mode 100644 index 0000000000..8c82d8a815 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/BoundServiceDefinition.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +import java.net.URI; + +/** + * Represents a service offered by a component, that has a particular binding associated with it. + * + * @version $Rev$ $Date$ + */ +public class BoundServiceDefinition<B extends Binding> extends ServiceDefinition { + private B binding; + private URI target; + + public BoundServiceDefinition(String name, ServiceContract contract, boolean remotable, B binding, URI target) { + super(name, contract, remotable); + this.binding = binding; + this.target = target; + } + + public BoundServiceDefinition() { + } + + public B getBinding() { + return binding; + } + + public void setBinding(B binding) { + this.binding = binding; + } + + public URI getTarget() { + return target; + } + + public void setTarget(URI target) { + this.target = target; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java new file mode 100644 index 0000000000..de4abbd4e8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java @@ -0,0 +1,154 @@ +/* + * 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.spi.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a component. + * <p>A component is a configured instance of an implementation. The services provided and consumed + * and the available configuration properties are defined by the implementation (represented by + * its componentType).</p> + * <p>Every component has a name which uniquely identifies it within the scope of the composite + * that contains it; the name must be different from the names of all other components, services and references + * immediately contained in the composite (directly or through an <include> element).</p> + * <p>A component may define a {@link PropertyValue} that overrides the default value of a {@link Property} + * defined in the componentType.</p> + * <p>It may also define a {@link ReferenceTarget} for a {@link ReferenceDefinition} defined in the componentType. + * The ReferenceTarget must resolve to another component or a reference in the enclosing composite.</p> + * <p>Components may specify an initialization level that will determine the order in which it will be eagerly + * initialized relative to other components from the enclosing composite that are in the same scope. This can be + * used to define a startup sequence for components that are otherwise independent. Any initialization required + * to resolve references between components will override this initialization order.</p> + * + * @version $Rev$ $Date$ + */ +public class ComponentDefinition<I extends Implementation<?>> extends ModelObject { + private String name; + private Integer initLevel; + private final I implementation; + private final Map<String, ReferenceTarget> referenceTargets = new HashMap<String, ReferenceTarget>(); + private final Map<String, PropertyValue<?>> propertyValues = new HashMap<String, PropertyValue<?>>(); + + /** + * Constructor specifying the component's name and implementation. + * + * @param name the name of this component + * @param implementation the implementation of this component + */ + public ComponentDefinition(String name, I implementation) { + this.name = name; + this.implementation = implementation; + } + + /** + * Constructor specifying the implementation of this component. + * + * @param implementation the implementation of this component + */ + public ComponentDefinition(I implementation) { + this.implementation = implementation; + } + + /** + * Returns the {@link Implementation} of this component. + * + * @return the implementation of this component + */ + public I getImplementation() { + return implementation; + } + + /** + * Returns the name of this component. + * + * @return the name of this component + */ + public String getName() { + return name; + } + + /** + * Sets the name of this component. + * + * @param name the name of this component + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the initialization level of this component. + * + * @return the initialization level of this component + */ + public Integer getInitLevel() { + return initLevel; + } + + /** + * Sets the initialization level of this component. + * If set to null then the level from the componentType is used. + * If set to zero or a negative value then the component will not be eagerly initialized. + * + * @param initLevel the initialization level of this component + */ + public void setInitLevel(Integer initLevel) { + this.initLevel = initLevel; + } + + /** + * Returns a live Map of the {@link ReferenceTarget targets} configured by this component definition. + * + * @return the reference targets configured by this component + */ + public Map<String, ReferenceTarget> getReferenceTargets() { + return referenceTargets; + } + + /** + * Add a reference target configuration to this component. + * Any existing configuration for the reference named in the target is replaced. + * + * @param target the target to add + */ + public void add(ReferenceTarget target) { + referenceTargets.put(target.getReferenceName(), target); + } + + /** + * Returns a live Map of {@link PropertyValue property values} configured by this component definition. + * + * @return the property values configured by this component + */ + public Map<String, PropertyValue<?>> getPropertyValues() { + return propertyValues; + } + + /** + * Add a property value configuration to this component. + * Any existing configuration for the property names in the property value is replaced. + * + * @param value the property value to add + */ + public void add(PropertyValue<?> value) { + propertyValues.put(value.getName(), value); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java new file mode 100644 index 0000000000..5d254d5437 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java @@ -0,0 +1,143 @@ +/* + * 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.spi.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * <p>The definition of the configurable aspects of an implementation in terms of the services it exposes, + * the services it references, and properties that can be used to configure it.</p> + * <p>A service represents an addressable interface provided by the implementation. Such a service + * may be the target of a wire from another component.</p> + * <p>A reference represents a requirement that an implementation has on a service provided by another + * component or by a resource outside the SCA system. Such a reference may be the source of a wire to another + * component.</p> + * <p>A property allows the behaviour of the implementation to be configured through externally set values.</p> + * <p>A component type may also declare that it wishes to be initialized upon activation of the scope that + * contains it and may specify an order relative to other eagerly initializing components. For example, an + * implementation that pre-loads some form of cache could declare that it should be eagerly initialized at + * the start of the scope so that the cache load occured on startup rather than first use.</p> + * + * @version $Rev$ $Date$ + */ +public class ComponentType<S extends ServiceDefinition, R extends ReferenceDefinition, P extends Property<?>> + extends ModelObject { + private int initLevel; + private final Map<String, S> services = new HashMap<String, S>(); + private final Map<String, R> references = new HashMap<String, R>(); + private final Map<String, P> properties = new HashMap<String, P>(); + + /** + * Returns the default initialization level for components of this type. + * A value greater than zero indicates that components should be eagerly initialized. + * + * @return the default initialization level + */ + public int getInitLevel() { + return initLevel; + } + + /** + * Sets the default initialization level for components of this type. + * A value greater than zero indicates that components should be eagerly initialized. + * + * @param initLevel default initialization level for components of this type + */ + public void setInitLevel(int initLevel) { + this.initLevel = initLevel; + } + + /** + * Returns true if this component should be eagerly initialized. + * + * @return true if this component should be eagerly initialized + */ + public boolean isEagerInit() { + return initLevel > 0; + } + + /** + * Obsolete method for indicating that this component should be eagerly initialized. + * If true, sets the init level to 50; if false, sets it to zero. + * + * @param eagerInit flag indicating that this component should be eagerly initialized + */ + @Deprecated + public void setEagerInit(boolean eagerInit) { + initLevel = eagerInit ? 50 : 0; + } + + /** + * Returns a live Map of the services provided by the implementation. + * + * @return a live Map of the services provided by the implementation + */ + public Map<String, S> getServices() { + return services; + } + + /** + * Add a service to those provided by the implementation. + * Any existing service with the same name is replaced. + * + * @param service a service provided by the implementation + */ + public void add(S service) { + services.put(service.getName(), service); + } + + /** + * Returns a live Map of references to services consumed by the implementation. + * + * @return a live Map of references to services consumed by the implementation + */ + public Map<String, R> getReferences() { + return references; + } + + /** + * Add a reference to a service consumed by the implementation. + * Any existing reference with the same name is replaced. + * + * @param reference a reference to a service consumed by the implementation + */ + public void add(R reference) { + references.put(reference.getName(), reference); + } + + /** + * Returns a live Map of properties that can be used to configure the implementation. + * + * @return a live Map of properties that can be used to configure the implementation + */ + public Map<String, P> getProperties() { + return properties; + } + + /** + * Add a property that can be used to configure the implementation. + * Any existing property with the same name is replaced. + * + * @param property a property that can be used to configure the implementation + */ + public void add(P property) { + properties.put(property.getName(), property); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java new file mode 100644 index 0000000000..c13cceca8c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java @@ -0,0 +1,146 @@ +/* + * 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.spi.model; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A specialization of component type for composite components. + * + * @version $Rev$ $Date$ + */ +public class CompositeComponentType<S extends ServiceDefinition, + R extends ReferenceDefinition, + P extends Property<?>> extends ComponentType<S, R, P> { + + private String name; + private final Map<String, ComponentDefinition<? extends Implementation<?>>> components = + new HashMap<String, ComponentDefinition<? extends Implementation<?>>>(); + private final Map<String, Include> includes = new HashMap<String, Include>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + @SuppressWarnings("unchecked") + /** + * Get all properties including the ones are from included composites + * @return + */ + public Map<String, P> getProperties() { + Map<String, P> view = new HashMap<String, P>(super.getProperties()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getProperties()); + } + return Collections.unmodifiableMap(view); + } + + @Override + @SuppressWarnings("unchecked") + /** + * Get all references including the ones are from included composites + * @return + */ + public Map<String, R> getReferences() { + Map<String, R> view = new HashMap<String, R>(super.getReferences()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getReferences()); + } + return Collections.unmodifiableMap(view); + } + + @SuppressWarnings("unchecked") + @Override + /** + * Get all services including the ones are from included composites + * @return + */ + public Map<String, S> getServices() { + Map<String, S> view = new HashMap<String, S>(super.getServices()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getServices()); + } + return Collections.unmodifiableMap(view); + } + + /** + * Get all components including the ones are from included composites + * @return + */ + @SuppressWarnings("unchecked") + public Map<String, ComponentDefinition<? extends Implementation<?>>> getComponents() { + Map<String, ComponentDefinition<? extends Implementation<?>>> view = + new HashMap<String, ComponentDefinition<? extends Implementation<?>>>(components); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getComponents()); + } + return Collections.unmodifiableMap(view); + } + + /** + * Get declared properties in this composite type, included doesn't count + * @return + */ + public Map<String, P> getDeclaredProperties() { + return super.getProperties(); + } + + /** + * Get declared references in this composite type, included doesn't count + * @return + */ + public Map<String, R> getDeclaredReferences() { + return super.getReferences(); + } + + /** + * Get declared services in this composite type, included doesn't count + * @return + */ + public Map<String, S> getDeclaredServices() { + return super.getServices(); + } + + /** + * Get declared components in this composite type, included doesn't count + * @return + */ + public Map<String, ComponentDefinition<? extends Implementation<?>>> getDeclaredComponents() { + return components; + } + + public void add(ComponentDefinition<? extends Implementation<?>> componentDefinition) { + components.put(componentDefinition.getName(), componentDefinition); + } + + public Map<String, Include> getIncludes() { + return includes; + } + + public void add(Include include) { + includes.put(include.getName(), include); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.java new file mode 100644 index 0000000000..6948c52286 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.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.spi.model; + +import java.net.URL; + +/** + * A specialization of an implementation associated with composite components + * + * @version $Rev$ $Date$ + */ +public class CompositeImplementation extends Implementation<CompositeComponentType> { + private String name; + private URL scdlLocation; + private ClassLoader classLoader; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public URL getScdlLocation() { + return scdlLocation; + } + + public void setScdlLocation(URL scdlLocation) { + this.scdlLocation = scdlLocation; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java new file mode 100644 index 0000000000..c98c113d95 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java @@ -0,0 +1,223 @@ +/* + * 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.spi.model; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Representation of the type of data associated with an operation. Data is represented in two forms: the physical form + * used by the runtime and a logical form used by the assembly. The physical form is a Java Type because the runtime is + * written in Java. This may be the same form used by the application but it may not; for example, an application that + * is performing stream processing may want a physical form such as an {@link java.io.InputStream InputStream} to + * semantially operate on application data such as a purchase order. The logical description is that used by the + * assembly model and is an identifier into some well-known type space; examples may be a Java type represented by its + * Class or an XML type represented by its QName. Every data type may also contain metadata describing the expected + * data; for example, it could specify a preferred data binding technology or the size of a typical instance. + * + * @version $Rev$ $Date$ + */ +public class DataType<L> extends ModelObject { + private String dataBinding = Object.class.getName(); + + private final Type physical; + + private final L logical; + + private final Map<String, Object> metadata = new HashMap<String, Object>(); + + /** + * Construct a data type specifying the physical and logical types. + * + * @param physical the physical class used by the runtime + * @param logical the logical type + * @see #getLogical() + */ + public DataType(Type physical, L logical) { + this.physical = physical; + this.logical = logical; + if (physical instanceof Class) { + this.dataBinding = ((Class) physical).getName(); + } + } + + public DataType(String dataBinding, Type physical, L logical) { + this.dataBinding = dataBinding; + this.physical = physical; + this.logical = logical; + } + + /** + * Returns the physical type used by the runtime. + * + * @return the physical type used by the runtime + */ + public Type getPhysical() { + return physical; + } + + /** + * Returns the logical identifier used by the assembly. The type of this value identifies the logical type system in + * use. Known values are: <ul> <li>a java.lang.reflect.Type identifies a Java type by name and ClassLoader; this + * includes Java Classes as they are specializations of Type</li> <li>a javax.xml.namespace.QName identifies an XML + * type by local name and namespace</li> </ul> + * + * @return the logical type name + */ + public L getLogical() { + return logical; + } + + /** + * Returns all metadata about this type. + * + * @return all metadata about this type + */ + public Map<String, ?> getMetadata() { + return metadata; + } + + /** + * Returns the specified metadata item or null if not present. + * + * @param name the name of the metadata item + * @return the value, or null if not present + */ + public Object getMetadata(String name) { + return metadata.get(name); + } + + /** + * Sets the specified metadata value. A null value undefines it. + * + * @param name the name of the metadata item + * @param value the value, or null to undefine + * @return the old value for the item, or null if not present + */ + public Object setMetadata(String name, Object value) { + if (value == null) { + return metadata.remove(name); + } else { + return metadata.put(name, value); + } + } + + public String getDataBinding() { + if (dataBinding == null) { + // databinding is not set at the DataType level, check the operation + Operation<?> operation = (Operation<?>) getMetadata(Operation.class.getName()); + if (operation != null) { + return operation.getDataBinding(); + } + } + return dataBinding; + } + + /** + * @param dataBinding the dataBinding to set + */ + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + public int hashCode() { + int result; + result = dataBinding != null ? dataBinding.hashCode() : 0; + result = 29 * result + (physical != null ? physical.hashCode() : 0); + result = 29 * result + (logical != null ? logical.hashCode() : 0); + // Commented the following line out since it causes infinite loop from Operation.hashCode() + // if the metadata map contains the Operation + // result = 29 * result + (metadata != null ? metadata.hashCode() : 0); + return result; + } + + public boolean equals(Object o){ + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final DataType dataType = (DataType) o; + + if (dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null) { + return false; + } + if (logical != null ? !logical.equals(dataType.logical) : dataType.logical != null) { + return false; + } + return !(physical != null ? !physical.equals(dataType.physical) : dataType.physical != null); + + } + +// @SuppressWarnings("unchecked") +// public boolean equals(Object o) { +// if (this == o) { +// return true; +// } +// if (o == null || getClass() != o.getClass()) { +// return false; +// } +// +// final DataType dataType = (DataType) o; +// +// if (logical instanceof Class && dataType.logical instanceof Class) { +// Class<?> logicalClass = (Class<?>) logical; +// Class<?> targetLogicalClass = (Class<?>) dataType.logical; +// if (!logicalClass.isAssignableFrom(targetLogicalClass)) { +// return false; +// } +// } else { +// if (logical != null ? !logical.equals(dataType.logical) : dataType.logical != null) { +// return false; +// } +// } +// if (physical instanceof Class && dataType.physical instanceof Class) { +// Class<?> physicalClass = (Class<?>) physical; +// Class<?> physicalTargetClass = (Class<?>) dataType.physical; +// if (dataBinding != null +// && dataType.dataBinding != null +// && dataBinding.equals(physicalClass.getName()) +// && dataType.dataBinding.equals(physicalTargetClass.getName())) { +// return physicalClass.isAssignableFrom(physicalTargetClass); +// } +// if (!physicalClass.isAssignableFrom(physicalTargetClass)) { +// return false; +// } +// return !(dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null); +// +// +// } +// +// if (dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null) { +// return false; +// } +// +// return !(physical != null ? !physical.equals(dataType.physical) : dataType.physical != null); +// } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(physical).append(" ").append(dataBinding).append(" ").append(logical); + return sb.toString(); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.java new file mode 100644 index 0000000000..8520ab49e8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.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.spi.model; + +/** + * Represents a component implementation + * + * @version $Rev$ $Date$ + */ +public abstract class Implementation<T extends ComponentType> extends ModelObject { + private T componentType; + + protected Implementation() { + } + + protected Implementation(T componentType) { + this.componentType = componentType; + } + + public T getComponentType() { + return componentType; + } + + public void setComponentType(T componentType) { + this.componentType = componentType; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Include.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Include.java new file mode 100644 index 0000000000..ac320a2b5c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Include.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.spi.model; + +import java.net.URL; + +/** + * Model object that represents the include of a composite by value. + * + * @version $Rev$ $Date$ + */ +public class Include extends ModelObject { + private String name; + private URL scdlLocation; + private CompositeComponentType included; + + /** + * Returns the name of the composite that is being included. + * @return the name of the composite that is being included + */ + public String getName() { + return name; + } + + /** + * Sets the name of the composite that is being included. + * @param name the name of the composite that is being included + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the location of the SCDL for composite being included. + * @return the location of the SCDL for composite being included + */ + public URL getScdlLocation() { + return scdlLocation; + } + + /** + * Sets the location of the SCDL for composite being included. + * @param scdlLocation the location of the SCDL for composite being included + */ + public void setScdlLocation(URL scdlLocation) { + this.scdlLocation = scdlLocation; + } + + /** + * Returns the composite that was included. + * @return the composite that was included + */ + public CompositeComponentType getIncluded() { + return included; + } + + /** + * Sets the composite that was included. + * @param included the composite that was included + */ + public void setIncluded(CompositeComponentType included) { + this.included = included; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/InteractionScope.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/InteractionScope.java new file mode 100644 index 0000000000..4e15e353c6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/InteractionScope.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.spi.model; + +/** + * Represents the interaction scope specifed for a service + * + * @version $Rev$ $Date$ + */ +public enum InteractionScope { + CONVERSATIONAL, + NONCONVERSATIONAL +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.java new file mode 100644 index 0000000000..2d5a0802e6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * The base class for assembly model subtypes + * + * @version $Rev$ $Date$ + */ +public abstract class ModelObject { + private final Map<Object, Object> extensions = new HashMap<Object, Object>(); + + protected ModelObject() { + } + + public Map<Object, Object> getExtensions() { + return extensions; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.java new file mode 100644 index 0000000000..f7ec8759f8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.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.spi.model; + +/** + * Enumeration for multiplicity. + */ +public enum Multiplicity { + /** + * Indicates a relationship that is optionally connected to the requestor and which, if supplied, must be connected + * to exactly one provider. + */ + ZERO_ONE, + + /** + * Indicates a relationship that must be connected between exactly one requestor and exactly one provider. + */ + ONE_ONE, + + /** + * Indicates a relationship that is optionally connects the requestor to zero to unbounded providers. + */ + ZERO_N, + + /** + * Indicates a relationship that must be connected at the requestor and which connects it to zero to unbounded + * providers. + */ + ONE_N + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java new file mode 100644 index 0000000000..b461f0e730 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java @@ -0,0 +1,351 @@ +/* + * 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.spi.model; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.idl.WrapperInfo; + +/** + * Represents an operation that is part of a service contract. The type paramter of this operation identifies the + * logical type system for all data types. + * + * @version $Rev$ $Date$ + */ +public class Operation<T> { + private static final String NAME = Operation.class.getName(); + + protected Map<String, Object> metaData; + + private final String name; + + private final DataType<T> outputType; + + private final DataType<List<DataType<T>>> inputType; + + private final List<DataType<T>> faultTypes; + + private boolean nonBlocking; + + private ServiceContract<T> contract; + + private boolean callback; + + private String dataBinding; + + private boolean wrapperStyle; + private WrapperInfo wrapper; + + /** + * Construct a minimally-specified operation + * + * @param name the name of the operation + * @param inputType the data types of parameters passed to the operation + * @param outputType the data type returned by the operation + * @param faultTypes the data type of faults raised by the operation + */ + public Operation(String name, + DataType<List<DataType<T>>> inputType, + DataType<T> outputType, + List<DataType<T>> faultTypes) { + this(name, inputType, outputType, faultTypes, false, null); + } + + /** + * Construct an operation + * + * @param name the name of the operation + * @param inputType the data types of parameters passed to the operation + * @param outputType the data type returned by the operation + * @param faultTypes the data type of faults raised by the operation + * @param nonBlocking if the operation is non-blocking + * @param dataBinding the data-binding type required by the operation + */ + public Operation(final String name, + final DataType<List<DataType<T>>> inputType, + final DataType<T> outputType, + final List<DataType<T>> faultTypes, + boolean nonBlocking, + String dataBinding) { + super(); + this.name = name; + List<DataType<T>> types = Collections.emptyList(); + this.inputType = (inputType != null) ? inputType : new DataType<List<DataType<T>>>(Object[].class, types); + this.outputType = (outputType != null) ? outputType : new DataType<T>(void.class, null); + this.faultTypes = (faultTypes == null) ? types : faultTypes; + this.nonBlocking = nonBlocking; + this.dataBinding = dataBinding; + // Register the operation with the types + for (DataType<?> d : this.inputType.getLogical()) { + d.setMetadata(NAME, this); + } + this.outputType.setMetadata(NAME, this); + for (DataType<?> d : this.faultTypes) { + d.setMetadata(NAME, this); + } + } + + /** + * Returns the service contract the operation is part of. + * + * @return the service contract the operation is part of. + */ + public ServiceContract<T> getServiceContract() { + return contract; + } + + /** + * Sets the service contract the operation is part of. + * + * @param contract the service contract the operation is part of. + */ + public void setServiceContract(ServiceContract<T> contract) { + this.contract = contract; + } + + /** + * Returns true if the operation is part of the callback contract. + * + * @return true if the operation is part of the callback contract. + */ + public boolean isCallback() { + return callback; + } + + /** + * Sets whether the operation is part of the callback contract. + * + * @param callback whether the operation is part of the callback contract. + */ + public void setCallback(boolean callback) { + this.callback = callback; + } + + /** + * Returns the name of the operation. + * + * @return the name of the operation + */ + public String getName() { + return name; + } + + /** + * Returns the data type returned by the operation. + * + * @return the data type returned by the operation + */ + public DataType<T> getOutputType() { + return outputType; + } + + /** + * Returns the data types of the parameters passed to the operation. + * <p/> + * The inputType's logical type is a list of DataTypes which describes the parameter types + * + * @return the data types of the parameters passed to the operation + */ + public DataType<List<DataType<T>>> getInputType() { + return inputType; + } + + /** + * Returns the data types of the faults raised by the operation. + * + * @return the data types of the faults raised by the operation + */ + public List<DataType<T>> getFaultTypes() { + if (faultTypes == null) { + return Collections.emptyList(); + } + return faultTypes; + } + + /** + * Returns true if the operation is non-blocking. A non-blocking operation may not have completed execution at the + * time an invocation of the operation returns. + * + * @return true if the operation is non-blocking + */ + public boolean isNonBlocking() { + return nonBlocking; + } + + /** + * Returns the data binding type specified for the operation or null. + * + * @return the data binding type specified for the operation or null. + */ + public String getDataBinding() { + return (dataBinding == null && contract != null) ? contract.getDataBinding() : dataBinding; + } + + /** + * Set the databinding for this operation + * + * @param dataBinding The databinding + */ + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + /** + * Returns a map of metadata key to value mappings for the operation. + * + * @return a map of metadata key to value mappings for the operation. + */ + public Map<String, Object> getMetaData() { + if (metaData == null) { + return Collections.emptyMap(); + } + return metaData; + } + + /** + * Adds metadata associated with the operation. + * + * @param key the metadata key + * @param val the metadata value + */ + public void setMetaData(String key, Object val) { + if (metaData == null) { + metaData = new HashMap<String, Object>(); + } + metaData.put(key, val); + } + + /** + * Sets if the operation is non-blocking + */ + public void setNonBlocking(boolean nonBlocking) { + this.nonBlocking = nonBlocking; + } + + public String toString() { + return name; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final Operation operation = (Operation) o; + + if (name != null ? !name.equals(operation.name) : operation.name != null) { + return false; + } + + // HACK: If the operation is mappable, then the equality test is relaxed + if (isMappable()) { + return true; + } + + if (faultTypes == null && operation.faultTypes != null) { + return false; + } else if (faultTypes != null + && operation.faultTypes != null + && faultTypes.size() != 0 + && operation.faultTypes.size() != 0) { + if (faultTypes.size() < operation.faultTypes.size()) { + return false; + } else { + for (int i = 0; i < operation.faultTypes.size(); i++) { + if (!faultTypes.get(i).equals(operation.faultTypes.get(i))) { + return false; + } + } + } + } + + if (inputType != null ? !inputType.equals(operation.inputType) : operation.inputType != null) { + return false; + } + return !(outputType != null ? !outputType.equals(operation.outputType) : operation.outputType != null); + } + + public int hashCode() { + int result; + result = name != null ? name.hashCode() : 0; + // HACK: + if (isMappable()) { + return result; + } + result = 29 * result + (outputType != null ? outputType.hashCode() : 0); + result = 29 * result + (inputType != null ? inputType.hashCode() : 0); + result = 29 * result + (faultTypes != null ? faultTypes.hashCode() : 0); + return result; + } + + /** + * Returns true if the operation may be mapped to another target operation through an mediation + */ + private boolean isMappable() { + if (contract != null) { + return contract.isRemotable(); + } else { + return false; + } + } + + /** + * Returns true if the operation is wrapper style + * + * @return the wrapperStyle + */ + public boolean isWrapperStyle() { + return wrapperStyle; + } + + /** + * Return the Wrapper information for this operation is it's wrapper style + * + * @return The Wrapper + */ + public WrapperInfo getWrapper() { + if (!isWrapperStyle()) { + throw new IllegalStateException("The operation is not wrapper style."); + } else { + return wrapper; + } + } + + /** + * @param wrapper the wrapper to set + */ + public void setWrapper(WrapperInfo wrapper) { + this.wrapper = wrapper; + } + + /** + * @param wrapperStyle the wrapperStyle to set + */ + public void setWrapperStyle(boolean wrapperStyle) { + this.wrapperStyle = wrapperStyle; + } + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/OverrideOptions.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/OverrideOptions.java new file mode 100644 index 0000000000..cc86b2670a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/OverrideOptions.java @@ -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. + */ + +package org.apache.tuscany.spi.model; + +/** + * <ul> + * <li>no – the value may not be overridden by the higher composite. In this + * case, a value must be provided for the reference or property as part of its + * declaration. + * <li>may – the value may be overridden by the composite. This is the default + * for references. + * <li>must – no value is specified and the using composite must specify one. + * </ul> + */ +public enum OverrideOptions { + NO, MAY, MUST +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Property.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Property.java new file mode 100644 index 0000000000..700b099da7 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Property.java @@ -0,0 +1,105 @@ +/* + * 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.spi.model; + +import javax.xml.namespace.QName; + +import org.w3c.dom.Document; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * A component property + * + * @version $Rev$ $Date$ + */ +public class Property<T> extends ModelObject { + private String name; + private ObjectFactory<T> defaultValueFactory; + private QName xmlType; + private Class<T> javaType; + private boolean many; + private OverrideOptions override; + private Document defaultValue; + + public Property() { + } + + public Property(String name, QName xmlType, Class<T> javaType) { + this.name = name; + this.xmlType = xmlType; + this.javaType = javaType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ObjectFactory<T> getDefaultValueFactory() { + return defaultValueFactory; + } + + public void setDefaultValueFactory(ObjectFactory<T> factory) { + this.defaultValueFactory = factory; + } + + public QName getXmlType() { + return xmlType; + } + + public void setXmlType(QName xmlType) { + this.xmlType = xmlType; + } + + public Class<T> getJavaType() { + return javaType; + } + + public void setJavaType(Class<T> javaType) { + this.javaType = javaType; + } + + public boolean isMany() { + return many; + } + + public void setMany(boolean many) { + this.many = many; + } + + public OverrideOptions getOverride() { + return override; + } + + public void setOverride(OverrideOptions override) { + this.override = override; + } + + public Document getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(Document defaultValue) { + this.defaultValue = defaultValue; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java new file mode 100644 index 0000000000..93eaa74f52 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +import org.apache.tuscany.spi.ObjectFactory; +import org.w3c.dom.Document; + +/** + * Represents a configured component property + * + * @version $Rev$ $Date$ + */ +public class PropertyValue<T> extends ModelObject { + private String name; + private String source; + private String file; + private Document value; + private ObjectFactory<T> valueFactory; + + public PropertyValue() { + } + + /** + * Constructor specifying the name of a property and the XPath source expression. + * + * @param name the name of the property which this value is for + * @param source an XPath expression whose result will be the actual value + * @param file A URI that the property value can be loaded from + */ + public PropertyValue(String name, String source, String file) { + this.name = name; + this.source = source; + this.file = file; + } + + /** + * @param name + * @param value + */ + public PropertyValue(String name, Document value) { + this.name = name; + this.value = value; + } + + public PropertyValue(String name, ObjectFactory<T> valueFactory) { + this.name = name; + this.valueFactory = valueFactory; + } + + /** + * Returns the name of the property that this value is for. + * @return the name of the property that this value is for + */ + public String getName() { + return name; + } + + /** + * Sets the name of the property that this value is for. + * @param name the name of the property that this value is for + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns an XPath expression that should be evaluated to get the actual property value. + * + * @return an XPath expression that should be evaluated to get the actual property value + */ + public String getSource() { + return source; + } + + /** + * Sets an XPath expression that should be evaluated to get the actual property value. + * @param source an XPath expression that should be evaluated to get the actual property value + */ + public void setSource(String source) { + this.source = source; + } + + public ObjectFactory<T> getValueFactory() { + return valueFactory; + } + + public void setValueFactory(ObjectFactory<T> valueFactory) { + this.valueFactory = valueFactory; + } + + public Document getValue() { + return value; + } + + public void setValue(Document value) { + this.value = value; + } + + /** + * @return the file + */ + public String getFile() { + return file; + } + + /** + * @param file the file to set + */ + public void setFile(String file) { + this.file = file; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.java new file mode 100644 index 0000000000..f167272705 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.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.spi.model; + +/** + * Represents a component reference + * + * @version $Rev$ $Date$ + */ +public class ReferenceDefinition extends ModelObject { + private String name; + private ServiceContract serviceContract; + private Multiplicity multiplicity; + private boolean autowire; + private boolean required; + + public ReferenceDefinition() { + } + + public ReferenceDefinition(String name, ServiceContract serviceContract) { + this.name = name; + this.serviceContract = serviceContract; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + public void setServiceContract(ServiceContract serviceContract) { + this.serviceContract = serviceContract; + } + + public Multiplicity getMultiplicity() { + return multiplicity; + } + + public void setMultiplicity(Multiplicity multiplicity) { + this.multiplicity = multiplicity; + } + + public boolean isAutowire() { + return autowire; + } + + public void setAutowire(boolean autowire) { + this.autowire = autowire; + } + + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.java new file mode 100644 index 0000000000..db0bdb2b22 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.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.spi.model; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents the set of targets configured on a reference + * + * @version $Rev$ $Date$ + */ +public class ReferenceTarget extends ModelObject { + private String referenceName; + private List<URI> targets = new ArrayList<URI>(); + + public String getReferenceName() { + return referenceName; + } + + public void setReferenceName(String referenceName) { + this.referenceName = referenceName; + } + + public List<URI> getTargets() { + return targets; + } + + public void addTarget(URI target) { + targets.add(target); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Scope.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Scope.java new file mode 100644 index 0000000000..9995cd4ec5 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/Scope.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +/** + * The default implementation scopes supported by assemblies. + */ +public class Scope { + public static final Scope STATELESS = new Scope("STATELESS"); + public static final Scope REQUEST = new Scope("REQUEST"); + public static final Scope SESSION = new Scope("SESSION"); + public static final Scope MODULE = new Scope("MODULE"); + public static final Scope COMPOSITE = new Scope("COMPOSITE"); + public static final Scope UNDEFINED = new Scope("UNDEFINED"); + + private String scope; + + public Scope(String scope) { + this.scope = scope.toUpperCase().intern(); + } + + public String getScope() { + return scope; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Scope scope1 = (Scope) o; + return !(scope != null ? scope != scope1.scope.intern() : scope1.scope != null); + } + + public int hashCode() { + return scope != null ? scope.hashCode() : 0; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java new file mode 100644 index 0000000000..91d5611689 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java @@ -0,0 +1,246 @@ +/* + * 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.spi.model; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Base class representing service contract information + * + * @version $Rev$ $Date$ + */ +public abstract class ServiceContract<T> extends ModelObject { + protected InteractionScope interactionScope; + protected boolean remotable; + protected Class<?> interfaceClass; + protected String interfaceName; + protected String callbackName; + protected Class<?> callbackClass; + protected Map<String, Operation<T>> operations; + protected Map<String, Operation<T>> callbackOperations; + protected String dataBinding; + protected Map<String, Object> metaData; + + protected ServiceContract() { + } + + protected ServiceContract(Class<?> interfaceClass) { + this.interfaceClass = interfaceClass; + } + + protected ServiceContract(String interfaceName) { + this.interfaceName = interfaceName; + } + + /** + * Returns the interface name for the contract + * + * @return the interface name for the contract + */ + public String getInterfaceName() { + return interfaceName; + } + + /** + * Sets the interface name for the contract + */ + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + /** + * Returns the class used to represent the service contract + */ + public Class<?> getInterfaceClass() { + return interfaceClass; + } + + /** + * Sets the class used to represent the service contract + */ + public void setInterfaceClass(Class<?> interfaceClass) { + this.interfaceClass = interfaceClass; + } + + /** + * Returns the service interaction scope + */ + public InteractionScope getInteractionScope() { + return interactionScope; + } + + /** + * Sets the service interaction scope + */ + public void setInteractionScope(InteractionScope interactionScope) { + this.interactionScope = interactionScope; + } + + /** + * @return the remotable + */ + public boolean isRemotable() { + return remotable; + } + + /** + * @param remotable the remotable to set + */ + public void setRemotable(boolean remotable) { + this.remotable = remotable; + } + + /** + * Returns the name of the callback or null if the contract is unidirectional + */ + public String getCallbackName() { + return callbackName; + } + + /** + * Sets the name of the callback service + */ + public void setCallbackName(String callbackName) { + this.callbackName = callbackName; + } + + /** + * Returns the name of the callback service + */ + public Class<?> getCallbackClass() { + return callbackClass; + } + + public void setCallbackClass(Class<?> callbackClass) { + this.callbackClass = callbackClass; + } + + public Map<String, Operation<T>> getOperations() { + if (operations == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(operations); + } + + public void setOperations(Map<String, Operation<T>> operations) { + for (Operation<T> operation : operations.values()) { + operation.setServiceContract(this); + } + this.operations = operations; + } + + public Map<String, Operation<T>> getCallbackOperations() { + if (callbackOperations == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(callbackOperations); + } + + public void setCallbackOperations(Map<String, Operation<T>> callbacksOperations) { + for (Operation<T> operation : callbacksOperations.values()) { + operation.setServiceContract(this); + operation.setCallback(true); + } + this.callbackOperations = callbacksOperations; + } + + public String getDataBinding() { + return dataBinding; + } + + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + /** + * Returns a map of metadata key to value mappings for the operation. + * + * @return a map of metadata key to value mappings for the operation. + */ + public Map<String, Object> getMetaData() { + if (metaData == null) { + return Collections.emptyMap(); + } + return metaData; + } + + /** + * Adds metadata associated with the operation. + * + * @param key the metadata key + * @param val the metadata value + */ + public void setMetaData(String key, Object val) { + if (metaData == null) { + metaData = new HashMap<String, Object>(); + } + metaData.put(key, val); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final ServiceContract that = (ServiceContract) o; + + if (callbackName != null ? !callbackName.equals(that.callbackName) : that.callbackName != null) { + return false; + } + if (callbackOperations != null ? !callbackOperations.equals(that.callbackOperations) + : that.callbackOperations != null) { + return false; + } + if (interfaceClass != null ? !interfaceClass.equals(that.interfaceClass) : that.interfaceClass != null) { + return false; + } + if (interfaceName != null ? !interfaceName.equals(that.interfaceName) : that.interfaceName != null) { + return false; + } + return !(operations != null ? !operations.equals(that.operations) : that.operations != null); + + } + + public int hashCode() { + int result; + result = interfaceClass != null ? interfaceClass.hashCode() : 0; + result = 29 * result + (interfaceName != null ? interfaceName.hashCode() : 0); + result = 29 * result + (callbackName != null ? callbackName.hashCode() : 0); + result = 29 * result + (operations != null ? operations.hashCode() : 0); + result = 29 * result + (callbackOperations != null ? callbackOperations.hashCode() : 0); + return result; + } + + public String toString() { + if (interfaceName != null) { + return new StringBuilder().append("ServiceContract[").append(interfaceName).append("]").toString(); + } else if (interfaceClass != null) { + return new StringBuilder().append("ServiceContract[").append(interfaceClass.getName()).append("]") + .toString(); + } else { + return super.toString(); + } + + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java new file mode 100644 index 0000000000..1667ff9272 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java @@ -0,0 +1,83 @@ +/* + * 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.spi.model; + +/** + * Represents a service offered by a component + * + * @version $Rev$ $Date$ + */ +public class ServiceDefinition extends ModelObject { + private String name; + private ServiceContract serviceContract; + private boolean remotable; + private String callbackRefName; + + public ServiceDefinition() { + } + + public ServiceDefinition(String name, ServiceContract serviceContract, boolean remotable) { + this.name = name; + this.serviceContract = serviceContract; + this.remotable = remotable; + } + + public ServiceDefinition(String name, ServiceContract serviceContract, boolean remotable, String callbackRefName) { + this.name = name; + this.serviceContract = serviceContract; + this.remotable = remotable; + this.callbackRefName = callbackRefName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + public void setServiceContract(ServiceContract serviceContract) { + this.serviceContract = serviceContract; + } + + public boolean isRemotable() { + return remotable; + } + + public void setRemotable(boolean remotable) { + this.remotable = remotable; + } + + /** + * Returns the callback name. + */ + public String getCallbackReferenceName() { + return callbackRefName; + } + + public void setCallbackReferenceName(String callbackRefName) { + this.callbackRefName = callbackRefName; + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.java new file mode 100644 index 0000000000..7ae91811b6 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.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.spi.model; + +import java.net.URI; + +/** + * Represents a wire specified in an assembly + * + * @version $Rev$ $Date$ + */ +public class WireDefinition extends ModelObject { + private URI source; + private URI target; + + public URI getSource() { + return source; + } + + public void setSource(URI source) { + this.source = source; + } + + public URI getTarget() { + return target; + } + + public void setTarget(URI target) { + this.target = target; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java new file mode 100644 index 0000000000..2c85f846ac --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java @@ -0,0 +1,70 @@ +/* + * 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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundWire; + +/** + * A registry for policy builders that dispatches to the appropriate builder when converting an assembly to runtime + * artifacts. Policy builders operate on either a source- or target-side wires. + * + * @version $Rev$ $Date$ + */ +public interface PolicyBuilderRegistry { + + int INITIAL = 0; + int EXTENSION = 1; + int FINAL = 2; + + /** + * Registers a target-side policy builder. Called by extensions to register their builders. + * + * @param phase the phase hwne the builder must be run + * @param builder the builder to register + */ + void registerTargetBuilder(int phase, TargetPolicyBuilder builder); + + /** + * Registers a source-side policy builder. Called by extensions to register their builders. + * + * @param phase the phase hwne the builder must be run + * @param builder the builder to register + */ + void registerSourceBuilder(int phase, SourcePolicyBuilder builder); + + /** + * Evaluates source-side policy metadata for referenceDefinition and updates the curresponding collection of wire + * configurations + * + * @throws BuilderException + */ + void buildSource(ReferenceDefinition referenceDefinition, OutboundWire wire) throws BuilderException; + + /** + * Evaluates target-side policy metadata for configured reference and updates the curresponding collection of wire + * configurations + * + * @throws BuilderException + */ + void buildTarget(ServiceDefinition serviceDefinition, InboundWire wire) throws BuilderException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.java new file mode 100644 index 0000000000..66a7dd0e20 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.wire.OutboundWire; + +/** + * Implementations contribute {@link org.apache.tuscany.spi.wire.Interceptor}s or {@link + * org.apache.tuscany.spi.wire.MessageHandler}s that handle source-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SourcePolicyBuilder { + + /** + * @param referenceDefinition + * @param wire + * @throws BuilderException + */ + void build(ReferenceDefinition referenceDefinition, OutboundWire wire) throws BuilderException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.java new file mode 100644 index 0000000000..79f40e6558 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.wire.InboundWire; + +/** + * Implementations contribute {@link org.apache.tuscany.spi.wire.Interceptor}s or {@link + * org.apache.tuscany.spi.wire.MessageHandler}s that handle target-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface TargetPolicyBuilder { + + /** + * @param serviceDefinition + * @param wire + * @throws BuilderException + */ + void build(ServiceDefinition serviceDefinition, InboundWire wire) throws BuilderException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java new file mode 100644 index 0000000000..777cfbd3e9 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java @@ -0,0 +1,33 @@ +/* + * 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.spi.services; + +import org.osoa.sca.annotations.Service; + +/** + * Empty interface for a service component that has no operations. + * This can be used as a default service interface by components that + * do not wish the base class to be used as the interface as specified + * by the defaulting rules. + * + * @version $Rev$ $Date$ + */ +@Service +public interface VoidService { +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java new file mode 100644 index 0000000000..4da522d196 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java @@ -0,0 +1,197 @@ +/* + * 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.spi.services.artifact; + +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +/** + * Description of some packaged artifact such as a JAR file or a Composite. + * + * @version $Rev$ $Date$ + */ +public class Artifact { + + /* Artifact group */ + private String group; + + /* Artifact name */ + private String name; + + /* Artifact version */ + private String version; + + /* Artifact classifier */ + private String classifier; + + /* Artifact type */ + private String type; + + /* Artifact url */ + private URL url; + + /* Transitive dependencies */ + private Set<Artifact> dependencies = new HashSet<Artifact>(); + + /** + * Adds a transitive dependency to the artifact. + * + * @param artifact Dependency to be added. + */ + public void addDependency(Artifact artifact) { + dependencies.add(artifact); + } + + /** + * Gets the URLs for all the transitive dependencies. + * + * @return Sets of URLs for all the transitive dependencies. + */ + public Set<URL> getUrls() { + + Set<URL> urls = new HashSet<URL>(); + + for (Artifact artifact : dependencies) { + urls.add(artifact.getUrl()); + } + urls.add(getUrl()); + + return urls; + + } + + /** + * Returns the name of a logical grouping to which this artifact belongs. For example, this might represent the + * original publisher of the artifact. + * + * @return the name of a logical grouping to which this artifact belongs + */ + public String getGroup() { + return group; + } + + /** + * Sets the name of a logical grouping to which this artifact belongs. + * + * @param group the name of a logical grouping to which this artifact belongs + */ + public void setGroup(String group) { + this.group = group; + } + + /** + * Returns the name of an artifact. + * + * @return the name of an artifact + */ + public String getName() { + return name; + } + + /** + * Sets the name of an artifact. + * + * @param name the name of an artifact + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the version of an artifact. + * + * @return the version of an artifact + */ + public String getVersion() { + return version; + } + + /** + * Sets the version of an artifact. + * + * @param version the version of an artifact + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Returns a way of classifying an artifact. This can be used to distinguish variants of an artifact that provide + * the same function but which may have platform specific requirements. For example, it may contain the name of a + * hardware platform for artifacts that contain native code. + * + * @return a way of classifying an artifact + */ + public String getClassifier() { + return classifier; + } + + /** + * Sets a way of classifying an artifact + * + * @param classifier a way of classifying an artifact + */ + public void setClassifier(String classifier) { + this.classifier = classifier; + } + + /** + * Returns the type of artifact. + * + * @return the type of artifact + */ + public String getType() { + return type; + } + + /** + * Sets the type of artifact. + * + * @param type the type of artifact + */ + public void setType(String type) { + this.type = type; + } + + /** + * Returns a URL from which the artifact can be obtained. + * + * @return a URL from which the artifact can be obtained + */ + public URL getUrl() { + return url; + } + + /** + * Sets a URL from which the artifact can be obtained. + * + * @param url a URL from which the artifact can be obtained + */ + public void setUrl(URL url) { + this.url = url; + } + + + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(group).append(':').append(name).append(':').append(version).append(':').append(type); + return buf.toString(); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.java new file mode 100644 index 0000000000..b0f590e163 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.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.spi.services.artifact; + +import java.util.Collection; + +/** + * Abstraction for a repository of SCA and other artifacts. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactRepository { + /** + * Resolve an artifact. + * This ensures that the information associated with an artifact is fully populated; + * Specifically, after this operation the URL should contain a location where the artifact can be obtained. + * + * @param artifact the artifact to be resolved + */ + void resolve(Artifact artifact); + + /** + * Resolve a collection of Artifacts. + * + * @param artifacts a collection of artifacts to be resolved + * @see #resolve(Artifact) + */ + void resolve(Collection<? extends Artifact> artifacts); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.java new file mode 100644 index 0000000000..9675cdce53 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.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.spi.services.work; + +/** + * A callback inyterface that can be optionally used for registering + * interest in status of asynchronously scheduled unit of work. + * + */ +public interface NotificationListener<T extends Runnable> { + + /** + * Callback method when the unit of work is accepted. + * + * @param work Work that was accepted. + */ + void workAccepted(T work); + + /** + * Callback method when the unit of work is successfully completed. + * + * @param work Work that was succesfully completed. + */ + void workCompleted(T work); + + /** + * Callback when the unit of work is started. + * + * @param work Unit of work that was started. + */ + void workStarted(T work); + + /** + * Callback when the unit of work is rejected. + * + * @param work Unit of work that was rejected. + */ + void workRejected(T work); + + /** + * Callnack when the unit of work fails to complete. + * + * @param work Unit of work that failed to complete. + * @param error Error that caused the unit of work to fail. + */ + void workFailed(T work, Throwable error); + + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.java new file mode 100644 index 0000000000..0824990c93 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.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.spi.services.work; + +/** + * Defines the contract for scheduling asychronous units of work. + * + * <p> + * Units of work can be scheduled with an optional <code>NotificationListener</code>. + * If a notification listener is specified, the caller will be notified regarding the + * status of the work. The unit of work can either be completed, rejected or completed + * with an error. If the work completed with an error, the caller is notfied with the + * error details. + * </p> + * + */ +public interface WorkScheduler { + + /** + * Schedules a unit of work for future execution. The notification listener + * is used to register interest in callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + * @param listener Notification listener for callbacks. + */ + <T extends Runnable>void scheduleWork(T work, NotificationListener<T> listener); + + /** + * Schedules a unit of work for future execution. The notification listener + * is used to register interest in callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + */ + <T extends Runnable>void scheduleWork(T work); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.java new file mode 100644 index 0000000000..72dc8ee5d2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.services.work; + +/** + * Exception thrown by the work scheduler in case of unexpected exceptions. + * + */ +public class WorkSchedulerException extends RuntimeException { + + /** + * Wraps the root cause. + * + * @param cause Root cause for the exception. + */ + public WorkSchedulerException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInboundInvocationHandler.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInboundInvocationHandler.java new file mode 100644 index 0000000000..6177810b0f --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInboundInvocationHandler.java @@ -0,0 +1,72 @@ +/* + * 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.spi.wire; + +import java.lang.reflect.InvocationTargetException; + + +/** + * Base class for dispatching an invocation through an {@link InboundInvocationChain} + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractInboundInvocationHandler { + + /** + * Dispatches a client request made on a proxy + */ + public Object invoke(InboundInvocationChain chain, TargetInvoker invoker, Object[] args) throws Throwable { + Interceptor headInterceptor = chain.getHeadInterceptor(); + if (headInterceptor == null) { + try { + // short-circuit the dispatch and invoke the target directly + if (chain.getTargetInvoker() == null) { + throw new AssertionError("No target invoker [" + chain.getOperation().getName() + "]"); + } + return chain.getTargetInvoker().invokeTarget(args); + } catch (InvocationTargetException e) { + // the cause was thrown by the target so throw it + throw e.getCause(); + } + } else { + Message msg = new MessageImpl(); + msg.setTargetInvoker(invoker); + Object messageId = getMessageId(); + if (messageId == null) { + messageId = new MessageId(); + } + msg.setMessageId(messageId); + Object corrId = getCorrelationId(); + msg.setCorrelationId(corrId); + msg.setBody(args); + Message resp; + // dispatch the wire down the chain and get the response + resp = headInterceptor.invoke(msg); + Object body = resp.getBody(); + if (resp.isFault()) { + throw (Throwable) body; + } + return body; + } + } + + protected abstract Object getMessageId(); + + protected abstract Object getCorrelationId(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractOutboundInvocationHandler.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractOutboundInvocationHandler.java new file mode 100644 index 0000000000..2e66534f30 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractOutboundInvocationHandler.java @@ -0,0 +1,74 @@ +/* + * 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.spi.wire; + +import java.lang.reflect.InvocationTargetException; + + +/** + * Base class for performing invocations on an outbound chain. Subclasses are responsible for retrieving and supplying + * the appropriate chain, target invoker and invocation arguments. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractOutboundInvocationHandler { + + protected Object invoke(OutboundInvocationChain chain, TargetInvoker invoker, Object[] args) throws Throwable { + Interceptor headInterceptor = chain.getHeadInterceptor(); + if (headInterceptor == null) { + try { + // short-circuit the dispatch and invoke the target directly + TargetInvoker targetInvoker = chain.getTargetInvoker(); + if (targetInvoker == null) { + String name = chain.getOperation().getName(); + throw new AssertionError("No target invoker [" + name + "]"); + } + return targetInvoker.invokeTarget(args); + } catch (InvocationTargetException e) { + // the cause was thrown by the target so throw it + throw e.getCause(); + } + } else { + Message msg = new MessageImpl(); + msg.setTargetInvoker(invoker); + msg.setFromAddress(getFromAddress()); + Object messageId = getMessageId(); + if (messageId == null) { + messageId = new MessageId(); + } + msg.setMessageId(messageId); + Object corrId = getCorrelationId(); + msg.setCorrelationId(corrId); + msg.setBody(args); + // dispatch the wire down the chain and get the response + Message resp = headInterceptor.invoke(msg); + Object body = resp.getBody(); + if (resp.isFault()) { + throw (Throwable) body; + } + return body; + } + } + + protected abstract Object getFromAddress(); + + protected abstract Object getMessageId(); + + protected abstract Object getCorrelationId(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundInvocationChain.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundInvocationChain.java new file mode 100644 index 0000000000..22522286a7 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundInvocationChain.java @@ -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. + */ +package org.apache.tuscany.spi.wire; + +/** + * A set of interceptors and handlers (contained in request and response message channels) associated with the inbound + * side of a wire for an operation. Inbound chains may start with request {@link MessageHandler}s and contain at least + * one {@link Interceptor} processed after the handlers prior to dipatching to the target instance. Inbound invocation + * chains may also contain a set of response <code>MessageHandler</code>s which are processed after dispatching to the + * target instance. + * <p/> + * + * @version $$Rev$$ $$Date$$ + */ +public interface InboundInvocationChain extends InvocationChain { + + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundWire.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundWire.java new file mode 100644 index 0000000000..ca9ab65f20 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InboundWire.java @@ -0,0 +1,106 @@ +/* + * 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.spi.wire; + +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; + +/** + * Implementations are responsible for managing the inbound side of a wire, including the invocation chains associated + * with each service operation. + * + * @version $$Rev$$ $$Date$$ + */ +public interface InboundWire extends RuntimeWire { + + /** + * Returns the name of the target service of the wire + */ + String getServiceName(); + + /** + * Sets the name of the target service of the wire + */ + void setServiceName(String name); + + /** + * Returns the invocation chain for each operation on a service specified by a reference or a target + * service. + */ + Map<Operation<?>, InboundInvocationChain> getInvocationChains(); + + /** + * Adds the collection of invocation chains keyed by operation + */ + void addInvocationChains(Map<Operation<?>, InboundInvocationChain> chains); + + /** + * Adds the invocation chain associated with the given operation + */ + void addInvocationChain(Operation<?> operation, InboundInvocationChain chain); + + /** + * Returns the callback invocation configuration for each operation on a service specified by a reference or a + * target service. + */ + Map<Operation<?>, OutboundInvocationChain> getSourceCallbackInvocationChains(Object targetAddr); + + /** + * Adds the collection of callback invocation chains keyed by operation for a given target addr + */ + void addSourceCallbackInvocationChains(Object targetAddr, Map<Operation<?>, OutboundInvocationChain> chains); + + /** + * Adds the callback invocation chain associated with the given operation for a given target addr + */ + void addSourceCallbackInvocationChain(Object targetAddr, Operation<?> operation, OutboundInvocationChain chain); + + /** + * Returns the name of the callback associated with the service of the wire + */ + String getCallbackReferenceName(); + + /** + * Sets the name of the callback associated with the service of the wire + */ + void setCallbackReferenceName(String callbackReferenceName); + + /** + * Set when a wire can be optimized; that is when no handlers or interceptors exist on either end + */ + void setTargetWire(OutboundWire wire); + + /** + * Creates an association between a message id and the address of the SCAObject that the corresponding message + * originates from + */ + void addMapping(Object messageId, Object fromAddress); + + /** + * Retrieves the SCAObject address that is associated with a message id + */ + Object retrieveMapping(Object messageId); + + /** + * Removes an association between a message id and the address of the SCAObject that the corresponding message + * originates from + */ + void removeMapping(Object messageId); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java new file mode 100644 index 0000000000..383114f076 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.wire; + +/** + * Denotes imcompatible service contracts for a wire + */ +public class IncompatibleServiceContractException extends WireException { + + private static final long serialVersionUID = 5127478601823295587L; + + public IncompatibleServiceContractException() { + } + + /** + * @param message + */ + public IncompatibleServiceContractException(String message) { + super(message); + } + + /** + * @param message + * @param cause + */ + public IncompatibleServiceContractException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param cause + */ + public IncompatibleServiceContractException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.java new file mode 100644 index 0000000000..ad38ed1cf1 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.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.spi.wire; + +/** + * Synchronous, around-style mediation associated with a client- or target- side wire. + * + * @version $Rev$ $Date$ + */ +public interface Interceptor { + + /** + * Process a synchronous wire + * + * @param msg the request Message for the wire + * @return the response Message from the wire + */ + Message invoke(Message msg); + + /** + * Sets the next interceptor + */ + void setNext(Interceptor next); + + /** + * Returns the next interceptor or null + */ + Interceptor getNext(); + + /** + * Returns true if the interceptor can be optimized away from a wire + */ + boolean isOptimizable(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.java new file mode 100644 index 0000000000..82e1a52adf --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.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.spi.wire; + +import org.apache.tuscany.spi.model.Operation; + +/** + * An inbound or outbound invocation pipeline for a service operation. Wires consist of 1..n invocation chains + * associated with the operations of the service contract the wire represents. Invocation chains are associated with the + * outbound or inbound side of a wire are bridged or "connected" when an assembly is processed. Outbound chains are only + * connected to inbound chains and vice versa. + * <p/> + * Invocation chains contain at least one {@link Interceptor} that process invocations in an around-style manner. In + * some scenarios, a service proxy may only contain inbound invocation chains, for example, when a service is resolved + * through a locate operation by a non-component client. In this case, there will be no outbound invocation chains and + * the target invoker will be held by the target-side and passed down the pipeline. + * <p/> + * A {@link Message} is used to pass data associated with an invocation through the chain. <code>Message</code>s contain + * a {@link TargetInvoker} responsible for dispatching to a target instance and may be cached on the source-side. + * Caching allows various optimizations such as avoiding target instance resolution when the client-side lifecycle scope + * is a shorter duration than the target. + * + * @version $Rev$ $Date$ + */ +public interface InvocationChain { + /** + * Returns the target operation for this invocation chain + */ + Operation getOperation(); + + /** + * Sets the target invoker to pass down the chain + */ + void setTargetInvoker(TargetInvoker invoker); + + /** + * Returns the target invoker that is passed down the chain + */ + TargetInvoker getTargetInvoker(); + + /** + * Adds an interceptor to the chain + */ + void addInterceptor(Interceptor interceptor); + + /** + * Adds an interceptor at the given position in the interceptor stack + * + * @param index the position in the interceptor stack to add the interceptor + * @param interceptor the interceptor to add + */ + void addInterceptor(int index, Interceptor interceptor); + + /** + * Returns the first interceptor in the chain + */ + Interceptor getHeadInterceptor(); + + /** + * Returns the last interceptor in the chain + */ + Interceptor getTailInterceptor(); + + /** + * Sets the head interceptor of the bridged target-side chain + */ + void setTargetInterceptor(Interceptor interceptor); + + /** + * Returns the head interceptor of the birdged target-side chain + */ + Interceptor getTargetInterceptor(); + + /** + * Signals to the chain that its configuration is complete. Implementations may use this callback to prepare their + * invocation chains. + */ + void prepare(); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java new file mode 100644 index 0000000000..c2ba19c48a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.wire; + +import org.osoa.sca.ServiceRuntimeException; + +/** + * Denotes a runtime exception thrown during an invocation over a wire + * + * @version $Rev$ $Date$ + */ +public class InvocationRuntimeException extends ServiceRuntimeException { + + public InvocationRuntimeException() { + super(); + } + + public InvocationRuntimeException(String message) { + super(message); + } + + public InvocationRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public InvocationRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Message.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Message.java new file mode 100644 index 0000000000..dd89445a78 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/Message.java @@ -0,0 +1,88 @@ +/* + * 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.spi.wire; + +/** + * Represents a request, response, or exception flowing through a wire + * + * @version $Rev $Date + */ +public interface Message { + + /** + * Returns the body of the message, which will be the payload or parameters associated with the wire + */ + Object getBody(); + + /** + * Sets the body of the message. + */ + void setBody(Object body); + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + void setTargetInvoker(TargetInvoker invoker); + + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + TargetInvoker getTargetInvoker(); + + /** + * Returns the 'address' of the SCAObject where this message originates + */ + Object getFromAddress(); + + /** + * Sets the 'address' of the SCAObject where this message originates + */ + void setFromAddress(Object fromAddress); + + /** + * Returns the id of the message + */ + Object getMessageId(); + + /** + * Sets the id of the message + */ + void setMessageId(Object messageId); + + /** + * Returns the correlation id of the message + */ + Object getCorrelationId(); + + /** + * Sets the correlation id of the message + */ + void setCorrelationId(Object correlationId); + + /** + * Test if the message represents a fault/exception + * @return true if the message body is a fault object, false is the body is a normal payload + */ + boolean isFault(); + + /** + * Set the message body with a fault object. After this method is called, isFault() returns true. + * @param fault The fault object represents an exception + */ + void setBodyWithFault(Object fault); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.java new file mode 100644 index 0000000000..b1011e4f29 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.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.spi.wire; + +/** + * A unique identifier for a message flowing on a wire, potentially end-to-end (ie, through more than one SCAObject to + * SCAObject hop). + */ +public class MessageId { + + private long timestamp; + + public MessageId() { + this.timestamp = System.currentTimeMillis(); + } + + public long getTimestamp() { + return timestamp; + } + + public String toString() { + return "MsgId[" + timestamp + "]"; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.java new file mode 100644 index 0000000000..3e44db4690 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.java @@ -0,0 +1,87 @@ +/* + * 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.spi.wire; + +/** + * The default implementation of a message flowed through a wire during an invocation + * + * @version $Rev $Date + */ +public class MessageImpl implements Message { + + private Object body; + private TargetInvoker invoker; + private Object fromAddress; + private Object messageId; + private Object correlationId; + private boolean isFault; + + public MessageImpl() { + } + + public Object getBody() { + return body; + } + + public void setBody(Object body) { + this.isFault = false; + this.body = body; + } + + public void setTargetInvoker(TargetInvoker invoker) { + this.invoker = invoker; + } + + public TargetInvoker getTargetInvoker() { + return invoker; + } + + public Object getFromAddress() { + return fromAddress; + } + + public void setFromAddress(Object fromAddress) { + this.fromAddress = fromAddress; + } + + public Object getMessageId() { + return messageId; + } + + public void setMessageId(Object messageId) { + this.messageId = messageId; + } + + public Object getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(Object correlationId) { + this.correlationId = correlationId; + } + + public boolean isFault() { + return isFault; + } + + public void setBodyWithFault(Object fault) { + this.isFault = true; + this.body = fault; + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundInvocationChain.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundInvocationChain.java new file mode 100644 index 0000000000..b15678a4a8 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundInvocationChain.java @@ -0,0 +1,28 @@ +/* + * 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.spi.wire; + +/** + * Responsible for flowing a request to a target service and invoking an operation. + * + * @version $$Rev$$ $$Date$$ + */ +public interface OutboundInvocationChain extends InvocationChain { + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundWire.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundWire.java new file mode 100644 index 0000000000..0d58d6a3e2 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/OutboundWire.java @@ -0,0 +1,102 @@ +/* + * 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.spi.wire; + +import java.util.Map; + +import org.apache.tuscany.spi.QualifiedName; +import org.apache.tuscany.spi.model.Operation; + +/** + * Implementations are responsible for managing the reference side of a wire, including the invocation chains associated + * with each service operation. An <code>OutboundWire</code> is connected to an {@link InboundWire} through their + * invocation chains. + * + * @version $$Rev$$ $$Date$$ + */ +public interface OutboundWire extends RuntimeWire { + + /** + * Returns the name of the source reference + */ + String getReferenceName(); + + /** + * Sets the name of the source reference + */ + void setReferenceName(String name); + + /** + * Returns the name of the target + */ + QualifiedName getTargetName(); + + /** + * Sets the name of the target + */ + void setTargetName(QualifiedName name); + + /** + * Sets the callback interface type generated proxies implement + */ + void setCallbackInterface(Class<?> interfaze); + + /** + * Returns the callback interface type implemented by generated proxies + */ + Class<?> getCallbackInterface(); + + /** + * Returns the invocation configuration for each operation on a service specified by a reference or a target + * service. + */ + Map<Operation<?>, OutboundInvocationChain> getInvocationChains(); + + /** + * Adds the collection of invocation chains keyed by operation + */ + void addInvocationChains(Map<Operation<?>, OutboundInvocationChain> chains); + + /** + * Adds the invocation chain associated with the given operation + */ + void addInvocationChain(Operation<?> operation, OutboundInvocationChain chain); + + /** + * Returns the callback invocation configuration for each operation on a service specified by a reference or a + * target service. + */ + Map<Operation<?>, InboundInvocationChain> getTargetCallbackInvocationChains(); + + /** + * Adds the collection of callback invocation chains keyed by operation + */ + void addTargetCallbackInvocationChains(Map<Operation<?>, InboundInvocationChain> chains); + + /** + * Adds the callback invocation chain associated with the given operation + */ + void addTargetCallbackInvocationChain(Operation<?> operation, InboundInvocationChain chain); + + /** + * Set when a wire can be optimized; that is when no handlers or interceptors exist on either end + */ + void setTargetWire(InboundWire wire); + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.java new file mode 100644 index 0000000000..0f213c9871 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.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.spi.wire; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Denotes an error creating a proxy + * + * @version $$Rev$$ $$Date$$ + */ +public class ProxyCreationException extends TuscanyRuntimeException { + public ProxyCreationException() { + } + + public ProxyCreationException(String message) { + super(message); + } + + public ProxyCreationException(String message, Throwable cause) { + super(message, cause); + } + + public ProxyCreationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/RuntimeWire.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/RuntimeWire.java new file mode 100644 index 0000000000..0c39b50d6a --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/RuntimeWire.java @@ -0,0 +1,70 @@ +/* + * 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.spi.wire; + +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.component.SCAObject; + +/** + * The base wire type used to connect references and services + * + * @version $$Rev$$ $$Date$$ + */ +public interface RuntimeWire { + + /** + * Returns the non-proxied target instance for this wire + */ + Object getTargetService() throws TargetException; + + /** + * Returns the service contract associated with the wire + * + * @return the service contract associated with the wire + */ + ServiceContract getServiceContract(); + + /** + * Sets the contract associated with the wire + * + * @param contract the contract associated with the wire + */ + void setServiceContract(ServiceContract contract); + + /** + * Adds an interface type generated proxies implement + */ + void addInterface(Class<?> claz); + + /** + * Returns true if the wire and all of its interceptors and handlers can be optimized + */ + boolean isOptimizable(); + + /** + * Returns the SCAObject that contains this wire + */ + SCAObject getContainer(); + + /** + * Sets the name of the SCAObject that contains this wire + */ + void setContainer(SCAObject container); +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.java new file mode 100644 index 0000000000..5edcd29286 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.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.spi.wire; + +import java.lang.reflect.InvocationTargetException; + +/** + * Implementations are responsible for resolving a target and performing the actual invocation on it, for example, a + * component implementation instance or a service client. + * + * @version $Rev$ $Date$ + */ +public interface TargetInvoker extends Cloneable { + + /** + * Invokes an operation on a target with the given payload. Used in optmized cases where messages do not need to be + * flowed such as in non-proxied wires. + * + * @throws InvocationTargetException + */ + Object invokeTarget(final Object payload) throws InvocationTargetException; + + /** + * Invokes an operation on a target with the given message + * + * @throws InvocationRuntimeException + */ + Message invoke(Message msg) throws InvocationRuntimeException; + + /** + * Determines whether the proxy can be cached on the client/source side + */ + boolean isCacheable(); + + /** + * Sets whether the target service instance may be cached by the invoker. This is a possible optimization when a + * wire is configured for a "down-scope" reference, i.e. a reference from a source of a shorter lifetime to a source + * of greater lifetime. + */ + void setCacheable(boolean cacheable); + + /** + * Determines if the target invoker can be discarded during wire optimization + */ + boolean isOptimizable(); + + /** + * Implementations must support deep cloning + */ + Object clone() throws CloneNotSupportedException; +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireException.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireException.java new file mode 100644 index 0000000000..2574bede2c --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireException.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.spi.wire; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Denotes a top-level exception dealing with a wire + */ +public abstract class WireException extends TuscanyException { + + public WireException() { + super(); + } + + public WireException(String message) { + super(message); + } + + public WireException(String message, Throwable cause) { + super(message, cause); + } + + public WireException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.java new file mode 100644 index 0000000000..325f26ba91 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.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.spi.wire; + +import java.lang.reflect.Method; + +/** + * Implementations are responsible for dispatching an operation down an invocation chain + * + * @version $$Rev$$ $$Date$$ + */ +public interface WireInvocationHandler { + + Object invoke(Method method, Object[] args) throws Throwable; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireService.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireService.java new file mode 100644 index 0000000000..6e97916b95 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireService.java @@ -0,0 +1,156 @@ +/* + * 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.spi.wire; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Creates proxies that implement Java interfaces and invocation handlers for fronting wires + * + * @version $$Rev$$ $$Date$$ + */ + +public interface WireService { + + /** + * Creates a Java proxy for the given wire + * + * @param wire the wire to proxy + * @return the proxy + * @throws ProxyCreationException + */ + Object createProxy(RuntimeWire wire) throws ProxyCreationException; + + /** + * Creates a Java proxy for the service contract callback + * + * @param contract the service contract + * @return the proxy + * @throws ProxyCreationException + */ + Object createCallbackProxy(ServiceContract<?> contract, InboundWire wire) throws ProxyCreationException; + + + /** + * Creates an {@link WireInvocationHandler} for the given wire + * + * @param wire the wire to create the invocation handler for + * @return the invocation handler + */ + WireInvocationHandler createHandler(RuntimeWire wire); + + /** + * Creates a wire invocation handler for flowing invocations through a callback + * + * @return the invocation handler for flowing invocations through a callback + */ + WireInvocationHandler createCallbackHandler(InboundWire wire); + + /** + * Creates an outbound invocation chain for a given operation + * + * @param operation the operation to create the chain for + * @return the outbound invocation chain for a given operation + */ + OutboundInvocationChain createOutboundChain(Operation<?> operation); + + /** + * Creates an inbound invocation chain for a given operation + * + * @param operation the operation to create the chain for + * @return the inbound invocation chain for a given operation + */ + InboundInvocationChain createInboundChain(Operation<?> operation); + + /** + * Creates a wire for flowing inbound invocations to a service + * + * @param service the model representation of the service + * @return the wire for flowing inbound invocations to a service + */ + InboundWire createWire(ServiceDefinition service); + + /** + * Creates a wire for flowing outbound invocations to a reference + * + * @param reference the model artifact representing the reference on the source side + * @param def the model artifact representing the target reference + * @return the wire for flowing outbound invocations to a reference + */ + OutboundWire createWire(ReferenceTarget reference, ReferenceDefinition def); + + /** + * Creates wires for a component and injects them on the component + * + * @param component the component + * @param definition the model artifact representing the component + */ + void createWires(Component component, ComponentDefinition<?> definition); + + /** + * Creates wires for a reference and injects them on the reference + * + * @param reference the reference + * @param contract the model artifact representing the service contract for the reference + */ + void createWires(Reference reference, ServiceContract<?> contract); + + /** + * Creates wires for a service and injects them on the service + * + * @param service the service + * @param targetName the target nane + * @param contract the service contract + */ + void createWires(Service service, String targetName, ServiceContract<?> contract); + + /** + * Check the compatiblity of the source and the target service contracts.<p> A wire may only connect a source to a + * target if the target implements an interface that is compatible with the interface required by the source. The + * source and the target are compatible if: + * <p/> + * <ol> <li>the source interface and the target interface MUST either both be remotable or they are both local + * <li>the methods on the target interface MUST be the same as or be a superset of the methods in the interface + * specified on the source <li>compatibility for the individual method is defined as compatibility of the signature, + * that is method name, input types, and output types MUST BE the same. <li>the order of the input and output types + * also MUST BE the same. <li>the set of Faults and Exceptions expected by the source MUST BE the same or be a + * superset of those specified by the service. <li>other specified attributes of the two interfaces MUST match, + * including Scope and Callback interface </ol> + * <p/> + * <p>Please note this test is not symetric: the success of checkCompatibility(A, B) does NOT imply that + * checkCompatibility(B, A) + * + * @param source The source service contract + * @param target The target service contract + * @param ignoreCallback Indicate the callback should be checked + * @throws IncompatibleServiceContractException + * If the source service contract is not compatible with the target one + */ + void checkCompatibility(ServiceContract<?> source, ServiceContract<?> target, boolean ignoreCallback) + throws IncompatibleServiceContractException; + +} diff --git a/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireServiceExtension.java b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireServiceExtension.java new file mode 100644 index 0000000000..1baa4b3029 --- /dev/null +++ b/branches/sca-java-M2/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/wire/WireServiceExtension.java @@ -0,0 +1,109 @@ +/* + * 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.spi.wire; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.policy.PolicyBuilderRegistry; + +/** + * Base class for wire service extensions + * + * @version $Rev$ $Date$ + */ +public abstract class WireServiceExtension implements WireService { + + protected PolicyBuilderRegistry policyRegistry; + protected WorkContext context; + + protected WireServiceExtension(WorkContext context, PolicyBuilderRegistry policyRegistry) { + this.policyRegistry = policyRegistry; + this.context = context; + } + + /** + * Compares two operations for wiring compatibility as defined by the SCA assembly specification, namely: <p/> <ol> + * <li>compatibility for the individual method is defined as compatibility of the signature, that is method name, + * input types, and output types MUST BE the same. <li>the order of the input and output types also MUST BE the + * same. <li>the set of Faults and Exceptions expected by the source MUST BE the same or be a superset of those + * specified by the service. </ol> + * + * @param source the source contract to compare + * @param target the target contract to compare + * @throws IncompatibleServiceContractException + * if the two contracts don't match + */ + public void checkCompatibility(ServiceContract<?> source, ServiceContract<?> target, boolean ignoreCallback) + throws IncompatibleServiceContractException { + if (source == target) { + // Shortcut for performance + return; + } + if (source.isRemotable() != target.isRemotable()) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("The remotable settings don't match"); + ex.setIdentifier(source.toString() + "," + target.toString()); + throw ex; + } + if (source.getInteractionScope() != target.getInteractionScope()) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("The interaction scopes don't match"); + ex.setIdentifier(source.toString() + "," + target.toString()); + throw ex; + } + + for (Operation<?> operation : source.getOperations().values()) { + Operation<?> targetOperation = target.getOperations().get(operation.getName()); + if (targetOperation == null) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("Operation not found on target"); + ex.setIdentifier(operation.getName()); + throw ex; + } + if (!operation.equals(targetOperation)) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("Target operation is not compatible"); + ex.setIdentifier(operation.getServiceContract().toString() + ":" + operation.getName()); + throw ex; + } + } + + if (ignoreCallback) { + return; + } + + for (Operation<?> operation : source.getCallbackOperations().values()) { + Operation<?> targetOperation = target.getCallbackOperations().get(operation.getName()); + if (targetOperation == null) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("Callback operation not found on target"); + ex.setIdentifier(operation.getName()); + throw ex; + } + if (!operation.equals(targetOperation)) { + IncompatibleServiceContractException ex = + new IncompatibleServiceContractException("Target callback operation is not compatible"); + ex.setIdentifier(operation.getName()); + throw ex; + } + } + } + +} |