Test copying pre-graduation code to see if it will work with ohloh

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@678758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
mcombellack 2008-07-22 13:25:57 +00:00
parent b2494153a0
commit 273d7efc7b
118 changed files with 13706 additions and 0 deletions

View file

@ -0,0 +1,205 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,6 @@
${pom.name}
Copyright (c) 2005 - 2008 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).

View file

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-modules</artifactId>
<version>1.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>tuscany-core</artifactId>
<name>Apache Tuscany SCA Core Runtime</name>
<dependencies>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-extensibility</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-core-spi</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-contribution</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-contribution-java</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-interface-java</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-commonj_1.1_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>wstx-asl</artifactId>
<version>3.2.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-Version>${tuscany.version}</Bundle-Version>
<Bundle-SymbolicName>org.apache.tuscany.sca.core</Bundle-SymbolicName>
<Bundle-Description>${pom.name}</Bundle-Description>
<Export-Package>org.apache.tuscany.sca.core*</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -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.sca.core.assembly;
/**
* Denotes an error starting the runtime
*
* @version $Rev$ $Date$
*/
public class ActivationException extends Exception {
private static final long serialVersionUID = 8612661660934426123L;
public ActivationException(String message) {
super(message);
}
public ActivationException(Throwable cause) {
super(cause);
}
}

View file

@ -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.sca.core.assembly;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.Composite;
import org.apache.tuscany.sca.core.context.ComponentContextHelper;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
/**
* Start/stop a composite
*
* @version $Rev$ $Date$
*/
public interface CompositeActivator {
/**
* Activate a composite
* @param composite
*/
void activate(Composite composite) throws ActivationException;
/**
* Activate a component reference
* @param component
* @param ref
*/
void start(RuntimeComponent component, RuntimeComponentReference ref);
/**
* Activate a component reference
* @param component
* @param ref
*/
void activate(RuntimeComponent component, RuntimeComponentReference ref);
/**
* Activate a component reference
* @param component
* @param ref
*/
void activate(RuntimeComponent component, RuntimeComponentService service);
/**
* De-activate a component reference
* @param component
* @param ref
*/
void deactivate(RuntimeComponent component, RuntimeComponentReference ref);
/**
* De-activate a component reference
* @param component
* @param ref
*/
void deactivate(RuntimeComponent component, RuntimeComponentService service);
/**
* Stop a composite
* @param composite
*/
void deactivate(Composite composite) throws ActivationException;
/**
* Start a component
* @param component
*/
void start(Component component) throws ActivationException;
/**
* Stop a component
* @param component
*/
void stop(Component component) throws ActivationException;
/**
* Start components in a composite
* @param composite
*/
void start(Composite composite) throws ActivationException;
/**
* Stop components in a composite
* @param composite
*/
void stop(Composite composite) throws ActivationException;
/**
* Get the component context helper
* @return
*/
ComponentContextHelper getComponentContextHelper();
/**
* Get the proxy factory
* @return
*/
ProxyFactory getProxyFactory();
/**
* Get the java interface factory
* @return
*/
JavaInterfaceFactory getJavaInterfaceFactory();
ConversationManager getConversationManager();
/**
* Configure the runtime component with component context
* @param component
*/
void configureComponentContext(RuntimeComponent component);
/**
* Resolve a component by URI in the domain
* @param componentURI
* @return
*/
Component resolve(String componentURI);
/**
* Set the domain composite
* @param domainComposite
*/
void setDomainComposite(Composite domainComposite);
/**
* Get the domain composite
* @return
*/
Composite getDomainComposite();
}

View file

@ -0,0 +1,186 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Contract;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* @version $Rev$ $Date$
*/
public class EndpointReferenceImpl implements EndpointReference {
private RuntimeComponent component;
private Contract contract;
private Binding binding;
private InterfaceContract interfaceContract;
private String uri;
private EndpointReference callbackEndpoint;
private ReferenceParameters parameters = new ReferenceParametersImpl();
/**
* @param component
* @param contract
* @param binding
* @param interfaceContract
*/
public EndpointReferenceImpl(RuntimeComponent component,
Contract contract,
Binding binding,
InterfaceContract interfaceContract) {
super();
this.component = component;
this.contract = contract;
this.binding = binding;
this.interfaceContract = interfaceContract;
this.uri = (component != null ? component.getURI() : "") + '/' +
(contract != null ? contract.getName() : "");
}
/**
* @param uri
*/
public EndpointReferenceImpl(String uri) {
super();
this.uri = uri;
}
public Binding getBinding() {
return binding;
}
public void setBinding(Binding binding) {
this.binding = binding;
}
public RuntimeComponent getComponent() {
return component;
}
public void setComponent(RuntimeComponent component) {
this.component = component;
}
public Contract getContract() {
return contract;
}
public void setContract(Contract contract) {
this.contract = contract;
}
public InterfaceContract getInterfaceContract() {
return interfaceContract;
}
public void setInterfaceContract(InterfaceContract interfaceContract) {
this.interfaceContract = interfaceContract;
}
public String getURI() {
return uri;
}
public void setURI(String uri) {
this.uri = uri;
}
public EndpointReference getCallbackEndpoint() {
return callbackEndpoint;
}
public void setCallbackEndpoint(EndpointReference callbackEndpoint) {
this.callbackEndpoint = callbackEndpoint;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((uri == null) ? 0 : uri.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final EndpointReferenceImpl other = (EndpointReferenceImpl)obj;
if (uri == null) {
if (other.uri != null) {
return false;
}
} else if (!uri.equals(other.uri)) {
return false;
}
return true;
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
EndpointReferenceImpl copy = (EndpointReferenceImpl)super.clone();
/* [nash] no need to copy callback endpoint
if (callbackEndpoint != null) {
copy.callbackEndpoint = (EndpointReference)callbackEndpoint.clone();
}
*/
if (parameters != null) {
copy.parameters = (ReferenceParameters)parameters.clone();
}
return copy;
}
/**
* @return the parameters
*/
public ReferenceParameters getReferenceParameters() {
return parameters;
}
/**
* @param parameters the parameters to set
*/
public void setReferenceParameters(ReferenceParameters parameters) {
this.parameters = parameters;
}
public void mergeEndpoint(EndpointReference epr) {
this.component = epr.getComponent();
this.contract = epr.getContract();
this.binding = epr.getBinding();
this.interfaceContract = epr.getInterfaceContract();
this.uri = epr.getURI();
this.callbackEndpoint = epr.getCallbackEndpoint();
}
}

View file

@ -0,0 +1,162 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.apache.tuscany.sca.assembly.Endpoint;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.endpointresolver.EndpointResolver;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.ServiceUnavailableException;
/**
* @version $Rev$ $Date$
*/
public class EndpointWireImpl implements RuntimeWire {
private Endpoint endpoint;
private CompositeActivatorImpl compositeActivator;
private EndpointResolver endpointResolver;
private EndpointReference source;
private RuntimeWire wire;
/**
* @param endpoint
*/
public EndpointWireImpl(Endpoint endpoint, CompositeActivator compositeActivator) {
super();
this.endpoint = endpoint;
// TODO - improve the SPI to get rid of this cast
this.compositeActivator = (CompositeActivatorImpl)compositeActivator;
// store source configuration as we have most of this now. We don't though know what the
// target is yet.
Reference componentTypeRef = endpoint.getSourceComponentReference().getReference();
InterfaceContract sourceContract =
componentTypeRef == null ? endpoint.getSourceComponentReference().getInterfaceContract() : componentTypeRef.getInterfaceContract();
sourceContract = sourceContract.makeUnidirectional(false);
source = new EndpointReferenceImpl((RuntimeComponent)endpoint.getSourceComponent(),
endpoint.getSourceComponentReference(),
null,
sourceContract);
RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)endpoint.getSourceComponentReference());
endpointResolver = runtimeRef.getEndpointResolver(endpoint);
}
public synchronized List<InvocationChain> getInvocationChains() {
// where late binding happens. Find the endpoint provider and
// ask it to do the endpoint resolution.
if (endpoint.isUnresolved()){
// this method should locate a viable target service and complete the
// endpoint configuration
endpointResolver.resolve();
if (endpoint.isUnresolved()){
throw new ServiceUnavailableException("Unable to resolve service for component: " +
endpoint.getSourceComponent().getName() +
" reference: " +
endpoint.getSourceComponentReference().getName() +
" target: " +
endpoint.getTargetName());
}
}
if (wire == null){
RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)endpoint.getSourceComponentReference());
// add the resolved binding into the reference
runtimeRef.getBindings().add(endpoint.getSourceBinding());
// add a binding provider into the reference for the resolved binding
compositeActivator.addReferenceBindingProviderForEndpoint(endpoint);
// extract the binding provider that has been created
ReferenceBindingProvider bindingProvider = runtimeRef.getBindingProvider(endpoint.getSourceBinding());
// start the binding provider
bindingProvider.start();
// create the wire
compositeActivator.addReferenceWireForEndpoint(endpoint);
// extract the wire that has been created
wire = runtimeRef.getRuntimeWire(endpoint.getSourceBinding());
}
return wire.getInvocationChains();
}
public InvocationChain getInvocationChain(Operation operation) {
if (wire ==null){
return null;
} else {
return wire.getInvocationChain(operation);
}
}
public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
// not called as the endpoint wire only appears on the reference side
return null;
}
public Object invoke(Operation operation, Message msg) throws InvocationTargetException {
// not called as the endpoint wire only appears on the reference side
return null;
}
public EndpointReference getSource() {
return source;
}
public EndpointReference getTarget() {
return null;
}
public void setTarget(EndpointReference target) {
}
public void rebuild() {
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
EndpointWireImpl copy = (EndpointWireImpl)super.clone();
return copy;
}
}

View file

@ -0,0 +1,101 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.contribution.service.ContributionReadException;
import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
import org.apache.tuscany.sca.contribution.service.ContributionWriteException;
import org.apache.tuscany.sca.monitor.Monitor;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
/**
* Artifact processor for reference parameters.
*
* @version $Rev$ $Date$
*/
public class ReferenceParameterProcessor implements StAXArtifactProcessor<ReferenceParameters> {
private static final QName REFERENCE_PARAMETERS =
new QName("http://tuscany.apache.org/xmlns/sca/1.0", "referenceParameters", "tuscany");
/**
* Constructs a new processor.
*
* @param modelFactories
*/
public ReferenceParameterProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) {
}
/**
* @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#getArtifactType()
*/
public QName getArtifactType() {
return REFERENCE_PARAMETERS;
}
/**
* @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#read(javax.xml.stream.XMLStreamReader)
*/
public ReferenceParameters read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
ReferenceParameters parameters = new ReferenceParametersImpl();
parameters.setConversationID(reader.getAttributeValue(null, "conversationID"));
parameters.setCallbackID(reader.getAttributeValue(null, "callbackID"));
return parameters;
}
/**
* @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#write(java.lang.Object, javax.xml.stream.XMLStreamWriter)
*/
public void write(ReferenceParameters model, XMLStreamWriter writer) throws ContributionWriteException,
XMLStreamException {
writer.writeStartElement(REFERENCE_PARAMETERS.getPrefix(),
REFERENCE_PARAMETERS.getLocalPart(),
REFERENCE_PARAMETERS.getNamespaceURI());
writer.writeNamespace(REFERENCE_PARAMETERS.getPrefix(), REFERENCE_PARAMETERS.getNamespaceURI());
if (model.getConversationID() != null) {
writer.writeAttribute("conversationID", model.getConversationID().toString());
}
if (model.getCallbackID() != null) {
writer.writeAttribute("callbackID", model.getCallbackID().toString());
}
writer.writeEndElement();
}
/**
* @see org.apache.tuscany.sca.contribution.processor.ArtifactProcessor#getModelType()
*/
public Class<ReferenceParameters> getModelType() {
return ReferenceParameters.class;
}
/**
* @see org.apache.tuscany.sca.contribution.processor.ArtifactProcessor#resolve(java.lang.Object, org.apache.tuscany.sca.contribution.resolver.ModelResolver)
*/
public void resolve(ReferenceParameters model, ModelResolver resolver) throws ContributionResolveException {
}
}

View file

@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
/**
* @version $Rev$ $Date$
*/
public class ReferenceParametersImpl implements ReferenceParameters {
private Object callbackID;
private Object conversationID;
private EndpointReference callbackReference;
private Object callbackObjectID;
/**
* @return the callbackID
*/
public Object getCallbackID() {
return callbackID;
}
/**
* @param callbackID the callbackID to set
*/
public void setCallbackID(Object callbackID) {
this.callbackID = callbackID;
}
/**
* @return the conversationID
*/
public Object getConversationID() {
return conversationID;
}
/**
* @param conversationID the conversationID to set
*/
public void setConversationID(Object conversationID) {
this.conversationID = conversationID;
}
/**
* @see org.apache.tuscany.sca.runtime.ReferenceParameters#getCallbackReference()
*/
public EndpointReference getCallbackReference() {
return callbackReference;
}
/**
* @see org.apache.tuscany.sca.runtime.ReferenceParameters#setCallback(java.lang.Object)
*/
public void setCallbackReference(EndpointReference callback) {
this.callbackReference = callback;
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* @return the callbackObjectID
*/
public Object getCallbackObjectID() {
return callbackObjectID;
}
/**
* @param callbackObjectID the callbackObjectID to set
*/
public void setCallbackObjectID(Object callbackObjectID) {
this.callbackObjectID = callbackObjectID;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((callbackID == null) ? 0 : callbackID.hashCode());
result = prime * result + ((callbackObjectID == null) ? 0 : callbackObjectID.hashCode());
result = prime * result + ((callbackReference == null) ? 0 : callbackReference.hashCode());
result = prime * result + ((conversationID == null) ? 0 : conversationID.hashCode());
return result;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof ReferenceParametersImpl))
return false;
final ReferenceParametersImpl other = (ReferenceParametersImpl)obj;
if (callbackID == null) {
if (other.callbackID != null)
return false;
} else if (!callbackID.equals(other.callbackID))
return false;
if (callbackObjectID == null) {
if (other.callbackObjectID != null)
return false;
} else if (!callbackObjectID.equals(other.callbackObjectID))
return false;
if (callbackReference == null) {
if (other.callbackReference != null)
return false;
} else if (!callbackReference.equals(other.callbackReference))
return false;
if (conversationID == null) {
if (other.conversationID != null)
return false;
} else if (!conversationID.equals(other.conversationID))
return false;
return true;
}
}

View file

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.DefaultAssemblyFactory;
/**
* The runtime version of assembly factory
* @version $Rev$ $Date$
*/
public class RuntimeAssemblyFactory extends DefaultAssemblyFactory implements AssemblyFactory {
public RuntimeAssemblyFactory() {
super();
}
@Override
public Component createComponent() {
return new RuntimeComponentImpl();
}
@Override
public ComponentReference createComponentReference() {
return new RuntimeComponentReferenceImpl();
}
@Override
public ComponentService createComponentService() {
return new RuntimeComponentServiceImpl();
}
}

View file

@ -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.sca.core.assembly;
import java.util.ArrayList;
import java.util.List;
import org.apache.tuscany.sca.assembly.impl.ComponentImpl;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
import org.apache.tuscany.sca.core.scope.ScopeContainer;
import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.provider.PolicyProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
/**
* @version $Rev$ $Date$
*/
public class RuntimeComponentImpl extends ComponentImpl implements RuntimeComponent,
ScopedRuntimeComponent, ResolverExtension {
protected RuntimeComponentContext componentContext;
protected ImplementationProvider implementationProvider;
protected List<PolicyProvider> policyProviders = new ArrayList<PolicyProvider>();
protected ScopeContainer scopeContainer;
protected boolean started;
protected ModelResolver modelResolver;
/**
*/
public RuntimeComponentImpl() {
super();
}
public ImplementationProvider getImplementationProvider() {
return implementationProvider;
}
public void setImplementationProvider(ImplementationProvider provider) {
this.implementationProvider = provider;
}
public ScopeContainer getScopeContainer() {
return scopeContainer;
}
public void setScopeContainer(ScopeContainer scopeContainer) {
this.scopeContainer = scopeContainer;
}
public boolean isStarted() {
return started;
}
public void setStarted(boolean started) {
this.started = started;
}
/**
* @return the componentContext
*/
public RuntimeComponentContext getComponentContext() {
return componentContext;
}
/**
* @param componentContext the componentContext to set
*/
public void setComponentContext(RuntimeComponentContext componentContext) {
this.componentContext = componentContext;
}
public void addPolicyProvider(PolicyProvider policyProvider) {
policyProviders.add(policyProvider);
}
public List<PolicyProvider> getPolicyProviders() {
return policyProviders;
}
public ModelResolver getModelResolver() {
return modelResolver;
}
public void setModelResolver(ModelResolver modelResolver) {
this.modelResolver = modelResolver;
}
}

View file

@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Endpoint;
import org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl;
import org.apache.tuscany.sca.endpointresolver.EndpointResolver;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.provider.PolicyProvider;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeWire;
/**
* Implementation of a Component Reference.
*
* @version $Rev$ $Date$
*/
public class RuntimeComponentReferenceImpl extends ComponentReferenceImpl implements RuntimeComponentReference {
private ArrayList<RuntimeWire> wires;
private HashMap<Binding, ReferenceBindingProvider> bindingProviders =
new HashMap<Binding, ReferenceBindingProvider>();
private HashMap<Endpoint, EndpointResolver> endpointResolvers =
new HashMap<Endpoint, EndpointResolver>();
private HashMap<Binding, List<PolicyProvider>> policyProviders = new HashMap<Binding, List<PolicyProvider>>();
private RuntimeComponent component;
public RuntimeComponentReferenceImpl() {
super();
}
public synchronized List<RuntimeWire> getRuntimeWires() {
if (wires == null) {
wires = new ArrayList<RuntimeWire>();
component.getComponentContext().start(this);
}
return wires;
}
public RuntimeWire getRuntimeWire(Binding binding) {
for (RuntimeWire wire : getRuntimeWires()) {
if (wire.getSource().getBinding() == binding) {
return wire;
}
}
return null;
}
public ReferenceBindingProvider getBindingProvider(Binding binding) {
return bindingProviders.get(binding);
}
public void setBindingProvider(Binding binding, ReferenceBindingProvider bindingProvider) {
bindingProviders.put(binding, bindingProvider);
}
public EndpointResolver getEndpointResolver(Endpoint endpoint){
return endpointResolvers.get(endpoint);
}
public void setEndpointResolver(Endpoint endpoint, EndpointResolver endpointResolver){
endpointResolvers.put(endpoint, endpointResolver);
}
public Invoker getInvoker(Binding binding, Operation operation) {
RuntimeWire wire = getRuntimeWire(binding);
if (wire == null) {
return null;
}
InvocationChain chain = wire.getInvocationChain(operation);
return chain == null ? null : chain.getHeadInvoker();
}
/**
* @return the component
*/
public RuntimeComponent getComponent() {
return component;
}
/**
* @param component the component to set
*/
public void setComponent(RuntimeComponent component) {
this.component = component;
}
/**
* @see org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
RuntimeComponentReferenceImpl ref = (RuntimeComponentReferenceImpl)super.clone();
ref.wires = null;
ref.bindingProviders = new HashMap<Binding, ReferenceBindingProvider>();
ref.policyProviders = new HashMap<Binding, List<PolicyProvider>>();
return ref;
}
public void addPolicyProvider(Binding binding, PolicyProvider policyProvider) {
List<PolicyProvider> providers = policyProviders.get(binding);
if (providers == null) {
providers = new ArrayList<PolicyProvider>();
policyProviders.put(binding, providers);
}
providers.add(policyProvider);
}
public List<PolicyProvider> getPolicyProviders(Binding binding) {
return policyProviders.get(binding);
}
}

View file

@ -0,0 +1,158 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.impl.ComponentServiceImpl;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.provider.PolicyProvider;
import org.apache.tuscany.sca.provider.ServiceBindingProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.ServiceRuntimeException;
/**
* Implementation of a Component Service.
*
* @version $Rev$ $Date$
*/
public class RuntimeComponentServiceImpl extends ComponentServiceImpl implements RuntimeComponentService {
private ArrayList<RuntimeWire> wires = new ArrayList<RuntimeWire>();
private ArrayList<RuntimeWire> callbackWires = new ArrayList<RuntimeWire>();
private HashMap<Binding, ServiceBindingProvider> bindingProviders = new HashMap<Binding, ServiceBindingProvider>();
private HashMap<Binding, List<PolicyProvider>> policyProviders = new HashMap<Binding, List<PolicyProvider>>();
public RuntimeComponentServiceImpl() {
super();
}
public List<RuntimeWire> getRuntimeWires() {
return wires;
}
public RuntimeWire getRuntimeWire(Binding binding) {
for (RuntimeWire wire : wires) {
if (wire.getTarget().getBinding() == binding) {
return wire;
}
}
return null;
}
public RuntimeWire getRuntimeWire(Binding binding, InterfaceContract interfaceContract) {
RuntimeWire wire = getRuntimeWire(binding);
if (wire == null) {
return null;
}
if (interfaceContract != null && interfaceContract != wire.getSource().getInterfaceContract()) {
try {
// FIXME: [rfeng] We could avoid clone() using a better comparison of the two interface contracts
wire = (RuntimeWire)wire.clone();
wire.getSource().setInterfaceContract(interfaceContract);
wire.rebuild();
} catch (CloneNotSupportedException e) {
throw new ServiceRuntimeException(e);
}
}
return wire;
}
public List<RuntimeWire> getCallbackWires() {
return callbackWires;
}
public ServiceBindingProvider getBindingProvider(Binding binding) {
return bindingProviders.get(binding);
}
public void setBindingProvider(Binding binding, ServiceBindingProvider bindingProvider) {
bindingProviders.put(binding, bindingProvider);
}
public Invoker getInvoker(Binding binding, Operation operation) {
return getInvoker(binding, null, operation);
}
public Invoker getInvoker(Binding binding, InterfaceContract interfaceContract, Operation operation) {
InvocationChain chain = getInvocationChain(binding, interfaceContract, operation);
if (chain != null) {
return chain.getHeadInvoker();
} else {
return null;
}
}
public InvocationChain getInvocationChain(Binding binding, InterfaceContract interfaceContract, Operation operation) {
RuntimeWire wire = getRuntimeWire(binding);
if (wire == null) {
return null;
}
if (interfaceContract != null && interfaceContract != wire.getSource().getInterfaceContract()) {
try {
// FIXME: [rfeng] We could avoid clone() using a better comparison of the two interface contracts
wire = (RuntimeWire)wire.clone();
wire.getSource().setInterfaceContract(interfaceContract);
wire.rebuild();
} catch (CloneNotSupportedException e) {
throw new ServiceRuntimeException(e);
}
}
return wire.getInvocationChain(operation);
}
public InvocationChain getInvocationChain(Binding binding, Operation operation) {
return getInvocationChain(binding, null, operation);
}
/**
* @see org.apache.tuscany.sca.assembly.impl.ComponentServiceImpl#clone()
*/
@SuppressWarnings("unchecked")
@Override
public Object clone() throws CloneNotSupportedException {
RuntimeComponentServiceImpl clone = (RuntimeComponentServiceImpl)super.clone();
clone.bindingProviders = (HashMap<Binding, ServiceBindingProvider>)bindingProviders.clone();
clone.wires = (ArrayList<RuntimeWire>)wires.clone();
clone.callbackWires = (ArrayList<RuntimeWire>)callbackWires.clone();
clone.policyProviders = (HashMap<Binding, List<PolicyProvider>>)policyProviders.clone();
return clone;
}
public void addPolicyProvider(Binding binding, PolicyProvider policyProvider) {
List<PolicyProvider> providers = policyProviders.get(binding);
if (providers == null) {
providers = new ArrayList<PolicyProvider>();
policyProviders.put(binding, providers);
}
providers.add(policyProvider);
}
public List<PolicyProvider> getPolicyProviders(Binding binding) {
return policyProviders.get(binding);
}
}

View file

@ -0,0 +1,377 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.assembly;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Contract;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.invocation.InvocationChainImpl;
import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
import org.apache.tuscany.sca.core.invocation.RuntimeWireInvoker;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.invocation.Phase;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.provider.PolicyProvider;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.provider.ServiceBindingProvider;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
import org.apache.tuscany.sca.work.WorkScheduler;
import org.osoa.sca.ServiceRuntimeException;
/**
* @version $Rev$ $Date$
*/
public class RuntimeWireImpl implements RuntimeWire {
private EndpointReference wireSource;
private EndpointReference wireTarget;
private transient RuntimeWireProcessor wireProcessor;
private transient InterfaceContractMapper interfaceContractMapper;
private transient WorkScheduler workScheduler;
private transient MessageFactory messageFactory;
private transient ConversationManager conversationManager;
private transient RuntimeWireInvoker invoker;
// the following is a very simple cache that avoids re-cloning a wire
// when consecutive callbacks to the same endpoint are made
private EndpointReference lastCallback;
private RuntimeWire cachedWire;
private boolean wireReserved;
private RuntimeWireImpl clonedFrom;
private List<InvocationChain> chains;
/**
* @param source
* @param target
* @param interfaceContractMapper
* @param workScheduler
* @param wireProcessor
* @param messageFactory
* @param conversationManager
*/
public RuntimeWireImpl(EndpointReference source,
EndpointReference target,
InterfaceContractMapper interfaceContractMapper,
WorkScheduler workScheduler,
RuntimeWireProcessor wireProcessor,
MessageFactory messageFactory,
ConversationManager conversationManager) {
super();
this.wireSource = source;
this.wireTarget = target;
this.interfaceContractMapper = interfaceContractMapper;
this.workScheduler = workScheduler;
this.wireProcessor = wireProcessor;
this.messageFactory = messageFactory;
this.conversationManager = conversationManager;
this.invoker = new RuntimeWireInvoker(this.messageFactory, this.conversationManager, this);
}
public synchronized List<InvocationChain> getInvocationChains() {
if (chains == null) {
initInvocationChains();
}
return chains;
}
public InvocationChain getInvocationChain(Operation operation) {
for (InvocationChain chain : getInvocationChains()) {
Operation op = null;
if (wireSource.getContract() != null) {
// Reference chain
op = chain.getSourceOperation();
} else {
// Service chain
op = chain.getTargetOperation();
}
if (interfaceContractMapper.isCompatible(operation, op, op.getInterface().isRemotable())) {
return chain;
}
}
return null;
}
public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
Message msg = messageFactory.createMessage();
msg.setBody(args);
return invoker.invoke(operation, msg);
}
public Object invoke(Operation operation, Message msg) throws InvocationTargetException {
return invoker.invoke(operation, msg);
}
/**
* Initialize the invocation chains
*/
private void initInvocationChains() {
chains = new ArrayList<InvocationChain>();
InterfaceContract sourceContract = wireSource.getInterfaceContract();
InterfaceContract targetContract = wireTarget.getInterfaceContract();
Contract source = wireSource.getContract();
if (source instanceof RuntimeComponentReference) {
// It's the reference wire
RuntimeComponentReference reference = (RuntimeComponentReference)wireSource.getContract();
Binding refBinding = wireSource.getBinding();
for (Operation operation : sourceContract.getInterface().getOperations()) {
Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
if (targetOperation == null) {
throw new ServiceRuntimeException("No matching operation for " + operation.getName()
+ " is found in reference "
+ wireSource.getComponent().getURI()
+ "#"
+ reference.getName());
}
InvocationChain chain = new InvocationChainImpl(operation, targetOperation, true);
if (operation.isNonBlocking()) {
addNonBlockingInterceptor(reference, refBinding, chain);
}
addReferenceBindingInterceptor(reference, refBinding, chain, operation);
chains.add(chain);
}
} else {
// It's the service wire
RuntimeComponentService service = (RuntimeComponentService)wireTarget.getContract();
RuntimeComponent serviceComponent = wireTarget.getComponent();
Binding serviceBinding = wireTarget.getBinding();
for (Operation operation : sourceContract.getInterface().getOperations()) {
Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
if (targetOperation == null) {
throw new ServiceRuntimeException("No matching operation for " + operation.getName()
+ " is found in service "
+ serviceComponent.getURI()
+ "#"
+ service.getName());
}
InvocationChain chain = new InvocationChainImpl(operation, targetOperation, false);
if (operation.isNonBlocking()) {
addNonBlockingInterceptor(service, serviceBinding, chain);
}
addImplementationInterceptor(serviceComponent, service, chain, targetOperation);
chains.add(chain);
}
}
wireProcessor.process(this);
}
public EndpointReference getSource() {
return wireSource;
}
public EndpointReference getTarget() {
return wireTarget;
}
public void setTarget(EndpointReference target) {
if (this.wireTarget != target) {
rebuild();
}
this.wireTarget = target;
}
public void rebuild() {
this.chains = null;
}
/**
* Add the interceptor for a reference binding
*
* @param reference
* @param binding
* @param chain
* @param operation
*/
private void addReferenceBindingInterceptor(ComponentReference reference,
Binding binding,
InvocationChain chain,
Operation operation) {
ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
if (provider != null) {
Invoker invoker = provider.createInvoker(operation);
if (invoker != null) {
chain.addInvoker(invoker);
}
}
List<PolicyProvider> pps = ((RuntimeComponentReference)reference).getPolicyProviders(binding);
if (pps != null) {
for (PolicyProvider p : pps) {
Interceptor interceptor = p.createInterceptor(operation);
if (interceptor != null) {
chain.addInterceptor(p.getPhase(), p.createInterceptor(operation));
}
}
}
}
/**
* Add the interceptor for a binding
*
* @param reference
* @param binding
* @param chain
* @param operation
*/
private void addServiceBindingInterceptor(ComponentReference service,
Binding binding,
InvocationChain chain,
Operation operation) {
List<PolicyProvider> pps = ((RuntimeComponentService)service).getPolicyProviders(binding);
if (pps != null) {
for (PolicyProvider p : pps) {
Interceptor interceptor = p.createInterceptor(operation);
if (interceptor != null) {
chain.addInterceptor(p.getPhase(), p.createInterceptor(operation));
}
}
}
}
/**
* Add a non-blocking interceptor if the reference binding needs it
*
* @param reference
* @param binding
* @param chain
*/
private void addNonBlockingInterceptor(ComponentReference reference, Binding binding, InvocationChain chain) {
ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
if (provider != null) {
boolean supportsOneWayInvocation = provider.supportsOneWayInvocation();
if (!supportsOneWayInvocation) {
chain.addInterceptor(Phase.REFERENCE, new NonBlockingInterceptor(workScheduler));
}
}
}
/**
* Add a non-blocking interceptor if the service binding needs it
*
* @param service
* @param binding
* @param chain
*/
private void addNonBlockingInterceptor(ComponentService service, Binding binding, InvocationChain chain) {
ServiceBindingProvider provider = ((RuntimeComponentService)service).getBindingProvider(binding);
if (provider != null) {
if (!provider.supportsOneWayInvocation()) {
chain.addInterceptor(Phase.SERVICE, new NonBlockingInterceptor(workScheduler));
}
}
}
/**
* Add the interceptor for a component implementation
*
* @param component
* @param service
* @param chain
* @param operation
*/
private void addImplementationInterceptor(Component component,
ComponentService service,
InvocationChain chain,
Operation operation) {
ImplementationProvider provider = ((RuntimeComponent)component).getImplementationProvider();
if (provider != null) {
Invoker invoker = null;
invoker = provider.createInvoker((RuntimeComponentService)service, operation);
chain.addInvoker(invoker);
}
List<PolicyProvider> pps = ((RuntimeComponent)component).getPolicyProviders();
if (pps != null) {
for (PolicyProvider p : pps) {
Interceptor interceptor = p.createInterceptor(operation);
if (interceptor != null) {
chain.addInterceptor(p.getPhase(), p.createInterceptor(operation));
}
}
}
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
RuntimeWireImpl copy = (RuntimeWireImpl)super.clone();
copy.wireSource = (EndpointReference)wireSource.clone();
copy.wireTarget = (EndpointReference)wireTarget.clone();
copy.invoker = new RuntimeWireInvoker(copy.messageFactory, copy.conversationManager, copy);
return copy;
}
/**
* @return the conversationManager
*/
public ConversationManager getConversationManager() {
return conversationManager;
}
public synchronized RuntimeWire lookupCache(EndpointReference callback) {
if (lastCallback != null && callback.getURI().equals(lastCallback.getURI()) && !wireReserved) {
wireReserved = true;
return cachedWire;
} else {
return null;
}
}
public synchronized void addToCache(EndpointReference callback, RuntimeWire clonedWire) {
((RuntimeWireImpl)clonedWire).setClonedFrom(this);
lastCallback = callback;
cachedWire = clonedWire;
wireReserved = true;
}
public synchronized void releaseClonedWire(RuntimeWire wire) {
if (cachedWire == wire) {
wireReserved = false;
}
}
public synchronized void releaseWire() {
clonedFrom.releaseClonedWire(this);
}
private void setClonedFrom(RuntimeWireImpl wire) {
clonedFrom = wire;
}
}

