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:
parent
b2494153a0
commit
273d7efc7b
118 changed files with 13706 additions and 0 deletions
205
sandbox/mcombellack/ohloh/tags/test/LICENSE
Normal file
205
sandbox/mcombellack/ohloh/tags/test/LICENSE
Normal 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.
|
||||
|
||||
|
||||
|
6
sandbox/mcombellack/ohloh/tags/test/NOTICE
Normal file
6
sandbox/mcombellack/ohloh/tags/test/NOTICE
Normal 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/).
|
||||
|
101
sandbox/mcombellack/ohloh/tags/test/pom.xml
Normal file
101
sandbox/mcombellack/ohloh/tags/test/pom.xml
Normal 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>
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue