Package org.restlet.ext.wadl

Source Code of org.restlet.ext.wadl.WadlServerResource

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.ext.wadl;

import java.util.ArrayList;
import java.util.List;

import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Parameter;
import org.restlet.data.Reference;
import org.restlet.engine.header.HeaderConstants;
import org.restlet.representation.Representation;
import org.restlet.representation.Variant;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import org.restlet.util.Series;

/**
* Resource that is able to automatically describe itself with WADL. This
* description can be customized by overriding the {@link #describe()} and
* {@link #describeMethod(Method, MethodInfo)} methods.<br>
* <br>
* When used to describe a class of resources in the context of a parent
* application, a special instance will be created using the default constructor
* (with no request, response associated). In this case, the resource should do
* its best to return the generic information when the WADL description methods
* are invoked, like {@link #describe()} and delegate methods.
*
* @author Jerome Louvel
*/
public class WadlServerResource extends ServerResource {

    /**
     * Indicates if the resource should be automatically described via WADL when
     * an OPTIONS request is handled.
     */
    private volatile boolean autoDescribing;

    /**
     * The description of this documented resource. Is seen as the text content
     * of the "doc" tag of the "resource" element in a WADL document.
     */
    private volatile String description;

    /**
     * The name of this documented resource. Is seen as the title of the "doc"
     * tag of the "resource" element in a WADL document.
     */
    private volatile String name;

    /**
     * Constructor.
     */
    public WadlServerResource() {
        this.autoDescribing = true;
    }

    /**
     * Indicates if the given method exposes its WADL description. By default,
     * HEAD and OPTIONS are not exposed. This method is called by
     * {@link #describe(String, ResourceInfo)}.
     *
     * @param method
     *            The method
     * @return True if the method exposes its description, false otherwise.
     */
    public boolean canDescribe(Method method) {
        return !(Method.HEAD.equals(method) || Method.OPTIONS.equals(method));
    }

    /**
     * Creates a new HTML representation for a given {@link ApplicationInfo}
     * instance describing an application.
     *
     * @param applicationInfo
     *            The application description.
     * @return The created {@link WadlRepresentation}.
     */
    protected Representation createHtmlRepresentation(
            ApplicationInfo applicationInfo) {
        return new WadlRepresentation(applicationInfo).getHtmlRepresentation();
    }

    /**
     * Creates a new WADL representation for a given {@link ApplicationInfo}
     * instance describing an application.
     *
     * @param applicationInfo
     *            The application description.
     * @return The created {@link WadlRepresentation}.
     */
    protected Representation createWadlRepresentation(
            ApplicationInfo applicationInfo) {
        return new WadlRepresentation(applicationInfo);
    }

    /**
     * Describes the resource as a standalone WADL document.
     *
     * @return The WADL description.
     */
    protected Representation describe() {
        return describe(getPreferredWadlVariant());
    }

    /**
     * Updates the description of the parent application. This is typically used
     * to add documentation on global representations used by several methods or
     * resources. Does nothing by default.
     *
     * @param applicationInfo
     *            The parent application.
     */
    protected void describe(ApplicationInfo applicationInfo) {
    }

    /**
     * Describes a representation class and variant couple as WADL information.
     * The variant contains the target media type that can be converted to by
     * one of the available Restlet converters.
     *
     * @param methodInfo
     *            The parent method description.
     * @param representationClass
     *            The representation bean class.
     * @param variant
     *            The target variant.
     * @return The WADL representation information.
     */
    protected RepresentationInfo describe(MethodInfo methodInfo,
            Class<?> representationClass, Variant variant) {
        return new RepresentationInfo(variant);
    }

    /**
     * Describes a representation class and variant couple as WADL information
     * for the given method and request. The variant contains the target media
     * type that can be converted to by one of the available Restlet converters.<br>
     * <br>
     * By default, it calls {@link #describe(MethodInfo, Class, Variant)}.
     *
     * @param methodInfo
     *            The parent method description.
     * @param requestInfo
     *            The parent request description.
     * @param representationClass
     *            The representation bean class.
     * @param variant
     *            The target variant.
     * @return The WADL representation information.
     */
    protected RepresentationInfo describe(MethodInfo methodInfo,
            RequestInfo requestInfo, Class<?> representationClass,
            Variant variant) {
        return describe(methodInfo, representationClass, variant);
    }

    /**
     * Describes a representation class and variant couple as WADL information
     * for the given method and response. The variant contains the target media
     * type that can be converted to by one of the available Restlet converters.<br>
     * <br>
     * By default, it calls {@link #describe(MethodInfo, Class, Variant)}.
     *
     * @param methodInfo
     *            The parent method description.
     * @param responseInfo
     *            The parent response description.
     * @param representationClass
     *            The representation bean class.
     * @param variant
     *            The target variant.
     * @return The WADL representation information.
     */
    protected RepresentationInfo describe(MethodInfo methodInfo,
            ResponseInfo responseInfo, Class<?> representationClass,
            Variant variant) {
        return describe(methodInfo, representationClass, variant);
    }