View file

@ -0,0 +1,539 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.context;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.UUID;
import javax.xml.stream.XMLStreamReader;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.OptimizableBinding;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.SCABinding;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl;
import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
import org.apache.tuscany.sca.core.assembly.EndpointWireImpl;
import org.apache.tuscany.sca.core.assembly.ReferenceParametersImpl;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.conversation.ConversationState;
import org.apache.tuscany.sca.core.conversation.ExtendedConversation;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.Conversation;
import org.osoa.sca.ServiceRuntimeException;
/**
* Base class for implementations of service and callback references.
*
* @version $Rev$ $Date$
* @param <B> the type of the business interface
*/
public class CallableReferenceImpl<B> implements CallableReference<B>, Externalizable {
static final long serialVersionUID = -521548304761848325L;
protected transient CompositeActivator compositeActivator;
protected transient ProxyFactory proxyFactory;
protected transient Class<B> businessInterface;
protected transient Object proxy;
// if the wire targets a conversational service this holds the conversation state
protected transient ConversationManager conversationManager;
protected transient ExtendedConversation conversation;
protected transient Object conversationID;
protected Object callbackID; // The callbackID should be serializable
protected transient RuntimeComponent component;
protected transient RuntimeComponentReference reference;
protected transient Binding binding;
protected String scdl;
private transient RuntimeComponentReference clonedRef;
private transient ReferenceParameters refParams;
private transient XMLStreamReader xmlReader;
private transient RuntimeWire endpointWire;
/*
* Public constructor for Externalizable serialization/deserialization
*/
public CallableReferenceImpl() {
super();
}
/*
* Public constructor for use by XMLStreamReader2CallableReference
*/
public CallableReferenceImpl(XMLStreamReader xmlReader) throws Exception {
this.xmlReader = xmlReader;
resolve();
}
protected CallableReferenceImpl(Class<B> businessInterface,
RuntimeComponent component,
RuntimeComponentReference reference,
Binding binding,
ProxyFactory proxyFactory,
CompositeActivator compositeActivator) {
this.proxyFactory = proxyFactory;
this.businessInterface = businessInterface;
this.component = component;
this.reference = reference;
this.binding = binding;
// FIXME: The SCA Specification is not clear how we should handle multiplicity
// for CallableReference
if (this.binding == null) {
this.binding = this.reference.getBinding(SCABinding.class);
if (this.binding == null) {
this.binding = this.reference.getBindings().get(0);
}
}
// FIXME: Should we normalize the componentName/serviceName URI into an absolute SCA URI in the SCA binding?
// sca:component1/component11/component112/service1?
this.compositeActivator = compositeActivator;
this.conversationManager = this.compositeActivator.getConversationManager();
initCallbackID();
}
public CallableReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
this.businessInterface = businessInterface;
bind(wire);
}
public RuntimeWire getRuntimeWire() {
try {
resolve();
if (endpointWire != null){
return endpointWire;
} else if (reference != null) {
return reference.getRuntimeWire(binding);
} else {
return null;
}
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
protected void bind(RuntimeWire wire) {
if (wire != null) {
if (wire instanceof EndpointWireImpl){
endpointWire = wire;
}
this.component = wire.getSource().getComponent();
this.reference = (RuntimeComponentReference)wire.getSource().getContract();
this.binding = wire.getSource().getBinding();
this.compositeActivator = ((ComponentContextImpl)component.getComponentContext()).getCompositeActivator();
this.conversationManager = this.compositeActivator.getConversationManager();
initCallbackID();
}
}
protected void initCallbackID() {
if (reference.getInterfaceContract().getCallbackInterface() != null) {
this.callbackID = createCallbackID();
}
}
public B getProxy() throws ObjectCreationException {
try {
if (proxy == null) {
proxy = createProxy();
}
return businessInterface.cast(proxy);
} catch (Exception e) {
throw new ObjectCreationException(e);
}
}
public void setProxy(Object proxy) {
this.proxy = proxy;
}
protected Object createProxy() throws Exception {
return proxyFactory.createProxy(this);
}
public B getService() {
try {
resolve();
return getProxy();
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public Class<B> getBusinessInterface() {
try {
resolve();
return businessInterface;
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public boolean isConversational() {
try {
resolve();
return reference == null ? false : reference.getInterfaceContract().getInterface().isConversational();
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public Conversation getConversation() {
try {
// resolve from XML just in case this CallableReference is the result of
// passing a CallableReference as a parameter
resolve();
if (conversation == null || conversation.getState() == ConversationState.ENDED) {
conversation = null;
}
return conversation;
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public Object getCallbackID() {
try {
resolve();
return callbackID;
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
/**
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
final boolean hasSCDL = in.readBoolean();
if (hasSCDL) {
this.scdl = in.readUTF();
} else {
this.scdl = null;
}
}
/**
* @throws IOException
*/
private synchronized void resolve() throws Exception {
if ((scdl != null || xmlReader != null) && component == null && reference == null) {
ComponentContextHelper componentContextHelper = ComponentContextHelper.getCurrentComponentContextHelper();
if (componentContextHelper != null) {
this.compositeActivator = ComponentContextHelper.getCurrentCompositeActivator();
this.conversationManager = this.compositeActivator.getConversationManager();
Component c;
if (xmlReader != null) {
c = componentContextHelper.fromXML(xmlReader);
xmlReader = null; // OK to GC this now
} else {
c = componentContextHelper.fromXML(scdl);
scdl = null; // OK to GC this now
}
this.component = (RuntimeComponent)c;
compositeActivator.configureComponentContext(this.component);
this.reference = (RuntimeComponentReference)c.getReferences().get(0);
this.reference.setComponent(this.component);
clonedRef = reference;
ReferenceParameters parameters = null;
for (Object ext : reference.getExtensions()) {
if (ext instanceof ReferenceParameters) {
parameters = (ReferenceParameters)ext;
break;
}
}
if (parameters != null) {
refParams = parameters;
this.callbackID = parameters.getCallbackID();
attachConversation(parameters.getConversationID());
}
for (Binding binding : reference.getBindings()) {
if (binding instanceof OptimizableBinding) {
// Split up the URI
final String[] splitURI = splitComponentURI(binding.getURI());
final String componentURI = splitURI[0];
final String serviceName = splitURI[1];
// Resolve the Component
final Component targetComponent = resolveComponentURI(componentURI);
// Find the Service
final ComponentService targetService = resolveService(serviceName, targetComponent);
OptimizableBinding optimizableBinding = (OptimizableBinding)binding;
optimizableBinding.setTargetComponent(targetComponent);
optimizableBinding.setTargetComponentService(targetService);
if (targetService != null) {
for (Binding serviceBinding : targetService.getBindings()) {
if (serviceBinding.getClass() == binding.getClass()) {
optimizableBinding.setTargetBinding(serviceBinding);
break;
}
}
}
}
}
// FIXME: The SCA Specification is not clear how we should handle multiplicity
// for CallableReference
if (binding == null) {
binding = reference.getBinding(SCABinding.class);
if (binding == null) {
binding = reference.getBindings().get(0);
}
}
Interface i = reference.getInterfaceContract().getInterface();
if (i instanceof JavaInterface) {
JavaInterface javaInterface = (JavaInterface)i;
if (javaInterface.isUnresolved()) {
// Allow privileged access to get ClassLoader. Requires RuntimePermission in
// security policy.
ClassLoader classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
javaInterface.setJavaClass(classLoader.loadClass(javaInterface.getName()));
compositeActivator.getJavaInterfaceFactory().createJavaInterface(javaInterface,
javaInterface.getJavaClass());
//FIXME: If the interface needs XSDs to be loaded (e.g., for static SDO),
// this needs to be done here. We usually search for XSDs in the current
// contribution at resolve time. Is it possible to locate the current
// contribution at runtime?
}
this.businessInterface = (Class<B>)javaInterface.getJavaClass();
}
this.proxyFactory = compositeActivator.getProxyFactory();
}
} else {
this.compositeActivator = ComponentContextHelper.getCurrentCompositeActivator();
if (this.compositeActivator != null) {
this.proxyFactory = this.compositeActivator.getProxyFactory();
}
}
}
/**
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
try {
final String xml = toXMLString();
if (xml == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
out.writeUTF(toXMLString());
}
} catch (Exception e) {
// e.printStackTrace();
throw new IOException(e.getMessage());
}
}
public String toXMLString() throws IOException {
if (reference != null) {
if (clonedRef == null) {
try {
clonedRef = (RuntimeComponentReference)reference.clone();
} catch (CloneNotSupportedException e) {
// will not happen
}
}
if (refParams == null) {
refParams = new ReferenceParametersImpl();
// remove any existing reference parameters from the clone
Object toRemove = null;
for (Object extension : clonedRef.getExtensions()){
if (extension instanceof ReferenceParameters){
toRemove = extension;
}
}
if (toRemove != null){
clonedRef.getExtensions().remove(toRemove);
}
// add the new reference parameter object
clonedRef.getExtensions().add(refParams);
}
refParams.setCallbackID(callbackID);
if (conversation != null){
refParams.setConversationID(conversation.getConversationID());
}
return ((CompositeActivatorImpl)compositeActivator).getComponentContextHelper()
.toXML(component, clonedRef);
} else {
return scdl;
}
}
/**
* Create a callback id
*
* @return the callback id
*/
private String createCallbackID() {
return UUID.randomUUID().toString();
}
public void attachCallbackID(Object callbackID) {
this.callbackID = callbackID;
}
public void attachConversationID(Object conversationID) {
this.conversationID = conversationID;
}
public void attachConversation(ExtendedConversation conversation) {
this.conversation = conversation;
}
public void attachConversation(Object conversationID) {
if (conversationID != null) {
ExtendedConversation conversation = conversationManager.getConversation(conversationID);
if (conversation == null){
conversation = conversationManager.startConversation(conversationID);
}
this.conversation = conversation;
} else {
this.conversation = null;
}
}
protected ReferenceParameters getReferenceParameters() {
ReferenceParameters parameters = new ReferenceParametersImpl();
parameters.setCallbackID(callbackID);
if (getConversation() != null) {
parameters.setConversationID(conversation.getConversationID());
}
return parameters;
}
public EndpointReference getEndpointReference() {
try {
resolve();
// Use the interface contract of the reference on the component type
Reference componentTypeRef = reference.getReference();
InterfaceContract sourceContract =
componentTypeRef == null ? reference.getInterfaceContract() : componentTypeRef.getInterfaceContract();
sourceContract = sourceContract.makeUnidirectional(false);
EndpointReference epr = new EndpointReferenceImpl(component, reference, binding, sourceContract);
ReferenceParameters parameters = getReferenceParameters();
epr.setReferenceParameters(parameters);
return epr;
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public XMLStreamReader getXMLReader() {
return xmlReader;
}
/**
* Resolves the specified URI to a Component using the compositeActivator.
*
* @param componentURI The URI of the Component to resolve
* @return The Component for the specified URI or null if not founds
*/
protected Component resolveComponentURI(String componentURI) {
final String[] splitUri = splitComponentURI(componentURI);
return compositeActivator.resolve(splitUri[0]);
}
/**
* This method will split the specified URI into the Component URI
* and Service Name.
*
* @param componentURI The URI to split
* @return [0] = Component URI [1] = ServiceName
*/
protected String[] splitComponentURI(String componentURI) {
final String[] result = new String[2];
if (componentURI.startsWith("/")) {
componentURI = componentURI.substring(1);
}
final int index = componentURI.lastIndexOf('/');
String serviceName = "";
if (index > -1) {
serviceName = componentURI.substring(index + 1);
componentURI = componentURI.substring(0, index);
}
// Return the results
result[0] = componentURI;
result[1] = serviceName;
return result;
}
/**
* Examines the Services on the specified Component and returns the Service that matches the
* specified name.
*
* @param serviceName The name of the Service to resolve on the Component
* @param targetComponent The Component containing the Services
* @return The Service with the specified serviceName or null if no such Service found.
*/
protected ComponentService resolveService(String serviceName, Component targetComponent) {
ComponentService targetService = null;
if (targetComponent != null) {
if ("".equals(serviceName)) {
targetService = ComponentContextHelper.getSingleService(targetComponent);
} else {
for (ComponentService service : targetComponent.getServices()) {
if (service.getName().equals(serviceName)) {
targetService = service;
break;
}
}
}
}
return targetService;
}
}

View file

@ -0,0 +1,320 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.context;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Composite;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.assembly.OptimizableBinding;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.osoa.sca.ServiceRuntimeException;
/**
* @version $Rev$ $Date$
*/
public class ComponentContextHelper {
private final AssemblyFactory assemblyFactory;
private final JavaInterfaceFactory javaInterfaceFactory;
private final StAXArtifactProcessorExtensionPoint staxProcessors;
/**
* @param assemblyFactory The factory to create assembly models
* @param processors The extension point for StAX artifact processors
*/
public ComponentContextHelper(AssemblyFactory assemblyFactory,
JavaInterfaceFactory javaInterfaceFactory,
StAXArtifactProcessorExtensionPoint processors) {
this.assemblyFactory = assemblyFactory;
this.javaInterfaceFactory = javaInterfaceFactory;
this.staxProcessors = processors;
}
/**
* Create a self-reference for a component service
* @param component
* @param service
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
public ComponentReference createSelfReference(Component component,
ComponentService service,
Class<?> businessInterface) throws CloneNotSupportedException,
InvalidInterfaceException {
ComponentReference componentReference = assemblyFactory.createComponentReference();
componentReference.setName("$self$." + service.getName());
for (Binding binding : service.getBindings()) {
if (binding instanceof OptimizableBinding) {
OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
optimizableBinding.setTargetBinding(binding);
optimizableBinding.setTargetComponent(component);
optimizableBinding.setTargetComponentService(service);
componentReference.getBindings().add(optimizableBinding);
} else {
componentReference.getBindings().add(binding);
}
}
componentReference.setCallback(service.getCallback());
componentReference.getTargets().add(service);
componentReference.getPolicySets().addAll(service.getPolicySets());
componentReference.getRequiredIntents().addAll(service.getRequiredIntents());
InterfaceContract interfaceContract = service.getInterfaceContract();
Service componentTypeService = service.getService();
if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
interfaceContract = componentTypeService.getInterfaceContract();
}
interfaceContract = getInterfaceContract(interfaceContract, businessInterface);
componentReference.setInterfaceContract(interfaceContract);
componentReference.setMultiplicity(Multiplicity.ONE_ONE);
// component.getReferences().add(componentReference);
return componentReference;
}
/**
* @param interfaceContract
* @param businessInterface
* @return
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
private InterfaceContract getInterfaceContract(InterfaceContract interfaceContract, Class<?> businessInterface)
throws CloneNotSupportedException, InvalidInterfaceException {
Interface interfaze = interfaceContract.getInterface();
boolean compatible = false;
if (interfaze instanceof JavaInterface) {
Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
if (businessInterface.isAssignableFrom(cls)) {
compatible = true;
}
}
if (!compatible) {
// The interface is not assignable from the interface contract
interfaceContract = (InterfaceContract)interfaceContract.clone();
interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface));
}
return interfaceContract;
}
/**
* Bind a component reference to a component service
* @param <B>
* @param businessInterface
* @param reference
* @param service
* @return
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
public RuntimeComponentReference bindComponentReference(Class<?> businessInterface,
RuntimeComponentReference reference,
RuntimeComponent component,
RuntimeComponentService service)
throws CloneNotSupportedException, InvalidInterfaceException {
RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
InterfaceContract interfaceContract = reference.getInterfaceContract();
Reference componentTypeReference = reference.getReference();
if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
interfaceContract = componentTypeReference.getInterfaceContract();
}
InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
if (refInterfaceContract != interfaceContract) {
ref = (RuntimeComponentReference)reference.clone();
ref.setInterfaceContract(interfaceContract);
}
ref.setComponent(component);
ref.getTargets().add(service);
ref.getBindings().clear();
for (Binding binding : service.getBindings()) {
if (binding instanceof OptimizableBinding) {
OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
optimizableBinding.setTargetBinding(binding);
optimizableBinding.setTargetComponent(component);
optimizableBinding.setTargetComponentService(service);
ref.getBindings().add(optimizableBinding);
} else {
ref.getBindings().add(binding);
}
}
return ref;
}
public void write(Component component, ComponentReference reference, Writer writer) throws IOException {
write(component, reference, null, writer);
}
public void write(Component component, ComponentReference reference, ComponentService service, Writer writer) throws IOException {
try {
StAXArtifactProcessor<Composite> processor = staxProcessors.getProcessor(Composite.class);
Composite composite = assemblyFactory.createComposite();
composite.setName(new QName("http://tuscany.apache.org/xmlns/sca/1.0", "default"));
Component comp = assemblyFactory.createComponent();
comp.setName("default");
comp.setURI(component.getURI());
composite.getComponents().add(comp);
if (reference != null) {
comp.getReferences().add(reference);
}
if (service != null) {
comp.getServices().add(service);
}
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(writer);
processor.write(composite, streamWriter);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public String toXML(Component component, ComponentReference reference) throws IOException {
StringWriter writer = new StringWriter();
write(component, reference, writer);
return writer.toString();
}
public String toXML(Component component, ComponentService service) throws IOException {
StringWriter writer = new StringWriter();
write(component, null, service, writer);
return writer.toString();
}
public RuntimeComponent read(Reader reader) throws IOException {
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(reader);
return read(streamReader);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public RuntimeComponent read(XMLStreamReader streamReader) throws IOException {
try {
StAXArtifactProcessor<Composite> processor = staxProcessors.getProcessor(Composite.class);
Composite composite = processor.read(streamReader);
RuntimeComponent component = (RuntimeComponent)composite.getComponents().get(0);
return component;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public Component fromXML(String xml) throws IOException {
return read(new StringReader(xml));
}
public Component fromXML(XMLStreamReader streamReader) throws IOException {
return read(streamReader);
}
public static RuntimeComponent getCurrentComponent() {
Message message = ThreadMessageContext.getMessageContext();
if (message != null) {
EndpointReference to = message.getTo();
if (to == null) {
return null;
}
RuntimeComponent component = message.getTo().getComponent();
return component;
}
return null;
}
public static CompositeActivator getCurrentCompositeActivator() {
RuntimeComponent component = getCurrentComponent();
if (component != null) {
ComponentContextImpl context = (ComponentContextImpl)component.getComponentContext();
return context.getCompositeActivator();
}
return null;
}
public static ComponentContextHelper getCurrentComponentContextHelper() {
CompositeActivator activator = getCurrentCompositeActivator();
if (activator != null) {
return activator.getComponentContextHelper();
}
return null;
}
/**
* @param component
*/
public static ComponentService getSingleService(Component component) {
ComponentService targetService;
List<ComponentService> services = component.getServices();
List<ComponentService> regularServices = new ArrayList<ComponentService>();
for (ComponentService service : services) {
if (service.isCallback()) {
continue;
}
String name = service.getName();
if (!name.startsWith("$") || name.startsWith("$dynamic$")) {
regularServices.add(service);
}
}
if (regularServices.size() == 0) {
throw new ServiceRuntimeException("No service is declared on component " + component.getURI());
}
if (regularServices.size() != 1) {
throw new ServiceRuntimeException("More than one service is declared on component " + component.getURI()
+ ". Service name is required to get the service.");
}
targetService = regularServices.get(0);
return targetService;
}
}

View file

@ -0,0 +1,396 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.context;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentProperty;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.assembly.OptimizableBinding;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.context.PropertyValueFactory;
import org.apache.tuscany.sca.context.RequestContextFactory;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.osoa.sca.CallableReference;
import org.osoa.sca.RequestContext;
import org.osoa.sca.ServiceReference;
import org.osoa.sca.ServiceRuntimeException;
/**
* Implementation of ComponentContext that delegates to a ComponentContextProvider.
*
* @version $Rev$ $Date$
*/
public class ComponentContextImpl implements RuntimeComponentContext {
private final RuntimeComponent component;
private final CompositeActivator compositeActivator;
private final RequestContextFactory requestContextFactory;
private final ProxyFactory proxyFactory;
private final AssemblyFactory assemblyFactory;
private final JavaInterfaceFactory javaInterfaceFactory;
/**
* This is a reference to the PropertyValueFactory that is provided by the Implementation
* that can be used to get the value from a Property Object.
*
* @see #setPropertyValueFactory(PropertyValueFactory)
* @see #getProperty(Class, String)
*/
private PropertyValueFactory propertyFactory;
public ComponentContextImpl(CompositeActivator compositeActivator,
AssemblyFactory assemblyFactory,
ProxyFactory proxyFactory,
InterfaceContractMapper interfaceContractMapper,
RequestContextFactory requestContextFactory,
JavaInterfaceFactory javaInterfaceFactory,
RuntimeComponent component) {
super();
this.compositeActivator = compositeActivator;
this.assemblyFactory = assemblyFactory;
this.proxyFactory = proxyFactory;
this.requestContextFactory = requestContextFactory;
this.javaInterfaceFactory = javaInterfaceFactory;
this.component = component;
}
public String getURI() {
return component.getURI();
}
public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
return (R)proxyFactory.cast(target);
}
public <B> B getService(Class<B> businessInterface, String referenceName) {
ServiceReference<B> serviceRef = getServiceReference(businessInterface, referenceName);
return serviceRef.getService();
}
public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
try {
for (ComponentReference ref : component.getReferences()) {
if (referenceName.equals(ref.getName())) {
return getServiceReference(businessInterface, (RuntimeComponentReference)ref, null);
}
}
throw new ServiceRuntimeException("Reference not found: " + referenceName);
} catch (ServiceRuntimeException e) {
throw e;
} catch (Exception e) {
throw new ServiceRuntimeException(e.getMessage(), e);
}
}
/**
* The Implementation is responsible for calling this method to set the
* PropertyValueFactory that is used to get the Property Value from
* a Tuscany Property object.
*
* @param factory The PropertyValueFactory to use
*
* @see #getProperty(Class, String)
*/
public void setPropertyValueFactory(PropertyValueFactory factory) {
propertyFactory = factory;
}
/**
* Gets the value for the specified property with the specified type.
*
* @param type The type of the property value we are getting
* @param propertyName The name of the property we are getting
* @param B The class of the property value we are getting
*
* @throws ServiceRuntimeException If a Property for the specified propertyName
* is not found
*
* @see #setPropertyValueFactory(PropertyValueFactory)
*/
public <B> B getProperty(Class<B> type, String propertyName) {
for (ComponentProperty p : component.getProperties()) {
if (propertyName.equals(p.getName())) {
return propertyFactory.createPropertyValue(p, type);
}
}
throw new ServiceRuntimeException("Property not found: " + propertyName);
}
public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface) {
ComponentService service = ComponentContextHelper.getSingleService(component);
try {
return createSelfReference(businessInterface, service);
} catch (Exception e) {
throw new ServiceRuntimeException(e.getMessage(), e);
}
}
public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, String serviceName) {
try {
for (ComponentService service : component.getServices()) {
if (serviceName.equals(service.getName())) {
return createSelfReference(businessInterface, service);
}
}
throw new ServiceRuntimeException("Service not found: " + serviceName);
} catch (ServiceRuntimeException e) {
throw e;
} catch (Exception e) {
throw new ServiceRuntimeException(e.getMessage(), e);
}
}
/**
* @param <B>
* @param businessInterface
* @param service
* @return
*/
public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, ComponentService service) {
try {
RuntimeComponentReference ref =
(RuntimeComponentReference)createSelfReference(component, service, businessInterface);
ref.setComponent(component);
return getServiceReference(businessInterface, ref, null);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public RequestContext getRequestContext() {
if (requestContextFactory != null) {
return requestContextFactory.createRequestContext();
} else {
return new RequestContextImpl(proxyFactory);
}
}
/**
* @param businessInterface
* @param reference
* @return
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, RuntimeComponentReference reference, Binding binding) {
try {
RuntimeComponentReference ref = (RuntimeComponentReference)reference;
InterfaceContract interfaceContract = reference.getInterfaceContract();
Reference componentTypeReference = reference.getReference();
if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
interfaceContract = componentTypeReference.getInterfaceContract();
}
InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
if (refInterfaceContract != interfaceContract) {
ref = (RuntimeComponentReference)reference.clone();
ref.setInterfaceContract(interfaceContract);
}
ref.setComponent(component);
return new ServiceReferenceImpl<B>(businessInterface, component, ref, binding, proxyFactory, compositeActivator);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
/**
* Bind a component reference to a component service
* @param <B>
* @param businessInterface
* @param reference
* @param service
* @return
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface,
RuntimeComponentReference reference,
RuntimeComponent component,
RuntimeComponentService service) {
try {
RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
InterfaceContract interfaceContract = reference.getInterfaceContract();
Reference componentTypeReference = reference.getReference();
if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
interfaceContract = componentTypeReference.getInterfaceContract();
}
InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
if (refInterfaceContract != interfaceContract) {
ref = (RuntimeComponentReference)reference.clone();
ref.setInterfaceContract(interfaceContract);
}
ref.getTargets().add(service);
ref.getBindings().clear();
for (Binding binding : service.getBindings()) {
if (binding instanceof OptimizableBinding) {
OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
optimizableBinding.setTargetBinding(binding);
optimizableBinding.setTargetComponent(component);
optimizableBinding.setTargetComponentService(service);
ref.getBindings().add(optimizableBinding);
} else {
ref.getBindings().add(binding);
}
}
return new ServiceReferenceImpl<B>(businessInterface, component, ref, proxyFactory, compositeActivator);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
public <B> CallableReference<B> getCallableReference(Class<B> businessInterface,
RuntimeComponent component,
RuntimeComponentService service) {
try {
if (businessInterface == null) {
InterfaceContract contract = service.getInterfaceContract();
businessInterface = (Class<B>)((JavaInterface)contract.getInterface()).getJavaClass();
}
RuntimeComponentReference ref =
(RuntimeComponentReference)createSelfReference(component, service, businessInterface);
ref.setComponent(component);
return new CallableReferenceImpl<B>(businessInterface, component, ref, null, proxyFactory,
compositeActivator);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
}
/**
* Create a self-reference for a component service
* @param component
* @param service
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
private ComponentReference createSelfReference(Component component,
ComponentService service,
Class<?> businessInterface) throws CloneNotSupportedException,
InvalidInterfaceException {
ComponentReference componentReference = assemblyFactory.createComponentReference();
componentReference.setName("$self$." + service.getName());
for (Binding binding : service.getBindings()) {
if (binding instanceof OptimizableBinding) {
OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
optimizableBinding.setTargetBinding(binding);
optimizableBinding.setTargetComponent(component);
optimizableBinding.setTargetComponentService(service);
componentReference.getBindings().add(optimizableBinding);
} else {
componentReference.getBindings().add(binding);
}
}
componentReference.setCallback(service.getCallback());
componentReference.getTargets().add(service);
componentReference.getPolicySets().addAll(service.getPolicySets());
componentReference.getRequiredIntents().addAll(service.getRequiredIntents());
InterfaceContract interfaceContract = service.getInterfaceContract();
Service componentTypeService = service.getService();
if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
interfaceContract = componentTypeService.getInterfaceContract();
}
interfaceContract = getInterfaceContract(interfaceContract, businessInterface);
componentReference.setInterfaceContract(interfaceContract);
componentReference.setMultiplicity(Multiplicity.ONE_ONE);
// component.getReferences().add(componentReference);
return componentReference;
}
/**
* @param interfaceContract
* @param businessInterface
* @return
* @throws CloneNotSupportedException
* @throws InvalidInterfaceException
*/
private InterfaceContract getInterfaceContract(InterfaceContract interfaceContract, Class<?> businessInterface)
throws CloneNotSupportedException, InvalidInterfaceException {
Interface interfaze = interfaceContract.getInterface();
boolean compatible = false;
if (interfaze instanceof JavaInterface) {
Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
if (businessInterface.isAssignableFrom(cls)) {
compatible = true;
}
}
if (!compatible) {
// The interface is not assignable from the interface contract
interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(businessInterface);
interfaceContract.setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
interfaceContract.setCallbackInterface(javaInterfaceFactory.createJavaInterface(callInterface
.getCallbackClass()));
}
}
return interfaceContract;
}
/**
* @return the compositeActivator
*/
public CompositeActivator getCompositeActivator() {
return compositeActivator;
}
/**
* @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#start(org.apache.tuscany.sca.runtime.RuntimeComponentReference)
*/
public void start(RuntimeComponentReference reference) {
compositeActivator.start(component, reference);
}
/**
* @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#read(java.io.Reader)
*/
public RuntimeComponent read(Reader reader) throws IOException {
RuntimeComponent component = compositeActivator.getComponentContextHelper().read(reader);
compositeActivator.configureComponentContext(component);
return component;
}
/**
* @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#write(org.apache.tuscany.sca.runtime.RuntimeComponentReference, java.io.Writer)
*/
public void write(RuntimeComponentReference reference, Writer writer) throws IOException {
compositeActivator.getComponentContextHelper().write(component, reference, writer);
}
}

View file

@ -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.sca.core.context;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.context.ComponentContextFactory;
import org.apache.tuscany.sca.context.RequestContextFactory;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.osoa.sca.ComponentContext;
/**
* @version $Rev$ $Date$
*/
public class DefaultComponentContextFactory implements ComponentContextFactory {
private final CompositeActivator compositeActivator;
private final RequestContextFactory requestContextFactory;
private final ProxyFactory proxyFactory;
private final AssemblyFactory assemblyFactory;
private final JavaInterfaceFactory javaInterfaceFactory;
private final InterfaceContractMapper interfaceContractMapper;
public DefaultComponentContextFactory(CompositeActivator compositeActivator,
AssemblyFactory assemblyFactory,
ProxyFactory proxyFactory,
InterfaceContractMapper interfaceContractMapper,
RequestContextFactory requestContextFactory,
JavaInterfaceFactory javaInterfaceFactory) {
super();
this.compositeActivator = compositeActivator;
this.assemblyFactory = assemblyFactory;
this.proxyFactory = proxyFactory;
this.requestContextFactory = requestContextFactory;
this.javaInterfaceFactory = javaInterfaceFactory;
this.interfaceContractMapper = interfaceContractMapper;
}
/**
* @see org.apache.tuscany.sca.context.ComponentContextFactory#createComponentContext(org.apache.tuscany.sca.runtime.RuntimeComponent, org.apache.tuscany.sca.context.RequestContextFactory)
*/
public ComponentContext createComponentContext(RuntimeComponent component,
RequestContextFactory requestContextFactory) {
if (requestContextFactory == null) {
requestContextFactory = this.requestContextFactory;
}
return new ComponentContextImpl(compositeActivator, assemblyFactory, proxyFactory, interfaceContractMapper,
requestContextFactory, javaInterfaceFactory, component);
}
}

View file

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.context;
import org.apache.tuscany.sca.core.scope.TargetDestructionException;
import org.apache.tuscany.sca.core.scope.TargetInitializationException;
/**
* Provides lifecycle management for an implementation instance associated with
* a component for use by the component's associated {@link org.apache.tuscany.sca.core.scope.ScopeContainer}
*
* @version $Rev$ $Date$
*/
public interface InstanceWrapper<T> {
/**
* @return
*/
T getInstance();
/**
* @throws TargetInitializationException
*/
void start() throws TargetInitializationException;
/**
* @throws TargetDestructionException
*/
void stop() throws TargetDestructionException;
}

View file

@ -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.sca.core.context;
import java.util.List;
import javax.security.auth.Subject;
import org.apache.tuscany.sca.core.invocation.CallbackReferenceImpl;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.RequestContext;
/**
* @version $Rev$ $Date$
*/
public class RequestContextImpl implements RequestContext {
private ProxyFactory proxyFactory;
public RequestContextImpl(ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
}
public Subject getSecuritySubject() {
throw new UnsupportedOperationException();
}
public String getServiceName() {
return ThreadMessageContext.getMessageContext().getTo().getContract().getName();
}
@SuppressWarnings("unchecked")
public <B> CallableReference<B> getServiceReference() {
Message msgContext = ThreadMessageContext.getMessageContext();
// FIXME: [rfeng] Is this the service reference matching the caller side?
EndpointReference to = msgContext.getTo();
RuntimeComponentService service = (RuntimeComponentService) to.getContract();
RuntimeComponent component = (RuntimeComponent) to.getComponent();
CallableReference<B> callableReference = component.getComponentContext().getCallableReference(null, component, service);
ReferenceParameters parameters = msgContext.getFrom().getReferenceParameters();
((CallableReferenceImpl<B>) callableReference).attachCallbackID(parameters.getCallbackID());
((CallableReferenceImpl<B>) callableReference).attachConversation(parameters.getConversationID());
return callableReference;
}
@SuppressWarnings("unchecked")
public <CB> CB getCallback() {
CallableReference<CB> cb = getCallbackReference();
if (cb == null) {
return null;
}
return cb.getService();
}
@SuppressWarnings("unchecked")
public <CB> CallableReference<CB> getCallbackReference() {
Message msgContext = ThreadMessageContext.getMessageContext();
EndpointReference to = msgContext.getTo();
RuntimeComponentService service = (RuntimeComponentService) to.getContract();
RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference();
if (callbackReference == null) {
return null;
}
JavaInterface javaInterface = (JavaInterface) callbackReference.getInterfaceContract().getInterface();
Class<CB> javaClass = (Class<CB>)javaInterface.getJavaClass();
List<RuntimeWire> wires = callbackReference.getRuntimeWires();
CallbackReferenceImpl ref = CallbackReferenceImpl.newInstance(javaClass, proxyFactory, wires);
if (ref != null) {
//ref.resolveTarget();
ReferenceParameters parameters = msgContext.getFrom().getReferenceParameters();
ref.attachCallbackID(parameters.getCallbackID());
if (ref.getConversation() != null) {
ref.attachConversationID(parameters.getConversationID());
}
}
return ref;
}
}

View file

@ -0,0 +1,132 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.context;
import javax.xml.stream.XMLStreamReader;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.conversation.ConversationState;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.ServiceReference;
/**
* Default implementation of a ServiceReference.
*
* @version $Rev$ $Date$
* @param <B> the type of the business interface
*/
public class ServiceReferenceImpl<B> extends CallableReferenceImpl<B> implements ServiceReference<B> {
private static final long serialVersionUID = 6763709434194361540L;
protected transient Object callback;
/*
* Public constructor for Externalizable serialization/deserialization
*/
public ServiceReferenceImpl() {
super();
}
/*
* Public constructor for use by XMLStreamReader2CallableReference
*/
public ServiceReferenceImpl(XMLStreamReader xmlReader) throws Exception {
super(xmlReader);
}
/**
* @param businessInterface
* @param wire
* @param proxyFactory
*/
public ServiceReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
super(businessInterface, wire, proxyFactory);
}
public ServiceReferenceImpl(Class<B> businessInterface,
RuntimeComponent component,
RuntimeComponentReference reference,
ProxyFactory proxyFactory,
CompositeActivator compositeActivator) {
super(businessInterface, component, reference, null, proxyFactory, compositeActivator);
}
public ServiceReferenceImpl(Class<B> businessInterface,
RuntimeComponent component,
RuntimeComponentReference reference,
Binding binding,
ProxyFactory proxyFactory,
CompositeActivator compositeActivator) {
super(businessInterface, component, reference, binding, proxyFactory, compositeActivator);
}
public Object getConversationID() {
return conversationID;
}
public void setConversationID(Object conversationID) throws IllegalStateException {
if (conversation == null || conversation.getState() != ConversationState.ENDED) {
this.conversationID = conversationID;
this.conversation = null;
} else {
throw new IllegalStateException("Trying to set the conversationId on a service reference but the state of the conversation "
+ conversation.getConversationID()
+ " is "
+ conversation.getState());
}
}
public void setCallbackID(Object callbackID) {
this.callbackID = callbackID;
}
public Object getCallback() {
return callback;
}
public void setCallback(Object callback) {
if (callback != null && !(callback instanceof CallableReference)) {
//FIXME: need to check if callback object supports the callback interface
// returned by reference.getInterfaceContract().getCallbackInterface()
}
this.callback = callback;
}
protected ReferenceParameters getReferenceParameters() {
ReferenceParameters parameters = super.getReferenceParameters();
if (callback != null) {
if (callback instanceof ServiceReference) {
EndpointReference callbackRef = ((CallableReferenceImpl)callback).getEndpointReference();
parameters.setCallbackReference(callbackRef);
} else {
EndpointReference callbackRef = getRuntimeWire().getSource().getCallbackEndpoint();
parameters.setCallbackReference(callbackRef);
parameters.setCallbackObjectID(callback);
}
}
return parameters;
}
}

View file

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
/**
* Listener for the events of a conversation
*
* @version $Rev$ $Date$
*/
public interface ConversationListener {
/**
* The conversation is started
*/
void conversationStarted(ExtendedConversation conversation);
/**
* The conversation is ended
*/
void conversationEnded(ExtendedConversation conversation);
/**
* The conversation is expired
*/
void conversationExpired(ExtendedConversation conversation);
}

View file

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
/**
* The manager of conversations
*
* @version $Rev$ $Date$
*/
public interface ConversationManager {
/**
* @param conversationID
* @return
*/
ExtendedConversation startConversation(Object conversationID);
/**
* @param conversationID
*/
void endConversation(Object conversationID);
/**
* @param conversationID
* @return
*/
ExtendedConversation getConversation(Object conversationID);
/**
* @param conversationID
*/
void expireConversation(Object conversationID);
/**
* Add a listener to this conversation
* @param listener
*/
void addListener(ConversationListener listener);
/**
* Remove a listener from this conversation
* @param listener
*/
void removeListener(ConversationListener listener);
/**
* @return the default max age for a conversation
*/
long getMaxAge();
/**
* @return the default max idle time for a conversation
*/
long getMaxIdleTime();
}

View file

@ -0,0 +1,215 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @version $Rev$ $Date$
*/
public class ConversationManagerImpl implements ConversationManager {
private List<ConversationListener> listeners = Collections.synchronizedList(new ArrayList<ConversationListener>());
private Map<Object, ExtendedConversation> conversations = new ConcurrentHashMap<Object, ExtendedConversation>();
/**
* the default max age. this is set to 1 hour
*/
private static final long DEFAULT_MAX_AGE = 60 * 60 * 1000; ;
/**
* the default max idle time. this is set to 1 hour
*/
private static final long DEFAULT_MAX_IDLE_TIME = 60 * 60 * 1000;
/**
* the globally used max age
*/
private final long maxAge;
/**
* the globally used max idle time
*/
private final long maxIdleTime;
/**
* the reaper thread
*/
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
/**
* constructor
*/
public ConversationManagerImpl() {
long mit = DEFAULT_MAX_IDLE_TIME;
long ma = DEFAULT_MAX_AGE;
// Allow privileged access to read system property. Requires PropertyPermission in security
// policy.
String aProperty = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("org.apache.tuscany.sca.core.scope.ConversationalScopeContainer.MaxIdleTime");
}
});
if (aProperty != null) {
try {
mit = (new Long(aProperty) * 1000);
} catch (NumberFormatException nfe) {
// Ignore
}
}
// Allow privileged access to read system property. Requires PropertyPermission in security
// policy.
aProperty = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("org.apache.tuscany.sca.core.scope.ConversationalScopeContainer.MaxAge");
}
});
if (aProperty != null) {
try {
ma = (new Long(aProperty) * 1000);
} catch (NumberFormatException nfe) {
// Ignore
}
}
maxAge = ma;
maxIdleTime = mit;
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationManager#addListener(org.apache.tuscany.sca.core.conversation.ConversationListener)
*/
public void addListener(ConversationListener listener) {
listeners.add(listener);
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationManager#endConversation(org.apache.tuscany.sca.core.conversation.ExtendedConversation)
*/
public void endConversation(Object conversationID) {
ExtendedConversation conv = getConversation(conversationID);
if (conv != null) {
conv.setState(ConversationState.ENDED);
for (ConversationListener listener : listeners) {
listener.conversationEnded(conv);
}
conv.setConversationID(null);
conversations.remove(conversationID);
} else {
throw new IllegalStateException("Conversation " + conversationID + " doesn't exist.");
}
}
public void expireConversation(Object conversationID) {
ExtendedConversation conv = getConversation(conversationID);
if (conv != null) {
for (ConversationListener listener : listeners) {
listener.conversationExpired(conv);
}
conversations.remove(conversationID);
} else {
throw new IllegalStateException("Conversation " + conversationID + " doesn't exist.");
}
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationManager#getConversation(java.lang.Object)
*/
public ExtendedConversation getConversation(Object conversationID) {
return conversations.get(conversationID);
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationManager#removeListener(org.apache.tuscany.sca.core.conversation.ConversationListener)
*/
public void removeListener(ConversationListener listener) {
listeners.remove(listener);
}
/**
* starts the reaper thread
*/
public void scheduleConversation(ExtendedConversationImpl aConversation, long time)
{
this.scheduler.schedule(aConversation, time, TimeUnit.MILLISECONDS);
}
/**
* stops the reaper thread
*/
public synchronized void stopReaper() {
// Prevent the scheduler from submitting any additional reapers,
// initiate an orderly shutdown if a reaper task is in progress.
this.scheduler.shutdown();
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationManager#startConversation(java.lang.Object)
*/
public ExtendedConversation startConversation(Object conversationID) {
if (conversationID == null) {
conversationID = UUID.randomUUID().toString();
}
ExtendedConversation conversation = getConversation(conversationID);
if (conversation != null && conversation.getState() != ConversationState.ENDED) {
throw new IllegalStateException(conversation + " already exists.");
}
conversation = new ExtendedConversationImpl(
this, conversationID, ConversationState.STARTED);
conversations.put(conversationID, conversation);
for (ConversationListener listener : listeners) {
listener.conversationStarted(conversation);
}
return conversation;
}
/**
* return the default max idle time
* @param impProvider the implementation Provider to extract any ConversationAttribute details
*/
public long getMaxIdleTime() {
return maxIdleTime;
}
/**
* returns the default max age
* @param impProvider the implementation Provider to extract any ConversationAttribute details
*/
public long getMaxAge(){
return maxAge;
}
}

View file

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
/**
* The states of a conversation
*
* @version $Rev$ $Date$
*/
public enum ConversationState {
STARTED, ENDED, EXPIRED
}

View file

@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.osoa.sca.Conversation;
/**
* An extended interface over org.osoa.Conversation
*
* @version $Rev$ $Date$
*/
public interface ExtendedConversation extends Conversation {
/**
* Get the state of a conversation
* @return The state
*/
ConversationState getState();
/**
* @param state the state to set
*/
void setState(ConversationState state);
/**
* @param conversationID the conversationID to set
*/
void setConversationID(Object conversationID);
/**
* will check whether this conversation has expired and update state if it has
* @return true if it has expired
*/
boolean isExpired();
/**
* updates the last time this conversation was referenced
*/
void updateLastReferencedTime();
void initializeConversationAttributes(RuntimeComponent targetComponent);
/**
* @return true if the conversational attributes have been initialized
*/
boolean conversationalAttributesInitialized();
}

View file

@ -0,0 +1,265 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.conversation;
import org.apache.tuscany.sca.core.scope.ScopedImplementationProvider;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
*
* @version $Rev$ $Date$
*/
public class ExtendedConversationImpl implements ExtendedConversation, Runnable {
private final ConversationManagerImpl manager;
private volatile Object conversationID;
private ConversationState state;
/**
* syncs access to the state
*/
private final Object stateSync = new Object();
/**
* the maximum time a conversation can exist
*/
private long expirationTime = 0;
/**
* the maximum time this conversation can be idle
*/
private long maxIdleTime = 0;
/**
* the maximum age of this conversation
*/
private long maxAge = 0;
/**
* the time that this object was created
*/
private long creationTime;
/**
* the time that this object was last referenced
*/
private long lastReferencedTime;
/**
* boolean to ensure expiry only occurs once
*/
private boolean expired = false;
/**
* boolean to indicate if the conversation attributes have
* been set. In the case where a remote binding is used
* within a composite the JDKInvocationHandler can create the
* conversation but the conversationAttributes are not available
* until the conversation is retrieved by the RuntimeWireInvoker
*/
private boolean conversationAttributesInitialized = false;
/**
* Constructor
* @param manager the conversation manager
* @param conversationID the conversation id associated with this conversation
* @param state the initial state of this conversation
* @param aMaxAge the maximum age of the conversation
* @param aMaxIdleTime the maximum idle time
*/
public ExtendedConversationImpl(ConversationManagerImpl manager,
Object conversationID, ConversationState state) {
super();
this.creationTime = System.currentTimeMillis();
this.lastReferencedTime = creationTime;
this.manager = manager;
this.conversationID = conversationID;
this.state = state;
}
/**
* will check whether this conversation has expired and update state if it has
* @return true if it has expired
*/
public boolean isExpired() {
long currentTime;
synchronized (stateSync) {
// if the attributes haven't been initialized then
// this conversation object can't expire
if (conversationAttributesInitialized == false) {
return false;
}
// check state first
if (state == ConversationState.EXPIRED) {
return true;
}
// check whether the time is finished
currentTime = System.currentTimeMillis();
if (((this.lastReferencedTime + this.maxIdleTime) <= currentTime)
|| (this.expirationTime <= currentTime)) {
setState(ConversationState.EXPIRED);
return true;
}
}
scheduleNextExpiryTime(currentTime);
return false;
}
/**
* schedule next expiry time
*/
public void scheduleNextExpiryTime(long currentTime) {
if ((lastReferencedTime + maxIdleTime) < expirationTime){
manager.scheduleConversation(this, (lastReferencedTime + maxIdleTime) - currentTime);
} else {
manager.scheduleConversation(this, expirationTime - currentTime);
}
}
/**
* updates the last time this conversation was referenced
*/
public void updateLastReferencedTime() {
this.lastReferencedTime = System.currentTimeMillis();
if (conversationAttributesInitialized == true){
scheduleNextExpiryTime(lastReferencedTime);
}
}
public ConversationState getState() {
synchronized (stateSync){
return state;
}
}
public void end() {
manager.endConversation(conversationID);
}
public Object getConversationID() {
return conversationID;
}
/**
* @param state the state to set
*/
public void setState(ConversationState state) {
synchronized (stateSync){
this.state = state;
}
}
/**
* @param conversationID the conversationID to set
*/
public void setConversationID(Object conversationID) {
synchronized (stateSync){
if (state != ConversationState.ENDED) {
throw new IllegalStateException("The state of conversation " + conversationID + " " + state);
}
}
this.conversationID = conversationID;
}
/**
* @param maxAge the maximum age of this conversation
*/
public void initializeConversationAttributes(RuntimeComponent targetComponent){
if (targetComponent != null){
this.maxAge = getMaxIdleTime(targetComponent.getImplementationProvider());
this.maxIdleTime = getMaxAge(targetComponent.getImplementationProvider());
this.expirationTime = creationTime + maxAge;
this.conversationAttributesInitialized = true;
}
}
/**
* @return true if the conversational attributes have been initialized
*/
public boolean conversationalAttributesInitialized(){
return this.conversationAttributesInitialized;
}
/**
* return the max idle time
* @param impProvider the implementation Provider to extract any ConversationAttribute details
*/
private long getMaxIdleTime(ImplementationProvider impProvider) {
// Check to see if the maxIdleTime has been specified using @ConversationAttributes.
// Implementation annotated attributes are honoured first.
if ((impProvider != null) &&
(impProvider instanceof ScopedImplementationProvider)) {
ScopedImplementationProvider aScopedImpl =
(ScopedImplementationProvider) impProvider;
long maxIdleTime = aScopedImpl.getMaxIdleTime();
if (maxIdleTime > 0) {
return maxIdleTime;
}
}
return manager.getMaxIdleTime();
}
/**
* returns the max age
* @param impProvider the implementation Provider to extract any ConversationAttribute details
*/
private long getMaxAge(ImplementationProvider impProvider){
// Check to see if the maxAge has been specified using @ConversationAttributes.
// Implementation annotated attributes are honoured first.
if ((impProvider != null) &&
(impProvider instanceof ScopedImplementationProvider)) {
ScopedImplementationProvider aScopedImpl =
(ScopedImplementationProvider) impProvider;
long maxAge = aScopedImpl.getMaxAge();
if (maxAge > 0) {
return maxAge;
}
}
return manager.getMaxAge();
}
/**
* called when expiring
*/
public void run() {
synchronized (stateSync){
if (!expired){
if (isExpired()) {
expired = true;
try {
manager.expireConversation(getConversationID());
} catch (IllegalStateException ise) {
// ignore this.. this can occur if another thread has subsequently ended
// the conversation
}
}
}
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.tuscany.sca.event.Event;
import org.apache.tuscany.sca.event.EventFilter;
import org.apache.tuscany.sca.event.EventPublisher;
import org.apache.tuscany.sca.event.RuntimeEventListener;
import org.apache.tuscany.sca.event.TrueFilter;
/**
* Base implementation of an <code>EventPublisher</code>
*
* @version $Rev$ $Date$
*/
public abstract class BaseEventPublisher implements EventPublisher {
protected static final EventFilter TRUE_FILTER = new TrueFilter();
protected Map<EventFilter, List<RuntimeEventListener>> listeners;
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;
}
}

View file

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import java.net.URI;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a component starts
*
* @version $Rev$ $Date$
*/
public class ComponentStart implements Event {
private Object source;
private URI uri;
/**
* Creates a component start event
*
* @param source the source of the event
* @param componentURI the URI of the component being started
*/
public ComponentStart(Object source, URI componentURI) {
this.source = source;
this.uri = componentURI;
}
public URI getComponentURI() {
return uri;
}
public Object getSource() {
return source;
}
}

View file

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import java.net.URI;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a component stops
*
* @version $Rev$ $Date$
*/
public class ComponentStop implements Event {
private Object source;
private URI uri;
/**
* Creates a component stop event
*
* @param source the source of the event
* @param componentUri the composite component associated the component being stopped
*/
public ComponentStop(Object source, URI componentUri) {
this.source = source;
this.uri = componentUri;
}
public URI getComponentURI() {
return uri;
}
public Object getSource() {
return source;
}
}

View file

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a conversation is expired
*
* @version $Rev$ $Date$
*/
public class ConversationEnd implements Event {
private Object source;
private Object id;
/**
* Creates a new event
*
* @param source the source of the event
* @param id the id of the conversation being ended
*/
public ConversationEnd(Object source, Object id) {
this.source = source;
this.id = id;
}
public Object getSource() {
return source;
}
public Object getConversationID() {
return id;
}
}

View file

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a conversation has started
*
* @version $Rev$ $Date$
*/
public class ConversationStart implements Event {
private Object source;
private Object id;
/**
* Creates a new event
*
* @param source the source of the event
* @param id the id of the conversation being started
*/
public ConversationStart(Object source, Object id) {
this.source = source;
this.id = id;
}
public Object getSource() {
return source;
}
public Object getConversationID() {
return id;
}
}

View file

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when an HTTP-based session is expired
*
* @version $Rev$ $Date$
*/
public class HttpSessionEnd implements Event {
private Object source;
private Object id;
/**
* Creates a new event
*
* @param source the source of the event
* @param id the id of the HTTP session being ended
*/
public HttpSessionEnd(Object source, Object id) {
this.source = source;
this.id = id;
}
public Object getSource() {
return source;
}
public Object getSessionID() {
return id;
}
}

View file

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when an HTTP-based session has started
*
* @version $Rev$ $Date$
*/
public class HttpSessionStart implements Event {
private Object source;
private Object id;
/**
* Creates a new event
*
* @param source the source of the event
* @param id the id of the HTTP session being started
*/
public HttpSessionStart(Object source, Object id) {
this.source = source;
this.id = id;
}
public Object getSource() {
return source;
}
public Object getSessionID() {
return id;
}
}

View file

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a request completes or is ended
*
* @version $Rev$ $Date$
*/
public class RequestEnd implements Event {
private Object source;
/**
* Creates a new event
*
* @param source the source of the event
*/
public RequestEnd(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}

View file

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import org.apache.tuscany.sca.event.Event;
/**
* Propagated when a request is started in the runtime
*
* @version $Rev$ $Date$
*/
public class RequestStart implements Event {
private Object source;
/**
* Creates a new event
*
* @param source the source of the event
*/
public RequestStart(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}

View file

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.factory;
/**
* Denotes an error creating a new object instance
*
* @version $Rev$ $Date$
*/
public class ObjectCreationException extends RuntimeException {
private static final long serialVersionUID = -6423113430265944499L;
public ObjectCreationException() {
super();
}
public ObjectCreationException(String message, Throwable cause) {
super(message, cause);
}
public ObjectCreationException(String message) {
super(message);
}
public ObjectCreationException(Throwable cause) {
super(cause);
}
}

View file

@ -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.sca.core.factory;
/**
* 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;
}

View file

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
import org.apache.tuscany.sca.core.factory.ObjectFactory;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.osoa.sca.CallableReference;
/**
* Uses a wire to return a CallableReference
*
* @version $Rev$ $Date$
*/
public class CallableReferenceObjectFactory implements ObjectFactory<CallableReference<?>> {
private Class<?> businessInterface;
private RuntimeComponent component;
private RuntimeComponentReference reference;
private Binding binding;
/**
* Constructor.
*
* To support the @Reference protected CallableReference<MyService> ref;
*
* @param businessInterface the interface to inject
* @param component the component defining the reference to be injected
* @param reference the reference to be injected
* @param binding the binding for the reference
*/
public CallableReferenceObjectFactory(Class<?> businessInterface,
RuntimeComponent component,
RuntimeComponentReference reference,
Binding binding) {
this.businessInterface = businessInterface;
this.component = component;
this.reference = reference;
this.binding = binding;
}
public CallableReference<?> getInstance() throws ObjectCreationException {
return component.getComponentContext().getServiceReference(businessInterface, reference, binding);
}
}

View file

@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.osoa.sca.NoRegisteredCallbackException;
/**
* An interceptor applied to the forward direction of a wire that ensures the callback target implements the required
* service contract. This is required as callback targets may be set dynamically by service implementations.
*
* @version $Rev$ $Date$
*/
public class CallbackInterfaceInterceptor implements Interceptor {
private Invoker next;
public CallbackInterfaceInterceptor() {
}
public Message invoke(Message msg) {
ReferenceParameters parameters = msg.getFrom().getReferenceParameters();
if (parameters.getCallbackObjectID() != null || parameters.getCallbackReference() != msg.getFrom()
.getCallbackEndpoint()) {
return next.invoke(msg);
} else {
throw new NoRegisteredCallbackException("Callback target does not implement the callback interface");
}
}
public void setNext(Invoker next) {
this.next = next;
}
public Invoker getNext() {
return next;
}
}

View file

@ -0,0 +1,271 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Contract;
import org.apache.tuscany.sca.assembly.OptimizableBinding;
import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
import org.apache.tuscany.sca.core.assembly.RuntimeComponentReferenceImpl;
import org.apache.tuscany.sca.core.assembly.RuntimeWireImpl;
import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
import org.apache.tuscany.sca.core.context.ComponentContextHelper;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.apache.tuscany.sca.runtime.RuntimeWire;
/**
* Returns proxy instance for a wire callback
*
* @version $Rev: 576055 $ $Date: 2007-09-16 08:11:45 +0100 (Sun, 16 Sep 2007) $
*/
public class CallbackReferenceImpl<B> extends CallableReferenceImpl<B> {
private RuntimeWire wire;
private List<RuntimeWire> wires;
private EndpointReference resolvedEndpoint;
private Object convID;
public static CallbackReferenceImpl newInstance(Class interfaze,
ProxyFactory proxyFactory,
List<RuntimeWire> wires) {
if (getCallbackEndpoint(ThreadMessageContext.getMessageContext()) != null) {
return new CallbackReferenceImpl(interfaze, proxyFactory, wires);
} else {
return null;
}
}
/**
* Public constructor for Externalizable serialization/deserialization.
*/
public CallbackReferenceImpl() {
super();
}
private CallbackReferenceImpl(Class<B> interfaze, ProxyFactory proxyFactory, List<RuntimeWire> wires) {
super(interfaze, null, proxyFactory);
this.wires = wires;
init();
}
public void init() {
Message msgContext = ThreadMessageContext.getMessageContext();
wire = selectCallbackWire(msgContext);
if (wire == null) {
//FIXME: need better exception
throw new RuntimeException("No callback binding found for " + msgContext.getTo().getURI());
}
resolvedEndpoint = getCallbackEndpoint(msgContext);
convID = msgContext.getFrom().getReferenceParameters().getConversationID();
callbackID = msgContext.getFrom().getReferenceParameters().getCallbackID();
}
@Override
protected Object createProxy() throws Exception {
return proxyFactory.createCallbackProxy(this);
}
protected RuntimeWire getCallbackWire() {
if (resolvedEndpoint == null) {
return null;
} else {
return cloneAndBind(wire);
}
}
protected Object getConvID() {
return convID;
}
protected EndpointReference getResolvedEndpoint() {
return resolvedEndpoint;
}
private RuntimeWire selectCallbackWire(Message msgContext) {
// look for callback binding with same name as service binding
EndpointReference to = msgContext.getTo();
if (to == null) {
//FIXME: need better exception
throw new RuntimeException("Destination for forward call is not available");
}
for (RuntimeWire wire : wires) {
if (wire.getSource().getBinding().getName().equals(to.getBinding().getName())) {
return wire;
}
}
// if no match, look for callback binding with same type as service binding
for (RuntimeWire wire : wires) {
if (wire.getSource().getBinding().getClass() == to.getBinding().getClass()) {
return wire;
}
}
// no suitable callback wire was found
return null;
}
/**
* @param msgContext
*/
private static EndpointReference getCallbackEndpoint(Message msgContext) {
EndpointReference from = msgContext.getFrom();
if (from == null) {
return null;
}
return from.getReferenceParameters().getCallbackReference();
}
private RuntimeWire cloneAndBind(RuntimeWire wire) {
RuntimeWire boundWire = null;
if (resolvedEndpoint != null) {
boundWire = ((RuntimeWireImpl)wire).lookupCache(resolvedEndpoint);
if (boundWire != null) {
return boundWire;
}
try {
Contract contract = resolvedEndpoint.getContract();
RuntimeComponentReference ref = null;
if (contract == null) {
boundWire = (RuntimeWire)wire.clone();
} else if (contract instanceof RuntimeComponentReference) {
ref = (RuntimeComponentReference)contract;
boundWire = ref.getRuntimeWire(resolvedEndpoint.getBinding());
} else { // contract instanceof RuntimeComponentService
ref = bind((RuntimeComponentReference)wire.getSource().getContract(),
resolvedEndpoint.getComponent(),
(RuntimeComponentService)contract);
boundWire = ref.getRuntimeWires().get(0);
}
configureWire(boundWire);
((RuntimeWireImpl)wire).addToCache(resolvedEndpoint, boundWire);
} catch (CloneNotSupportedException e) {
// will not happen
}
}
return boundWire;
}
private static RuntimeComponentReference bind(RuntimeComponentReference reference,
RuntimeComponent component,
RuntimeComponentService service) throws CloneNotSupportedException {
RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
ref.getTargets().add(service);
ref.getBindings().clear();
for (Binding binding : service.getBindings()) {
if (binding instanceof OptimizableBinding) {
OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
optimizableBinding.setTargetBinding(binding);
optimizableBinding.setTargetComponent(component);
optimizableBinding.setTargetComponentService(service);
ref.getBindings().add(optimizableBinding);
} else {
ref.getBindings().add(binding);
}
}
return ref;
}
private void configureWire(RuntimeWire wire) {
// need to set the endpoint on the binding also so that when the chains are created next
// the sca binding can decide whether to provide local or remote invokers.
// TODO - there is a problem here though in that I'm setting a target on a
// binding that may possibly be trying to point at two things in the multi threaded
// case. Need to confirm the general model here and how the clone and bind part
// is intended to work
Binding binding = wire.getSource().getBinding();
binding.setURI(resolvedEndpoint.getURI());
// also need to set the target contract as it varies for the sca binding depending on
// whether it is local or remote
RuntimeComponentReference ref = (RuntimeComponentReference)wire.getSource().getContract();
wire.getTarget().setInterfaceContract(ref.getBindingProvider(binding).getBindingInterfaceContract());
}
/**
* {@inheritDoc}
*/
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
this.callbackID = in.readObject();
this.convID = in.readObject();
this.compositeActivator = ComponentContextHelper.getCurrentCompositeActivator();
// Get the target Component and Service from the URI
final String uri = in.readUTF();
final String[] splitURI = super.splitComponentURI(uri);
final String componentURI = splitURI[0];
final String serviceName = splitURI[1];
final Component targetComponent = super.resolveComponentURI(componentURI);
final ComponentService targetService = super.resolveService(serviceName, targetComponent);
final InterfaceContract targetServiceIfaceContract = targetService.getInterfaceContract();
// Re-create the resolved Endpoint
this.resolvedEndpoint = new EndpointReferenceImpl(
(RuntimeComponent) targetComponent, targetService, null,
targetServiceIfaceContract);
// Copy the Java Interface from the Service
final JavaInterface ji = (JavaInterface) targetServiceIfaceContract.getInterface();
this.businessInterface = (Class<B>) ji.getJavaClass();
// We need to re-create the callback wire. We need to do this on a clone of the Service
// wire since we need to change some details on it.
// FIXME: Is this the best way to do this?
final RuntimeWire cbWire = ((RuntimeComponentService) targetService).getRuntimeWires().get(0);
try {
this.wire = (RuntimeWireImpl) cbWire.clone();
} catch (CloneNotSupportedException e) {
throw new IOException(e.toString());
}
// Setup the reference on the cloned wire
final RuntimeComponentReference ref = new RuntimeComponentReferenceImpl();
ref.setComponent((RuntimeComponent) targetComponent);
ref.setInterfaceContract(targetServiceIfaceContract);
((EndpointReferenceImpl) this.wire.getSource()).setContract(ref);
}
/**
* {@inheritDoc}
*/
@Override
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(this.callbackID);
out.writeObject(this.convID);
out.writeUTF(this.resolvedEndpoint.getURI());
}
}

View file

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.List;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
import org.apache.tuscany.sca.core.factory.ObjectFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
/**
* Uses a wire to return a CallableReference
*
* @version $Rev: 574648 $ $Date: 2007-09-11 18:45:36 +0100 (Tue, 11 Sep 2007) $
*/
public class CallbackReferenceObjectFactory implements ObjectFactory<CallableReference<?>> {
private Class<?> businessInterface;
private ProxyFactory proxyFactory;
private List<RuntimeWire> wires;
public CallbackReferenceObjectFactory(Class<?> interfaze, ProxyFactory proxyFactory, List<RuntimeWire> wires) {
this.businessInterface = interfaze;
this.proxyFactory = proxyFactory;
this.wires = wires;
}
public CallableReference<?> getInstance() throws ObjectCreationException {
return CallbackReferenceImpl.newInstance(businessInterface, proxyFactory, wires);
}
}

View file

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.List;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
import org.apache.tuscany.sca.core.factory.ObjectFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
/**
* Returns proxy instance for a wire callback
*
* @version $Rev$ $Date$
*/
public class CallbackWireObjectFactory<B> implements ObjectFactory<B> {
private Class<B> businessInterface;
private ProxyFactory proxyFactory;
private List<RuntimeWire> wires;
public CallbackWireObjectFactory(Class<B> interfaze, ProxyFactory proxyFactory, List<RuntimeWire> wires) {
this.businessInterface = interfaze;
this.proxyFactory = proxyFactory;
this.wires = wires;
}
public B getInstance() throws ObjectCreationException {
return proxyFactory.createCallbackProxy(businessInterface, wires);
}
}

View file

@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.lang.reflect.Method;
import java.util.List;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.ServiceReference;
/**
* The implementation of a wire service that uses cglib dynamic proxies
*
* @version $Rev$ $Date$
*/
@SuppressWarnings("unused")
public class CglibProxyFactory implements ProxyFactory {
private MessageFactory messageFactory;
public CglibProxyFactory(MessageFactory messageFactory, InterfaceContractMapper mapper) {
this.messageFactory = messageFactory;
}
public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
ServiceReference<T> serviceReference = new ServiceReferenceImpl(interfaze, wire, this);
return createProxy(serviceReference);
}
/**
* create the proxy with cglib. use the same JDKInvocationHandler as
* JDKProxyService.
*/
public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
Enhancer enhancer = new Enhancer();
Class<T> interfaze = callableReference.getBusinessInterface();
enhancer.setSuperclass(interfaze);
enhancer.setCallback(new CglibMethodInterceptor<T>(callableReference));
Object proxy = enhancer.create();
((CallableReferenceImpl)callableReference).setProxy(proxy);
return interfaze.cast(proxy);
}
/**
* create the callback proxy with cglib. use the same
* JDKCallbackInvocationHandler as JDKProxyService.
*/
public <T> T createCallbackProxy(Class<T> interfaze, final List<RuntimeWire> wires) throws ProxyCreationException {
CallbackReferenceImpl<T> callbackReference = CallbackReferenceImpl.newInstance(interfaze, this, wires);
return callbackReference != null ? createCallbackProxy(callbackReference) : null;
}
/**
* create the callback proxy with cglib. use the same
* JDKCallbackInvocationHandler as JDKProxyService.
*/
public <T> T createCallbackProxy(CallbackReferenceImpl<T> callbackReference) throws ProxyCreationException {
Enhancer enhancer = new Enhancer();
Class<T> interfaze = callbackReference.getBusinessInterface();
enhancer.setSuperclass(interfaze);
enhancer.setCallback(new CglibMethodInterceptor<T>(callbackReference));
Object proxy = enhancer.create();
callbackReference.setProxy(proxy);
return interfaze.cast(proxy);
}
@SuppressWarnings("unchecked")
public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
if (isProxyClass(target.getClass())) {
Factory factory = (Factory)target;
Callback[] callbacks = factory.getCallbacks();
if (callbacks.length != 1 || !(callbacks[0] instanceof CglibMethodInterceptor)) {
throw new IllegalArgumentException("The object is not a known proxy.");
}
CglibMethodInterceptor interceptor = (CglibMethodInterceptor)callbacks[0];
return (R)interceptor.invocationHandler.getCallableReference();
} else {
throw new IllegalArgumentException("The object is not a known proxy.");
}
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
*/
public boolean isProxyClass(Class<?> clazz) {
return Factory.class.isAssignableFrom(clazz);
}
private class CglibMethodInterceptor<T> implements MethodInterceptor {
private JDKInvocationHandler invocationHandler;
public CglibMethodInterceptor(CallableReference<T> callableReference) {
invocationHandler = new JDKInvocationHandler(messageFactory, callableReference);
}
public CglibMethodInterceptor(CallbackReferenceImpl<T> callbackReference) {
invocationHandler = new JDKCallbackInvocationHandler(messageFactory, callbackReference);
}
/*
public CglibMethodInterceptor(Class<T> interfaze, RuntimeWire wire) {
ServiceReference<T> serviceRef = new ServiceReferenceImpl<T>(interfaze, wire, CglibProxyFactory.this);
invocationHandler = new JDKInvocationHandler(messageFactory, serviceRef);
}
public CglibMethodInterceptor(Class<T> interfaze, List<RuntimeWire> wires) {
CallbackReferenceImpl ref = new CallbackReferenceImpl(interfaze, CglibProxyFactory.this, wires);
invocationHandler = new JDKCallbackInvocationHandler(messageFactory, ref);
}
*/
/**
* @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
*/
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object result = invocationHandler.invoke(proxy, method, args);
return result;
}
}
}

View file

@ -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.sca.core.invocation;
import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.invocation.MessageFactory;
/**
* Default implementation of a ProxyFactoryExtensionPoint.
*
* @version $Rev$ $Date$
*/
public class DefaultProxyFactoryExtensionPoint implements ProxyFactoryExtensionPoint {
private InterfaceContractMapper interfaceContractMapper;
private MessageFactory messageFactory;
private ProxyFactory interfaceFactory;
private ProxyFactory classFactory;
public DefaultProxyFactoryExtensionPoint(ExtensionPointRegistry extensionPoints) {
UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
this.messageFactory = modelFactories.getFactory(MessageFactory.class);
interfaceFactory = new JDKProxyFactory(messageFactory, interfaceContractMapper);
}
public DefaultProxyFactoryExtensionPoint(MessageFactory messageFactory, InterfaceContractMapper mapper) {
this.interfaceContractMapper = mapper;
this.messageFactory = messageFactory;
interfaceFactory = new JDKProxyFactory(messageFactory, mapper);
}
public ProxyFactory getClassProxyFactory() {
return classFactory;
}
public ProxyFactory getInterfaceProxyFactory() {
return interfaceFactory;
}
public void setClassProxyFactory(ProxyFactory factory) {
this.classFactory = factory;
}
public void setInterfaceProxyFactory(ProxyFactory factory) {
this.interfaceFactory = factory;
}
}

View file

@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.List;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
/**
* An extensible proxy factory.
*
* @version $Rev: $ $Date: $
*/
public class ExtensibleProxyFactory implements ProxyFactory {
private ProxyFactoryExtensionPoint proxyFactories;
public ExtensibleProxyFactory(ProxyFactoryExtensionPoint proxyFactories) {
this.proxyFactories = proxyFactories;
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#cast(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
if (interfaceFactory.isProxyClass(target.getClass())) {
return (R)interfaceFactory.cast(target);
} else if (classFactory != null && classFactory.isProxyClass(target.getClass())) {
return (R)classFactory.cast(target);
} else {
throw new IllegalArgumentException("The target is not a callable proxy");
}
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#createCallbackProxy(java.lang.Class,
* java.util.List)
*/
public <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
if (interfaze.isInterface()) {
return interfaceFactory.createCallbackProxy(interfaze, wires);
} else {
return classFactory.createCallbackProxy(interfaze, wires);
}
}
public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
if (callableReference.getBusinessInterface().isInterface()) {
return interfaceFactory.createProxy(callableReference);
} else {
return classFactory.createProxy(callableReference);
}
}
public <T> T createCallbackProxy(CallbackReferenceImpl<T> callbackReference) throws ProxyCreationException {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
if (callbackReference.getBusinessInterface().isInterface()) {
return interfaceFactory.createCallbackProxy(callbackReference);
} else {
return classFactory.createCallbackProxy(callbackReference);
}
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#createProxy(java.lang.Class,
* org.apache.tuscany.sca.runtime.RuntimeWire)
*/
public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
if (interfaze.isInterface()) {
return interfaceFactory.createProxy(interfaze, wire);
} else {
return classFactory.createProxy(interfaze, wire);
}
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
*/
public boolean isProxyClass(Class<?> clazz) {
ProxyFactory interfaceFactory = proxyFactories.getInterfaceProxyFactory();
ProxyFactory classFactory = proxyFactories.getClassProxyFactory();
return interfaceFactory.isProxyClass(clazz) || (classFactory != null && classFactory.isProxyClass(clazz));
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
/**
* The default implementation of an extensible <code>WireProcessor</code>
*
* @version $Rev$ $Date$
*/
public class ExtensibleWireProcessor implements RuntimeWireProcessor {
private RuntimeWireProcessorExtensionPoint processors;
public ExtensibleWireProcessor(RuntimeWireProcessorExtensionPoint processors) {
this.processors = processors;
}
public void process(RuntimeWire wire) {
for (RuntimeWireProcessor processor : processors.getWireProcessors()) {
processor.process(wire);
}
}
}

View file

@ -0,0 +1,189 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Phase;
/**
* Default implementation of an invocation chain
*
* @version $Rev$ $Date$
*/
public class InvocationChainImpl implements InvocationChain {
private Operation sourceOperation;
private Operation targetOperation;
private List<Node> nodes = new ArrayList<Node>();
// FIXME: Not a good practice to use static reference
private static final PhaseManager phaseManager = new PhaseManager();
private boolean forReference;
private boolean allowsPassByReference;
public InvocationChainImpl(Operation sourceOperation, Operation targetOperation, boolean forReference) {
assert sourceOperation != null;
assert targetOperation != null;
this.targetOperation = targetOperation;
this.sourceOperation = sourceOperation;
this.forReference = forReference;
}
public Operation getTargetOperation() {
return targetOperation;
}
public void setTargetOperation(Operation operation) {
this.targetOperation = operation;
}
public void addInterceptor(Interceptor interceptor) {
String phase = forReference ? Phase.REFERENCE : Phase.SERVICE;
addInterceptor(phase, interceptor);
}
public void addInvoker(Invoker invoker) {
String phase = forReference ? Phase.REFERENCE_BINDING : Phase.IMPLEMENTATION;
addInvoker(phase, invoker);
}
public Invoker getHeadInvoker() {
return nodes.isEmpty() ? null : nodes.get(0).getInvoker();
}
public Invoker getTailInvoker() {
return nodes.isEmpty() ? null : nodes.get(nodes.size() - 1).getInvoker();
}
/**
* @return the sourceOperation
*/
public Operation getSourceOperation() {
return sourceOperation;
}
/**
* @param sourceOperation the sourceOperation to set
*/
public void setSourceOperation(Operation sourceOperation) {
this.sourceOperation = sourceOperation;
}
public void addInterceptor(int index, Interceptor interceptor) {
addInterceptor(interceptor);
}
public void addInterceptor(String phase, Interceptor interceptor) {
addInvoker(phase, interceptor);
}
private void addInvoker(String phase, Invoker invoker) {
int index = phaseManager.getAllPhases().indexOf(phase);
if (index == -1) {
throw new IllegalArgumentException("Invalid phase name: " + phase);
}
Node node = new Node(index, invoker);
ListIterator<Node> li = nodes.listIterator();
Node before = null, after = null;
boolean found = false;
while (li.hasNext()) {
before = after;
after = li.next();
if (after.getPhaseIndex() > index) {
// Move back
li.previous();
li.add(node);
found = true;
break;
}
}
if (!found) {
// Add to the end
nodes.add(node);
before = after;
after = null;
}
// Relink the interceptors
if (before != null) {
if (before.getInvoker() instanceof Interceptor) {
((Interceptor)before.getInvoker()).setNext(invoker);
}
}
if (after != null) {
if (invoker instanceof Interceptor) {
((Interceptor)invoker).setNext(after.getInvoker());
}
}
}
public boolean allowsPassByReference() {
if (allowsPassByReference) {
// No need to check the invokers
return true;
}
// Check if any of the invokers allows pass-by-reference
boolean allowsPBR = false;
for (Node i : nodes) {
if (i.getInvoker() instanceof DataExchangeSemantics) {
if (((DataExchangeSemantics)i.getInvoker()).allowsPassByReference()) {
allowsPBR = true;
break;
}
}
}
return allowsPBR;
}
public void setAllowsPassByReference(boolean allowsPBR) {
this.allowsPassByReference = allowsPBR;
}
private static class Node {
private int phaseIndex;
private Invoker invoker;
public Node(int phaseIndex, Invoker invoker) {
super();
this.phaseIndex = phaseIndex;
this.invoker = invoker;
}
public int getPhaseIndex() {
return phaseIndex;
}
public Invoker getInvoker() {
return invoker;
}
public String toString() {
return "(" + phaseIndex + ")" + invoker;
}
}
}

View file

@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.tuscany.sca.core.assembly.RuntimeWireImpl;
import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
import org.apache.tuscany.sca.core.conversation.ConversationState;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.NoRegisteredCallbackException;
import org.osoa.sca.ServiceRuntimeException;
/**
* Responsible for dispatching to a callback through a wire. <p/> TODO cache
* target invoker
*
* @version $Rev$ $Date$
*/
public class JDKCallbackInvocationHandler extends JDKInvocationHandler {
private static final long serialVersionUID = -3350283555825935609L;
public JDKCallbackInvocationHandler(MessageFactory messageFactory, CallbackReferenceImpl ref) {
super(messageFactory, ref);
this.fixedWire = false;
}
@Override
@SuppressWarnings( {"unchecked"})
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class == method.getDeclaringClass()) {
return invokeObjectMethod(method, args);
}
// obtain a dedicated wire to be used for this callback invocation
RuntimeWire wire = ((CallbackReferenceImpl)callableReference).getCallbackWire();
if (wire == null) {
//FIXME: need better exception
throw new ServiceRuntimeException("No callback wire found");
}
// set the conversational state based on the interface that
// is specified for the reference that this wire belongs to
initConversational(wire);
// set the conversation id into the conversation object. This is
// a special case for callbacks as, unless otherwise set manually,
// the callback should use the same conversation id as was received
// on the incoming call to this component
if (conversational) {
if (conversation == null || conversation.getState() == ConversationState.ENDED) {
conversation = null;
}
Object convID = conversation == null ? null : conversation.getConversationID();
// create a conversation id if one doesn't exist
// already, i.e. the conversation is just starting
if (convID == null) {
convID = ((CallbackReferenceImpl)callableReference).getConvID();
if (convID != null) {
conversation = ((RuntimeWireImpl)wire).getConversationManager().getConversation(convID);
if (callableReference != null) {
((CallableReferenceImpl)callableReference).attachConversation(conversation);
}
}
}
}
setEndpoint(((CallbackReferenceImpl)callableReference).getResolvedEndpoint());
InvocationChain chain = getInvocationChain(method, wire);
if (chain == null) {
throw new IllegalArgumentException("No matching operation is found: " + method);
}
try {
return invoke(chain, args, wire, wire.getSource());
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof NoRegisteredCallbackException) {
throw t;
}
throw e;
} finally {
// allow the cloned wire to be reused by subsequent callbacks
((RuntimeWireImpl)wire).releaseWire();
}
}
}

View file

@ -0,0 +1,516 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.tuscany.sca.core.assembly.RuntimeWireImpl;
import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.conversation.ConversationState;
import org.apache.tuscany.sca.core.conversation.ExtendedConversation;
import org.apache.tuscany.sca.core.scope.Scope;
import org.apache.tuscany.sca.core.scope.ScopeContainer;
import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
import org.apache.tuscany.sca.core.scope.TargetDestructionException;
import org.apache.tuscany.sca.core.scope.TargetResolutionException;
import org.apache.tuscany.sca.interfacedef.ConversationSequence;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.ConversationEndedException;
import org.osoa.sca.ServiceReference;
import org.osoa.sca.ServiceRuntimeException;
/**
* @version $Rev$ $Date$
*/
public class JDKInvocationHandler implements InvocationHandler, Serializable {
private static final long serialVersionUID = -3366410500152201371L;
protected boolean conversational;
protected ExtendedConversation conversation;
protected MessageFactory messageFactory;
protected EndpointReference source;
protected EndpointReference target;
protected RuntimeWire wire;
protected CallableReference<?> callableReference;
protected Class<?> businessInterface;
protected boolean fixedWire = true;
protected transient Map<Method, InvocationChain> chains = new HashMap<Method, InvocationChain>();
public JDKInvocationHandler(MessageFactory messageFactory, Class<?> businessInterface, RuntimeWire wire) {
this.messageFactory = messageFactory;
this.wire = wire;
this.businessInterface = businessInterface;
init(this.wire);
}
public JDKInvocationHandler(MessageFactory messageFactory, CallableReference<?> callableReference) {
this.messageFactory = messageFactory;
this.callableReference = callableReference;
if (callableReference != null) {
this.businessInterface = callableReference.getBusinessInterface();
this.conversation = (ExtendedConversation)callableReference.getConversation();
this.wire = ((CallableReferenceImpl<?>)callableReference).getRuntimeWire();
if (wire != null) {
init(wire);
}
}
}
protected void init(RuntimeWire wire) {
if (wire != null) {
try {
// Clone the endpoint reference so that reference parameters can be changed
source = (EndpointReference)wire.getSource().clone();
} catch (CloneNotSupportedException e) {
throw new ServiceRuntimeException(e);
}
initConversational(wire);
}
}
protected void initConversational(RuntimeWire wire) {
InterfaceContract contract = wire.getSource().getInterfaceContract();
this.conversational = contract.getInterface().isConversational();
}
protected Object getCallbackID() {
if (callableReference != null) {
return callableReference.getCallbackID();
} else {
return null;
}
}
protected Object getConversationID() {
if (callableReference != null && callableReference instanceof ServiceReference) {
return ((ServiceReference)callableReference).getConversationID();
} else {
return null;
}
}
protected Object getCallbackObject() {
if (callableReference != null && callableReference instanceof ServiceReference) {
return ((ServiceReference)callableReference).getCallback();
} else {
return null;
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class == method.getDeclaringClass()) {
return invokeObjectMethod(method, args);
}
if (wire == null) {
throw new ServiceRuntimeException("No runtime wire is available");
}
InvocationChain chain = getInvocationChain(method, wire);
if (chain == null) {
throw new IllegalArgumentException("No matching operation is found: " + method);
}
// send the invocation down the wire
Object result = invoke(chain, args, wire, source);
return result;
}
/**
* Handle the methods on the Object.class
* @param method
* @param args
*/
protected Object invokeObjectMethod(Method method, Object[] args) throws Throwable {
String name = method.getName();
if ("toString".equals(name)) {
return "[Proxy - " + toString() + "]";
} else if ("equals".equals(name)) {
Object obj = args[0];
if (obj == null) {
return false;
}
if (!Proxy.isProxyClass(obj.getClass())) {
return false;
}
return equals(Proxy.getInvocationHandler(obj));
} else if ("hashCode".equals(name)) {
return hashCode();
} else {
return method.invoke(this);
}
}
/**
* Determines if the given operation matches the given method
*
* @return true if the operation matches, false if does not
*/
// FIXME: Should it be in the InterfaceContractMapper?
@SuppressWarnings("unchecked")
private static boolean match(Operation operation, Method method) {
if (operation instanceof JavaOperation) {
JavaOperation javaOp = (JavaOperation)operation;
Method m = javaOp.getJavaMethod();
if (!method.getName().equals(m.getName())) {
return false;
}
if (method.equals(m)) {
return true;
}
} else {
if (!method.getName().equals(operation.getName())) {
return false;
}
}
// For remotable interface, operation is not overloaded.
if (operation.getInterface().isRemotable()) {
return true;
}
Class<?>[] params = method.getParameterTypes();
DataType<List<DataType>> inputType = null;
if (operation.isWrapperStyle()) {
inputType = operation.getWrapper().getUnwrappedInputType();
} else {
inputType = operation.getInputType();
}
List<DataType> types = inputType.getLogical();
boolean matched = true;
if (types.size() == params.length && method.getName().equals(operation.getName())) {
for (int i = 0; i < params.length; i++) {
Class<?> clazz = params[i];
Class<?> type = types.get(i).getPhysical();
// Object.class.isAssignableFrom(int.class) returns false
if (type != Object.class && (!type.isAssignableFrom(clazz))) {
matched = false;
}
}
} else {
matched = false;
}
return matched;
}
protected synchronized InvocationChain getInvocationChain(Method method, RuntimeWire wire) {
if (fixedWire && chains.containsKey(method)) {
return chains.get(method);
}
InvocationChain found = null;
for (InvocationChain chain : wire.getInvocationChains()) {
Operation operation = chain.getSourceOperation();
if (operation.isDynamic()) {
operation.setName(method.getName());
found = chain;
break;
} else if (match(operation, method)) {
found = chain;
break;
}
}
if (fixedWire) {
chains.put(method, found);
}
return found;
}
protected void setEndpoint(EndpointReference endpoint) {
this.target = endpoint;
}
protected Object invoke(InvocationChain chain, Object[] args, RuntimeWire wire, EndpointReference source)
throws Throwable {
Message msg = messageFactory.createMessage();
msg.setFrom(source);
if (target != null) {
msg.setTo(target);
} else {
msg.setTo(wire.getTarget());
}
Invoker headInvoker = chain.getHeadInvoker();
Operation operation = chain.getTargetOperation();
msg.setOperation(operation);
msg.setBody(args);
Message msgContext = ThreadMessageContext.getMessageContext();
Object currentConversationID = msgContext.getFrom().getReferenceParameters().getConversationID();
conversationPreinvoke(msg, wire);
handleCallback(msg, wire, currentConversationID);
ThreadMessageContext.setMessageContext(msg);
boolean abnormalEndConversation = false;
try {
// dispatch the wire down the chain and get the response
Message resp = headInvoker.invoke(msg);
Object body = resp.getBody();
if (resp.isFault()) {
// mark the conversation as ended if the exception is not a business exception
if (currentConversationID != null ){
try {
boolean businessException = false;
for (DataType dataType : operation.getFaultTypes()){
if (dataType.getPhysical() == ((Throwable)body).getClass()){
businessException = true;
break;
}
}
if (businessException == false){
abnormalEndConversation = true;
}
} catch (Exception ex){
// TODO - sure what the best course of action is here. We have
// a system exception in the middle of a business exception
}
}
throw (Throwable)body;
}
return body;
} finally {
conversationPostInvoke(msg, wire, abnormalEndConversation);
ThreadMessageContext.setMessageContext(msgContext);
}
}
/**
* @param msg
* @param wire
* @param interfaze
* @throws TargetResolutionException
*/
private void handleCallback(Message msg, RuntimeWire wire, Object currentConversationID)
throws TargetResolutionException {
ReferenceParameters parameters = msg.getFrom().getReferenceParameters();
parameters.setCallbackID(getCallbackID());
if (msg.getFrom() == null || msg.getFrom().getCallbackEndpoint() == null) {
return;
}
parameters.setCallbackReference(msg.getFrom().getCallbackEndpoint());
// If we are passing out a callback target
// register the calling component instance against this
// new conversation id so that stateful callbacks will be
// able to find it
Object callbackObject = getCallbackObject();
if (conversational && callbackObject == null) {
// the component instance is already registered
// so add another registration
ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
if (scopeContainer != null && currentConversationID != null) {
scopeContainer.addWrapperReference(currentConversationID, conversation.getConversationID());
}
}
Interface interfaze = msg.getFrom().getCallbackEndpoint().getInterfaceContract().getInterface();
if (callbackObject != null) {
if (callbackObject instanceof ServiceReference) {
EndpointReference callbackRef = ((CallableReferenceImpl)callbackObject).getEndpointReference();
parameters.setCallbackReference(callbackRef);
} else {
if (interfaze != null) {
if (!interfaze.isConversational()) {
throw new IllegalArgumentException(
"Callback object for stateless callback is not a ServiceReference");
} else {
if (!(callbackObject instanceof Serializable)) {
throw new IllegalArgumentException(
"Callback object for stateful callback is not Serializable");
}
ScopeContainer scopeContainer = getConversationalScopeContainer(wire);
if (scopeContainer != null) {
InstanceWrapper wrapper = new CallbackObjectWrapper(callbackObject);
scopeContainer.registerWrapper(wrapper, conversation.getConversationID());
}
parameters.setCallbackObjectID(callbackObject);
}
}
}
}
}
/**
* Pre-invoke for the conversation handling
* @param msg
* @throws TargetResolutionException
*/
private void conversationPreinvoke(Message msg, RuntimeWire wire) {
if (!conversational) {
// Not conversational or the conversation has been started
return;
}
ConversationManager conversationManager = ((RuntimeWireImpl)wire).getConversationManager();
if (conversation == null || conversation.getState() == ConversationState.ENDED) {
conversation = conversationManager.startConversation(getConversationID());
// if this is a local wire then set up the conversation timeouts here based on the
// parameters from the component
if (wire.getTarget().getComponent() != null){
conversation.initializeConversationAttributes(wire.getTarget().getComponent());
}
// connect the conversation to the CallableReference so it can be retrieve in the future
if (callableReference != null) {
((CallableReferenceImpl)callableReference).attachConversation(conversation);
}
} else if (conversation.isExpired()) {
throw new ConversationEndedException("Conversation " + conversation.getConversationID() + " has expired.");
}
// if this is a local wire then schedule conversation timeouts based on the timeout
// parameters from the service implementation. If this isn't a local wire then
// the RuntimeWireInvoker will take care of this
if (wire.getTarget().getComponent() != null){
conversation.updateLastReferencedTime();
}
msg.getFrom().getReferenceParameters().setConversationID(conversation.getConversationID());
}
/**
* Post-invoke for the conversation handling
* @param wire
* @param operation
* @throws TargetDestructionException
*/
@SuppressWarnings("unchecked")
private void conversationPostInvoke(Message msg, RuntimeWire wire, boolean abnormalEndConversation)
throws TargetDestructionException {
Operation operation = msg.getOperation();
ConversationSequence sequence = operation.getConversationSequence();
// We check that conversation has not already ended as there is only one
// conversation manager in the runtime and so, in the case of remote bindings,
// the conversation will already have been stopped when we get back to the client
if ((sequence == ConversationSequence.CONVERSATION_END || abnormalEndConversation) &&
(conversation.getState() != ConversationState.ENDED)) {
// remove conversation id from scope container
ScopeContainer scopeContainer = getConversationalScopeContainer(wire);
if (scopeContainer != null) {
scopeContainer.remove(conversation.getConversationID());
}
conversation.end();
}
}
private ScopeContainer<Object> getConversationalScopeContainer(RuntimeWire wire) {
ScopeContainer<Object> scopeContainer = null;
RuntimeComponent runtimeComponent = wire.getSource().getComponent();
if (runtimeComponent instanceof ScopedRuntimeComponent) {
ScopedRuntimeComponent scopedRuntimeComponent = (ScopedRuntimeComponent)runtimeComponent;
ScopeContainer<Object> tmpScopeContainer = scopedRuntimeComponent.getScopeContainer();
if ((tmpScopeContainer != null) && (tmpScopeContainer.getScope() == Scope.CONVERSATION)) {
scopeContainer = tmpScopeContainer;
}
}
return scopeContainer;
}
/**
* Creates a new conversation id
*
* @return the conversation id
*/
private Object createConversationID() {
if (getConversationID() != null) {
return getConversationID();
} else {
return UUID.randomUUID().toString();
}
}
/**
* @return the callableReference
*/
public CallableReference<?> getCallableReference() {
return callableReference;
}
/**
* @param callableReference the callableReference to set
*/
public void setCallableReference(CallableReference<?> callableReference) {
this.callableReference = callableReference;
}
/**
* Minimal wrapper for a callback object contained in a ServiceReference
*/
private static class CallbackObjectWrapper<T> implements InstanceWrapper<T> {
private T instance;
private CallbackObjectWrapper(T instance) {
this.instance = instance;
}
public T getInstance() {
return instance;
}
public void start() {
// do nothing
}
public void stop() {
// do nothing
}
}
}

View file

@ -0,0 +1,103 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List;
import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
import org.osoa.sca.ServiceReference;
/**
* the default implementation of a wire service that uses JDK dynamic proxies
*
* @version $Rev$ $Date$
*/
public class JDKProxyFactory implements ProxyFactory {
protected InterfaceContractMapper contractMapper;
private MessageFactory messageFactory;
public JDKProxyFactory(MessageFactory messageFactory, InterfaceContractMapper mapper) {
this.contractMapper = mapper;
this.messageFactory = messageFactory;
}
/**
* The original createProxy method assumes that the proxy doesn't want to
* share conversation state so sets the conversation object to null
*/
public <T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException {
ServiceReference<T> serviceReference = new ServiceReferenceImpl(interfaze, wire, this);
return createProxy(serviceReference);
}
public <T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException {
assert callableReference != null;
final Class<T> interfaze = callableReference.getBusinessInterface();
InvocationHandler handler = new JDKInvocationHandler(messageFactory, callableReference);
// Allow privileged access to class loader. Requires RuntimePermission in security policy.
ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return interfaze.getClassLoader();
}
});
Object proxy = Proxy.newProxyInstance(cl, new Class[] {interfaze}, handler);
((CallableReferenceImpl)callableReference).setProxy(proxy);
return interfaze.cast(proxy);
}
public <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException {
CallbackReferenceImpl<T> callbackReference = CallbackReferenceImpl.newInstance(interfaze, this, wires);
return callbackReference != null ? createCallbackProxy(callbackReference) : null;
}
public <T> T createCallbackProxy(CallbackReferenceImpl<T> callbackReference) throws ProxyCreationException {
assert callbackReference != null;
Class<T> interfaze = callbackReference.getBusinessInterface();
InvocationHandler handler = new JDKCallbackInvocationHandler(messageFactory, callbackReference);
ClassLoader cl = interfaze.getClassLoader();
Object proxy = Proxy.newProxyInstance(cl, new Class[] {interfaze}, handler);
callbackReference.setProxy(proxy);
return interfaze.cast(proxy);
}
public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
InvocationHandler handler = Proxy.getInvocationHandler(target);
if (handler instanceof JDKInvocationHandler) {
return (R)((JDKInvocationHandler)handler).getCallableReference();
} else {
throw new IllegalArgumentException("The object is not a known proxy.");
}
}
/**
* @see org.apache.tuscany.sca.core.invocation.ProxyFactory#isProxyClass(java.lang.Class)
*/
public boolean isProxyClass(Class<?> clazz) {
return Proxy.isProxyClass(clazz);
}
}

