diff --git a/resteasy/pom.xml b/resteasy/pom.xml index 85e32d7e..c6aee130 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -31,7 +31,7 @@ Ozark RESTEasy - 2.2.1.GA + 4.0.0-SNAPSHOT diff --git a/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkClassProcessor.java b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkClassProcessor.java new file mode 100644 index 00000000..c73ddea0 --- /dev/null +++ b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkClassProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright © 2017 Ivar Grimstad (ivar.grimstad@gmail.com) + * + * 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.mvcspec.ozark.resteasy.metadata; + +import org.jboss.resteasy.spi.metadata.ResourceClass; +import org.jboss.resteasy.spi.metadata.ResourceClassProcessor; +import org.mvcspec.ozark.util.AnnotationUtils; + +import javax.mvc.annotation.Controller; +import javax.ws.rs.ext.Provider; + +/** + * Custom implementation of the RESTEasy {@link ResourceClassProcessor} SPI which adds + * @Produces("text/html") to controller methods if they don't define some other + * media type. + * + * @author Christian Kaltepoth + */ +@Provider +public class OzarkClassProcessor implements ResourceClassProcessor { + + @Override + public ResourceClass process(ResourceClass clazz) { + + // we only need to wrap resources with at least one controller method here + if (AnnotationUtils.hasAnnotationOnClassOrMethod(clazz.getClazz(), Controller.class)) { + return new OzarkResourceClass(clazz); + } + + return clazz; + + } + +} diff --git a/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceClass.java b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceClass.java new file mode 100644 index 00000000..7afef2ec --- /dev/null +++ b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceClass.java @@ -0,0 +1,83 @@ +/* + * Copyright © 2017 Ivar Grimstad (ivar.grimstad@gmail.com) + * + * 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.mvcspec.ozark.resteasy.metadata; + +import org.jboss.resteasy.spi.metadata.FieldParameter; +import org.jboss.resteasy.spi.metadata.ResourceClass; +import org.jboss.resteasy.spi.metadata.ResourceConstructor; +import org.jboss.resteasy.spi.metadata.ResourceLocator; +import org.jboss.resteasy.spi.metadata.ResourceMethod; +import org.jboss.resteasy.spi.metadata.SetterParameter; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Wrapper for {@link ResourceClass} which wraps methods in {@link OzarkResourceMethod}. + * + * @author Christian Kaltepoth + */ +public class OzarkResourceClass implements ResourceClass { + + private final ResourceClass delegate; + private final ResourceMethod[] resourceMethods; + + public OzarkResourceClass(ResourceClass delegate) { + this.delegate = delegate; + + // wrap methods so we can add @Produces("text/html") if required + this.resourceMethods = Arrays.stream(this.delegate.getResourceMethods()) + .map(OzarkResourceMethod::new) + .collect(Collectors.toList()) + .toArray(new ResourceMethod[0]); + + } + + @Override + public String getPath() { + return delegate.getPath(); + } + + @Override + public Class getClazz() { + return delegate.getClazz(); + } + + @Override + public ResourceConstructor getConstructor() { + return delegate.getConstructor(); + } + + @Override + public FieldParameter[] getFields() { + return delegate.getFields(); + } + + @Override + public SetterParameter[] getSetters() { + return delegate.getSetters(); + } + + @Override + public ResourceMethod[] getResourceMethods() { + return resourceMethods; + } + + @Override + public ResourceLocator[] getResourceLocators() { + return delegate.getResourceLocators(); + } +} diff --git a/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceMethod.java b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceMethod.java new file mode 100644 index 00000000..d50fc123 --- /dev/null +++ b/resteasy/src/main/java/org/mvcspec/ozark/resteasy/metadata/OzarkResourceMethod.java @@ -0,0 +1,118 @@ +/* + * Copyright © 2017 Ivar Grimstad (ivar.grimstad@gmail.com) + * + * 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.mvcspec.ozark.resteasy.metadata; + +import org.jboss.resteasy.spi.metadata.MethodParameter; +import org.jboss.resteasy.spi.metadata.ResourceClass; +import org.jboss.resteasy.spi.metadata.ResourceMethod; +import org.mvcspec.ozark.util.AnnotationUtils; + +import javax.mvc.annotation.Controller; +import javax.ws.rs.core.MediaType; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Set; + +/** + * Wrapper for {@link ResourceMethod} which adds @Produces("text/html") to controller + * methods if no other media type was specified. + * + * @author Christian Kaltepoth + */ +public class OzarkResourceMethod implements ResourceMethod { + + private final ResourceMethod delegate; + private final MediaType[] produces; + + public OzarkResourceMethod(ResourceMethod delegate) { + this.delegate = delegate; + + boolean isMediaTypeSpecified = delegate.getProduces() != null && delegate.getProduces().length > 0; + + boolean isControllerMethod = AnnotationUtils.hasAnnotation(delegate.getMethod(), Controller.class) + || AnnotationUtils.hasAnnotation(delegate.getResourceClass().getClazz(), Controller.class); + + this.produces = isControllerMethod && !isMediaTypeSpecified + ? new MediaType[]{MediaType.TEXT_HTML_TYPE} + : delegate.getProduces(); + + } + + @Override + public Set getHttpMethods() { + return delegate.getHttpMethods(); + } + + @Override + public MediaType[] getProduces() { + return produces; + } + + @Override + public MediaType[] getConsumes() { + return delegate.getConsumes(); + } + + @Override + public boolean isAsynchronous() { + return delegate.isAsynchronous(); + } + + @Override + public void markAsynchronous() { + delegate.markAsynchronous(); + } + + @Override + public ResourceClass getResourceClass() { + return delegate.getResourceClass(); + } + + @Override + public Class getReturnType() { + return delegate.getReturnType(); + } + + @Override + public Type getGenericReturnType() { + return delegate.getGenericReturnType(); + } + + @Override + public Method getMethod() { + return delegate.getMethod(); + } + + @Override + public Method getAnnotatedMethod() { + return delegate.getAnnotatedMethod(); + } + + @Override + public MethodParameter[] getParams() { + return delegate.getParams(); + } + + @Override + public String getFullpath() { + return delegate.getFullpath(); + } + + @Override + public String getPath() { + return delegate.getPath(); + } +}