Import work in progress code for comet binding runtime
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1124666 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c3565b5e7c
commit
b3c3c7de51
25 changed files with 2166 additions and 0 deletions
sca-java-2.x/trunk/unreleased/modules/binding-comet-runtime
LICENSE
META-INF
NOTICEpom.xmlsrc
main
java
META-INF
org/apache/tuscany/sca/binding/comet/runtime
resources
test
java/org/apache/tuscany/sca/test
resources
|
@ -0,0 +1,238 @@
|
|||
|
||||
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.
|
||||
|
||||
===============================================================================================================
|
||||
|
||||
Apache Tuscany SCA for Java Subcomponents
|
||||
=========================================:
|
||||
|
||||
The Tuscany SCA for Java release includes a number of subcomponents with
|
||||
separate copyright notices and license terms. Your use of the source
|
||||
code for the these subcomponents is subject to the terms and
|
||||
conditions of the following licenses.
|
||||
|
||||
=================================================================================================================
|
||||
|
||||
This module includes files under the following MIT license:
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Manifest-Version: 1.0
|
||||
SCA-Version: 1.1
|
||||
Bundle-Name: Apache Tuscany SCA Comet Binding Model
|
||||
Bundle-Vendor: The Apache Software Foundation
|
||||
Bundle-Version: 2.0.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
Bundle-Description: Apache Tuscany SCA Comet Binding Model
|
||||
Import-Package: javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
org.apache.commons.codec,
|
||||
org.apache.commons.codec.net,
|
||||
org.apache.http,
|
||||
org.apache.http.client,
|
||||
org.apache.http.client.methods,
|
||||
org.apache.http.client.utils,
|
||||
org.apache.http.conn,
|
||||
org.apache.http.impl.client,
|
||||
org.apache.tuscany.sca.assembly;version="2.0.0",
|
||||
org.apache.tuscany.sca.binding.comet;version="2.0.0",
|
||||
org.apache.tuscany.sca.core;version="2.0.0",
|
||||
org.apache.tuscany.sca.host.http;version="2.0.0",
|
||||
org.apache.tuscany.sca.interfacedef;version="2.0.0",
|
||||
org.apache.tuscany.sca.invocation;version="2.0.0",
|
||||
org.apache.tuscany.sca.provider;version="2.0.0",
|
||||
org.apache.tuscany.sca.runtime;version="2.0.0",
|
||||
org.codehaus.jackson,
|
||||
org.codehaus.jackson.map
|
||||
Bundle-SymbolicName: org.apache.tuscany.sca.binding.comet.runtime
|
||||
Bundle-DocURL: http://www.apache.org/
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
|
|
@ -0,0 +1,6 @@
|
|||
${pom.name}
|
||||
Copyright (c) 2005 - 2011 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?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>2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-binding-comet-runtime</artifactId>
|
||||
<name>Apache Tuscany SCA Comet Binding Runtime</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-base-runtime-pom</artifactId>
|
||||
<type>pom</type>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.atmosphere</groupId>
|
||||
<artifactId>atmosphere-commons</artifactId>
|
||||
<version>0.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.atmosphere</groupId>
|
||||
<artifactId>atmosphere-runtime</artifactId>
|
||||
<version>0.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-servlet_3.0_spec</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty</artifactId>
|
||||
<version>6.1.26</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gson-googlecode-repository</id>
|
||||
<url>http://google-gson.googlecode.com/svn/mavenrepo</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.apache.tuscany.sca.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
|
||||
import org.apache.tuscany.sca.invocation.InvokerAsyncResponse;
|
||||
import org.apache.tuscany.sca.invocation.Message;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
|
||||
public class CometAsyncResponseInvoker implements InvokerAsyncResponse {
|
||||
|
||||
private RuntimeEndpoint endpoint;
|
||||
|
||||
public CometAsyncResponseInvoker(ExtensionPointRegistry extensionPoints, RuntimeEndpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeAsyncResponse(Message msg) {
|
||||
System.out.println("In invokeAsyncResponse!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.binding.comet.CometBinding;
|
||||
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
|
||||
import org.apache.tuscany.sca.host.http.ServletHost;
|
||||
import org.apache.tuscany.sca.host.http.ServletHostHelper;
|
||||
import org.apache.tuscany.sca.provider.BindingProviderFactory;
|
||||
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
|
||||
import org.apache.tuscany.sca.provider.ServiceBindingProvider;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
|
||||
|
||||
/**
|
||||
* Factory for binding providers.
|
||||
*/
|
||||
public class CometBindingProviderFactory implements BindingProviderFactory<CometBinding> {
|
||||
|
||||
/**
|
||||
* Underlying servlet host. Injected by constructor.
|
||||
*/
|
||||
private final ServletHost servletHost;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public CometBindingProviderFactory(final ExtensionPointRegistry extensionPoints) {
|
||||
this.servletHost = ServletHostHelper.getServletHost(extensionPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<CometBinding> getModelType() {
|
||||
return CometBinding.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a provider for a reference that has comet binding specified in
|
||||
* the scdl.
|
||||
*/
|
||||
@Override
|
||||
public ReferenceBindingProvider createReferenceBindingProvider(final RuntimeEndpointReference endpoint) {
|
||||
return new CometReferenceBindingProvider(endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a provider for a service that has comet binding specified in the
|
||||
* scdl.
|
||||
*/
|
||||
@Override
|
||||
public ServiceBindingProvider createServiceBindingProvider(final RuntimeEndpoint endpoint) {
|
||||
return new CometServiceBindingProvider(endpoint, this.servletHost);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.binding.comet.runtime;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
|
||||
public class CometComponentContext {
|
||||
|
||||
private Map<String, RuntimeEndpoint> endpoints;
|
||||
private Map<String, Operation> operations;
|
||||
|
||||
public CometComponentContext() {
|
||||
endpoints = new ConcurrentHashMap<String, RuntimeEndpoint>();
|
||||
operations = new ConcurrentHashMap<String, Operation>();
|
||||
}
|
||||
|
||||
public void addEndpoint(String key, RuntimeEndpoint endpoint) {
|
||||
endpoints.put(key, endpoint);
|
||||
}
|
||||
|
||||
public void addOperation(String key, Operation operation) {
|
||||
operations.put(key, operation);
|
||||
}
|
||||
|
||||
public RuntimeEndpoint getEndpoint(String key) {
|
||||
return endpoints.get(key);
|
||||
}
|
||||
|
||||
public Operation getOperation(String key) {
|
||||
return operations.get(key);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.assembly.EndpointReference;
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.handler.CometBindingHandler;
|
||||
import org.apache.tuscany.sca.core.invocation.impl.MessageImpl;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import org.apache.tuscany.sca.invocation.Invoker;
|
||||
import org.apache.tuscany.sca.invocation.Message;
|
||||
|
||||
public class CometInvoker implements Invoker {
|
||||
|
||||
protected Operation operation;
|
||||
protected EndpointReference endpoint;
|
||||
|
||||
public CometInvoker(final Operation operation, final EndpointReference endpoint) {
|
||||
this.operation = operation;
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message invoke(final Message msg) {
|
||||
String operation = msg.getOperation().getName();
|
||||
CometMessageContext context = msg.getBindingContext();
|
||||
CometBindingHandler handler = context.getCometHandler();
|
||||
Message message = new MessageImpl();
|
||||
if (operation.equals("sendResponse")) {
|
||||
String callbackMethod = context.getCallbackMethod();
|
||||
Object[] body = msg.getBody();
|
||||
handler.respondToClient(callbackMethod, body[0]);
|
||||
} else if (operation.equals("isClientConnected")) {
|
||||
message.setBody(handler.isClientConnected());
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.handler.CometBindingHandler;
|
||||
|
||||
public class CometMessageContext {
|
||||
|
||||
private CometBindingHandler cometHandler;
|
||||
|
||||
private String callbackMethod;
|
||||
|
||||
public CometMessageContext(CometBindingHandler cometHandler, String callbackMethod) {
|
||||
this.cometHandler = cometHandler;
|
||||
this.callbackMethod = callbackMethod;
|
||||
}
|
||||
|
||||
public CometBindingHandler getCometHandler() {
|
||||
return cometHandler;
|
||||
}
|
||||
|
||||
public void setCometHandler(CometBindingHandler cometHandler) {
|
||||
this.cometHandler = cometHandler;
|
||||
}
|
||||
|
||||
public String getCallbackMethod() {
|
||||
return callbackMethod;
|
||||
}
|
||||
|
||||
public void setCallbackMethod(String callbackMethod) {
|
||||
this.callbackMethod = callbackMethod;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.assembly.EndpointReference;
|
||||
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import org.apache.tuscany.sca.invocation.Invoker;
|
||||
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
|
||||
|
||||
/**
|
||||
* Provider for references that have comet binding specified in the scdl. Not
|
||||
* used as comet binding references would occur in client browser's Javascript.
|
||||
*/
|
||||
public class CometReferenceBindingProvider implements ReferenceBindingProvider {
|
||||
|
||||
/**
|
||||
* Endpoint for which the binding provider is created.
|
||||
*/
|
||||
private final EndpointReference endpoint;
|
||||
|
||||
public CometReferenceBindingProvider(final EndpointReference endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Invoker createInvoker(final Operation operation) {
|
||||
return new CometInvoker(operation, this.endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* No behavior.
|
||||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
}
|
||||
|
||||
/**
|
||||
* No behavior.
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceContract getBindingInterfaceContract() {
|
||||
return endpoint.getReference().getInterfaceContract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOneWayInvocation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.assembly.ComponentService;
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.javascript.JavascriptGenerator;
|
||||
import org.apache.tuscany.sca.host.http.ServletHost;
|
||||
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.invocation.InvokerAsyncResponse;
|
||||
import org.apache.tuscany.sca.provider.EndpointAsyncProvider;
|
||||
import org.apache.tuscany.sca.provider.ServiceBindingProvider;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
|
||||
/**
|
||||
* Provider for services having comet binding specified in the scdl.
|
||||
*/
|
||||
public class CometServiceBindingProvider implements ServiceBindingProvider, EndpointAsyncProvider {
|
||||
|
||||
/**
|
||||
* Service's endpoint.
|
||||
*/
|
||||
private final RuntimeEndpoint endpoint;
|
||||
|
||||
/**
|
||||
* The underlying servlet host.
|
||||
*/
|
||||
private final ServletHost servletHost;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param endpoint
|
||||
* the given endpoint
|
||||
* @param servletHost
|
||||
* the given servlet host
|
||||
*/
|
||||
public CometServiceBindingProvider(final RuntimeEndpoint endpoint, final ServletHost servletHost) {
|
||||
this.endpoint = endpoint;
|
||||
this.servletHost = servletHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to start the provider.
|
||||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
ServletFactory.registerServlet(this.servletHost);
|
||||
final ComponentService service = this.endpoint.getService();
|
||||
final Interface serviceInterface = service.getInterfaceContract().getInterface();
|
||||
JavascriptGenerator.generateServiceProxy(service);
|
||||
for (final Operation operation : serviceInterface.getOperations()) {
|
||||
JavascriptGenerator.generateMethodProxy(service, operation);
|
||||
ServletFactory.registerOperation(this.endpoint, operation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to stop the provider.
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
ServletFactory.unregisterServlet(this.servletHost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceContract getBindingInterfaceContract() {
|
||||
return endpoint.getService().getInterfaceContract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOneWayInvocation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNativeAsync() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvokerAsyncResponse createAsyncResponseInvoker() {
|
||||
return new CometAsyncResponseInvoker(null, endpoint);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime;
|
||||
|
||||
import org.apache.tuscany.sca.host.http.ServletHost;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
import org.atmosphere.cpr.AtmosphereServlet;
|
||||
|
||||
/**
|
||||
* This class is used to create two servlets: one exposing all the comet
|
||||
* services, the other one exposing the javascript toolkit. Exposing all comet
|
||||
* services through a single servlet is needed as the browsers are undergone by
|
||||
* the two http connection limit so all comet services should send their
|
||||
* responses via the same http connection to the same client. Dispatching to the
|
||||
* corresponding endpoint and operation is done internally using Jersey RESTful
|
||||
* Web Services integration with the AtmosphereServlet. The Javascript toolkit
|
||||
* servlet is unique as it is not tied to any of the services - it offers a
|
||||
* global API.
|
||||
*/
|
||||
public final class ServletFactory {
|
||||
|
||||
/**
|
||||
* Init-param key for the AtmosphereServlet defining where to look for
|
||||
* Jersey classes.
|
||||
*/
|
||||
private static final String PACKAGE_KEY = "com.sun.jersey.config.property.packages";
|
||||
|
||||
/**
|
||||
* Package of the class handling dispatching to endpoints.
|
||||
*/
|
||||
private static final String PACKAGE_VALUE = "org.apache.tuscany.sca.binding.comet.runtime.handler";
|
||||
|
||||
/**
|
||||
* Package of the class handling Javascript toolkit retrieval.
|
||||
*/
|
||||
private static final String JS_PACKAGE_VALUE = "org.apache.tuscany.sca.binding.comet.runtime.javascript";
|
||||
|
||||
/**
|
||||
* Key in the ServletContext where the comet component context is stored.
|
||||
*/
|
||||
public static final String COMET_COMPONENT_CONTEXT_KEY = "org.apache.tuscany.sca.binding.comet.operations";
|
||||
|
||||
/**
|
||||
* Path where services will be exposed.
|
||||
*/
|
||||
public static final String PATH = "/tuscany-comet/*";
|
||||
|
||||
/**
|
||||
* Path where Javascript toolkit will be exposed.
|
||||
*/
|
||||
public static final String JS_PATH = "/org.apache.tuscany.sca.cometComponentContext.js/*";
|
||||
|
||||
/**
|
||||
* The servlet that is exposing the comet services.
|
||||
*/
|
||||
private static AtmosphereServlet cometServlet = null;
|
||||
|
||||
/**
|
||||
* The servlet that is exposing the Javascript toolkit.
|
||||
*/
|
||||
private static AtmosphereServlet javascriptServlet = null;
|
||||
|
||||
/**
|
||||
* Private constructor for the singleton class.
|
||||
*/
|
||||
private ServletFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called by CometServiceBindingProvider for each endpoint in order
|
||||
* to create the two singleton servlets.
|
||||
*
|
||||
* @param servletHost
|
||||
* the underlying servlet host
|
||||
*/
|
||||
public static synchronized void registerServlet(
|
||||
final ServletHost servletHost) {
|
||||
registerCometServlet(servletHost);
|
||||
registerJavascriptServlet(servletHost);
|
||||
}
|
||||
|
||||
private static void registerCometServlet(ServletHost servletHost) {
|
||||
if (ServletFactory.cometServlet == null) {
|
||||
ServletFactory.cometServlet = new AtmosphereServlet();
|
||||
ServletFactory.cometServlet.addInitParameter(
|
||||
ServletFactory.PACKAGE_KEY, ServletFactory.PACKAGE_VALUE);
|
||||
servletHost.addServletMapping(ServletFactory.PATH,
|
||||
ServletFactory.cometServlet);
|
||||
final CometComponentContext context = new CometComponentContext();
|
||||
ServletFactory.cometServlet.getServletContext().setAttribute(
|
||||
ServletFactory.COMET_COMPONENT_CONTEXT_KEY, context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerJavascriptServlet(ServletHost servletHost) {
|
||||
if (ServletFactory.javascriptServlet == null) {
|
||||
ServletFactory.javascriptServlet = new AtmosphereServlet();
|
||||
ServletFactory.javascriptServlet
|
||||
.addInitParameter(ServletFactory.PACKAGE_KEY,
|
||||
ServletFactory.JS_PACKAGE_VALUE);
|
||||
servletHost.addServletMapping(ServletFactory.JS_PATH,
|
||||
ServletFactory.javascriptServlet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called by CometServiceBindingProvider for each endpoint operation
|
||||
* in order to store all the operations the servlet will serve.
|
||||
*
|
||||
* @param endpoint
|
||||
* the endpoint
|
||||
* @param operation
|
||||
* the operation
|
||||
*/
|
||||
public static void registerOperation(final RuntimeEndpoint endpoint,
|
||||
final Operation operation) {
|
||||
final String url = "/" + endpoint.getService().getName() + "/"
|
||||
+ operation.getName();
|
||||
CometComponentContext context = (CometComponentContext) cometServlet
|
||||
.getServletContext().getAttribute(COMET_COMPONENT_CONTEXT_KEY);
|
||||
context.addEndpoint(url, endpoint);
|
||||
context.addOperation(url, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called by CometServiceBindingProvider for each endpoint operation
|
||||
* in order to remove the two servlets.
|
||||
*
|
||||
* @param servletHost
|
||||
* the underlying servlet host
|
||||
*/
|
||||
public static void unregisterServlet(final ServletHost servletHost) {
|
||||
synchronized (servletHost) {
|
||||
servletHost.removeServletMapping(ServletFactory.PATH);
|
||||
servletHost.removeServletMapping(ServletFactory.JS_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime.callback;
|
||||
|
||||
import org.oasisopen.sca.annotation.Remotable;
|
||||
|
||||
@Remotable
|
||||
public interface CometCallback {
|
||||
|
||||
void sendResponse(Object response);
|
||||
|
||||
boolean isClientConnected();
|
||||
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime.handler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
|
||||
import org.apache.tuscany.sca.assembly.EndpointReference;
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.CometComponentContext;
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.CometMessageContext;
|
||||
import org.apache.tuscany.sca.binding.comet.runtime.ServletFactory;
|
||||
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointImpl;
|
||||
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointReferenceImpl;
|
||||
import org.apache.tuscany.sca.core.invocation.impl.MessageImpl;
|
||||
import org.apache.tuscany.sca.interfacedef.DataType;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import org.apache.tuscany.sca.invocation.Message;
|
||||
import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
|
||||
import org.atmosphere.annotation.Broadcast;
|
||||
import org.atmosphere.cpr.Broadcaster;
|
||||
import org.atmosphere.cpr.DefaultBroadcaster;
|
||||
import org.atmosphere.jersey.SuspendResponse;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.sun.jersey.spi.container.servlet.PerSession;
|
||||
|
||||
/**
|
||||
* Class serving calls coming for comet services and operations.
|
||||
*/
|
||||
@Path("/")
|
||||
@Produces("text/html;charset=ISO-8859-1")
|
||||
@PerSession
|
||||
public class CometBindingHandler {
|
||||
|
||||
/**
|
||||
* The object used to suspend the response and send async responses back to
|
||||
* client.
|
||||
*/
|
||||
private Broadcaster broadcaster;
|
||||
|
||||
/**
|
||||
* JSON converter.
|
||||
*/
|
||||
private Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* The underlying servlet context.
|
||||
*/
|
||||
@Context
|
||||
private ServletContext sc;
|
||||
|
||||
@Context
|
||||
private HttpServletRequest request;
|
||||
|
||||
private CometComponentContext context;
|
||||
|
||||
/**
|
||||
* Method called at comet connect time. This suspends the response and keeps
|
||||
* the connection opened.
|
||||
*
|
||||
* @return the suspended response
|
||||
*/
|
||||
@GET
|
||||
public SuspendResponse<String> connect() {
|
||||
System.out.println("-- connect -- Session Id: " + request.getSession().getId());
|
||||
if (broadcaster == null) {
|
||||
broadcaster = new DefaultBroadcaster();
|
||||
context = (CometComponentContext) sc.getAttribute(ServletFactory.COMET_COMPONENT_CONTEXT_KEY);
|
||||
}
|
||||
return new SuspendResponse.SuspendResponseBuilder<String>().broadcaster(this.broadcaster).outputComments(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called on service calls.
|
||||
*
|
||||
* @param service
|
||||
* service called
|
||||
* @param method
|
||||
* operation called
|
||||
* @param callbackMethod
|
||||
* the callback method from Javascript
|
||||
* @param jsonData
|
||||
* arguments for the method sent as JSON array
|
||||
* @return object used by the Broadcaster to send response through the
|
||||
* persisted connection
|
||||
* @throws InvocationTargetException
|
||||
* if problems occur at service invocation
|
||||
*/
|
||||
@POST
|
||||
@Path("/{service}/{method}")
|
||||
@Broadcast
|
||||
public void handleRequest(@PathParam("service") final String service, @PathParam("method") final String method,
|
||||
@FormParam("callback") final String callbackMethod, @FormParam("params") final String jsonData)
|
||||
throws InvocationTargetException {
|
||||
System.out.println("-- handleRequest -- Session Id: " + request.getSession().getId());
|
||||
final String url = "/" + service + "/" + method;
|
||||
final RuntimeEndpoint wire = context.getEndpoint(url);
|
||||
final Operation operation = context.getOperation(url);
|
||||
|
||||
final Object[] args = decodeJsonDataForOperation(jsonData, operation);
|
||||
Message msg = createMessageWithMockedCometReference(args, callbackMethod);
|
||||
Object response = wire.invoke(operation, args);
|
||||
System.out.println("Response: " + gson.toJson(response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert request parameters from JSON to operation parameter types.
|
||||
*
|
||||
* @param jsonData
|
||||
* @param operation
|
||||
* @return
|
||||
*/
|
||||
private Object[] decodeJsonDataForOperation(String jsonData, Operation operation) {
|
||||
Object[] args = new Object[operation.getInputType().getLogical().size()];
|
||||
final String[] json = this.parseArray(jsonData);
|
||||
int index = 0;
|
||||
// convert each argument to the corresponding class
|
||||
for (final DataType<?> dataType : operation.getInputType().getLogical()) {
|
||||
args[index] = this.gson.fromJson(json[index], dataType.getPhysical());
|
||||
index++;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the message to be sent with a mocked EndpointReference in the
|
||||
* 'from' field as the request comes from a browser (there is no actual
|
||||
* comet reference running in a controlled environment).
|
||||
*
|
||||
* @param args
|
||||
* @param callbackMethod
|
||||
* @return
|
||||
*/
|
||||
private Message createMessageWithMockedCometReference(Object[] args, String callbackMethod) {
|
||||
Message msg = new MessageImpl();
|
||||
msg.setBody(args);
|
||||
CometMessageContext messageContext = new CometMessageContext(this, callbackMethod);
|
||||
msg.setBindingContext(messageContext);
|
||||
EndpointReference re = new RuntimeEndpointReferenceImpl();
|
||||
re.setCallbackEndpoint(new RuntimeEndpointImpl());
|
||||
msg.setFrom(re);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the JSON array containing the arguments for the method call in
|
||||
* order to avoid converting JSON to Object[]. Converting each object
|
||||
* separately to it's corresponding type avoids type mismatch problems at
|
||||
* service invocation.
|
||||
*
|
||||
* @param jsonArray
|
||||
* the JSON array
|
||||
* @return an array of JSON formatted objects
|
||||
*/
|
||||
private String[] parseArray(final String jsonArray) {
|
||||
final List<String> objects = new ArrayList<String>();
|
||||
int bracketNum = 0;
|
||||
int parNum = 0;
|
||||
int startPos = 1;
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
switch (jsonArray.charAt(i)) {
|
||||
case '{':
|
||||
bracketNum++;
|
||||
break;
|
||||
case '}':
|
||||
bracketNum--;
|
||||
break;
|
||||
case '[':
|
||||
parNum++;
|
||||
break;
|
||||
case ']':
|
||||
parNum--;
|
||||
break;
|
||||
case ',':
|
||||
if ((bracketNum == 0) && (parNum == 1)) {
|
||||
objects.add(jsonArray.substring(startPos, i));
|
||||
startPos = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add last object
|
||||
objects.add(jsonArray.substring(startPos, jsonArray.length() - 1));
|
||||
return objects.toArray(new String[] {});
|
||||
}
|
||||
|
||||
public void respondToClient(String callbackMethod, Object response) {
|
||||
broadcaster.broadcast(callbackMethod + "($.secureEvalJSON('" + this.gson.toJson(response) + "'))");
|
||||
}
|
||||
|
||||
public boolean isClientConnected() {
|
||||
return !broadcaster.getAtmosphereResources().isEmpty();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.binding.comet.runtime.javascript;
|
||||
|
||||
import org.apache.tuscany.sca.assembly.ComponentService;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
|
||||
/**
|
||||
* This class generates proxies for the comet services.
|
||||
*/
|
||||
public class JavascriptGenerator {
|
||||
|
||||
/**
|
||||
* Namespace for the Tuscany Comet Javascript toolkit.
|
||||
*/
|
||||
public static final String JS_NAMESPACE = "SCA";
|
||||
|
||||
/**
|
||||
* Name for the SCA component context.
|
||||
*/
|
||||
private static final String COMPONENT_CONTEXT = "this.CometComponentContext";
|
||||
|
||||
/**
|
||||
* Name for the object performing comet specific tasks.
|
||||
*/
|
||||
private static final String TUSCANY_COMET = "SCA.TuscanyComet";
|
||||
|
||||
/**
|
||||
* Generated Javascript.
|
||||
*/
|
||||
private static StringBuffer javascript = new StringBuffer();
|
||||
|
||||
/**
|
||||
* Default constructor for utility class.
|
||||
*/
|
||||
private JavascriptGenerator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the generated Javascript.
|
||||
*
|
||||
* @return the generated Javascript
|
||||
*/
|
||||
public static StringBuffer getJavascript() {
|
||||
return JavascriptGenerator.javascript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the proxy for a service.
|
||||
*
|
||||
* @param service the service for which generation is performed
|
||||
*/
|
||||
public static void generateServiceProxy(final ComponentService service) {
|
||||
JavascriptGenerator.javascript.append(JavascriptGenerator.COMPONENT_CONTEXT + "."
|
||||
+ service.getName()
|
||||
+ " = new Object();\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the method inside the service proxy for the specified
|
||||
* operation.
|
||||
*
|
||||
* @param service the service containing the operation
|
||||
* @param operation the operation
|
||||
*/
|
||||
public static void generateMethodProxy(final ComponentService service, final Operation operation) {
|
||||
JavascriptGenerator.javascript.append(JavascriptGenerator.COMPONENT_CONTEXT + "."
|
||||
+ service.getName()
|
||||
+ "."
|
||||
+ operation.getName()
|
||||
+ " = function(");
|
||||
for (int i = 0; i < operation.getInputType().getLogical().size(); i++) {
|
||||
JavascriptGenerator.javascript.append("p" + i + ", ");
|
||||
}
|
||||
JavascriptGenerator.javascript.append("callbackMethod) {\n");
|
||||
// send method argumets as JSON array
|
||||
JavascriptGenerator.javascript.append(" var params = [];\n");
|
||||
for (int i = 0; i < operation.getInputType().getLogical().size(); i++) {
|
||||
JavascriptGenerator.javascript.append(" params.push(p" + i + ");\n");
|
||||
}
|
||||
JavascriptGenerator.javascript.append(" " + JavascriptGenerator.TUSCANY_COMET
|
||||
+ ".callAsync('"
|
||||
+ service.getName()
|
||||
+ "/"
|
||||
+ operation.getName()
|
||||
+ "', $.toJSON(params), callbackMethod);\n");
|
||||
JavascriptGenerator.javascript.append("}\n");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.binding.comet.runtime.javascript;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
/**
|
||||
* Class serving the calls performed to retrieve the Javascript toolkit.
|
||||
*/
|
||||
@Path("/")
|
||||
@Produces("text/javascript")
|
||||
public class JavascriptResource {
|
||||
|
||||
/**
|
||||
* Dependencies for the Tuscany Comet Javascript API.
|
||||
*/
|
||||
private static final String[] DEPENDENCIES = {"/jquery.atmosphere.js", "/jquery.json-2.2.min.js",
|
||||
"/cometComponentContext.js"};
|
||||
|
||||
/**
|
||||
* Method called when the Javascript toolkit is requested.
|
||||
*
|
||||
* @return InputStream containing the Javascript code.
|
||||
*/
|
||||
@GET
|
||||
public InputStream getJavascript() {
|
||||
InputStream stream = null;
|
||||
// add dependencies in the specified order
|
||||
for (final String dependency : JavascriptResource.DEPENDENCIES) {
|
||||
if (stream == null) {
|
||||
stream = this.getClass().getResourceAsStream(dependency);
|
||||
} else {
|
||||
stream = new SequenceInputStream(stream, this.getClass().getResourceAsStream(dependency));
|
||||
}
|
||||
}
|
||||
// add generated proxies
|
||||
final String generatedJs = JavascriptGenerator.getJavascript().toString() + "\n}";
|
||||
return new SequenceInputStream(stream, new ByteArrayInputStream(generatedJs.getBytes()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT 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 binding extension
|
||||
org.apache.tuscany.sca.binding.comet.runtime.CometBindingProviderFactory;model=org.apache.tuscany.sca.binding.comet.CometBinding
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
var SCA = new function() {
|
||||
|
||||
this.TuscanyComet = {
|
||||
appUrl: 'tuscany-comet',
|
||||
connectedEndpoint : null,
|
||||
connect : function(transport) {
|
||||
$.atmosphere.subscribe(document.location.toString() + this.appUrl,
|
||||
this.callback,
|
||||
$.atmosphere.request = {
|
||||
transport : transport
|
||||
});
|
||||
this.connectedEndpoint = $.atmosphere.response;
|
||||
},
|
||||
callAsync : function(url, params, callbackMethod) {
|
||||
this.connectedEndpoint.push(document.location.toString()
|
||||
+ this.appUrl + '/' + url,
|
||||
null,
|
||||
$.atmosphere.request = {
|
||||
method : 'POST',
|
||||
data : 'callback=' + callbackMethod.name + '¶ms=' + params
|
||||
});
|
||||
},
|
||||
callback : function(response) {
|
||||
eval(response.responseBody);
|
||||
}
|
||||
};
|
||||
|
||||
this.CometComponentContext = new Object();
|
|
@ -0,0 +1,534 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
jQuery.atmosphere = function()
|
||||
{
|
||||
var activeRequest;
|
||||
$(window).unload(function()
|
||||
{
|
||||
if (activeRequest)
|
||||
activeRequest.abort();
|
||||
});
|
||||
|
||||
return {
|
||||
version : 0.7,
|
||||
response : {
|
||||
status: 200,
|
||||
responseBody : '',
|
||||
headers : [],
|
||||
state : "messageReceived",
|
||||
transport : "polling",
|
||||
push : [],
|
||||
error: null,
|
||||
id : 0
|
||||
},
|
||||
|
||||
request : {},
|
||||
logLevel : 'info',
|
||||
callbacks: [],
|
||||
activeTransport : null,
|
||||
websocket : null,
|
||||
killHiddenIFrame : null,
|
||||
|
||||
subscribe: function(url, callback, request)
|
||||
{
|
||||
jQuery.atmosphere.request = jQuery.extend({
|
||||
timeout: 300000,
|
||||
method: 'GET',
|
||||
headers: {},
|
||||
contentType : "text/html;charset=ISO-8859-1",
|
||||
cache: true,
|
||||
async: true,
|
||||
ifModified: false,
|
||||
callback: null,
|
||||
dataType: '',
|
||||
url : url,
|
||||
data : '',
|
||||
suspend : true,
|
||||
maxRequest : 60,
|
||||
lastIndex : 0,
|
||||
logLevel : 'info',
|
||||
requestCount : 0,
|
||||
fallbackTransport : 'streaming',
|
||||
transport : 'long-polling'
|
||||
|
||||
}, request);
|
||||
|
||||
logLevel = jQuery.atmosphere.request.logLevel || 'info';
|
||||
if (callback != null) {
|
||||
jQuery.atmosphere.addCallback(callback);
|
||||
jQuery.atmosphere.request.callback = callback;
|
||||
}
|
||||
|
||||
if (jQuery.atmosphere.request.transport != jQuery.atmosphere.activeTransport) {
|
||||
jQuery.atmosphere.closeSuspendedConnection();
|
||||
}
|
||||
jQuery.atmosphere.activeTransport = jQuery.atmosphere.request.transport;
|
||||
|
||||
if (jQuery.atmosphere.request.transport != 'websocket') {
|
||||
jQuery.atmosphere.executeRequest();
|
||||
} else if (jQuery.atmosphere.request.transport == 'websocket') {
|
||||
if (!window.WebSocket) {
|
||||
jQuery.atmosphere.log(logLevel, ["Websocket is not supported, using request.fallbackTransport"]);
|
||||
jQuery.atmosphere.request.transport = jQuery.atmosphere.request.fallbackTransport;
|
||||
jQuery.atmosphere.executeRequest();
|
||||
}
|
||||
else {
|
||||
jQuery.atmosphere.executeWebSocket();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Always make sure one transport is used, not two at the same time except for Websocket.
|
||||
*/
|
||||
closeSuspendedConnection : function () {
|
||||
if (activeRequest != null) {
|
||||
activeRequest.abort();
|
||||
}
|
||||
|
||||
if (jQuery.atmosphere.websocket != null) {
|
||||
jQuery.atmosphere.websocket.close();
|
||||
jQuery.atmosphere.websocket = null;
|
||||
}
|
||||
},
|
||||
|
||||
executeRequest: function()
|
||||
{
|
||||
|
||||
if (jQuery.atmosphere.request.transport == 'streaming') {
|
||||
if ($.browser.msie) {
|
||||
jQuery.atmosphere.ieStreaming();
|
||||
return;
|
||||
} else if ((typeof window.addEventStream) == 'function') {
|
||||
jQuery.atmosphere.operaStreaming();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (jQuery.atmosphere.request.requestCount++ < jQuery.atmosphere.request.maxRequest) {
|
||||
jQuery.atmosphere.response.push = function (url)
|
||||
{
|
||||
jQuery.atmosphere.request.callback = null;
|
||||
jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
|
||||
};
|
||||
|
||||
var request = jQuery.atmosphere.request;
|
||||
var response = jQuery.atmosphere.response;
|
||||
if (request.transport != 'polling') {
|
||||
response.transport = request.transport;
|
||||
}
|
||||
|
||||
var ajaxRequest;
|
||||
var error = false;
|
||||
if ($.browser.msie) {
|
||||
var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]
|
||||
for (var i = 0; i < activexmodes.length; i++) {
|
||||
try {
|
||||
ajaxRequest = new ActiveXObject(activexmodes[i])
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
}
|
||||
} else if (window.XMLHttpRequest) {
|
||||
ajaxRequest = new XMLHttpRequest();
|
||||
}
|
||||
|
||||
if (request.suspend) {
|
||||
activeRequest = ajaxRequest;
|
||||
}
|
||||
|
||||
ajaxRequest.open(request.method, request.url, true);
|
||||
ajaxRequest.setRequestHeader("X-Atmosphere-Framework", jQuery.atmosphere.version);
|
||||
ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport);
|
||||
ajaxRequest.setRequestHeader("X-Cache-Date", new Date());
|
||||
|
||||
if (!$.browser.msie) {
|
||||
ajaxRequest.onerror = function()
|
||||
{
|
||||
error = true;
|
||||
try {
|
||||
response.status = XMLHttpRequest.status;
|
||||
}
|
||||
catch(e) {
|
||||
response.status = 404;
|
||||
}
|
||||
|
||||
response.state = "error";
|
||||
jQuery.atmosphere.invokeCallback(response);
|
||||
ajaxRequest.abort();
|
||||
activeRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
ajaxRequest.onreadystatechange = function()
|
||||
{
|
||||
var junkForWebkit = false;
|
||||
var update = false;
|
||||
if (ajaxRequest.readyState == 4) {
|
||||
jQuery.atmosphere.request = request;
|
||||
if (request.suspend && ajaxRequest.status == 200) {
|
||||
jQuery.atmosphere.executeRequest();
|
||||
}
|
||||
|
||||
if ($.browser.msie) {
|
||||
update = true;
|
||||
}
|
||||
} else if (!$.browser.msie && ajaxRequest.readyState == 3 && ajaxRequest.status == 200) {
|
||||
update = true;
|
||||
} else {
|
||||
clearTimeout(request.id);
|
||||
}
|
||||
|
||||
if (update) {
|
||||
if (request.transport == 'streaming') {
|
||||
response.responseBody = ajaxRequest.responseText.substring(request.lastIndex, ajaxRequest.responseText.length);
|
||||
request.lastIndex = ajaxRequest.responseText.length;
|
||||
|
||||
if (response.responseBody.indexOf("<!--") != -1) {
|
||||
junkForWebkit = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
response.responseBody = ajaxRequest.responseText;
|
||||
}
|
||||
|
||||
if (response.responseBody.indexOf("parent.callback") != -1) {
|
||||
var start = response.responseBody.indexOf("('") + 2;
|
||||
var end = response.responseBody.indexOf("')");
|
||||
response.responseBody = response.responseBody.substring(start, end);
|
||||
}
|
||||
|
||||
if (junkForWebkit) return;
|
||||
|
||||
try {
|
||||
response.status = ajaxRequest.status;
|
||||
response.headers = ajaxRequest.getAllResponseHeaders();
|
||||
}
|
||||
catch(e) {
|
||||
response.status = 404;
|
||||
}
|
||||
|
||||
if (request.suspend) {
|
||||
response.state = "messageReceived";
|
||||
} else {
|
||||
response.state = "messagePublished";
|
||||
}
|
||||
jQuery.atmosphere.invokeCallback(response);
|
||||
}
|
||||
}
|
||||
ajaxRequest.send(request.data);
|
||||
|
||||
if (request.suspend) {
|
||||
request.id = setTimeout(function()
|
||||
{
|
||||
ajaxRequest.abort();
|
||||
jQuery.atmosphere.subscribe(request.url, null, request);
|
||||
|
||||
}, request.timeout);
|
||||
}
|
||||
} else {
|
||||
jQuery.atmosphere.log(logLevel, ["Max re-connection reached."]);
|
||||
}
|
||||
},
|
||||
|
||||
operaStreaming: function()
|
||||
{
|
||||
|
||||
var url = jQuery.atmosphere.request.url;
|
||||
var es = document.createElement('event-source');
|
||||
var response = jQuery.atmosphere.response;
|
||||
|
||||
jQuery.atmosphere.response.push = function (url)
|
||||
{
|
||||
jQuery.atmosphere.request.transport = 'polling';
|
||||
jQuery.atmosphere.request.callback = null;
|
||||
jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
|
||||
};
|
||||
|
||||
es.setAttribute('src', url);
|
||||
// without this check opera 9.5 would make two connections.
|
||||
if (opera.version() < 9.5) {
|
||||
document.body.appendChild(es);
|
||||
}
|
||||
|
||||
var operaCallback = function (event) {
|
||||
if (event.data) {
|
||||
var junkForWebkit = false;
|
||||
|
||||
response.responseBody = event.data;
|
||||
if (event.data.indexOf("<!--") != -1) {
|
||||
junkForWebkit = true;
|
||||
}
|
||||
|
||||
if (response.responseBody.indexOf("parent.callback") != -1) {
|
||||
var start = response.responseBody.indexOf("('") + 2;
|
||||
var end = response.responseBody.indexOf("')");
|
||||
response.responseBody = response.responseBody.substring(start, end);
|
||||
}
|
||||
|
||||
if (junkForWebkit) return;
|
||||
|
||||
response.state = "messageReceived";
|
||||
jQuery.atmosphere.invokeCallback(response);
|
||||
}
|
||||
};
|
||||
|
||||
es.addEventListener('payload', operaCallback, false);
|
||||
|
||||
},
|
||||
|
||||
ieStreaming : function()
|
||||
{
|
||||
var url = jQuery.atmosphere.request.url;
|
||||
jQuery.atmosphere.response.push = function (url)
|
||||
{
|
||||
jQuery.atmosphere.request.transport = 'polling';
|
||||
jQuery.atmosphere.request.callback = null;
|
||||
jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
|
||||
};
|
||||
|
||||
transferDoc = new ActiveXObject("htmlfile");
|
||||
transferDoc.open();
|
||||
transferDoc.close();
|
||||
var ifrDiv = transferDoc.createElement("div");
|
||||
transferDoc.body.appendChild(ifrDiv);
|
||||
ifrDiv.innerHTML = "<iframe src='" + url + "'></iframe>";
|
||||
transferDoc.parentWindow.callback = jQuery.atmosphere.streamingCallback;
|
||||
}
|
||||
,
|
||||
|
||||
streamingCallback : function(args)
|
||||
{
|
||||
var response = jQuery.atmosphere.response;
|
||||
response.transport = "streaming";
|
||||
response.status = 200;
|
||||
response.responseBody = args;
|
||||
response.state = "messageReceived";
|
||||
|
||||
jQuery.atmosphere.invokeCallback(response);
|
||||
}
|
||||
,
|
||||
|
||||
executeWebSocket : function()
|
||||
{
|
||||
var request = jQuery.atmosphere.request;
|
||||
jQuery.atmosphere.log(logLevel, ["Invoking executeWebSocket"]);
|
||||
jQuery.atmosphere.response.transport = "websocket";
|
||||
var url = jQuery.atmosphere.request.url;
|
||||
var callback = jQuery.atmosphere.request.callback;
|
||||
var location = url.replace('http:', 'ws:').replace('https:', 'wss:');
|
||||
|
||||
var websocket = new WebSocket(location);
|
||||
jQuery.atmosphere.websocket = websocket;
|
||||
|
||||
jQuery.atmosphere.response.push = function (url)
|
||||
{
|
||||
var data;
|
||||
var ws = jQuery.atmosphere.websocket;
|
||||
try {
|
||||
data = jQuery.atmosphere.request.data;
|
||||
ws.send(jQuery.atmosphere.request.data);
|
||||
} catch (e) {
|
||||
jQuery.atmosphere.log(logLevel, ["Websocket failed. Downgrading to Comet and resending " + data]);
|
||||
// Websocket is not supported, reconnect using the fallback transport.
|
||||
request.transport = request.fallbackTransport;
|
||||
jQuery.atmosphere.request = request;
|
||||
jQuery.atmosphere.executeRequest();
|
||||
|
||||
// Repost the data.
|
||||
jQuery.atmosphere.request.suspend = false;
|
||||
jQuery.atmosphere.request.method = 'POST';
|
||||
jQuery.atmosphere.request.data = data;
|
||||
jQuery.atmosphere.response.state = 'messageReceived';
|
||||
jQuery.atmosphere.response.transport = request.fallbackTransport;
|
||||
jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
|
||||
|
||||
ws.onclose = function(message) {
|
||||
}
|
||||
ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
websocket.onopen = function(message)
|
||||
{
|
||||
jQuery.atmosphere.response.state = 'openning';
|
||||
jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
|
||||
};
|
||||
|
||||
websocket.onmessage = function(message)
|
||||
{
|
||||
var data = message.data;
|
||||
if (data.indexOf("parent.callback") != -1) {
|
||||
var start = data.indexOf("('") + 2;
|
||||
var end = data.indexOf("')");
|
||||
jQuery.atmosphere.response.responseBody = data.substring(start, end);
|
||||
}
|
||||
else {
|
||||
jQuery.atmosphere.response.responseBody = data;
|
||||
}
|
||||
jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
|
||||
};
|
||||
|
||||
websocket.onerror = function(message)
|
||||
{
|
||||
jQuery.atmosphere.response.state = 'error';
|
||||
jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
|
||||
};
|
||||
|
||||
websocket.onclose = function(message)
|
||||
{
|
||||
jQuery.atmosphere.response.state = 'closed';
|
||||
jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
|
||||
};
|
||||
}
|
||||
,
|
||||
|
||||
addCallback: function(func)
|
||||
{
|
||||
if (jQuery.inArray(func, jQuery.atmosphere.callbacks) == -1) {
|
||||
jQuery.atmosphere.callbacks.push(func);
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
removeCallback: function(func)
|
||||
{
|
||||
if (jQuery.inArray(func, jQuery.atmosphere.callbacks) != -1) {
|
||||
jQuery.atmosphere.callbacks.splice(index);
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
invokeCallback: function(response)
|
||||
{
|
||||
var call = function (index, func)
|
||||
{
|
||||
func(response);
|
||||
};
|
||||
|
||||
jQuery.atmosphere.log(logLevel, ["Invoking " + jQuery.atmosphere.callbacks.length + " callbacks"]);
|
||||
if (jQuery.atmosphere.callbacks.length > 0) {
|
||||
jQuery.each(jQuery.atmosphere.callbacks, call);
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
publish: function(url, callback, request)
|
||||
{
|
||||
jQuery.atmosphere.request = jQuery.extend({
|
||||
connected: false,
|
||||
timeout: 60000,
|
||||
method: 'POST',
|
||||
headers: {},
|
||||
cache: true,
|
||||
async: true,
|
||||
ifModified: false,
|
||||
callback: null,
|
||||
dataType: '',
|
||||
url : url,
|
||||
data : '',
|
||||
suspend : false,
|
||||
maxRequest : 60,
|
||||
logLevel : 'info',
|
||||
requestCount : 0,
|
||||
transport: 'polling'
|
||||
}, request);
|
||||
|
||||
if (callback != null) {
|
||||
jQuery.atmosphere.addCallback(callback);
|
||||
}
|
||||
jQuery.atmosphere.request.transport = 'polling';
|
||||
if (jQuery.atmosphere.request.transport != 'websocket') {
|
||||
jQuery.atmosphere.executeRequest();
|
||||
} else if (jQuery.atmosphere.request.transport == 'websocket') {
|
||||
if (!window.WebSocket) {
|
||||
alert("WebSocket not supported by this browser");
|
||||
}
|
||||
else {
|
||||
jQuery.atmosphere.executeWebSocket();
|
||||
}
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
unload: function (arg) {
|
||||
if (window.addEventListener) {
|
||||
document.addEventListener('unload', arg, false);
|
||||
window.addEventListener('unload', arg, false);
|
||||
} else { // IE
|
||||
document.attachEvent('onunload', arg);
|
||||
window.attachEvent('onunload', arg);
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
kill_load_bar : function() {
|
||||
if (jQuery.atmosphere.killHiddenIFrame == null) {
|
||||
jQuery.atmosphere.killHiddenIFrame = document.createElement('iframe');
|
||||
var ifr = jQuery.atmosphere.killHiddenIFrame;
|
||||
ifr.style.display = 'block';
|
||||
ifr.style.width = '0';
|
||||
ifr.style.height = '0';
|
||||
ifr.style.border = '0';
|
||||
ifr.style.margin = '0';
|
||||
ifr.style.padding = '0';
|
||||
ifr.style.overflow = 'hidden';
|
||||
ifr.style.visibility = 'hidden';
|
||||
}
|
||||
document.body.appendChild(ifr);
|
||||
ifr.src = 'about:blank';
|
||||
document.body.removeChild(ifr);
|
||||
}
|
||||
,
|
||||
|
||||
log: function (level, args)
|
||||
{
|
||||
if (window.console)
|
||||
{
|
||||
var logger = window.console[level];
|
||||
if (typeof logger == 'function')
|
||||
{
|
||||
logger.apply(window.console, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
warn: function()
|
||||
{
|
||||
log('warn', arguments);
|
||||
}
|
||||
,
|
||||
|
||||
|
||||
info :function()
|
||||
{
|
||||
if (logLevel != 'warn')
|
||||
{
|
||||
log('info', arguments);
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
debug: function()
|
||||
{
|
||||
if (logLevel == 'debug')
|
||||
{
|
||||
log('debug', arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
();
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
(function($){$.toJSON=function(o)
|
||||
{if(typeof(JSON)=='object'&&JSON.stringify)
|
||||
return JSON.stringify(o);var type=typeof(o);if(o===null)
|
||||
return"null";if(type=="undefined")
|
||||
return undefined;if(type=="number"||type=="boolean")
|
||||
return o+"";if(type=="string")
|
||||
return $.quoteString(o);if(type=='object')
|
||||
{if(typeof o.toJSON=="function")
|
||||
return $.toJSON(o.toJSON());if(o.constructor===Date)
|
||||
{var month=o.getUTCMonth()+1;if(month<10)month='0'+month;var day=o.getUTCDate();if(day<10)day='0'+day;var year=o.getUTCFullYear();var hours=o.getUTCHours();if(hours<10)hours='0'+hours;var minutes=o.getUTCMinutes();if(minutes<10)minutes='0'+minutes;var seconds=o.getUTCSeconds();if(seconds<10)seconds='0'+seconds;var milli=o.getUTCMilliseconds();if(milli<100)milli='0'+milli;if(milli<10)milli='0'+milli;return'"'+year+'-'+month+'-'+day+'T'+
|
||||
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
|
||||
if(o.constructor===Array)
|
||||
{var ret=[];for(var i=0;i<o.length;i++)
|
||||
ret.push($.toJSON(o[i])||"null");return"["+ret.join(",")+"]";}
|
||||
var pairs=[];for(var k in o){var name;var type=typeof k;if(type=="number")
|
||||
name='"'+k+'"';else if(type=="string")
|
||||
name=$.quoteString(k);else
|
||||
continue;if(typeof o[k]=="function")
|
||||
continue;var val=$.toJSON(o[k]);pairs.push(name+":"+val);}
|
||||
return"{"+pairs.join(", ")+"}";}};$.evalJSON=function(src)
|
||||
{if(typeof(JSON)=='object'&&JSON.parse)
|
||||
return JSON.parse(src);return eval("("+src+")");};$.secureEvalJSON=function(src)
|
||||
{if(typeof(JSON)=='object'&&JSON.parse)
|
||||
return JSON.parse(src);var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
|
||||
return eval("("+src+")");else
|
||||
throw new SyntaxError("Error parsing JSON, source is not valid.");};$.quoteString=function(string)
|
||||
{if(string.match(_escapeable))
|
||||
{return'"'+string.replace(_escapeable,function(a)
|
||||
{var c=_meta[a];if(typeof c==='string')return c;c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
|
||||
return'"'+string+'"';};var _escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var _meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};})(jQuery);
|
|
@ -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.test;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.tuscany.sca.http.jetty.JettyServer;
|
||||
import org.apache.tuscany.sca.node.Contribution;
|
||||
import org.apache.tuscany.sca.node.ContributionLocationHelper;
|
||||
import org.apache.tuscany.sca.node.Node;
|
||||
import org.apache.tuscany.sca.node.NodeFactory;
|
||||
|
||||
/**
|
||||
* Test case for the comet binding.
|
||||
*/
|
||||
public class CometTestCase extends TestCase {
|
||||
|
||||
/**
|
||||
* Test consisting in starting up a node containing services exposed via the
|
||||
* comet binding.
|
||||
*/
|
||||
public void testComet() {
|
||||
JettyServer.portDefault = 8085;
|
||||
try {
|
||||
final String location = ContributionLocationHelper.getContributionLocation("test.composite");
|
||||
final Node node = NodeFactory.newInstance().createNode("test.composite", new Contribution("c1", location));
|
||||
node.start();
|
||||
// System.out.println("Press any key to stop the node.");
|
||||
// System.in.read();
|
||||
node.stop();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.tuscany.sca.test;
|
||||
|
||||
import org.oasisopen.sca.annotation.Remotable;
|
||||
|
||||
@Remotable
|
||||
public interface StockService {
|
||||
|
||||
String getQuotes();
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.tuscany.sca.test;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
import org.oasisopen.sca.annotation.Service;
|
||||
|
||||
@Service(StockService.class)
|
||||
public class StockServiceImpl implements StockService {
|
||||
|
||||
public static final int MAX_VALUE = 1000;
|
||||
private final Random random = new Random(new Date().getTime());
|
||||
|
||||
@Override
|
||||
public String getQuotes() {
|
||||
final Double value = Math.abs(this.random.nextDouble() * this.random.nextInt(StockServiceImpl.MAX_VALUE));
|
||||
return "ASF" + "#" + Double.valueOf(new DecimalFormat("#.##").format(value));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
-->
|
||||
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
|
||||
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
|
||||
targetNamespace="http://samples"
|
||||
name="Stock">
|
||||
|
||||
<component name="test">
|
||||
<implementation.java class="org.apache.tuscany.sca.test.StockServiceImpl"/>
|
||||
<service name="StockService">
|
||||
<interface.java interface="org.apache.tuscany.sca.test.StockService"/>
|
||||
<tuscany:binding.comet/>
|
||||
</service>
|
||||
</component>
|
||||
|
||||
</composite>
|
Loading…
Add table
Reference in a new issue