View file

@ -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.sca.core.invocation;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.invocation.MessageFactory;
/**
* Implementation of MessageFactory.
*
* @version $Rev$ $Date$
*/
public class MessageFactoryImpl implements MessageFactory {
public Message createMessage() {
return new MessageImpl();
}
}

View file

@ -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.sca.core.invocation;
import java.util.Hashtable;
import java.util.Map;
import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.EndpointReference;
/**
* 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 Object messageID;
private boolean isFault;
private Operation operation;
private Map<String, Object> qosContext = new Hashtable<String, Object>();
private EndpointReference from;
private EndpointReference to;
public MessageImpl() {
this.from = new EndpointReferenceImpl("/");
this.to = new EndpointReferenceImpl("/");
}
@SuppressWarnings("unchecked")
public <T> T getBody() {
return (T)body;
}
public <T> void setBody(T body) {
this.isFault = false;
this.body = body;
}
public Object getMessageID() {
return messageID;
}
public void setMessageID(Object messageId) {
this.messageID = messageId;
}
public boolean isFault() {
return isFault;
}
public void setFaultBody(Object fault) {
this.isFault = true;
this.body = fault;
}
public EndpointReference getFrom() {
return from;
}
public void setFrom(EndpointReference from) {
this.from = from;
}
public EndpointReference getTo() {
return to;
}
public void setTo(EndpointReference to) {
this.to = to;
}
public Operation getOperation() {
return operation;
}
public void setOperation(Operation op) {
this.operation = op;
}
public Map<String, Object> getQoSContext() {
return qosContext;
}
}

View file

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
/**
* Thrown when an {@link org.apache.tuscany.sca.core.factory.model.Operation} cannot be mapped to a method on an interface
* @version $Rev$ $Date$
*/
public class NoMethodForOperationException extends ProxyCreationException {
private static final long serialVersionUID = 5116536602309483679L;
public NoMethodForOperationException() {
}
public NoMethodForOperationException(String message) {
super(message);
}
public NoMethodForOperationException(String message, Throwable cause) {
super(message, cause);
}
public NoMethodForOperationException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,190 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.apache.tuscany.sca.work.WorkScheduler;
import org.osoa.sca.ServiceRuntimeException;
/**
* Adds non-blocking behavior to an invocation chain
*
* @version $Rev$ $Date$
*/
public class NonBlockingInterceptor implements Interceptor {
private static final Message RESPONSE = new ImmutableMessage();
/**
* The JDK logger that will be used to log messages.
*/
private static final Logger LOGGER = Logger.getLogger(NonBlockingInterceptor.class.getName());
private WorkScheduler workScheduler;
private Invoker next;
public NonBlockingInterceptor(WorkScheduler workScheduler) {
this.workScheduler = workScheduler;
}
public NonBlockingInterceptor(WorkScheduler workScheduler, Interceptor next) {
this.workScheduler = workScheduler;
this.next = next;
}
/**
* Sets desired workScheduler to NonBlockingInterceptor. This is a useful function for the extension framework
* to set desired workmanager on the InvocationChain, other than default workmanager which is set per Tuscany runtime.
* Using this function, extension framework can set desired workmanager on InvocationChain during post wire processing.
* @param workScheduler workScheduler which contains workmanager
*/
public void setWorkScheduler(WorkScheduler workScheduler){
this.workScheduler = workScheduler;
}
public Message invoke(final Message msg) {
// Schedule the invocation of the next interceptor in a new Work instance
try {
workScheduler.scheduleWork(new Runnable() {
public void run() {
Message context = ThreadMessageContext.setMessageContext(msg);
try {
Message response = null;
Throwable ex = null;
try {
response = next.invoke(msg);
} catch (Throwable t) {
ex = t;
}
// Tuscany-2225 - Did the @OneWay method complete successfully?
// (i.e. no exceptions)
if (response != null && response.isFault()) {
// The @OneWay method threw an Exception. Lets log it and
// then pass it on to the WorkScheduler so it can notify any
// listeners
ex = (Throwable)response.getBody();
}
if (ex != null) {
LOGGER.log(Level.SEVERE, "Exception from @OneWay invocation", ex);
throw new ServiceRuntimeException("Exception from @OneWay invocation", ex);
}
} finally {
ThreadMessageContext.setMessageContext(context);
}
}
});
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
return RESPONSE;
}
public Invoker getNext() {
return next;
}
public void setNext(Invoker next) {
this.next = next;
}
/**
* A dummy message passed back on an invocation
*/
private static class ImmutableMessage implements Message {
@SuppressWarnings("unchecked")
public Object getBody() {
return null;
}
public void setBody(Object body) {
if (body != null) {
throw new UnsupportedOperationException();
}
}
public void setCallbackWires(LinkedList<RuntimeWire> wires) {
}
public Object getMessageID() {
return null;
}
public void setMessageID(Object messageId) {
throw new UnsupportedOperationException();
}
public boolean isFault() {
return false;
}
public void setFaultBody(Object fault) {
throw new UnsupportedOperationException();
}
public EndpointReference getFrom() {
return null;
}
public EndpointReference getTo() {
return null;
}
public void setFrom(EndpointReference from) {
throw new UnsupportedOperationException();
}
public void setTo(EndpointReference to) {
throw new UnsupportedOperationException();
}
public Operation getOperation() {
return null;
}
public void setOperation(Operation op) {
throw new UnsupportedOperationException();
}
/**
* @see org.apache.tuscany.sca.invocation.Message#getReplyTo()
*/
public EndpointReference getReplyTo() {
return null;
}
public Map<String, Object> getQoSContext() {
return null;
}
}
}

View file

@ -0,0 +1,247 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
import org.apache.tuscany.sca.invocation.Phase;
import org.osoa.sca.ServiceRuntimeException;
/**
* @version $Rev$ $Date$
*/
public class PhaseManager {
private static final Logger log = Logger.getLogger(PhaseManager.class.getName());
public static final String STAGE_REFERENCE = "reference";
public static final String STAGE_SERVICE = "service";
public static final String STAGE_IMPLEMENTATION = "implementation";
private static final String[] SYSTEM_REFERENCE_PHASES =
{Phase.REFERENCE, Phase.REFERENCE_INTERFACE, Phase.REFERENCE_POLICY, Phase.REFERENCE_BINDING};
private static final String[] SYSTEM_SERVICE_PHASES =
{Phase.SERVICE_BINDING, Phase.SERVICE_POLICY, Phase.SERVICE_INTERFACE, Phase.SERVICE};
private static final String[] SYSTEM_IMPLEMENTATION_PHASES = {Phase.IMPLEMENTATION_POLICY, Phase.IMPLEMENTATION};
private String pattern = Phase.class.getName();
private Map<String, Stage> stages;
private List<String> phases;
public class Stage {
private String name;
private PhaseSorter<String> sorter = new PhaseSorter<String>();
private Set<String> firstSet = new HashSet<String>();
private Set<String> lastSet = new HashSet<String>();
private List<String> phases = new ArrayList<String>();
public Stage(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public PhaseSorter<String> getSorter() {
return sorter;
}
public Set<String> getFirstSet() {
return firstSet;
}
public Set<String> getLastSet() {
return lastSet;
}
public List<String> getPhases() {
return phases;
}
public String toString() {
return name + phases;
}
}
// For unit test purpose
PhaseManager(String pattern) {
super();
this.pattern = pattern;
}
public PhaseManager() {
}
private List<String> getPhases(String stage) {
Stage s = getStages().get(stage);
return s == null ? null : s.getPhases();
}
public List<String> getReferencePhases() {
return getPhases(STAGE_REFERENCE);
}
public List<String> getServicePhases() {
return getPhases(STAGE_SERVICE);
}
public List<String> getImplementationPhases() {
return getPhases(STAGE_IMPLEMENTATION);
}
public synchronized List<String> getAllPhases() {
if (phases == null) {
phases = new ArrayList<String>();
phases.addAll(getReferencePhases());
phases.addAll(getServicePhases());
phases.addAll(getImplementationPhases());
}
return phases;
}
public synchronized Map<String, Stage> getStages() {
if (stages != null) {
return stages;
}
init();
Set<ServiceDeclaration> services;
try {
services = ServiceDiscovery.getInstance().getServiceDeclarations(pattern);
} catch (IOException e) {
throw new ServiceRuntimeException(e);
}
for (ServiceDeclaration d : services) {
if (log.isLoggable(Level.FINE)) {
log.fine(d.getResource() + ": " + d.getAttributes());
}
String name = d.getAttributes().get("name");
if (name == null) {
throw new ServiceRuntimeException("Required attribute 'name' is missing.");
}
String stageName = d.getAttributes().get("stage");
if (stageName == null) {
throw new ServiceRuntimeException("Required attribute 'stage' is missing.");
}
Stage stage = stages.get(stageName);
if (stage == null) {
throw new ServiceRuntimeException("Invalid stage: " + stage);
}
PhaseSorter<String> graph = stage.getSorter();
Set<String> firstSet = stage.getFirstSet(), lastSet = stage.getLastSet();
String before = d.getAttributes().get("before");
String after = d.getAttributes().get("after");
if (before != null) {
StringTokenizer tokenizer = new StringTokenizer(before);
while (tokenizer.hasMoreTokens()) {
String p = tokenizer.nextToken();
if (!"*".equals(p)) {
graph.addEdge(name, p);
} else {
firstSet.add(name);
}
}
}
if (after != null) {
StringTokenizer tokenizer = new StringTokenizer(after);
while (tokenizer.hasMoreTokens()) {
String p = tokenizer.nextToken();
if (!"*".equals(p)) {
graph.addEdge(p, name);
} else {
lastSet.add(name);
}
}
}
graph.addVertext(name);
if(firstSet.size()>1) {
log.warning("More than one phases are declared to be first: "+firstSet);
}
for (String s : firstSet) {
for (String v : new HashSet<String>(graph.getVertices().keySet())) {
if (!firstSet.contains(v)) {
graph.addEdge(s, v);
}
}
}
if(lastSet.size()>1) {
log.warning("More than one phases are declared to be the last: "+lastSet);
}
for (String s : lastSet) {
for (String v : new HashSet<String>(graph.getVertices().keySet())) {
if (!lastSet.contains(v)) {
graph.addEdge(v, s);
}
}
}
}
for (Stage s : stages.values()) {
List<String> phases = s.getSorter().topologicalSort(false);
s.getPhases().clear();
s.getPhases().addAll(phases);
}
if (log.isLoggable(Level.FINE)) {
log.fine("Stages: " + stages);
}
return stages;
}
private void init() {
stages = new HashMap<String, Stage>();
Stage referenceStage = new Stage(STAGE_REFERENCE);
for (int i = 1; i < SYSTEM_REFERENCE_PHASES.length; i++) {
referenceStage.getSorter().addEdge(SYSTEM_REFERENCE_PHASES[i - 1], SYSTEM_REFERENCE_PHASES[i]);
}
referenceStage.getLastSet().add(Phase.REFERENCE_BINDING);
stages.put(referenceStage.getName(), referenceStage);
Stage serviceStage = new Stage(STAGE_SERVICE);
for (int i = 1; i < SYSTEM_SERVICE_PHASES.length; i++) {
serviceStage.getSorter().addEdge(SYSTEM_SERVICE_PHASES[i - 1], SYSTEM_SERVICE_PHASES[i]);
}
stages.put(serviceStage.getName(), serviceStage);
Stage implementationStage = new Stage(STAGE_IMPLEMENTATION);
for (int i = 1; i < SYSTEM_IMPLEMENTATION_PHASES.length; i++) {
implementationStage.getSorter().addEdge(SYSTEM_IMPLEMENTATION_PHASES[i - 1],
SYSTEM_IMPLEMENTATION_PHASES[i]);
}
implementationStage.getLastSet().add(Phase.IMPLEMENTATION);
stages.put(implementationStage.getName(), implementationStage);
}
}

View file

@ -0,0 +1,236 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Directed, weighted graph
*
* @param <V> The type of vertex object
* @param <E> The type of edge object
*
* @version $Rev$ $Date$
*/
public class PhaseSorter<V> implements Cloneable {
private final Map<V, Vertex> vertices = new HashMap<V, Vertex>();
/**
* Vertex of a graph
*/
public final class Vertex {
private V value;
// TODO: Do we want to support multiple edges for a vertex pair? If so,
// we should use a List instead of Map
private Map<Vertex, Edge> outEdges = new HashMap<Vertex, Edge>();
private Map<Vertex, Edge> inEdges = new HashMap<Vertex, Edge>();
private Vertex(V value) {
this.value = value;
}
@Override
public String toString() {
return "(" + value + ")";
}
public V getValue() {
return value;
}
public Map<Vertex, Edge> getOutEdges() {
return outEdges;
}
public Map<Vertex, Edge> getInEdges() {
return inEdges;
}
}
/**
* An Edge connects two vertices in one direction
*/
public final class Edge {
private Vertex sourceVertex;
private Vertex targetVertex;
public Edge(Vertex source, Vertex target) {
this.sourceVertex = source;
this.targetVertex = target;
}
@Override
public String toString() {
return sourceVertex + "->" + targetVertex;
}
public Vertex getTargetVertex() {
return targetVertex;
}
public void setTargetVertex(Vertex vertex) {
this.targetVertex = vertex;
}
public Vertex getSourceVertex() {
return sourceVertex;
}
public void setSourceVertex(Vertex sourceVertex) {
this.sourceVertex = sourceVertex;
}
}
public void addEdge(V source, V target) {
Vertex s = getVertex(source);
if (s == null) {
s = new Vertex(source);
vertices.put(source, s);
}
Vertex t = getVertex(target);
if (t == null) {
t = new Vertex(target);
vertices.put(target, t);
}
Edge edge = new Edge(s, t);
s.outEdges.put(t, edge);
t.inEdges.put(s, edge);
}
public void addVertext(V source) {
Vertex s = getVertex(source);
if (s == null) {
s = new Vertex(source);
vertices.put(source, s);
}
}
public Vertex getVertex(V source) {
Vertex s = vertices.get(source);
return s;
}
public boolean removeEdge(V source, V target) {
Vertex s = getVertex(source);
if (s == null) {
return false;
}
Vertex t = getVertex(target);
if (t == null) {
return false;
}
return s.outEdges.remove(t) != null && t.inEdges.remove(s) != null;
}
public void removeEdge(Edge edge) {
edge.sourceVertex.outEdges.remove(edge.targetVertex);
edge.targetVertex.inEdges.remove(edge.sourceVertex);
}
public void removeVertex(Vertex vertex) {
vertices.remove(vertex.getValue());
for (Edge e : new ArrayList<Edge>(vertex.outEdges.values())) {
removeEdge(e);
}
for (Edge e : new ArrayList<Edge>(vertex.inEdges.values())) {
removeEdge(e);
}
}
public Edge getEdge(Vertex source, Vertex target) {
return source.outEdges.get(target);
}
public Edge getEdge(V source, V target) {
Vertex sv = getVertex(source);
if (sv == null) {
return null;
}
Vertex tv = getVertex(target);
if (tv == null) {
return null;
}
return getEdge(getVertex(source), getVertex(target));
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for (Vertex v : vertices.values()) {
sb.append(v.outEdges.values()).append("\n");
}
return sb.toString();
}
public Map<V, Vertex> getVertices() {
return vertices;
}
public void addGraph(PhaseSorter<V> otherGraph) {
for (Vertex v : otherGraph.vertices.values()) {
for (Edge e : v.outEdges.values()) {
addEdge(e.sourceVertex.value, e.targetVertex.value);
}
}
}
private Vertex getFirst() {
for (Vertex v : vertices.values()) {
if (v.inEdges.isEmpty()) {
return v;
}
}
if (!vertices.isEmpty()) {
throw new IllegalArgumentException("Circular ordering has been detected: " + toString());
} else {
return null;
}
}
public List<V> topologicalSort(boolean readOnly) {
PhaseSorter<V> graph = (!readOnly) ? this : (PhaseSorter<V>)clone();
List<V> list = new ArrayList<V>();
while (true) {
Vertex v = graph.getFirst();
if (v == null) {
break;
}
list.add(v.getValue());
graph.removeVertex(v);
}
return list;
}
@Override
public Object clone() {
PhaseSorter<V> copy = new PhaseSorter<V>();
copy.addGraph(this);
return copy;
}
}

View file

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
/**
* Denotes an error creating a proxy
*
* @version $Rev$ $Date$
*/
public class ProxyCreationException extends ObjectCreationException {
private static final long serialVersionUID = 8002454344828513781L;
public ProxyCreationException() {
super();
}
public ProxyCreationException(String message, Throwable cause) {
super(message, cause);
}
public ProxyCreationException(String message) {
super(message);
}
public ProxyCreationException(Throwable cause) {
super(cause);
}
}

View file

@ -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.sca.core.invocation;
import java.util.List;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.CallableReference;
/**
* Creates proxies that implement Java interfaces and invocation handlers for fronting wires
*
* @version $Rev$ $Date$
*/
public interface ProxyFactory {
/**
* Creates a Java proxy for the given wire
*
* @param interfaze the interface the proxy implements
* @param wire the wire to proxy
* @return the proxy
* @throws ProxyCreationException
*/
<T> T createProxy(Class<T> interfaze, RuntimeWire wire) throws ProxyCreationException;
/**
* Creates a Java proxy for the given CallableReference
*
* @param callableReference The CallableReference
* @return the proxy
* @throws ProxyCreationException
*/
<T> T createProxy(CallableReference<T> callableReference) throws ProxyCreationException;
/**
* Creates a Java proxy for the service contract callback
*
* @param interfaze the interface the proxy should implement
* @return the proxy
* @throws ProxyCreationException
*/
<T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException;
/**
* Creates a Java proxy for the given callback reference
*
* @param callableReference The CallableReference
* @return the proxy
* @throws ProxyCreationException
*/
<T> T createCallbackProxy(CallbackReferenceImpl<T> callbackReference) throws ProxyCreationException;
/**
* Cast a proxy to a CallableReference.
*
* @param target a proxy generated by this implementation
* @return a CallableReference (or subclass) equivalent to this proxy
* @throws IllegalArgumentException if the object supplied is not a proxy
*/
<B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException;
/**
* Test if a given class is a generated proxy class by this factory
* @param clazz A java class or interface
* @return true if the class is a generated proxy class by this factory
*/
boolean isProxyClass(Class<?> clazz);
}

View file

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
/**
* The extension point to plug in proxy factories
* @version $Rev$ $Date$
*/
public interface ProxyFactoryExtensionPoint {
/**
* Get the proxy factory for java interfaces
* @return
*/
ProxyFactory getInterfaceProxyFactory();
/**
* Get the proxy factory for java classes
* @return
*/
ProxyFactory getClassProxyFactory();
/**
* Set the proxy factory for java interfaces
* @param factory
*/
void setInterfaceProxyFactory(ProxyFactory factory);
/**
* Set the proxy factory for java classes
* @param factory
*/
void setClassProxyFactory(ProxyFactory factory);
}

View file

@ -0,0 +1,245 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import java.lang.reflect.InvocationTargetException;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.conversation.ConversationState;
import org.apache.tuscany.sca.core.conversation.ExtendedConversation;
import org.apache.tuscany.sca.core.scope.Scope;
import org.apache.tuscany.sca.core.scope.ScopeContainer;
import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
import org.apache.tuscany.sca.core.scope.TargetDestructionException;
import org.apache.tuscany.sca.core.scope.TargetResolutionException;
import org.apache.tuscany.sca.interfacedef.ConversationSequence;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.ReferenceParameters;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.osoa.sca.ConversationEndedException;
import org.osoa.sca.ServiceRuntimeException;
/**
* @version $Rev$ $Date$
*/
public class RuntimeWireInvoker {
protected ConversationManager conversationManager;
protected boolean conversational;
protected ExtendedConversation conversation;
protected MessageFactory messageFactory;
protected Object conversationID;
protected Object callbackID;
protected Object callbackObject;
protected RuntimeWire wire;
public RuntimeWireInvoker(MessageFactory messageFactory, ConversationManager conversationManager, RuntimeWire wire) {
this.messageFactory = messageFactory;
this.wire = wire;
this.conversationManager = conversationManager;
init(wire);
}
protected void init(RuntimeWire wire) {
if (wire != null) {
ReferenceParameters parameters = wire.getSource().getReferenceParameters();
this.callbackID = parameters.getCallbackID();
this.callbackObject = parameters.getCallbackReference();
this.conversationID = parameters.getConversationID();
InterfaceContract contract = wire.getSource().getInterfaceContract();
this.conversational = contract.getInterface().isConversational();
}
}
public Object invoke(Operation operation, Message msg) throws InvocationTargetException {
return invoke(wire, operation, msg);
}
public Object invoke(RuntimeWire wire, Operation operation, Message msg) throws InvocationTargetException {
RuntimeWire runtimeWire = wire == null ? this.wire : wire;
InvocationChain chain = runtimeWire.getInvocationChain(operation);
return invoke(chain, msg, runtimeWire);
}
protected Object invoke(InvocationChain chain, Message msg, RuntimeWire wire) throws InvocationTargetException {
EndpointReference from = msg.getFrom();
EndpointReference epFrom = wire.getSource();
if (from != null) {
from.mergeEndpoint(epFrom);
} else {
msg.setFrom(epFrom);
}
msg.setTo(wire.getTarget());
Invoker headInvoker = chain.getHeadInvoker();
Operation operation = chain.getTargetOperation();
msg.setOperation(operation);
Message msgContext = ThreadMessageContext.getMessageContext();
Object currentConversationID = msgContext.getFrom().getReferenceParameters().getConversationID();
ThreadMessageContext.setMessageContext(msg);
try {
conversationPreinvoke(msg);
// handleCallback(msg, currentConversationID);
// dispatch the wire down the chain and get the response
Message resp = headInvoker.invoke(msg);
Object body = resp.getBody();
if (resp.isFault()) {
throw new InvocationTargetException((Throwable)body);
}
return body;
} catch (InvocationTargetException e) {
throw e;
} catch (Throwable e) {
throw new ServiceRuntimeException(e);
} finally {
try {
conversationPostInvoke(msg);
} catch (TargetDestructionException e) {
throw new ServiceRuntimeException(e);
} finally {
ThreadMessageContext.setMessageContext(msgContext);
}
}
}
/**
* @param msgContext
*/
protected EndpointReference getCallbackEndpoint(Message msgContext) {
EndpointReference from = msgContext.getFrom();
return from == null ? null : from.getReferenceParameters().getCallbackReference();
}
/**
* Pre-invoke for the conversation handling
* @param msg
* @throws TargetResolutionException
*/
private void conversationPreinvoke(Message msg) {
if (conversational) {
ReferenceParameters parameters = msg.getFrom().getReferenceParameters();
// in some cases the ConversationID that should be used comes in with the
// message, e.g. when ws binding is in use.
Object convID = parameters.getConversationID();
if (convID != null) {
conversationID = convID;
}
conversation = conversationManager.getConversation(conversationID);
if (conversation == null || conversation.getState() == ConversationState.ENDED) {
conversation = conversationManager.startConversation(conversationID);
conversation.initializeConversationAttributes(wire.getTarget().getComponent());
} else if (conversation.conversationalAttributesInitialized() == false) {
conversation.initializeConversationAttributes(wire.getTarget().getComponent());
} else if (conversation.isExpired()){
throw new ConversationEndedException("Conversation has expired.");
}
conversation.updateLastReferencedTime();
parameters.setConversationID(conversation.getConversationID());
}
}
/**
* Post-invoke for the conversation handling
* @param wire
* @param operation
* @throws TargetDestructionException
*/
@SuppressWarnings("unchecked")
private void conversationPostInvoke(Message msg) throws TargetDestructionException {
if (conversational) {
Operation operation = msg.getOperation();
ConversationSequence sequence = operation.getConversationSequence();
if (sequence == ConversationSequence.CONVERSATION_END) {
// in some cases the ConversationID that should be used comes in with the
// message, e.g. when ws binding is in use.
Object convID = msg.getFrom().getReferenceParameters().getConversationID();
if (convID != null) {
conversationID = convID;
}
conversation = conversationManager.getConversation(conversationID);
// remove conversation id from scope container
ScopeContainer scopeContainer = getConversationalScopeContainer(msg);
if (scopeContainer != null) {
scopeContainer.remove(conversation.getConversationID());
}
conversation.end();
}
}
}
@SuppressWarnings("unchecked")
private ScopeContainer getConversationalScopeContainer(Message msg) {
ScopeContainer scopeContainer = null;
RuntimeComponent component = msg.getTo().getComponent();
if (component instanceof ScopedRuntimeComponent) {
ScopedRuntimeComponent scopedRuntimeComponent = (ScopedRuntimeComponent)component;
ScopeContainer container = scopedRuntimeComponent.getScopeContainer();
if ((container != null) && (container.getScope() == Scope.CONVERSATION)) {
scopeContainer = container;
}
}
return scopeContainer;
}
/**
* Minimal wrapper for a callback object contained in a ServiceReference
*/
private static class CallbackObjectWrapper<T> implements InstanceWrapper<T> {
private T instance;
private CallbackObjectWrapper(T instance) {
this.instance = instance;
}
public T getInstance() {
return instance;
}
public void start() {
// do nothing
}
public void stop() {
// do nothing
}
}
}

View file

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
/**
* Raised when an error is encountered during a target invocation
*
* @version $Rev$ $Date$
*/
public class TargetInvocationException extends Exception {
private static final long serialVersionUID = -6553427708442761743L;
public TargetInvocationException() {
super();
}
public TargetInvocationException(String message, Throwable cause) {
super(message, cause);
}
public TargetInvocationException(String message) {
super(message);
}
public TargetInvocationException(Throwable cause) {
super(cause);
}
}

View file

@ -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.sca.core.invocation;
import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
import org.apache.tuscany.sca.invocation.Message;
/**
* Class for tunnelling a WorkContext through the invocation of a user class.
*
* @version $Rev$ $Date$
*/
public final class ThreadMessageContext {
private static final ThreadLocal<Message> CONTEXT = new ThreadLocal<Message>() {
@Override
protected synchronized Message initialValue() {
Message msg = new MessageImpl();
msg.setFrom(new EndpointReferenceImpl("/"));
return msg;
}
};
private ThreadMessageContext() {
}
/**
* Set the WorkContext for the current thread.
* The current work context is returned and must be restored after the invocation is complete.
* Typical usage would be:
* <pre>
* WorkContext old = PojoWorkContextTunnel.setThreadWorkContext(newContext);
* try {
* ... invoke user code ...
* } finally {
* PojoWorkContextTunnel.setThreadWorkContext(old);
* }
* </pre>
* @param context
* @return the current work context for the thread; this must be restored after the invocation is made
*/
public static Message setMessageContext(Message context) {
Message old = CONTEXT.get();
CONTEXT.set(context);
return old;
}
/**
* Returns the WorkContext for the current thread.
*
* @return the WorkContext for the current thread
*/
public static Message getMessageContext() {
return CONTEXT.get();
}
}

View file

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.invocation;
import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
import org.apache.tuscany.sca.core.factory.ObjectCreationException;
import org.apache.tuscany.sca.core.factory.ObjectFactory;
import org.apache.tuscany.sca.runtime.RuntimeWire;
/**
* Uses a wire to return an object instance
*
* @version $Rev$ $Date$
*/
public class WireObjectFactory<T> implements ObjectFactory<T> {
private Class<T> interfaze;
private RuntimeWire wire;
private ProxyFactory proxyService;
/**
* Constructor.
*
* @param interfaze the interface to inject on the client
* @param wire the backing wire
* @param proxyService the wire service to create the proxy
* @throws NoMethodForOperationException
*/
public WireObjectFactory(Class<T> interfaze, RuntimeWire wire, ProxyFactory proxyService) {
this.interfaze = interfaze;
this.wire = wire;
this.proxyService = proxyService;
}
public T getInstance() throws ObjectCreationException {
return new ServiceReferenceImpl<T>(interfaze, wire, proxyService).getProxy();
}
}

View file

@ -0,0 +1,200 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.event.Event;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* Implements functionality common to scope contexts.
*
* @version $Rev$ $Date$
*/
public abstract class AbstractScopeContainer<KEY> implements ScopeContainer<KEY> {
protected Map<KEY, InstanceWrapper<?>> wrappers = new ConcurrentHashMap<KEY, InstanceWrapper<?>>();
protected final Scope scope;
protected RuntimeComponent component;
protected volatile int lifecycleState = UNINITIALIZED;
public AbstractScopeContainer(Scope scope, RuntimeComponent component) {
this.scope = scope;
this.component = component;
}
protected void checkInit() {
if (getLifecycleState() != RUNNING) {
throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]");
}
}
/**
* Creates a new physical instance of a component, wrapped in an
* InstanceWrapper.
*
* @param component the component whose instance should be created
* @return a wrapped instance that has been injected but not yet started
* @throws TargetResolutionException if there was a problem creating the
* instance
*/
protected InstanceWrapper createInstanceWrapper() throws TargetResolutionException {
ImplementationProvider implementationProvider = component.getImplementationProvider();
if (implementationProvider instanceof ScopedImplementationProvider) {
return ((ScopedImplementationProvider)implementationProvider).createInstanceWrapper();
}
return null;
}
public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException {
return getWrapper(contextId); // TODO: what is this method supposed to do diff than getWrapper?
}
public Scope getScope() {
return scope;
}
public InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException {
return wrappers.get(contextId);
}
public void addWrapperReference(KEY existingContextId, KEY newContextId)
throws TargetResolutionException {
// do nothing here. the conversational scope container implements this
}
public void registerWrapper(InstanceWrapper wrapper, KEY contextId) throws TargetResolutionException {
// do nothing here. the conversational scope container implements this
}
public void onEvent(Event event) {
}
protected boolean isEagerInit() {
ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider();
if (implementationProvider instanceof ScopedImplementationProvider) {
return ((ScopedImplementationProvider)implementationProvider).isEagerInit();
}
return false;
}
public void returnWrapper(InstanceWrapper wrapper, KEY contextId) throws TargetDestructionException {
}
/**
* Default implementation of remove which does nothing
*
* @param contextId the identifier of the context to remove.
*/
public void remove(KEY contextId)
throws TargetDestructionException {
}
public synchronized void start() {
int lifecycleState = getLifecycleState();
if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
}
setLifecycleState(RUNNING);
}
public void startContext(KEY contextId) {
if(isEagerInit()) {
try {
getWrapper(contextId);
} catch (TargetResolutionException e) {
//
}
}
}
public synchronized void stop() {
int lifecycleState = getLifecycleState();
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
}
setLifecycleState(STOPPED);
}
public void stopContext(KEY contextId) {
wrappers.remove(contextId);
}
@Override
public String toString() {
String s;
switch (lifecycleState) {
case ScopeContainer.CONFIG_ERROR:
s = "CONFIG_ERROR";
break;
case ScopeContainer.ERROR:
s = "ERROR";
break;
case ScopeContainer.INITIALIZING:
s = "INITIALIZING";
break;
case ScopeContainer.INITIALIZED:
s = "INITIALIZED";
break;
case ScopeContainer.RUNNING:
s = "RUNNING";
break;
case ScopeContainer.STOPPING:
s = "STOPPING";
break;
case ScopeContainer.STOPPED:
s = "STOPPED";
break;
case ScopeContainer.UNINITIALIZED:
s = "UNINITIALIZED";
break;
default:
s = "UNKNOWN";
break;
}
return "In state [" + s + ']';
}
public RuntimeComponent getComponent() {
return component;
}
public void setComponent(RuntimeComponent component) {
this.component = component;
}
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;
}
}