    /**
     * Returns a WADL description of the current resource, leveraging the
     * {@link #getResourcePath()} method.
     *
     * @param info
     *            WADL description of the current resource to update.
     */
    public void describe(ResourceInfo info) {
        describe(getResourcePath(), info);
    }

    /**
     * Returns a WADL description of the current resource.
     *
     * @param path
     *            Path of the current resource.
     * @param info
     *            WADL description of the current resource to update.
     */
    public void describe(String path, ResourceInfo info) {
        ResourceInfo.describe(null, info, this, path);
    }

    /**
     * Describes the resource as a WADL document for the given variant.
     *
     * @param variant
     *            The WADL variant.
     * @return The WADL description.
     */
    protected Representation describe(Variant variant) {
        Representation result = null;

        if (variant != null) {
            ResourceInfo resource = new ResourceInfo();
            describe(resource);
            ApplicationInfo application = resource.createApplication();
            describe(application);

            if (MediaType.APPLICATION_WADL.equals(variant.getMediaType())) {
                result = createWadlRepresentation(application);
            } else if (MediaType.TEXT_HTML.equals(variant.getMediaType())) {
                result = createHtmlRepresentation(application);
            }
        }

        return result;
    }

    /**
     * Describes the DELETE method.
     *
     * @param info
     *            The method description to update.
     */
    protected void describeDelete(MethodInfo info) {
        MethodInfo.describeAnnotations(info, this);
    }

    /**
     * Describes the GET method.<br>
     * By default, it describes the response with the available variants based
     * on the {@link #getVariants()} method. Thus in the majority of cases, the
     * method of the super class must be called when overridden.
     *
     * @param info
     *            The method description to update.
     */
    protected void describeGet(MethodInfo info) {
        MethodInfo.describeAnnotations(info, this);
    }

    /**
     * Returns a WADL description of the current method.
     *
     * @return A WADL description of the current method.
     */
    protected MethodInfo describeMethod() {
        MethodInfo result = new MethodInfo();
        describeMethod(getMethod(), result);
        return result;
    }

    /**
     * Returns a WADL description of the given method.
     *
     * @param method
     *            The method to describe.
     * @param info
     *            The method description to update.
     */
    protected void describeMethod(Method method, MethodInfo info) {
        info.setName(method);

        if (Method.GET.equals(method)) {
            describeGet(info);
        } else if (Method.POST.equals(method)) {
            describePost(info);
        } else if (Method.PUT.equals(method)) {
            describePut(info);
        } else if (Method.DELETE.equals(method)) {
            describeDelete(info);
        } else if (Method.OPTIONS.equals(method)) {
            describeOptions(info);
        }
    }

    /**
     * Describes the OPTIONS method.<br>
     * By default it describes the response with the available variants based on
     * the {@link #getWadlVariants()} method.
     *
     * @param info
     *            The method description to update.
     */
    protected void describeOptions(MethodInfo info) {
        // Describe each variant
        for (Variant variant : getWadlVariants()) {
            RepresentationInfo result = new RepresentationInfo(variant);
            info.getResponse().getRepresentations().add(result);
        }
    }

    /**
     * Returns the description of the parameters of this resource. Returns null
     * by default.
     *
     * @return The description of the parameters.
     */
    protected List<ParameterInfo> describeParameters() {
        return null;
    }

    /**
     * Describes the POST method.
     *
     * @param info
     *            The method description to update.
     */
    protected void describePost(MethodInfo info) {
        MethodInfo.describeAnnotations(info, this);
    }

    /**
     * Describes the PUT method.
     *
     * @param info
     *            The method description to update.
     */
    protected void describePut(MethodInfo info) {
        MethodInfo.describeAnnotations(info, this);
    }

    @Override
    protected void doInit() throws ResourceException {
        super.doInit();
        this.autoDescribing = true;
    }

    /**
     * Returns the description of this documented resource. Is seen as the text
     * content of the "doc" tag of the "resource" element in a WADL document.
     *
     * @return The description of this documented resource.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Returns the set of headers as a collection of {@link Parameter} objects.
     *
     * @return The set of headers as a collection of {@link Parameter} objects.
     */
    private Form getHeaders() {
        return (Form) getRequestAttributes().get(
                HeaderConstants.ATTRIBUTE_HEADERS);
    }

    /**
     * Returns the name of this documented resource. Is seen as the title of the
     * "doc" tag of the "resource" element in a WADL document.
     *
     * @return The name of this documented resource.
     */
    public String getName() {
        return name;
    }

