Skip to content
This repository was archived by the owner on Dec 15, 2018. It is now read-only.

[WIP] RESTEasy module now automatically adds @Produces if required #155

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion resteasy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<name>Ozark RESTEasy</name>

<properties>
<resteasy.version>2.2.1.GA</resteasy.version>
<resteasy.version>4.0.0-SNAPSHOT</resteasy.version>
</properties>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright © 2017 Ivar Grimstad ([email protected])
*
* 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
* <code>@Produces("text/html")</code> 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;

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright © 2017 Ivar Grimstad ([email protected])
*
* 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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright © 2017 Ivar Grimstad ([email protected])
*
* 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 <code>@Produces("text/html")</code> 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<String> 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();
}
}