View file

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* A scope context which manages atomic component instances keyed by composite
*
* @version $Rev$ $Date$
*/
public class CompositeScopeContainer<KEY> extends AbstractScopeContainer<KEY> {
private InstanceWrapper<?> wrapper;
public CompositeScopeContainer(RuntimeComponent component) {
super(Scope.COMPOSITE, component);
}
@Override
public synchronized void stop() {
super.stop();
if (wrapper != null) {
try {
wrapper.stop();
} catch (TargetDestructionException e) {
throw new IllegalStateException(e);
}
}
wrapper = null;
}
@Override
public synchronized InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException {
if (wrapper == null) {
wrapper = createInstanceWrapper();
wrapper.start();
}
return wrapper;
}
@Override
public InstanceWrapper getAssociatedWrapper(KEY contextId) throws TargetResolutionException {
if (wrapper == null) {
throw new TargetNotFoundException(component.getURI());
}
return wrapper;
}
@Override
public synchronized void start() {
super.start();
if (isEagerInit()) {
try {
getWrapper(null);
} catch (TargetResolutionException e) {
throw new IllegalStateException(e);
}
}
}
}

View file

@ -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.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* @version $Rev$ $Date$
*/
public class CompositeScopeContainerFactory implements ScopeContainerFactory {
public ScopeContainer createScopeContainer(RuntimeComponent component) {
return new CompositeScopeContainer(component);
}
public Scope getScope() {
return Scope.COMPOSITE;
}
}

