org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.WadlGeneratorResourceDocSupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jersey-server Show documentation
Show all versions of jersey-server Show documentation
Jersey core server implementation
/*
* Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.server.wadl.internal.generators.resourcedoc;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.inject.Provider;
import javax.xml.parsers.SAXParserFactory;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.model.ResourceMethod;
import org.glassfish.jersey.server.wadl.WadlGenerator;
import org.glassfish.jersey.server.wadl.internal.ApplicationDescription;
import org.glassfish.jersey.server.wadl.internal.WadlUtils;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ClassDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.MethodDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ParamDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.RepresentationDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ResourceDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ResponseDocType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.WadlParamType;
import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.xhtml.Elements;
import com.sun.research.ws.wadl.Application;
import com.sun.research.ws.wadl.Doc;
import com.sun.research.ws.wadl.Method;
import com.sun.research.ws.wadl.Param;
import com.sun.research.ws.wadl.ParamStyle;
import com.sun.research.ws.wadl.Representation;
import com.sun.research.ws.wadl.Request;
import com.sun.research.ws.wadl.Resource;
import com.sun.research.ws.wadl.Resources;
import com.sun.research.ws.wadl.Response;
/**
* A {@link org.glassfish.jersey.server.wadl.WadlGenerator} implementation that enhances the generated wadl by
* information read from a resourcedoc (containing javadoc information about resource
* classes).
*
* The resourcedoc information can either be provided via a {@link File} ({@link #setResourceDocFile(File)}) reference or
* via an {@link InputStream} ({@link #setResourceDocStream(InputStream)}).
*
*
* The {@link File} should be used when using the maven-wadl-plugin for generating wadl offline,
* the {@link InputStream} should be used when the extended wadl is generated by jersey at runtime, e.g.
* using the {@link org.glassfish.jersey.server.wadl.config.WadlGeneratorConfig} for configuration.
*
*
* @author Martin Grotzke (martin.grotzke at freiheit.com)
* @author Miroslav Fuksa
*/
public class WadlGeneratorResourceDocSupport implements WadlGenerator {
private WadlGenerator delegate;
private File resourceDocFile;
private InputStream resourceDocStream;
private ResourceDocAccessor resourceDoc;
@Context
private Provider saxFactoryProvider;
public WadlGeneratorResourceDocSupport() {
}
public WadlGeneratorResourceDocSupport(final WadlGenerator wadlGenerator, final ResourceDocType resourceDoc) {
delegate = wadlGenerator;
this.resourceDoc = new ResourceDocAccessor(resourceDoc);
}
public void setWadlGeneratorDelegate(final WadlGenerator delegate) {
this.delegate = delegate;
}
/**
* Set the resourceDocFile
to the given file. Invoking this method is only allowed, as long as
* the resourceDocStream
is not set, otherwise an {@link IllegalStateException} will be thrown.
* @param resourceDocFile the resourcedoc file to set.
*/
public void setResourceDocFile(final File resourceDocFile) {
if (resourceDocStream != null) {
throw new IllegalStateException("The resourceDocStream property is already set,"
+ " therefore you cannot set the resourceDocFile property. Only one of both can be set at a time.");
}
this.resourceDocFile = resourceDocFile;
}
/**
* Set the resourceDocStream
to the given file. Invoking this method is only allowed, as long as
* the resourceDocFile
is not set, otherwise an {@link IllegalStateException} will be thrown.
*
* The resourcedoc stream must be closed by the client providing the stream.
*
* @param resourceDocStream the resourcedoc stream to set.
*/
public void setResourceDocStream(final InputStream resourceDocStream) {
if (this.resourceDocStream != null) {
throw new IllegalStateException("The resourceDocFile property is already set,"
+ " therefore you cannot set the resourceDocStream property. Only one of both can be set at a time.");
}
this.resourceDocStream = resourceDocStream;
}
public void init() throws Exception {
if (resourceDocFile == null && resourceDocStream == null) {
throw new IllegalStateException("Neither the resourceDocFile nor the resourceDocStream"
+ " is set, one of both is required.");
}
delegate.init();
try (final InputStream inputStream = resourceDocFile != null ? new FileInputStream(resourceDocFile) : resourceDocStream) {
final ResourceDocType resourceDocType =
WadlUtils.unmarshall(inputStream, saxFactoryProvider.get(), ResourceDocType.class);
resourceDoc = new ResourceDocAccessor(resourceDocType);
} finally {
resourceDocFile = null;
}
}
public String getRequiredJaxbContextPath() {
String name = Elements.class.getName();
name = name.substring(0, name.lastIndexOf('.'));
return delegate.getRequiredJaxbContextPath() == null
? name
: delegate.getRequiredJaxbContextPath() + ":" + name;
}
/**
* @return the {@link com.sun.research.ws.wadl.Application} created by the delegate.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createApplication()
*/
public Application createApplication() {
return delegate.createApplication();
}
/**
* @param r Jersey resource component for which the WADL reource is to be created.
* @param path path where the resource is exposed.
* @return the enhanced {@link com.sun.research.ws.wadl.Resource}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createResource(org.glassfish.jersey.server.model.Resource, String)
*/
public Resource createResource(final org.glassfish.jersey.server.model.Resource r, final String path) {
final Resource result = delegate.createResource(r, path);
for (final Class resourceClass : r.getHandlerClasses()) {
final ClassDocType classDoc = resourceDoc.getClassDoc(resourceClass);
if (classDoc != null && !isEmpty(classDoc.getCommentText())) {
final Doc doc = new Doc();
doc.getContent().add(classDoc.getCommentText());
result.getDoc().add(doc);
}
}
return result;
}
/**
* @param resource Jersey resource component.
* @param resourceMethod resource method.
* @return the enhanced {@link com.sun.research.ws.wadl.Method}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createMethod(org.glassfish.jersey.server.model.Resource,
* org.glassfish.jersey.server.model.ResourceMethod)
*/
public Method createMethod(final org.glassfish.jersey.server.model.Resource resource,
final ResourceMethod resourceMethod) {
final Method result = delegate.createMethod(resource, resourceMethod);
final java.lang.reflect.Method method = resourceMethod.getInvocable().getDefinitionMethod();
final MethodDocType methodDoc = resourceDoc.getMethodDoc(method.getDeclaringClass(), method);
if (methodDoc != null && !isEmpty(methodDoc.getCommentText())) {
final Doc doc = new Doc();
doc.getContent().add(methodDoc.getCommentText());
// doc.getOtherAttributes().put( new QName( "xmlns" ), "http://www.w3.org/1999/xhtml" );
result.getDoc().add(doc);
}
return result;
}
/**
* @param r Jersey resource component.
* @param m resource method.
* @param mediaType media type.
* @return the enhanced {@link com.sun.research.ws.wadl.Representation}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createRequestRepresentation(org.glassfish.jersey.server.model.Resource,
* org.glassfish.jersey.server.model.ResourceMethod, javax.ws.rs.core.MediaType)
*/
public Representation createRequestRepresentation(final org.glassfish.jersey.server.model.Resource r,
final org.glassfish.jersey.server.model.ResourceMethod m,
final MediaType mediaType) {
final Representation result = delegate.createRequestRepresentation(r, m, mediaType);
final RepresentationDocType requestRepresentation = resourceDoc.getRequestRepresentation(m.getInvocable()
.getDefinitionMethod().getDeclaringClass(),
m.getInvocable().getDefinitionMethod(), result.getMediaType()
);
if (requestRepresentation != null) {
result.setElement(requestRepresentation.getElement());
addDocForExample(result.getDoc(), requestRepresentation.getExample());
}
return result;
}
/**
* @param r Jersey resource component.
* @param m resource method.
* @return the enhanced {@link com.sun.research.ws.wadl.Request}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createRequest(org.glassfish.jersey.server.model.Resource,
* org.glassfish.jersey.server.model.ResourceMethod)
*/
public Request createRequest(final org.glassfish.jersey.server.model.Resource r,
final org.glassfish.jersey.server.model.ResourceMethod m) {
return delegate.createRequest(r, m);
}
/**
* @param r Jersey resource component.
* @param m resource method.
* @return the enhanced {@link com.sun.research.ws.wadl.Response}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createResponses(org.glassfish.jersey.server.model.Resource,
* org.glassfish.jersey.server.model.ResourceMethod)
*/
public List createResponses(final org.glassfish.jersey.server.model.Resource r,
final org.glassfish.jersey.server.model.ResourceMethod m) {
final ResponseDocType responseDoc = resourceDoc.getResponse(m.getInvocable().getDefinitionMethod().getDeclaringClass(),
m.getInvocable().getDefinitionMethod());
List responses = new ArrayList();
if (responseDoc != null && responseDoc.hasRepresentations()) {
for (final RepresentationDocType representationDoc : responseDoc.getRepresentations()) {
final Response response = new Response();
final Representation wadlRepresentation = new Representation();
wadlRepresentation.setElement(representationDoc.getElement());
wadlRepresentation.setMediaType(representationDoc.getMediaType());
addDocForExample(wadlRepresentation.getDoc(), representationDoc.getExample());
addDoc(wadlRepresentation.getDoc(), representationDoc.getDoc());
response.getStatus().add(representationDoc.getStatus());
response.getRepresentation().add(wadlRepresentation);
responses.add(response);
}
if (!responseDoc.getWadlParams().isEmpty()) {
for (final WadlParamType wadlParamType : responseDoc.getWadlParams()) {
final Param param = new Param();
param.setName(wadlParamType.getName());
param.setStyle(ParamStyle.fromValue(wadlParamType.getStyle()));
param.setType(wadlParamType.getType());
addDoc(param.getDoc(), wadlParamType.getDoc());
for (final Response response : responses) {
response.getParam().add(param);
}
}
}
if (!isEmpty(responseDoc.getReturnDoc())) {
for (final Response response : responses) {
addDoc(response.getDoc(), responseDoc.getReturnDoc());
}
}
} else {
responses = delegate.createResponses(r, m);
}
return responses;
}
private void addDocForExample(final List docs, final String example) {
if (!isEmpty(example)) {
final Doc doc = new Doc();
final Elements pElement = Elements.el("p")
.add(Elements.val("h6", "Example"))
.add(Elements.el("pre").add(Elements.val("code", example)));
doc.getContent().add(pElement);
docs.add(doc);
}
}
private void addDoc(final List docs, final String text) {
if (!isEmpty(text)) {
final Doc doc = new Doc();
doc.getContent().add(text);
docs.add(doc);
}
}
/**
* @param r Jersey resource component.
* @param m resource method.
* @param p method parameter.
* @return the enhanced {@link Param}.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createParam(org.glassfish.jersey.server.model.Resource,
* org.glassfish.jersey.server.model.ResourceMethod, org.glassfish.jersey.server.model.Parameter)
*/
public Param createParam(final org.glassfish.jersey.server.model.Resource r,
final org.glassfish.jersey.server.model.ResourceMethod m, final Parameter p) {
final Param result = delegate.createParam(r, m, p);
if (result != null) {
final ParamDocType paramDoc = resourceDoc.getParamDoc(m.getInvocable().getDefinitionMethod().getDeclaringClass(),
m.getInvocable().getDefinitionMethod(), p);
if (paramDoc != null && !isEmpty(paramDoc.getCommentText())) {
final Doc doc = new Doc();
doc.getContent().add(paramDoc.getCommentText());
result.getDoc().add(doc);
}
}
return result;
}
/**
* @return the {@link com.sun.research.ws.wadl.Resources} created by the delegate.
* @see org.glassfish.jersey.server.wadl.WadlGenerator#createResources()
*/
public Resources createResources() {
return delegate.createResources();
}
private boolean isEmpty(final String text) {
return text == null || text.isEmpty() || "".equals(text.trim());
}
// ================ methods for post build actions =======================
@Override
public ExternalGrammarDefinition createExternalGrammar() {
return delegate.createExternalGrammar();
}
@Override
public void attachTypes(final ApplicationDescription egd) {
delegate.attachTypes(egd);
}
}