Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: resty-gwt/resty-gwt
base: a519927e7f
...
head fork: resty-gwt/resty-gwt
compare: cors
  • 8 commits
  • 25 files changed
  • 0 commit comments
  • 2 contributors
Showing with 1,467 additions and 3 deletions.
  1. +3 −0  restygwt/src/main/java/org/fusesource/restygwt/RestyGWT.gwt.xml
  2. +24 −0 restygwt/src/main/java/org/fusesource/restygwt/client/DirectRestService.java
  3. +17 −0 restygwt/src/main/java/org/fusesource/restygwt/client/Method.java
  4. +42 −0 restygwt/src/main/java/org/fusesource/restygwt/client/REST.java
  5. +34 −0 restygwt/src/main/java/org/fusesource/restygwt/client/callback/CallbackAware.java
  6. +57 −0 restygwt/src/main/java/org/fusesource/restygwt/client/cors/CORS.java
  7. +104 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/CORSAnnotationResolver.java
  8. +87 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestBaseSourceCreator.java
  9. +155 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceClassCreator.java
  10. +35 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceGenerator.java
  11. +108 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceInterfaceClassCreator.java
  12. +124 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/util/AnnotationCopyUtil.java
  13. +58 −0 restygwt/src/main/java/org/fusesource/restygwt/rebind/util/OnceFirstIterator.java
  14. +52 −0 restygwt/src/test/java/org/fusesource/restygwt/DirectRestServiceTestGwt.gwt.xml
  15. +3 −0  restygwt/src/test/java/org/fusesource/restygwt/Event.gwt.xml
  16. +2 −0  restygwt/src/test/java/org/fusesource/restygwt/GwtAnnotationResolverTestSuite.java
  17. +2 −0  restygwt/src/test/java/org/fusesource/restygwt/GwtCompleteTestSuite.java
  18. +40 −0 restygwt/src/test/java/org/fusesource/restygwt/client/basic/DirectExampleService.java
  19. +88 −0 restygwt/src/test/java/org/fusesource/restygwt/client/basic/DirectRestServiceTestGwt.java
  20. +3 −3 restygwt/src/test/java/org/fusesource/restygwt/client/basic/QueryParamTestGwt.java
  21. +235 −0 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSAnnotationResolverTestGwt.java
  22. +43 −0 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceClassLevelOnly.java
  23. +46 −0 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceMethodLevelOnly.java
  24. +47 −0 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceMixedLevels.java
  25. +58 −0 restygwt/src/test/java/org/fusesource/restygwt/server/basic/DirectServiceTestGwtServlet.java