View file

@ -0,0 +1,288 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.core.conversation.ConversationListener;
import org.apache.tuscany.sca.core.conversation.ConversationManager;
import org.apache.tuscany.sca.core.conversation.ExtendedConversation;
import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.store.Store;
/**
* A scope context which manages atomic component instances keyed on ConversationID
*
* @version $Rev$ $Date$
*/
public class ConversationalScopeContainer extends AbstractScopeContainer<Object> implements ConversationListener {
private ConversationManager conversationManager;
private Map<Object, InstanceLifeCycleWrapper> instanceLifecycleCollection =
new ConcurrentHashMap<Object, InstanceLifeCycleWrapper>();
public ConversationalScopeContainer(Store aStore, RuntimeComponent component) {
super(Scope.CONVERSATION, component);
// Note: aStore is here to preserve the original factory interface. It is not currently used in this
// implementation since we do not support instance persistence.
// Check System properties to see if timeout values have been specified. All timeout values
// will be specified in seconds.
//
}
protected InstanceWrapper getInstanceWrapper(boolean create, Object contextId) throws TargetResolutionException {
// we might get a null context if the target service has
// conversational scope but only its callback interface
// is conversational. In this case we need to invent a
// conversation Id here to store the service against
// and populate the thread context
if (contextId == null) {
contextId = UUID.randomUUID().toString();
Message msgContext = ThreadMessageContext.getMessageContext();
if (msgContext != null) {
msgContext.getFrom().getReferenceParameters().setConversationID(contextId);
}
}
InstanceLifeCycleWrapper anInstanceWrapper = this.instanceLifecycleCollection.get(contextId);
if (anInstanceWrapper == null && !create)
return null;
if (anInstanceWrapper == null) {
anInstanceWrapper = new InstanceLifeCycleWrapper(contextId);
this.instanceLifecycleCollection.put(contextId, anInstanceWrapper);
}
return anInstanceWrapper.getInstanceWrapper(contextId);
}
@Override
public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException {
return getInstanceWrapper(true, contextId);
}
/**
* This method allows a new context id to be registered alongside an existing one. This happens in
* one case, when a conversation includes a stateful callback. The client component instance
* must be registered against all outgoing conversation ids so that the component instance
* can be found when the callback arrives
*
* @param existingContextId the context id against which the component is already registered
* @param context this should be a conversation object so that the conversation can b stored
* and reset when the component instance is removed
*/
public void addWrapperReference(Object existingContextId, Object contextId) throws TargetResolutionException {
// get the instance wrapper via the existing id
InstanceLifeCycleWrapper existingInstanceWrapper = this.instanceLifecycleCollection.get(existingContextId);
InstanceLifeCycleWrapper newInstanceWrapper = this.instanceLifecycleCollection.get(contextId);
// only add the extra reference once
if (newInstanceWrapper == null) {
// add the id to the list of ids that the wrapper holds. Used for reference
// counting and conversation resetting on destruction.
existingInstanceWrapper.addCallbackConversation(contextId);
// add the reference to the collection
this.instanceLifecycleCollection.put(contextId, existingInstanceWrapper);
}
}
public void registerWrapper(InstanceWrapper wrapper, Object contextId) throws TargetResolutionException {
// if a wrapper for a different instance is already registered for this contextId, remove it
InstanceLifeCycleWrapper anInstanceWrapper = this.instanceLifecycleCollection.get(contextId);
if (anInstanceWrapper != null) {
if (anInstanceWrapper.getInstanceWrapper(contextId).getInstance() != wrapper.getInstance()) {
remove(contextId);
} else {
return;
}
}
anInstanceWrapper = new InstanceLifeCycleWrapper(wrapper, contextId);
this.instanceLifecycleCollection.put(contextId, anInstanceWrapper);
}
// The remove is invoked when a conversation is explicitly ended. This can occur by using the @EndsConversation or API.
// In this case the instance is immediately removed. A new conversation will be started on the next operation
// associated with this conversationId's service reference.
//
@Override
public void remove(Object contextId) throws TargetDestructionException {
if (contextId != null) {
if (this.instanceLifecycleCollection.containsKey(contextId)) {
InstanceLifeCycleWrapper anInstanceLifeCycleWrapper = this.instanceLifecycleCollection.get(contextId);
this.instanceLifecycleCollection.remove(contextId);
anInstanceLifeCycleWrapper.removeInstanceWrapper(contextId);
}
}
}
/*
* This is an inner class that keeps track of the lifecycle of a conversation scoped
* implementation instance.
*
*/
private class InstanceLifeCycleWrapper {
private Object clientConversationId;
private List<Object> callbackConversations = new ArrayList<Object>();
private InstanceLifeCycleWrapper(Object contextId) throws TargetResolutionException {
this.clientConversationId = contextId;
this.createInstance(contextId);
}
private InstanceLifeCycleWrapper(InstanceWrapper wrapper, Object contextId) throws TargetResolutionException {
this.clientConversationId = contextId;
wrappers.put(contextId, wrapper);
}
// Associates a callback conversation with this instance. Each time the scope container
// is asked to remove an object given a ontextId an associated conversation object will
// have its conversationId reset to null. When the list of ids is empty the component instance
// will be removed from the scope container
private void addCallbackConversation(Object conversationID) {
InstanceWrapper ctx = getInstanceWrapper(clientConversationId);
callbackConversations.add(conversationID);
wrappers.put(conversationID, ctx);
}
//
// Return the backing implementation instance
//
private InstanceWrapper getInstanceWrapper(Object contextId) {
InstanceWrapper ctx = wrappers.get(contextId);
return ctx;
}
private void removeInstanceWrapper(Object contextId) throws TargetDestructionException {
InstanceWrapper ctx = getInstanceWrapper(contextId);
wrappers.remove(contextId);
// find out if we are dealing with the original client conversation id
// and reset accordingly
if ( ( clientConversationId != null ) && ( clientConversationId.equals(contextId)) ) {
clientConversationId = null;
} else {
// reset the conversationId in the conversation object if present
// so that and ending callback causes the conversation in the originating
// service reference in the client to be reset
callbackConversations.remove(contextId);
}
// stop the component if this removes the last reference
if (clientConversationId == null && callbackConversations.isEmpty()) {
ctx.stop();
}
}
private void createInstance(Object contextId) throws TargetResolutionException {
InstanceWrapper instanceWrapper = createInstanceWrapper();
instanceWrapper.start();
wrappers.put(contextId, instanceWrapper);
}
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationEnded(org.apache.tuscany.sca.core.conversation.ExtendedConversation)
*/
public void conversationEnded(ExtendedConversation conversation) {
try {
remove(conversation.getConversationID());
} catch (Exception ex) {
}
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationExpired(org.apache.tuscany.sca.core.conversation.ExtendedConversation)
*/
public void conversationExpired(ExtendedConversation conversation) {
Object conversationId = conversation.getConversationID();
InstanceLifeCycleWrapper ilcw = instanceLifecycleCollection.get(conversationId);
if (ilcw != null) {
// cycle through all the references to this instance and
// remove them from the underlying wrappers collection and
// from the lifecycle wrappers collection
for (Object conversationID : ilcw.callbackConversations) {
try{
ilcw.removeInstanceWrapper(conversationID);
remove(conversationID);
} catch(TargetDestructionException tde) {
System.out.println("Could not remove conversation id " + conversationID);
}
}
if (ilcw.clientConversationId != null) {
try{
ilcw.removeInstanceWrapper(ilcw.clientConversationId);
remove(ilcw.clientConversationId);
} catch(TargetDestructionException tde) {
System.out.println("Could not remove conversation id " + ilcw.clientConversationId);
}
}
}
}
/**
* @see org.apache.tuscany.sca.core.conversation.ConversationListener#conversationStarted(org.apache.tuscany.sca.core.conversation.ExtendedConversation)
*/
public void conversationStarted(ExtendedConversation conversation) {
startContext(conversation.getConversationID());
}
/**
* @return the conversationManager
*/
public ConversationManager getConversationManager() {
return conversationManager;
}
/**
* @param conversationManager the conversationManager to set
*/
public void setConversationManager(ConversationManager conversationManager) {
this.conversationManager = conversationManager;
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.store.Store;
/**
* @version $Rev$ $Date$
*/
public class ConversationalScopeContainerFactory implements ScopeContainerFactory {
private Store store;
public ConversationalScopeContainerFactory(Store store) {
super();
this.store = store;
}
public ScopeContainer createScopeContainer(RuntimeComponent component) {
return new ConversationalScopeContainer(store, component);
}
public Scope getScope() {
return Scope.CONVERSATION;
}
}

View file

@ -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.sca.core.scope;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.core.event.HttpSessionEnd;
import org.apache.tuscany.sca.event.Event;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* A scope context which manages atomic component instances keyed on HTTP
* session
*
* @version $Rev$ $Date$
*/
public class HttpSessionScopeContainer extends AbstractScopeContainer<Object> {
public HttpSessionScopeContainer(RuntimeComponent component) {
super(Scope.SESSION, component);
}
@Override
public void onEvent(Event event) {
checkInit();
if (event instanceof HttpSessionEnd) {
//FIXME key is not used
//Object key = ((HttpSessionEnd)event).getSessionID();
// FIXME: Remove the session id
}
}
@Override
public synchronized void start() {
if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
}
lifecycleState = RUNNING;
}
@Override
public synchronized void stop() {
lifecycleState = STOPPED;
}
protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException {
// Object key = workContext.getIdentifier(Scope.SESSION);
// FIXME: Need to fix this
Object key ="http-session-id";
assert key != null : "HTTP session key not bound in work context";
InstanceWrapper ctx = wrappers.get(key);
if (ctx == null && !create) {
return null;
}
if (ctx == null) {
ctx = super.createInstanceWrapper();
ctx.start();
wrappers.put(key, ctx);
}
return ctx;
}
@Override
public InstanceWrapper getWrapper(Object contextId) throws TargetResolutionException {
return getInstanceWrapper(true);
}
}

View file

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* @version $Rev$ $Date$
*/
public class HttpSessionScopeContainerFactory implements ScopeContainerFactory {
public HttpSessionScopeContainerFactory() {
super();
}
public ScopeContainer createScopeContainer(RuntimeComponent component) {
return new HttpSessionScopeContainer(component);
}
public Scope getScope() {
return Scope.SESSION;
}
}

View file

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.core.event.RequestEnd;
import org.apache.tuscany.sca.event.Event;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* A scope context which manages atomic component instances keyed on the current
* request context
*
* @version $Rev$ $Date$
*/
public class RequestScopeContainer extends AbstractScopeContainer<Thread> {
private final Map<Thread, InstanceWrapper> contexts;
public RequestScopeContainer(RuntimeComponent component) {
super(Scope.REQUEST, component);
contexts = new ConcurrentHashMap<Thread, InstanceWrapper>();
}
@Override
public void onEvent(Event event) {
checkInit();
if (event instanceof RequestEnd) {
// shutdownInstances(Thread.currentThread());
}
}
@Override
public synchronized void start() {
if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
}
lifecycleState = RUNNING;
}
@Override
public synchronized void stop() {
contexts.clear();
// synchronized (destroyQueues) {
// destroyQueues.clear();
// }
lifecycleState = STOPPED;
}
protected InstanceWrapper getInstanceWrapper(boolean create) throws TargetResolutionException {
InstanceWrapper ctx = wrappers.get(Thread.currentThread());
if (ctx == null && !create) {
return null;
}
if (ctx == null) {
ctx = super.createInstanceWrapper();
ctx.start();
wrappers.put(Thread.currentThread(), ctx);
}
return ctx;
}
@Override
public InstanceWrapper getWrapper(Thread contextId) throws TargetResolutionException {
return getInstanceWrapper(true);
}
}

View file

@ -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.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* @version $Rev$ $Date$
*/
public class RequestScopeContainerFactory implements ScopeContainerFactory {
public ScopeContainer createScopeContainer(RuntimeComponent component) {
return new RequestScopeContainer(component);
}
public Scope getScope() {
return Scope.REQUEST;
}
}

View file

@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
/**
* The default implementation scopes supported by assemblies.
*
* @version $Rev$ $Date$
*/
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 CONVERSATION = new Scope("CONVERSATION");
public static final Scope COMPOSITE = new Scope("COMPOSITE");
public static final Scope SYSTEM = new Scope("SYSTEM");
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;
}
@Override
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);
}
@Override
public int hashCode() {
return scope != null ? scope.hashCode() : 0;
}
@Override
public String toString() {
return scope;
}
}