    /**
     * Returns the first parameter found in the current context (entity, query,
     * headers, etc) with the given name.
     *
     * @param name
     *            The parameter name.
     * @return The first parameter found with the given name.
     */
    protected Parameter getParameter(String name) {
        Parameter result = null;
        Series<Parameter> set = getParameters(name);

        if (set != null) {
            result = set.getFirst(name);
        }

        return result;
    }

    /**
     * Returns a collection of parameters objects contained in the current
     * context (entity, query, headers, etc) given a ParameterInfo instance.
     *
     * @param parameterInfo
     *            The ParameterInfo instance.
     * @return A collection of parameters objects
     */
    private Series<Parameter> getParameters(ParameterInfo parameterInfo) {
        Series<Parameter> result = null;

        if (parameterInfo.getFixed() != null) {
            result = new Form();
            result.add(parameterInfo.getName(), parameterInfo.getFixed());
        } else if (ParameterStyle.HEADER.equals(parameterInfo.getStyle())) {
            result = getHeaders().subList(parameterInfo.getName());
        } else if (ParameterStyle.TEMPLATE.equals(parameterInfo.getStyle())) {
            Object parameter = getRequest().getAttributes().get(
                    parameterInfo.getName());
            if (parameter != null) {
                result = new Form();
                result.add(parameterInfo.getName(), Reference
                        .decode((String) parameter));
            }
        } else if (ParameterStyle.MATRIX.equals(parameterInfo.getStyle())) {
            result = getMatrix().subList(parameterInfo.getName());
        } else if (ParameterStyle.QUERY.equals(parameterInfo.getStyle())) {
            result = getQuery().subList(parameterInfo.getName());
        } else if (ParameterStyle.PLAIN.equals(parameterInfo.getStyle())) {
            // TODO not yet implemented.
        }

        if (result == null && parameterInfo.getDefaultValue() != null) {
            result = new Form();
            result
                    .add(parameterInfo.getName(), parameterInfo
                            .getDefaultValue());
        }

        return result;
    }

    /**
     * Returns a collection of parameters found in the current context (entity,
     * query, headers, etc) given a parameter name. It returns null if the
     * parameter name is unknown.
     *
     * @param name
     *            The name of the parameter.
     * @return A collection of parameters.
     */
    protected Series<Parameter> getParameters(String name) {
        Series<Parameter> result = null;

        if (describeParameters() != null) {
            for (ParameterInfo parameter : describeParameters()) {
                if (name.equals(parameter.getName())) {
                    result = getParameters(parameter);
                }
            }
        }

        return result;
    }

    /**
     * Returns the preferred WADL variant according to the client preferences
     * specified in the request.
     *
     * @return The preferred WADL variant.
     */
    protected Variant getPreferredWadlVariant() {
        Variant result = null;

        // Compute the preferred variant
        result = getRequest().getClientInfo().getPreferredVariant(
                getWadlVariants(),
                (getApplication() == null) ? null : getApplication()
                        .getMetadataService());

        return result;
    }

    /**
     * Returns the resource's relative path.
     *
     * @return The resource's relative path.
     */
    protected String getResourcePath() {
        Reference ref = new Reference(getRequest().getRootRef(), getRequest()
                .getResourceRef());
        return ref.getRemainingPart();
    }

    /**
     * Returns the application resources base URI.
     *
     * @return The application resources base URI.
     */
    protected Reference getResourcesBase() {
        return getRequest().getRootRef();
    }

    /**
     * Returns the available WADL variants.
     *
     * @return The available WADL variants.
     */
    protected List<Variant> getWadlVariants() {
        List<Variant> result = new ArrayList<Variant>();
        result.add(new Variant(MediaType.APPLICATION_WADL));
        result.add(new Variant(MediaType.TEXT_HTML));
        return result;
    }

    /**
     * Indicates if the resource should be automatically described via WADL when
     * an OPTIONS request is handled.
     *
     * @return True if the resource should be automatically described via WADL.
     */
    public boolean isAutoDescribing() {
        return this.autoDescribing;
    }

    @Override
    public Representation options() {
        if (isAutoDescribing()) {
            return describe();
        }

        return null;
    }

    /**
     * Indicates if the resource should be automatically described via WADL when
     * an OPTIONS request is handled.
     *
     * @param autoDescribed
     *            True if the resource should be automatically described via
     *            WADL.
     */
    public void setAutoDescribing(boolean autoDescribed) {
        this.autoDescribing = autoDescribed;
    }

    /**
     * Sets the description of this documented resource. Is seen as the text
     * content of the "doc" tag of the "resource" element in a WADL document.
     *
     * @param description
     *            The description of this documented resource.
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Sets the name of this documented resource. Is seen as the title of the
     * "doc" tag of the "resource" element in a WADL document.
     *
     * @param name
     *            The name of this documented resource.
     */
    public void setName(String name) {
        this.name = name;
    }

}
TOP

Related Classes of org.restlet.ext.wadl.WadlServerResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.