View
3  restygwt/src/main/java/org/fusesource/restygwt/RestyGWT.gwt.xml
@@ -38,6 +38,9 @@
<generate-with class="org.fusesource.restygwt.rebind.JsonEncoderDecoderGenerator">
<when-type-assignable class="org.fusesource.restygwt.client.JsonEncoderDecoder" />
</generate-with>
+ <generate-with class="org.fusesource.restygwt.rebind.DirectRestServiceGenerator">
+ <when-type-assignable class="org.fusesource.restygwt.client.DirectRestService" />
+ </generate-with>
<define-configuration-property name="org.fusesource.restygwt.jsontypeidresolver" is-multi-valued="true"/>
View
24 restygwt/src/main/java/org/fusesource/restygwt/client/DirectRestService.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.client;
+
+/**
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public interface DirectRestService {
+}
View
17 restygwt/src/main/java/org/fusesource/restygwt/client/Method.java
@@ -57,12 +57,29 @@
* @author chirino
*/
static private class MethodRequestBuilder extends RequestBuilder {
+
+ protected Map<String, String> duplicatedHeaders = new HashMap<String, String>();
+
public MethodRequestBuilder(String method, String url) {
super(method, url);
setHeader("X-HTTP-Method-Override", method);
}
+
+ @Override
+ public void setHeader(String header, String value) {
+ super.setHeader(header, value);
+ duplicatedHeaders.put(header, value);
+ }
+
+ /**
+ * Gets you the copy of the headers. Modifying this map wouldn't affect any request data.
+ */
+ public Map<String, String> getHeaders() {
+ return duplicatedHeaders;
+ }
+
}
public RequestBuilder builder;
View
42 restygwt/src/main/java/org/fusesource/restygwt/client/REST.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.client;
+
+import org.fusesource.restygwt.client.callback.CallbackAware;
+
+/**
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ * @param <T>
+ * @param <R>
+ */
+public class REST<T, R> {
+ private MethodCallback<R> callback;
+
+ public REST(MethodCallback<R> callback) {
+ this.callback = callback;
+ }
+
+ public static <T, R> REST<T, R> withCallback(MethodCallback<R> callback) {
+ return new REST<T, R>(callback);
+ }
+
+ public final <T extends DirectRestService> T call(T service) {
+ ((CallbackAware)service).setCallback(callback);
+ return service;
+ }
+}
View
34 restygwt/src/main/java/org/fusesource/restygwt/client/callback/CallbackAware.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.client.callback;
+
+import org.fusesource.restygwt.client.MethodCallback;
+
+/**
+ * Utility class for DirectRest services. Since DirectRest objects must know about the callback they are supposed
+ * to call, they need to implement this interface.
+ *
+ * @see org.fusesource.restygwt.client.REST
+ * @see org.fusesource.restygwt.client.DirectRestService
+ *
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public interface CallbackAware {
+ void setCallback(MethodCallback callback);
+
+}
View
57 restygwt/src/main/java/org/fusesource/restygwt/client/cors/CORS.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2009-2010 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.cors;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Signals that another domain should be used for requests.
+ *
+ * You can apply the annotation at class-level or at method-level.
+ * Method-level annotations override class-level (general) settings.
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CORS {
+
+ public static final String PROTOCOL = "cors_protocol";
+ public static final String PORT = "cors_port";
+ public static final String DOMAIN = "cors_domain";
+
+ /**
+ * The port, defaults to an empty string.
+ */
+ String port() default "";
+
+ /**
+ * The protocol, defaults to an empty string.
+ */
+ String protocol() default "";
+
+ /**
+ * The domain you want to access.
+ */
+ String domain();
+
+}
View
104 restygwt/src/main/java/org/fusesource/restygwt/rebind/CORSAnnotationResolver.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2009-2010 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.rebind;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.fusesource.restygwt.client.cors.CORS;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+
+/**
+ * A {@link AnnotationResolver} that specially applies to the {@link CORS} annotation.
+ */
+public class CORSAnnotationResolver implements AnnotationResolver {
+
+ /***
+ * Looks for {@link CORS} annotations at class- and method level.
+ */
+ @Override
+ public Map<String, String[]> resolveAnnotation(TreeLogger logger, JClassType jClass,
+ JMethod method, final String restMethod) throws UnableToCompleteException {
+ // get both the method and class annotations
+ CORS classAnnotation = jClass.getAnnotation(CORS.class);
+ CORS methodAnnotation = method.getAnnotation(CORS.class);
+ Map<String, String[]> results = new HashMap<String, String[]>();
+ String protocolValue = null;
+ String portValue = null;
+
+ // only do something if a CORS annotation is present
+ if (methodAnnotation != null || classAnnotation != null) {
+ // if there is a class-level annotation ...
+ if (classAnnotation != null) {
+ // ... assign a domain attribute
+ results.put(CORS.DOMAIN, new String[] {classAnnotation.domain()});
+
+ // ... get the protocol and port
+ if (!isNullOrEmpty(classAnnotation.protocol())) {
+ protocolValue = classAnnotation.protocol();
+ }
+ if (!isNullOrEmpty(classAnnotation.port())) {
+ portValue = classAnnotation.port();
+ }
+ }
+
+ // if there is a method level annotation ...
+ if (methodAnnotation != null) {
+ // ... override the domain may set at class level
+ results.put(CORS.DOMAIN, new String[] {methodAnnotation.domain()});
+
+ // ... get the protocol and port
+ if (!isNullOrEmpty(methodAnnotation.protocol())) {
+ protocolValue = methodAnnotation.protocol();
+ }
+ if (!isNullOrEmpty(methodAnnotation.port())) {
+ portValue = methodAnnotation.port();
+ }
+ }
+
+ // if no value is set ... assign the default one
+ if (protocolValue == null) {
+ results.put(CORS.PROTOCOL, new String[] {""});
+ } else {
+ results.put(CORS.PROTOCOL, new String[] {protocolValue});
+ }
+
+ // if no value is set ... assign the default one
+ if (portValue == null) {
+ results.put(CORS.PORT, new String[] {""});
+ } else {
+ results.put(CORS.PORT, new String[] {portValue});
+ }
+ }
+
+ return results;
+ }
+
+ /***
+ * Checks if the specified string is either null o r has a length of zero.
+ */
+ protected boolean isNullOrEmpty(String str) {
+ return str == null || str.trim().length() == 0;
+ }
+
+}
View
87 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestBaseSourceCreator.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.rebind;
+
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JGenericType;
+import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+
+/**
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public abstract class DirectRestBaseSourceCreator extends BaseSourceCreator {
+ public DirectRestBaseSourceCreator(TreeLogger logger, GeneratorContext context, JClassType source, String suffix) {
+ super(logger, context, source, suffix);
+ }
+
+ protected ClassSourceFileComposerFactory createClassSourceComposerFactory(ClassSourceFileComposerFactory.JavaSourceCategory createWhat,
+ String [] annotationDeclarations,
+ String [] extendedInterfaces) {
+ String genericTypeParameters = createClassDeclarationGenericType();
+
+ ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(
+ packageName,
+ shortName + genericTypeParameters
+ );
+
+ if (createWhat == ClassSourceFileComposerFactory.JavaSourceCategory.INTERFACE) {
+ composerFactory.makeInterface();
+ }
+
+ if (annotationDeclarations != null) {
+ for (String annotationDeclaration : annotationDeclarations) {
+ composerFactory.addAnnotationDeclaration(annotationDeclaration);
+ }
+ }
+
+ if (extendedInterfaces != null) {
+ for (String anInterface : extendedInterfaces) {
+ composerFactory.addImplementedInterface(anInterface);
+ }
+ }
+
+ return composerFactory;
+ }
+
+ private String createClassDeclarationGenericType() {
+ String parameters = "";
+ if(source instanceof JGenericType)
+ {
+ JGenericType genericType = (JGenericType)source;
+ StringBuilder builder = new StringBuilder();
+ builder.append("<");
+ boolean first = true;
+ for(JTypeParameter arg : genericType.getTypeParameters())
+ {
+ if(!first)
+ builder.append(",");
+ builder.append(arg.getName());
+ builder.append(" extends ");
+ builder.append(arg.getFirstBound().getParameterizedQualifiedSourceName());
+ first = false;
+ }
+ builder.append(">");
+ parameters = builder.toString();
+ }
+ return parameters;
+ }
+
+}
View
155 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceClassCreator.java
@@ -0,0 +1,155 @@
+package org.fusesource.restygwt.rebind;
+
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JParameter;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import org.fusesource.restygwt.client.Dispatcher;
+import org.fusesource.restygwt.client.MethodCallback;
+import org.fusesource.restygwt.client.Resource;
+import org.fusesource.restygwt.client.RestServiceProxy;
+import org.fusesource.restygwt.client.callback.CallbackAware;
+import org.fusesource.restygwt.rebind.util.OnceFirstIterator;
+
+import static com.google.gwt.user.rebind.ClassSourceFileComposerFactory.JavaSourceCategory;
+import static org.fusesource.restygwt.rebind.DirectRestServiceInterfaceClassCreator.DIRECT_REST_SERVICE_SUFFIX;
+
+public class DirectRestServiceClassCreator extends DirectRestBaseSourceCreator {
+ public static final String DIRECT_REST_IMPL_SUFFIX = DIRECT_REST_SERVICE_SUFFIX + "Impl";
+ public static final String VOID_QUALIFIED_NAME = "void";
+
+ public DirectRestServiceClassCreator(TreeLogger logger, GeneratorContext context, JClassType source) {
+ super(logger, context, source, DIRECT_REST_IMPL_SUFFIX);
+ }
+
+ @Override
+ protected ClassSourceFileComposerFactory createComposerFactory() throws UnableToCompleteException {
+ return createClassSourceComposerFactory( JavaSourceCategory.CLASS,
+ null,
+ new String[]{
+ source.getParameterizedQualifiedSourceName(),
+ CallbackAware.class.getCanonicalName(),
+ RestServiceProxy.class.getCanonicalName()
+ }
+ );
+ }
+
+ @Override
+ protected void generate() throws UnableToCompleteException {
+ createRestyServiceField();
+ createDelegateRestServiceProxyMethods();
+ createCallbackSupportMethodsAndField();
+ createServiceMethods();
+ }
+
+ private void createRestyServiceField() {
+ p("private " + source.getName() + DIRECT_REST_SERVICE_SUFFIX + " service = com.google.gwt.core.client.GWT.create(" +
+ source.getName() + DIRECT_REST_SERVICE_SUFFIX + ".class);");
+ }
+
+ private void createDelegateRestServiceProxyMethods() {
+ String resourceClass = Resource.class.getCanonicalName();
+ String dispatcherClass = Dispatcher.class.getCanonicalName();
+ String restServiceProxyClass = RestServiceProxy.class.getCanonicalName();
+
+ p("public final void setResource(" + resourceClass + " resource) {").i(1)
+ .p("((" + restServiceProxyClass + ")service).setResource(resource);").i(-1)
+ .p("}");
+
+ p("public final " + resourceClass + " getResource() {").i(1)
+ .p("return ((" + restServiceProxyClass + ")service).getResource();").i(-1)
+ .p("}");
+
+ p("public final void setDispatcher(" + dispatcherClass + " resource) {").i(1)
+ .p("((" + restServiceProxyClass + ")service).setDispatcher(resource);").i(-1)
+ .p("}");
+
+ p("public final " + dispatcherClass + " getDispatcher() {").i(1)
+ .p("return ((" + restServiceProxyClass + ")service).getDispatcher();").i(-1)
+ .p("}");
+ }
+
+ private void createCallbackSupportMethodsAndField() {
+ createCallbackField();
+ createCallbackSetter();
+ createVerifyCallbackMethod();
+ }
+
+ private void createServiceMethods() {
+ for (JMethod method : source.getInheritableMethods()) {
+ generateMethod(method);
+ }
+ }
+
+ private void generateMethod(JMethod method) {
+ p( getMethodDeclaration(method) + " {").i(1);
+ generateCallVerifyCallback(method);
+ generateCallServiceMethod(method);
+ generateReturnNull(method);
+ i(-1).p("}");
+ }
+
+ private String getMethodDeclaration(JMethod method) {
+ return method.getReadableDeclaration(false, true, false, false, true);
+ }
+
+ private void generateCallVerifyCallback(JMethod method) {
+ p("verifyCallback(\"" + method.getName() + "\");");
+ }
+
+ private void generateCallServiceMethod(JMethod method) {
+ StringBuilder stringBuilder = new StringBuilder();
+ OnceFirstIterator<String> comma = new OnceFirstIterator<String>("", ", ");
+
+ stringBuilder.append("service.")
+ .append(method.getName())
+ .append("(");
+
+ for (JParameter parameter : method.getParameters()) {
+ stringBuilder.append(comma.next())
+ .append(parameter.getName());
+ }
+
+ stringBuilder.append(comma.next())
+ .append("this.callback");
+
+ stringBuilder.append(");");
+
+ p(stringBuilder.toString());
+ }
+
+ private void generateReturnNull(JMethod method) {
+ // FIXME: check for primitives, void.
+ if (!isVoidMethod(method)) {
+ p("return null;");
+ }
+ }
+
+ public static boolean isVoidMethod(JMethod method) {
+ return VOID_QUALIFIED_NAME.equals(method.getReturnType().getQualifiedBinaryName());
+ }
+
+ private void createCallbackField() {
+ p("private " + MethodCallback.class.getCanonicalName() + " callback;");
+ }
+ private void createCallbackSetter() {
+ p( "public void setCallback(" + MethodCallback.class.getCanonicalName() + " callback) {").i(1)
+ .p("this.callback = callback;").i(-1)
+ .p("}");
+ }
+
+ private void createVerifyCallbackMethod() {
+ p( "public void verifyCallback(String methodName) {").i(1)
+ .p("if (this.callback == null) {").i(1)
+ .p("throw new IllegalArgumentException(" +
+ "\"You need to call this service with REST.withCallback(new MethodCallback<..>(){..}).call(service).\" + " +
+ "methodName + " +
+ "\"(..) and not try to access the service directly\");").i(-1)
+ .p("}").i(-1)
+ .p("}");
+ }
+
+}
View
35 restygwt/src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceGenerator.java
@@ -0,0 +1,35 @@
+package org.fusesource.restygwt.rebind;
+
+import com.google.gwt.core.ext.Generator;
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+
+public class DirectRestServiceGenerator extends Generator {
+ @Override
+ public String generate(TreeLogger logger, GeneratorContext context, String source) throws UnableToCompleteException {
+ try {
+ JClassType restService = find(logger, context, source);
+
+ DirectRestServiceInterfaceClassCreator restyInterfaceCreator =
+ new DirectRestServiceInterfaceClassCreator(logger, context, restService);
+ restyInterfaceCreator.create();
+
+ DirectRestServiceClassCreator generator = new DirectRestServiceClassCreator(logger, context, restService);
+
+ return generator.create();
+ } finally {
+ BaseSourceCreator.clearGeneratedClasses();
+ }
+ }
+
+ static JClassType find(TreeLogger logger, GeneratorContext context, String type) throws UnableToCompleteException {
+ JClassType rc = context.getTypeOracle().findType(type);
+ if (rc == null) {
+ logger.log(TreeLogger.ERROR, "TypeOracle could not find " + type);
+ throw new UnableToCompleteException();
+ }
+ return rc;
+ }
+}
View
108 .../src/main/java/org/fusesource/restygwt/rebind/DirectRestServiceInterfaceClassCreator.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.rebind;
+
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JParameter;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import org.fusesource.restygwt.client.RestService;
+import org.fusesource.restygwt.rebind.util.AnnotationCopyUtil;
+import org.fusesource.restygwt.rebind.util.OnceFirstIterator;
+
+import java.lang.annotation.Annotation;
+
+import static com.google.gwt.user.rebind.ClassSourceFileComposerFactory.JavaSourceCategory;
+import static org.fusesource.restygwt.rebind.DirectRestServiceClassCreator.isVoidMethod;
+
+/**
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public class DirectRestServiceInterfaceClassCreator extends DirectRestBaseSourceCreator {
+ public static final String DIRECT_REST_SERVICE_SUFFIX = "_DirectRestService";
+
+ public DirectRestServiceInterfaceClassCreator(TreeLogger logger, GeneratorContext context, JClassType source) {
+ super(logger, context, source, DIRECT_REST_SERVICE_SUFFIX);
+ }
+
+ @Override
+ protected ClassSourceFileComposerFactory createComposerFactory() throws UnableToCompleteException {
+ return createClassSourceComposerFactory(JavaSourceCategory.INTERFACE,
+ getAnnotationsAsStringArray(source.getAnnotations()),
+ new String[]{
+ RestService.class.getCanonicalName()
+ }
+ );
+ }
+
+ @Override
+ protected void generate() throws UnableToCompleteException {
+ for (JMethod method : source.getInheritableMethods()) {
+ p(getAnnotationsAsString(method.getAnnotations()));
+ p("void " + method.getName() + "(" + getMethodParameters(method) + getMethodCallback(method) + ");");
+ }
+ }
+
+ private String getMethodParameters(JMethod method) {
+ StringBuilder result = new StringBuilder("");
+
+ for (JParameter parameter : method.getParameters()) {
+ result.append(getAnnotationsAsString(parameter.getAnnotations()))
+ .append(" ")
+ .append(parameter.getType().getParameterizedQualifiedSourceName())
+ .append(" ")
+ .append(parameter.getName())
+ .append(", ");
+ }
+
+ return result.toString();
+ }
+
+ private String getMethodCallback(JMethod method) {
+ if (isVoidMethod(method)) {
+ return "org.fusesource.restygwt.client.MethodCallback<java.lang.Void> callback";
+ } else {
+ return "org.fusesource.restygwt.client.MethodCallback<" + method.getReturnType().getParameterizedQualifiedSourceName() + "> callback";
+ }
+ }
+
+ private String getAnnotationsAsString(Annotation[] annotations) {
+ StringBuilder result = new StringBuilder("");
+ OnceFirstIterator<String> space = new OnceFirstIterator<String>("", " ");
+
+ for (String annotation : getAnnotationsAsStringArray(annotations)) {
+ result.append(space.next()).append(annotation);
+ }
+
+ return result.toString();
+ }
+
+ private String[] getAnnotationsAsStringArray(Annotation[] annotations) {
+ String[] result = new String[annotations.length];
+
+ for (int i = 0; i < annotations.length; i++) {
+ Annotation annotation = annotations[i];
+ result[i] = AnnotationCopyUtil.getAnnotationAsString(annotation);
+ }
+
+ return result;
+ }
+}
View
124 restygwt/src/main/java/org/fusesource/restygwt/rebind/util/AnnotationCopyUtil.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.rebind.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+
+/**
+ * An utility class that gets a String representation of an annotation.
+ *
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public class AnnotationCopyUtil {
+ public static String getAnnotationAsString(Annotation annotation) {
+ StringBuilder result = encodeAnnotationName(annotation);
+
+ if (hasAnnotationAttributes(annotation)) {
+ encodeAnnotationAttributes(annotation, result);
+ }
+
+ return result.toString();
+ }
+
+ private static StringBuilder encodeAnnotationName(Annotation annotation) {
+ return new StringBuilder( "@" )
+ .append(annotation.annotationType().getCanonicalName());
+ }
+
+ private static boolean hasAnnotationAttributes(Annotation annotation) {
+ return annotation.annotationType().getDeclaredMethods().length != 0;
+ }
+
+ private static void encodeAnnotationAttributes(Annotation annotation, StringBuilder result) {
+ result.append("(");
+
+ OnceFirstIterator<String> comma = new OnceFirstIterator<String>("", ", ");
+ for (Method method : annotation.annotationType().getDeclaredMethods()) {
+ Object value = readAnnotationAttribute(annotation, method);
+
+ result.append( comma.next() )
+ .append(method.getName())
+ .append( " = " )
+ .append( encodeAnnotationValue(value) );
+ }
+
+ result.append(")");
+ }
+
+ private static Object readAnnotationAttribute(Annotation annotation, Method annotationAttribute) {
+ try {
+ return annotationAttribute.invoke(annotation);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to read attribute " + annotationAttribute + " from " + annotation, e);
+ }
+ }
+
+ private static String encodeAnnotationValue(Object value) {
+ if (value instanceof String) {
+ return readStringValue(value);
+ } else if (value instanceof Number) {
+ return readNumberValue(value);
+ } else if (value == null) {
+ return "null";
+ } else if (value.getClass().isArray()) {
+ return readArrayValue(value);
+ } else if (value.getClass().isAnnotation()) {
+ return getAnnotationAsString((Annotation) value);
+ } else if (value instanceof Boolean) {
+ return readBooleanValue((Boolean) value);
+ } else if (value instanceof Class) {
+ return readClassValue((Class) value);
+ }
+
+ return null;
+ }
+
+ private static String readBooleanValue(Boolean value) {
+ return Boolean.toString(value);
+ }
+
+ private static String readArrayValue(Object value) {
+ StringBuilder result = new StringBuilder();
+ OnceFirstIterator<String> comma = new OnceFirstIterator<String>("", ", ");
+
+ result.append("{");
+ for (int i = 0; i < Array.getLength(value); i++) {
+ Object arrayValue = Array.get(value, i);
+
+ result.append(comma.next())
+ .append(encodeAnnotationValue(arrayValue));
+ }
+ result.append("}");
+
+ return result.toString();
+ }
+
+ private static String readNumberValue(Object value) {
+ return value.toString();
+ }
+
+ private static String readStringValue(Object value) {
+ return "\"" + value.toString().replace("\"", "\\\"") + "\"";
+ }
+
+ private static String readClassValue(Class value) {
+ return value.getCanonicalName() + ".class";
+ }
+}
View
58 restygwt/src/main/java/org/fusesource/restygwt/rebind/util/OnceFirstIterator.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+package org.fusesource.restygwt.rebind.util;
+
+import java.util.Iterator;
+
+/**
+ * An iterator that returns the first time, the first value, and after it always the returns the next value.
+ * Useful for scenarios that have an <code>if (first) { first = true; ... }</code> inside a loop approach.
+ *
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ * @param <T>
+ */
+public class OnceFirstIterator<T> implements Iterator<T> {
+ private T firstValue;
+ private T nextValue;
+ private boolean firstReturned;
+
+ public OnceFirstIterator(T firstValue, T nextValue) {
+ this.firstValue = firstValue;
+ this.nextValue = nextValue;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ @Override
+ public T next() {
+ if (firstReturned) {
+ return nextValue;
+ } else {
+ firstReturned = true;
+ return firstValue;
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
View
52 restygwt/src/test/java/org/fusesource/restygwt/DirectRestServiceTestGwt.gwt.xml
@@ -0,0 +1,52 @@
+<!--
+
+ Copyright (C) 2009-2011 the original author or authors.
+ See the notice.md file distributed with this work for additional
+ information regarding copyright ownership.
+
+ 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.
+
+-->
+
+<module>
+ <inherits name='com.google.gwt.user.User' />
+ <inherits name='com.google.gwt.logging.Logging'/>
+ <inherits name='org.fusesource.restygwt.RestyGWT'/>
+
+ <!-- Logging Configuration -->
+ <set-property name="gwt.logging.enabled" value="TRUE"/>
+ <set-property name="gwt.logging.logLevel" value="ALL"/>
+
+ <source path='client'/>
+ <source path='example/client'/>
+
+ <servlet path='/api/*' class='org.fusesource.restygwt.server.CachingTestServlet' />
+ <servlet path='/testing/caching_and_block' class='org.fusesource.restygwt.server.event.EchoServlet' />
+ <servlet path='/testing/caching_and_queuing' class='org.fusesource.restygwt.server.event.EchoServlet' />
+
+ <!-- seen at http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/junit/JUnit.gwt.xml?r=5779 -->
+ <inherits name="com.google.gwt.benchmarks.Benchmarks"/>
+ <replace-with class="com.google.gwt.core.client.impl.StackTraceCreator.CollectorEmulated">
+ <when-type-is class="com.google.gwt.core.client.impl.StackTraceCreator.Collector" />
+ <none>
+ <when-property-is name="user.agent" value="gecko" />
+ <when-property-is name="user.agent" value="gecko1_8" />
+ <when-property-is name="user.agent" value="opera" />
+ </none>
+ </replace-with>
+
+ <set-configuration-property name="org.fusesource.restygwt.annotationresolver"
+ value="org.fusesource.restygwt.rebind.ModelChangeAnnotationResolver"/>
+
+ <servlet path='/api/*' class='org.fusesource.restygwt.server.basic.DirectServiceTestGwtServlet' />
+</module>
View
3  restygwt/src/test/java/org/fusesource/restygwt/Event.gwt.xml
@@ -51,7 +51,10 @@
<set-configuration-property name="org.fusesource.restygwt.annotationresolver"
value="org.fusesource.restygwt.rebind.ModelChangeAnnotationResolver"/>
+ <extend-configuration-property name="org.fusesource.restygwt.annotationresolver"
+ value="org.fusesource.restygwt.rebind.CORSAnnotationResolver"/>
+ <servlet path='/my/*' class='org.fusesource.restygwt.server.event.EchoServlet' />
<servlet path='/foo/*' class='org.fusesource.restygwt.server.event.EchoServlet' />
<source path='client'/>
View
2  restygwt/src/test/java/org/fusesource/restygwt/GwtAnnotationResolverTestSuite.java
@@ -21,6 +21,7 @@
import junit.framework.Test;
import junit.framework.TestCase;
+import org.fusesource.restygwt.client.cors.CORSAnnotationResolverTestGwt;
import org.fusesource.restygwt.client.event.ModelChangeAnnotationTestGwt;
import org.fusesource.restygwt.rebind.AnnotationResolver;
@@ -42,6 +43,7 @@ public static Test suite() {
GWTTestSuite suite = new GWTTestSuite("AnnotationResolver GwtTestCases" );
suite.addTestSuite(ModelChangeAnnotationTestGwt.class);
+ suite.addTestSuite(CORSAnnotationResolverTestGwt.class);
return suite;
}
View
2  restygwt/src/test/java/org/fusesource/restygwt/GwtCompleteTestSuite.java
@@ -35,6 +35,7 @@
import org.fusesource.restygwt.client.basic.ResourceTestGwt;
import org.fusesource.restygwt.client.basic.SubResourceClientGeneration;
import org.fusesource.restygwt.client.basic.TimeoutTestGwt;
+import org.fusesource.restygwt.client.basic.DirectRestServiceTestGwt;
import org.fusesource.restygwt.client.cache.VolatileQueueableCacheStorageTestGwt;
import org.fusesource.restygwt.client.codec.EncoderDecoderTestGwt;
import org.fusesource.restygwt.client.complex.JsonTypeIdResolver;
@@ -84,6 +85,7 @@ public static Test suite() {
suite.addTestSuite(JsonCreatorWithSubtypes.class);
suite.addTestSuite(PathParamTestGwt.class);
suite.addTestSuite(QueryParamTestGwt.class);
+ suite.addTestSuite(DirectRestServiceTestGwt.class);
return suite;
}
}
View
40 restygwt/src/test/java/org/fusesource/restygwt/client/basic/DirectExampleService.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.basic;
+
+import org.fusesource.restygwt.client.DirectRestService;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import java.util.List;
+
+/**
+ * Example of using the DirectRestService call.
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public interface DirectExampleService extends DirectRestService {
+ @GET @Path("/list")
+ List<ExampleDto> getExampleDtos(@QueryParam("id") String id);
+
+ @POST @Path("/store")
+ void storeDto(ExampleDto exampleDto);
+}
+
View
88 restygwt/src/test/java/org/fusesource/restygwt/client/basic/DirectRestServiceTestGwt.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.basic;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+import org.fusesource.restygwt.client.*;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public class DirectRestServiceTestGwt extends GWTTestCase {
+ @Override
+ public String getModuleName() {
+ return "org.fusesource.restygwt.DirectRestServiceTestGwt";
+ }
+
+ public void testCallingMethodsDirectlyShouldFail() {
+ delayTestFinish(10000);
+ DirectExampleService directExampleService = GWT.create(DirectExampleService.class);
+
+ try {
+ directExampleService.getExampleDtos("3");
+ fail("This code is unreachable, since the proxy can not be called directly.");
+ } catch (Exception e) {
+ finishTest();
+ }
+ }
+
+ public void testQueryCall() {
+ delayTestFinish(10000);
+ DirectExampleService directExampleService = GWT.create(DirectExampleService.class);
+
+ Resource resource = new Resource(GWT.getModuleBaseURL() + "api");
+ ((RestServiceProxy) directExampleService).setResource(resource);
+
+ REST.withCallback(new MethodCallback<List<ExampleDto>>() {
+ @Override
+ public void onSuccess(Method method, List<ExampleDto> response) {
+ assertEquals(3, response.size());
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable e) {
+ fail(e.getMessage());
+ }
+ }).call(directExampleService).getExampleDtos("3");
+ }
+
+ public void testVoidCall() {
+ delayTestFinish(10000);
+ DirectExampleService directExampleService = GWT.create(DirectExampleService.class);
+
+ Resource resource = new Resource(GWT.getModuleBaseURL() + "api");
+ ((RestServiceProxy) directExampleService).setResource(resource);
+
+ REST.withCallback(new MethodCallback<List<ExampleDto>>() {
+ @Override
+ public void onSuccess(Method method, List<ExampleDto> response) {
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable e) {
+ fail(e.getMessage());
+ }
+ }).call(directExampleService).storeDto(new ExampleDto());
+ }
+}
View
6 restygwt/src/test/java/org/fusesource/restygwt/client/basic/QueryParamTestGwt.java
@@ -38,7 +38,7 @@
*/
public class QueryParamTestGwt extends GWTTestCase {
- private TestRestService service;
+ private QueryTestRestService service;
@Override
public String getModuleName() {
@@ -46,7 +46,7 @@ public String getModuleName() {
}
@Path("/get")
- static interface TestRestService extends RestService {
+ static interface QueryTestRestService extends RestService {
void get(@QueryParam(value = "id") int id, MethodCallback<Echo> callback);
@@ -80,7 +80,7 @@ public void onFailure(Method method, Throwable exception) {
@Override
protected void gwtSetUp() throws Exception {
super.gwtSetUp();
- service = GWT.create(TestRestService.class);
+ service = GWT.create(QueryTestRestService.class);
Resource resource = new Resource(GWT.getModuleBaseURL() + "echo");
((RestServiceProxy) service).setResource(resource);
}
View
235 ...ygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSAnnotationResolverTestGwt.java
@@ -0,0 +1,235 @@
+/**
+ * Copyright (C) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.cors;
+
+import org.fusesource.restygwt.client.Method;
+import org.fusesource.restygwt.client.MethodCallback;
+import org.fusesource.restygwt.client.Resource;
+import org.fusesource.restygwt.client.RestServiceProxy;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * testcase for checking the data attribute of the method object.
+ */
+public class CORSAnnotationResolverTestGwt extends GWTTestCase {
+
+ @Override
+ public String getModuleName() {
+ return "org.fusesource.restygwt.Event";
+ }
+
+ public void testBasicFunctionality_ClassLevel1() {
+ CORSServiceClassLevelOnly service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceClassLevelOnly.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.getExampleDto(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"https\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+ public void testBasicFunctionality_ClassLevel2() {
+ CORSServiceClassLevelOnly service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceClassLevelOnly.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.postExample(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"https\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+ public void testBasicFunctionality_MethodLeve1() {
+ CORSServiceMethodLevelOnly service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceMethodLevelOnly.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.getExampleDto(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"https\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+ public void testBasicFunctionality_MethodLevel2() {
+ CORSServiceMethodLevelOnly service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceMethodLevelOnly.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.postExample(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api2.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"spdy\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+ public void testBasicFunctionality_MixedLevels1() {
+ CORSServiceMixedLevels service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceMixedLevels.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.getExampleDto(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"https\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"8080\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+ public void testBasicFunctionality_MixedLevels2() {
+ CORSServiceMixedLevels service = null;
+
+ try {
+ Resource resource = new Resource(GWT.getModuleBaseURL());
+ service = GWT.create(CORSServiceMixedLevels.class);
+ ((RestServiceProxy) service).setResource(resource);
+ assertNotNull(service);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("failed to generate CORSServiceClassLevelOnly");
+ }
+
+ delayTestFinish(1000);
+ // the request going nowhere, we merely want any response, so we can check for the data in the method object
+ service.postExample(new MethodCallback<Void>() {
+
+ @Override
+ public void onSuccess(Method method, Void response) {
+ assertEquals("[\"api2.host.com\"]", method.getData().get(CORS.DOMAIN));
+ assertEquals("[\"https\"]", method.getData().get(CORS.PROTOCOL));
+ assertEquals("[\"12345\"]", method.getData().get(CORS.PORT));
+ finishTest();
+ }
+
+ @Override
+ public void onFailure(Method method, Throwable exception) {
+ fail();
+ }
+
+ });
+ }
+
+}
View
43 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceClassLevelOnly.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.cors;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.fusesource.restygwt.client.MethodCallback;
+import org.fusesource.restygwt.client.RestService;
+import org.fusesource.restygwt.client.basic.ExampleDto;
+import org.fusesource.restygwt.client.cache.Domain;
+
+/**
+ * Supersimple example service for testing...
+ */
+@Domain({ExampleDto.class})
+@CORS(domain = "api.host.com", protocol = "https")
+public interface CORSServiceClassLevelOnly extends RestService {
+
+ @GET
+ @Path("/my/very/unique/path")
+ void getExampleDto(MethodCallback<Void> callback);
+
+ @POST
+ @Path("/my/very/unique/path")
+ void postExample(MethodCallback<Void> callback);
+
+}
View
46 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceMethodLevelOnly.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.cors;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.fusesource.restygwt.client.MethodCallback;
+import org.fusesource.restygwt.client.RestService;
+import org.fusesource.restygwt.client.basic.ExampleDto;
+import org.fusesource.restygwt.client.cache.Domain;
+
+/**
+ * Supersimple example service for testing...
+ */
+@Domain({ExampleDto.class})
+public interface CORSServiceMethodLevelOnly extends RestService {
+
+ @GET
+ @CORS(domain = "api.host.com", protocol = "https")
+ @Path("/my/very/unique/path")
+ void getExampleDto(MethodCallback<Void> callback);
+
+ @POST
+ @CORS(domain = "api2.host.com", protocol = "spdy")
+ @Path("/my/very/unique/path")
+ // path should be overridden
+ // different domains may be useful for Command Query Responsibility Segregation (CQRS)
+ void postExample(MethodCallback<Void> callback);
+
+}
View
47 restygwt/src/test/java/org/fusesource/restygwt/client/cors/CORSServiceMixedLevels.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.client.cors;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.fusesource.restygwt.client.MethodCallback;
+import org.fusesource.restygwt.client.RestService;
+import org.fusesource.restygwt.client.basic.ExampleDto;
+import org.fusesource.restygwt.client.cache.Domain;
+
+/**
+ * Supersimple example service for testing...
+ */
+@Domain({ExampleDto.class})
+@CORS(domain = "api.host.com", protocol = "https", port = "8080")
+public interface CORSServiceMixedLevels extends RestService {
+
+ @GET
+ @Path("/my/very/unique/path")
+ void getExampleDto(MethodCallback<Void> callback);
+
+ @POST
+ @CORS(domain = "api2.host.com", port = "12345")
+ @Path("/my/very/unique/path")
+ // still has https as protocol
+ // path should be overridden
+ // different domains may be useful for Command Query Responsibility Segregation (CQRS)
+ void postExample(MethodCallback<Void> callback);
+
+}
View
58 restygwt/src/test/java/org/fusesource/restygwt/server/basic/DirectServiceTestGwtServlet.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009-2011 the original author or authors.
+ * See the notice.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * 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.
+ */
+
+package org.fusesource.restygwt.server.basic;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * A servlet that just implements the services required for the direct service test.
+ *
+ * @author <a href="mailto:bogdan.mustiata@gmail.com">Bogdan Mustiata</<a>
+ */
+public class DirectServiceTestGwtServlet extends HttpServlet {
+
+ String EMPTY_RESPONSE = "";
+ String THREE_ELEMENT_LIST = "[{name:'1'},{name:'2'},{name:'3'}]";
+
+ @Override
+ protected void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+
+ if (request.getRequestURI().endsWith("/api/list")) {
+ response.getWriter().print(THREE_ELEMENT_LIST);
+ } else {
+ throw new IllegalArgumentException("Invalid servlet path called by service: " + request.getRequestURI());
+ }
+
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+
+ if (request.getRequestURI().endsWith("/api/store")) {
+ response.getWriter().print(EMPTY_RESPONSE);
+ } else {
+ throw new IllegalArgumentException("Invalid servlet path called by service: " + request.getRequestURI());
+ }
+ }
+}

No commit comments for this range

Something went wrong with that request. Please try again.