View file

@ -0,0 +1,159 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.event.RuntimeEventListener;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* Manages the lifecycle and visibility of instances associated with a an {@link RuntimeComponent}.
*
* @version $Rev$ $Date$
* @param <KEY> the type of IDs that this container uses to identify its contexts.
* For example, for COMPOSITE scope this could be the URI of the composite component,
* or for HTTP Session scope it might be the HTTP session ID.
*/
public interface ScopeContainer<KEY> extends RuntimeEventListener {
/**
* Returns the Scope that this container supports.
*
* @return the Scope that this container supports
*/
Scope getScope();
/**
* Start a new context with the supplied ID.
*
* @param contextId an ID that uniquely identifies the context.
*/
void startContext(KEY contextId);
/**
* Stop the context with the supplied ID.
*
* @param contextId an ID that uniquely identifies the context.
*/
void stopContext(KEY contextId);
/**
* Returns an instance wrapper associated with the current scope context, creating one if necessary
* @param contextId the id for the scope context
*
* @return the wrapper for the target instance
* @throws TargetResolutionException if there was a problem instantiating the target instance
*/
InstanceWrapper getWrapper(KEY contextId) throws TargetResolutionException;
/**
* Allows a component to be registered against more than one context id. This is required in the
* case of stateful callbacks where we want to identify the originating client component instance
* as the callback target but we don't want to reuse the clients original conversation id
*
* @param existingContextId an id that identifies an existing component instance
* @param newContextId a new id against which this component will also be registered
* @throws TargetResolutionException
*/
void addWrapperReference(KEY existingContextId, KEY newContextId)
throws TargetResolutionException;
/**
* Register an existing instance against a context id. This is needed
* for a stateful callback where the service reference for the forward call
* contains a callback object that is not a service reference.
*
* @param wrapper the instance wrapper for the instance to be registered
* @param contextId the id for the scope context
* @throws TargetResolutionException
*/
void registerWrapper(InstanceWrapper wrapper, KEY contextId)
throws TargetResolutionException;
/**
* Returns an implementation instance associated with the current scope context.
* If no instance is found, a {@link TargetNotFoundException} is thrown.
* @param contextId the id for the scope context
*
* @return the wrapper for the target instance
* @throws TargetResolutionException if there was a problem instantiating the target instance
*/
InstanceWrapper getAssociatedWrapper(KEY contextId)
throws TargetResolutionException;
/**
* Return a wrapper after use (for example, after invoking the instance).
* @param wrapper the wrapper for the target instance being returned
* @param contextId the id for the scope context
*
* @throws TargetDestructionException if there was a problem returning the target instance
*/
void returnWrapper(InstanceWrapper wrapper, KEY contextId)
throws TargetDestructionException;
/**
* Removes an identified component implementation instance associated with the current
* context from persistent storage
*
* @param contextId the identifier of the context to remove.
*/
void remove(KEY contextId)
throws TargetDestructionException;
/* 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 composite */
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.
*/
void start();
/**
* Stops the Lifecycle.
*/
void stop();
}

View file

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* Factory to create ScopeContainer for components
*
* @version $Rev$ $Date$
*/
public interface ScopeContainerFactory {
ScopeContainer createScopeContainer(RuntimeComponent component);
Scope getScope();
}

View file

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* Manages {@link ScopeContainer}s in the runtime
*
* @version $Rev$ $Date$
*/
public interface ScopeRegistry {
/**
* Returns the scope container for the given scope or null if one not found
*
* @param scope the scope
* @return the scope container for the given scope or null if one not found
*/
ScopeContainer getScopeContainer(RuntimeComponent component);
/**
* @param factory
*/
void register(ScopeContainerFactory factory);
}

View file

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* The default implementation of a scope registry
*
* @version $Rev$ $Date$
*/
public class ScopeRegistryImpl implements ScopeRegistry {
private final Map<Scope, ScopeContainerFactory> scopeCache = new ConcurrentHashMap<Scope, ScopeContainerFactory>();
public void register(ScopeContainerFactory factory) {
scopeCache.put(factory.getScope(), factory);
}
public ScopeContainer getScopeContainer(RuntimeComponent runtimeComponent) {
if (!(runtimeComponent instanceof ScopedRuntimeComponent)) {
return null;
}
ScopedRuntimeComponent component = (ScopedRuntimeComponent)runtimeComponent;
if (component.getScopeContainer() != null) {
return component.getScopeContainer();
}
ImplementationProvider implementationProvider = component.getImplementationProvider();
if (implementationProvider instanceof ScopedImplementationProvider) {
ScopedImplementationProvider provider = (ScopedImplementationProvider)implementationProvider;
Scope scope = provider.getScope();
if (scope == null) {
scope = Scope.STATELESS;
}
ScopeContainerFactory factory = scopeCache.get(scope);
ScopeContainer container = factory.createScopeContainer(component);
component.setScopeContainer(container);
return container;
}
return null;
}
}

View file

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.provider.ImplementationProvider;
/**
* A component implementation can implement this interface to provide scope
* management for the components
*
* @version $Rev$ $Date$
*/
public interface ScopedImplementationProvider extends ImplementationProvider {
/**
* Get the scope for the component implementation
*
* @return The scope for the component implementation, if null is returned,
* STATELESS will be used
*/
Scope getScope();
/**
* Indicate if the component needs to be eagerly initialized
*
* @return true if the component is marked to be eagerly initialized, false
* otherwise
*/
boolean isEagerInit();
/**
* @return the maxAge
*/
long getMaxAge();
/**
* @return the maxIdleTime
*/
long getMaxIdleTime();
/**
* Create a wrapper for the component instance for the scope management
*
* @return A wrapper for the component instance
*/
InstanceWrapper createInstanceWrapper();
}

View file

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* Scoped runtime component
*
* @version $Rev$ $Date$
*/
public interface ScopedRuntimeComponent extends RuntimeComponent {
/**
* Set the associated scope container
* @param scopeContainer
*/
void setScopeContainer(ScopeContainer scopeContainer);
/**
* Get the assoicated scope container
* @return
*/
ScopeContainer getScopeContainer();
}

View file

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
import org.apache.tuscany.sca.core.context.InstanceWrapper;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* A scope context which manages stateless atomic component instances in a non-pooled fashion.
*
* @version $Rev$ $Date$
*/
public class StatelessScopeContainer<KEY> extends AbstractScopeContainer<KEY> {
public StatelessScopeContainer(RuntimeComponent component) {
super(Scope.STATELESS, component);
}
@Override
public InstanceWrapper getWrapper(KEY contextId)
throws TargetResolutionException {
InstanceWrapper ctx = createInstanceWrapper();
ctx.start();
return ctx;
}
@Override
public InstanceWrapper getAssociatedWrapper(KEY contextId)
throws TargetResolutionException {
return getWrapper(contextId);
}
@Override
public void returnWrapper(InstanceWrapper wrapper, KEY contextId)
throws TargetDestructionException {
wrapper.stop();
}
}

View file

@ -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.sca.core.scope;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
/**
* @version $Rev$ $Date$
*/
public class StatelessScopeContainerFactory implements ScopeContainerFactory {
public ScopeContainer createScopeContainer(RuntimeComponent component) {
return new StatelessScopeContainer(component);
}
public Scope getScope() {
return Scope.STATELESS;
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
/**
* Denotes an error destroying a target
*
* @version $Rev$ $Date$
*/
public class TargetDestructionException extends TargetResolutionException {
private static final long serialVersionUID = -6126684147851674709L;
public TargetDestructionException() {
super();
}
public TargetDestructionException(String message, Throwable cause) {
super(message, cause);
}
public TargetDestructionException(String message) {
super(message);
}
public TargetDestructionException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
/**
* Denotes an error initializing a target
*
* @version $Rev$ $Date$
*/
public class TargetInitializationException extends TargetResolutionException {
private static final long serialVersionUID = -6228778208649752698L;
public TargetInitializationException() {
super();
}
public TargetInitializationException(String message, Throwable cause) {
super(message, cause);
}
public TargetInitializationException(String message) {
super(message);
}
public TargetInitializationException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
/**
* Thrown when a target of an operation cannot be found
*
* @version $Rev$ $Date$
*/
public class TargetNotFoundException extends TargetResolutionException {
private static final long serialVersionUID = 5541830480658471186L;
public TargetNotFoundException() {
super();
}
public TargetNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public TargetNotFoundException(String message) {
super(message);
}
public TargetNotFoundException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.scope;
/**
* Denotes an error retrieving a target instance
*
* @version $Rev$ $Date$
*/
public class TargetResolutionException extends Exception {
private static final long serialVersionUID = 2912513650522019405L;
public TargetResolutionException() {
super();
}
public TargetResolutionException(String message, Throwable cause) {
super(message, cause);
}
public TargetResolutionException(String message) {
super(message);
}
public TargetResolutionException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.store;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.tuscany.sca.core.event.BaseEventPublisher;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.store.DuplicateRecordException;
import org.apache.tuscany.sca.store.RecoveryListener;
import org.apache.tuscany.sca.store.Store;
import org.apache.tuscany.sca.store.StoreExpirationEvent;
import org.apache.tuscany.sca.store.StoreMonitor;
import org.apache.tuscany.sca.store.StoreWriteException;
import org.osoa.sca.annotations.Destroy;
import org.osoa.sca.annotations.EagerInit;
import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Property;
import org.osoa.sca.annotations.Service;
/**
* Implements a non-durable, non-transactional store using a simple in-memory map
*
* @version $Rev$ $Date$
*/
@Service(Store.class)
@EagerInit
public class MemoryStore extends BaseEventPublisher implements Store {
private Map<RuntimeComponent, Map<String, Record>> store;
// TODO integrate with a core threading scheme
private ScheduledExecutorService scheduler;
private long reaperInterval = 300000;
private StoreMonitor monitor;
private long defaultExpirationOffset = 600000; // 10 minutes
public MemoryStore(StoreMonitor monitor) {
this.monitor = monitor;
this.store = new ConcurrentHashMap<RuntimeComponent, Map<String, Record>>();
this.scheduler = Executors.newSingleThreadScheduledExecutor();
}
/**
* Returns the maximum default expiration offset for records in the store
*
* @return the maximum default expiration offset for records in the store
*/
public long getDefaultExpirationOffset() {
return defaultExpirationOffset;
}
/**
* Sets the maximum default expiration offset for records in the store
*/
@Property
public void setDefaultExpirationOffset(long defaultExpirationOffset) {
this.defaultExpirationOffset = defaultExpirationOffset;
}
/**
* Sets the interval for expired entry scanning to be performed
*/
@Property
public void setReaperInterval(long reaperInterval) {
this.reaperInterval = reaperInterval;
}
public long getReaperInterval() {
return reaperInterval;
}
@Init
public void init() {
scheduler.scheduleWithFixedDelay(new Reaper(), reaperInterval, reaperInterval, TimeUnit.MILLISECONDS);
monitor.start("In-memory store started");
}
@Destroy
public void destroy() {
scheduler.shutdown();
monitor.stop("In-memory store stopped");
}
public void insertRecord(RuntimeComponent owner, String id, Object object, long expiration) throws StoreWriteException {
Map<String, Record> map = store.get(owner);
if (map == null) {
map = new ConcurrentHashMap<String, Record>();
store.put(owner, map);
}
if (map.containsKey(id)) {
throw new DuplicateRecordException("Duplicate record: " + owner.getURI() +" : " + id);
}
map.put(id, new Record(object, expiration));
}
public void updateRecord(RuntimeComponent owner, String id, Object object, long expiration) throws StoreWriteException {
Map<String, Record> map = store.get(owner);
if (map == null) {
throw new StoreWriteException("Record not found: " + owner.getURI() +" : " + id);
}
Record record = map.get(id);
if (record == null) {
throw new StoreWriteException("Record not found: " + owner.getURI() +" : " + id);
}
record.data = object;
}
public Object readRecord(RuntimeComponent owner, String id) {
Map<String, Record> map = store.get(owner);
if (map == null) {
return null;
}
Record record = map.get(id);
if (record != null) {
return record.data;
}
return null;
}
public void removeRecords() {
store.clear();
}
public void removeRecord(RuntimeComponent owner, String id) throws StoreWriteException {
Map<String, Record> map = store.get(owner);
if (map == null) {
throw new StoreWriteException("Owner not found: " + owner.getURI() +" : " + id);
}
if (map.remove(id) == null) {
throw new StoreWriteException("Owner not found: " + owner.getURI() +" : " + id);
}
}
public void recover(RecoveryListener listener) {
throw new UnsupportedOperationException();
}
private class Record {
private Object data;
private long expiration = NEVER;
public Record(Object data, long expiration) {
this.data = data;
this.expiration = expiration;
}
public Object getData() {
return data;
}
public long getExpiration() {
return expiration;
}
}
private class Reaper implements Runnable {
public void run() {
long now = System.currentTimeMillis();
for (Map.Entry<RuntimeComponent, Map<String, Record>> entries : store.entrySet()) {
for (Map.Entry<String, Record> entry : entries.getValue().entrySet()) {
final long expiration = entry.getValue().expiration;
if (expiration != NEVER && now >= expiration) {
RuntimeComponent owner = entries.getKey();
Object instance = entry.getValue().getData();
// notify listeners of the expiration
StoreExpirationEvent event = new StoreExpirationEvent(this, owner, instance);
publish(event);
entries.getValue().remove(entry.getKey());
}
}
}
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.work;
/**
* JCA work wrapper.
*
* @version $Rev$ $Date$
*/
public class Jsr237Work<T extends Runnable> implements commonj.work.Work {
// Work that is being executed.
private T work;
/*
* Initializes the work instance.
*/
public Jsr237Work(T work) {
this.work = work;
}
/*
* Returns the completed work.
*/
public T getWork() {
return work;
}
/*
* Release the work.
*/
public void release() {
}
/*
* Work attributes are not daemon.
*/
public boolean isDaemon() {
return false;
}
/*
* Runs the work.
*/
public void run() {
work.run();
}
}

View file

@ -0,0 +1,192 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.work;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.tuscany.sca.work.NotificationListener;
import org.apache.tuscany.sca.work.WorkScheduler;
import org.apache.tuscany.sca.work.WorkSchedulerException;
import commonj.work.WorkEvent;
import commonj.work.WorkListener;
import commonj.work.WorkManager;
/**
* A work scheduler implementation based on a JSR 237 work manager.
* <p/>
* <p/>
* This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a
* work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work
* manager implementation available. For example, if the managed environment supports work manager the runtime can use
* the appropriate lookup mechanism to inject the work manager implementation. </p>
*
* @version $Rev$ $Date$
*/
public class Jsr237WorkScheduler implements WorkScheduler {
/**
* Underlying JSR-237 work manager
*/
private WorkManager jsr237WorkManager;
/**
* Initializes the JSR 237 work manager.
*
* @param jsr237WorkManager JSR 237 work manager.
*/
public Jsr237WorkScheduler() {
try {
InitialContext ctx = new InitialContext();
jsr237WorkManager = (WorkManager) ctx.lookup("java:comp/env/wm/TuscanyWorkManager");
} catch (NamingException e) {
// ignore
}
if (jsr237WorkManager == null) {
jsr237WorkManager = new ThreadPoolWorkManager(10);
}
}
/**
* 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.
*/
public <T extends Runnable> void scheduleWork(T work) {
scheduleWork(work, null);
}
/**
* 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.
*/
public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
if (work == null) {
throw new IllegalArgumentException("Work cannot be null");
}
Jsr237Work<T> jsr237Work = new Jsr237Work<T>(work);
try {
if (listener == null) {
jsr237WorkManager.schedule(jsr237Work);
} else {
Jsr237WorkListener<T> jsr237WorkListener = new Jsr237WorkListener<T>(listener, work);
jsr237WorkManager.schedule(jsr237Work, jsr237WorkListener);
}
} catch (IllegalArgumentException ex) {
if (listener != null) {
listener.workRejected(work);
} else {
throw new WorkSchedulerException(ex);
}
} catch (Exception ex) {
throw new WorkSchedulerException(ex);
}
}
public void destroy() {
if (jsr237WorkManager instanceof ThreadPoolWorkManager) {
// Allow privileged access to modify threads. Requires RuntimePermission in security
// policy.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
((ThreadPoolWorkManager)jsr237WorkManager).destroy();
return null;
}
});
}
}
/*
* WorkListener for keeping track of work status callbacks.
*
*/
private class Jsr237WorkListener<T extends Runnable> implements WorkListener {
// Notification listener
private NotificationListener<T> listener;
// Work
private T work;
/*
* Initializes the notification listener.
*/
public Jsr237WorkListener(NotificationListener<T> listener, T work) {
this.listener = listener;
this.work = work;
}
/*
* Callback when the work is accepted.
*/
public void workAccepted(WorkEvent workEvent) {
T work = getWork();
listener.workAccepted(work);
}
/*
* Callback when the work is rejected.
*/
public void workRejected(WorkEvent workEvent) {
T work = getWork();
listener.workRejected(work);
}
/*
* Callback when the work is started.
*/
public void workStarted(WorkEvent workEvent) {
T work = getWork();
listener.workStarted(work);
}
/*
* Callback when the work is completed.
*/
public void workCompleted(WorkEvent workEvent) {
T work = getWork();
Exception exception = workEvent.getException();
if (exception != null) {
listener.workFailed(work, exception);
} else {
listener.workCompleted(work);
}
}
/*
* Gets the underlying work from the work event.
*/
private T getWork() {
return work;
}
}
}

View file

@ -0,0 +1,235 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.work;
import java.rmi.server.UID;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadFactory;
import org.osoa.sca.annotations.Destroy;
import commonj.work.Work;
import commonj.work.WorkEvent;
import commonj.work.WorkException;
import commonj.work.WorkItem;
import commonj.work.WorkListener;
import commonj.work.WorkManager;
/**
* A thread-pool based implementation for the JSR-237 work manager.
* <p/>
* <p/>
* This implementation supports only local work.
* <p/>
* TODO Elaborate the implementation. </p>
*
* @version $Rev$ $Date$
*/
public class ThreadPoolWorkManager implements WorkManager {
// Map of work items currently handled by the work manager
private Map<WorkItemImpl, WorkListener> workItems = new ConcurrentHashMap<WorkItemImpl, WorkListener>();
// Thread-pool
private ExecutorService executor;
/**
* Initializes the thread-pool.
*
* @param threadPoolSize Thread-pool size.
* @throws IllegalArgumentException if threadPoolSize < 1
*/
public ThreadPoolWorkManager(int threadPoolSize) {
if (threadPoolSize < 1) {
throw new IllegalArgumentException("Invalid threadPoolSize of "
+ threadPoolSize + ". It must be >= 1");
}
// Creates a new Executor, use a custom ThreadFactory that
// creates daemon threads.
executor = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
}
/**
* Schedules a unit of work asynchronously.
*
* @param work Work that needs to be scheduled.
* @return Work Work item representing the asynchronous work
*/
public WorkItem schedule(Work work) throws IllegalArgumentException {
return schedule(work, null);
}
/**
* Schedules a unit of work asynchronously.
*
* @param work Work that needs to be scheduled.
* @param workListener Work listener for callbacks.
* @return Work Work item representing the asynchronous work
*/
public WorkItem schedule(Work work, WorkListener workListener) throws IllegalArgumentException {
WorkItemImpl workItem = new WorkItemImpl(new UID().toString(), work);
if (workListener != null) {
workItems.put(workItem, workListener);
}
workAccepted(workItem, work);
if (scheduleWork(work, workItem)) {
return workItem;
} else {
workItem.setStatus(WorkEvent.WORK_REJECTED);
if (workListener != null) {
workListener.workRejected(new WorkEventImpl(workItem));
}
throw new IllegalArgumentException("Unable to schedule work");
}
}
/**
* Wait for all the specified units of work to finish.
*
* @param works Units of the work that need to finish.
* @param timeout Timeout for waiting for the units of work to finish.
*/
public boolean waitForAll(Collection works, long timeout) {
throw new UnsupportedOperationException("waitForAll not supported");
}
/**
* Wait for any of the specified units of work to finish.
*
* @param works Units of the work that need to finish.
* @param timeout Timeout for waiting for the units of work to finish.
*/
public Collection waitForAny(Collection works, long timeout) {
throw new UnsupportedOperationException("waitForAny not supported");
}
/**
* Method provided for subclasses to indicate a work acceptance.
*
* @param workItem Work item representing the work that was accepted.
* @param work Work that was accepted.
*/
private void workAccepted(final WorkItemImpl workItem, final Work work) {
WorkListener listener = workItems.get(workItem);
if (listener != null) {
workItem.setStatus(WorkEvent.WORK_ACCEPTED);
WorkEvent event = new WorkEventImpl(workItem);
listener.workAccepted(event);
}
}
/*
* Method to indicate a work start.
*/
private void workStarted(final WorkItemImpl workItem, final Work work) {
WorkListener listener = workItems.get(workItem);
if (listener != null) {
workItem.setStatus(WorkEvent.WORK_STARTED);
WorkEvent event = new WorkEventImpl(workItem);
listener.workStarted(event);
}
}
/*
* Method to indicate a work completion.
*/
private void workCompleted(final WorkItemImpl workItem, final Work work) {
workCompleted(workItem, work, null);
}
/*
* Method to indicate a work completion.
*/
private void workCompleted(final WorkItemImpl workItem, final Work work, final WorkException exception) {
WorkListener listener = workItems.get(workItem);
if (listener != null) {
workItem.setStatus(WorkEvent.WORK_COMPLETED);
workItem.setResult(work);
workItem.setException(exception);
WorkEvent event = new WorkEventImpl(workItem);
listener.workCompleted(event);
workItems.remove(workItem);
}
}
/*
* Schedules the work using the ThreadPool.
*/
private boolean scheduleWork(final Work work, final WorkItemImpl workItem) {
try {
executor.execute(new DecoratingWork(workItem, work));
return true;
} catch (RejectedExecutionException ex) {
return false;
}
}
/*
* Class that decorates the original worker so that it can get callbacks when work is done.
*/
private final class DecoratingWork implements Runnable {
// Work item for this work.
private WorkItemImpl workItem;
// The original work.
private Work decoratedWork;
/*
* Initializes the work item and underlying work.
*/
private DecoratingWork(final WorkItemImpl workItem, final Work decoratedWork) {
this.workItem = workItem;
this.decoratedWork = decoratedWork;
}
/*
* Overrides the run method.
*/
public void run() {
workStarted(workItem, decoratedWork);
try {
decoratedWork.run();
workCompleted(workItem, decoratedWork);
} catch (Throwable th) {
workCompleted(workItem, decoratedWork, new WorkException(th.getMessage(), th));
}
}
}
@Destroy
public void destroy() {
executor.shutdown();
}
}

View file

@ -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.sca.core.work;
import commonj.work.WorkEvent;
import commonj.work.WorkException;
import commonj.work.WorkItem;
/**
* Default immutable implementation of the <code>WorkEvent</code> class.
*
* @version $Rev$ $Date$
*/
class WorkEventImpl implements WorkEvent {
// Work item for this event
private WorkItem workItem;
// Exception if something has gone wrong
private WorkException exception;
/**
* Instantiates the event.
*
* @param workItem Work item for this event.
*/
public WorkEventImpl(final WorkItemImpl workItem) {
this.workItem = workItem;
this.exception = workItem.getException();
}
/**
* Returns the work type based on whether the work was accepted, started,
* rejected or completed.
*
* @return Work type.
*/
public int getType() {
return workItem.getStatus();
}
/**
* Returns the work item associated with this work type.
*
* @return Work item.
*/
public WorkItem getWorkItem() {
return workItem;
}
/**
* Returns the exception if the work completed with an exception.
*
* @return Work exception.
*/
public WorkException getException() {
return exception;
}
}

View file

@ -0,0 +1,169 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.work;
import commonj.work.Work;
import commonj.work.WorkException;
import commonj.work.WorkItem;
/**
* An identity based immutable implementation of the <code>WorkItem</code>
* interface.
*
* @version $Rev$ $Date$
*/
class WorkItemImpl implements WorkItem {
// Id scoped for the VM
private String id;
// Status
private int status = -1;
// Result
private Work result;
// Original work
private Work originalWork;
// Exception
private WorkException exception;
/**
* Instantiates an id for this item.
*
* @param id of this work event.
*/
protected WorkItemImpl(final String id, final Work orginalWork) {
this.id = id;
this.originalWork = orginalWork;
}
/**
* Returns the id.
*
* @return Id of this item.
*/
public String getId() {
return id;
}
/**
* Returns the original work.
*
* @return Original work.
*/
public Work getOriginalWork() {
return originalWork;
}
/**
* Returns the work result if the work completed.
*
* @return Work.
* @throws WorkException If the work completed with an exception.
*/
public Work getResult() {
return result;
}
/**
* Sets the result.
*
* @param result Result.
*/
protected void setResult(final Work result) {
this.result = result;
}
/**
* Returns the exception if work completed with an exception.
*
* @return Work exception.
*/
protected WorkException getException() {
return exception;
}
/**
* Sets the exception.
*
* @param exception Exception.
*/
protected void setException(final WorkException exception) {
this.exception = exception;
}
/**
* Returns the work type based on whether the work was accepted, started,
* rejected or completed.
*
* @return Work status.
*/
public int getStatus() {
return status;
}
/**
* Sets the status.
*
* @param status Status.
*/
protected void setStatus(final int status) {
this.status = status;
}
/**
* @see Object#hashCode()
*/
@Override
public int hashCode() {
return id.hashCode();
}
/**
* Indicates whether some other object is "equal to" this one.
*
* @param obj Object to be compared.
* @return true if this object is the same as the obj argument; false
* otherwise..
*/
@Override
public boolean equals(final Object obj) {
return (obj != null) && (obj.getClass() == WorkItemImpl.class) && ((WorkItemImpl) obj).id.equals(id);
}
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* @param o Object to be compared.
* @return A negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
* @throws ClassCastException needs better documentation.
*/
public int compareTo(final Object o) {
if (o.getClass() != WorkItemImpl.class) {
throw new ClassCastException(o.getClass().getName());
} else {
return ((WorkItemImpl) o).getId().compareTo(getId());
}
}
}

View file

@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Implementation class for the artifact processor extension
org.apache.tuscany.sca.core.assembly.ReferenceParameterProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#referenceParameters,model=org.apache.tuscany.sca.runtime.ReferenceParameters

View file

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
org.apache.tuscany.sca.core.conversation.ConversationManagerImpl

View file

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
org.apache.tuscany.sca.core.invocation.DefaultProxyFactoryExtensionPoint

View file

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
org.apache.tuscany.sca.core.invocation.MessageFactoryImpl

View file

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
org.apache.tuscany.sca.core.work.Jsr237WorkScheduler

View file

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core;
import junit.framework.TestCase;
public class DefaultExtensionPointRegistryTestCase extends TestCase {
private ExtensionPointRegistry registry;
@Override
protected void setUp() throws Exception {
super.setUp();
registry = new DefaultExtensionPointRegistry();
}
public void testRegistry() {
MyRegistry service = new MyREgistryImpl();
registry.addExtensionPoint(service);
assertSame(service, registry.getExtensionPoint(MyRegistry.class));
registry.removeExtensionPoint(service);
assertNull(registry.getExtensionPoint(MyRegistry.class));
}
public static interface MyRegistry {
void doSomething();
}
private static class MyREgistryImpl implements MyRegistry {
public void doSomething() {
}
}
}

View file

@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.core.event;
import junit.framework.TestCase;
import org.apache.tuscany.sca.event.Event;
import org.apache.tuscany.sca.event.EventFilter;
import org.apache.tuscany.sca.event.EventPublisher;
import org.apache.tuscany.sca.event.RuntimeEventListener;
import org.apache.tuscany.sca.event.TrueFilter;
import org.easymock.EasyMock;
/**
* @version $Rev$ $Date$
*/
public class BaseEventPublisherTestCase extends TestCase {
EventPublisher publisher;
public void testFireListener() {
Event event = new TestEvent();
RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
listener.onEvent(EasyMock.same(event));
EasyMock.expectLastCall();
EasyMock.replay(listener);
publisher.addListener(listener);
publisher.publish(event);
EasyMock.verify(listener);
}
public void testRemoveListener() {
Event event = new TestEvent();
RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
EasyMock.replay(listener);
publisher.addListener(listener);
publisher.removeListener(listener);
publisher.publish(event);
EasyMock.verify(listener);
}
public void testFalseFilterListener() {
Event event = new TestEvent();
RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
EasyMock.replay(listener);
publisher.addListener(new FalseFilter(), listener);
publisher.publish(event);
EasyMock.verify(listener);
}
public void testTrueFilterListener() {
Event event = new TestEvent();
RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
listener.onEvent(EasyMock.same(event));
EasyMock.expectLastCall();
EasyMock.replay(listener);
publisher.addListener(new TrueFilter(), listener);
publisher.publish(event);
EasyMock.verify(listener);
}
@Override
protected void setUp() throws Exception {
publisher = new BaseEventPublisher() {
};
}
private class TestEvent implements Event {
public Object getSource() {
return null;
}
}
private class FalseFilter implements EventFilter {
public boolean match(Event event) {
return false;
}
}
}

Some files were not shown because too many files have changed in this diff Show more