org.glassfish.jersey.server.model.RuntimeResource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaxrs-ri Show documentation
Show all versions of jaxrs-ri Show documentation
A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle
(jaxrs-ri.jar).
Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and
contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external
RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source
bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external
RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI
sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from
the command line.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.jersey.server.model;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.glassfish.jersey.uri.PathPattern;
import jersey.repackaged.com.google.common.base.Function;
import jersey.repackaged.com.google.common.collect.Lists;
/**
* Runtime resource is a group of {@link Resource resources} with the same {@link Resource#getPath() path}
* regular expression. Runtime resource is constructed from {@link Resource resources} creating
* the {@link ResourceModel resource model}.
*
* Runtime resource can have child runtime resources which are groups of child resources of all resources constructing this
* runtime resource.
*
* The following example shows how Runtime resource structure is built from Resource model:
*
* @Path("{foo}")
* public class TemplateResourceFoo {
* @GET
* @Path("child")
* public String getFoo() {...}
*
* @Path("{x}")
* @GET
* public String getX() {...}
*
* @Path("{y}")
* @POST
* public String postY(String entity) {...}
* }
*
* @Path("{bar}")
* public class TemplateResourceBar {
* @Path("{z}")
* @PUT
* public String putZ(String entity) {...}
* }
*
*
* Will be represented by RuntimeResources:
*
*
* line
* RuntimeResource regex
* Grouped Resources (paths)
* Parent RuntimeResource (line)
*
*
* 1
* "/([^/]+?)"
* Resource("{foo}"), Resource("{bar}")
* no parent
*
*
* 2
* "child"
* Child Resource("child")
* 1
*
*
* 3
* "/([^/]+?)"
* Child Resource("{x}"), Child Resource("{y}"), Child Resource("{z}")
* 1
*
*
*
* @author Miroslav Fuksa (miroslav.fuksa at oracle.com)
*/
public class RuntimeResource implements ResourceModelComponent {
/**
* Runtime Resource builder.
*/
static class Builder {
private final List resources;
private final String regex;
private final List childRuntimeResourceBuilders;
/**
* Create new {@link RuntimeResource runtime resource} builder instance.
*
* @param resources List of resources with same regex that creates a RuntimeResource.
* @param childRuntimeResourceBuilders List of builders of child runtime resources that belong runtime resource.
* @param regex Path regular expression.
*/
public Builder(List resources, List childRuntimeResourceBuilders, String regex) {
this.childRuntimeResourceBuilders = childRuntimeResourceBuilders;
this.resources = resources;
this.regex = regex;
}
/**
* Build new RuntimeResource from this builder.
*
* @param parent Parent runtime resource.
* @return New RuntimeResource instance.
*/
public RuntimeResource build(RuntimeResource parent) {
return new RuntimeResource(resources, childRuntimeResourceBuilders, parent, regex);
}
}
/**
* Comparator of RuntimeResources based on rules respecting resource matching algorithm.
*/
public static final Comparator COMPARATOR = new Comparator() {
@Override
public int compare(RuntimeResource o1, RuntimeResource o2) {
return PathPattern.COMPARATOR.compare(o1.getPathPattern(), o2.getPathPattern());
}
};
private final String regex;
private final List resourceMethods;
private final List resourceLocators;
private final List childRuntimeResources;
private final List resources;
private final RuntimeResource parent;
private final PathPattern pathPattern;
private RuntimeResource(List resources,
List childRuntimeResourceBuilders,
RuntimeResource parent,
String regex) {
this.parent = parent;
this.pathPattern = resources.get(0).getPathPattern();
this.resources = Lists.newArrayList(resources);
this.regex = regex;
this.resourceMethods = Lists.newArrayList();
this.resourceLocators = Lists.newArrayList();
this.childRuntimeResources = Lists.newArrayList();
for (Builder childRuntimeResourceBuilder : childRuntimeResourceBuilders) {
this.childRuntimeResources.add(childRuntimeResourceBuilder.build(this));
}
Collections.sort(this.childRuntimeResources, COMPARATOR);
for (final Resource res : this.resources) {
this.resourceMethods.addAll(res.getResourceMethods());
final ResourceMethod resourceLocator = res.getResourceLocator();
if (resourceLocator != null) {
this.resourceLocators.add(resourceLocator);
}
}
}
/**
* Get child runtime resources of this resource.
*
* @return List of child runtime resource.
*/
public List getChildRuntimeResources() {
return childRuntimeResources;
}
/**
* Get regular expression of path pattern of this runtime resource.
*
* @return Matching regular expression.
*/
public String getRegex() {
return regex;
}
/**
* Get resource methods (excluding resource locators) of all {@link Resource resources} of this runtime resource.
*
* @return List of resource methods.
*/
public List getResourceMethods() {
return resourceMethods;
}
/**
* Get resource locators of all {@link Resource resources} of this runtime resource.
*
* Note that valid RuntimeResource should have only one resource locator. This method is used for validation purposes.
*
* @return List of resource locators.
*/
public List getResourceLocators() {
return resourceLocators;
}
/**
* Return the resource locator of this resource.
*
* @return Resource locator of this runtime resource.
*/
public ResourceMethod getResourceLocator() {
if (resourceLocators.size() >= 1) {
return resourceLocators.get(0);
} else {
return null;
}
}
/**
* Get parent of this runtime resource.
*
* @return Parent runtime resource if this runtime resource is a child resource, null otherwise.
*/
public RuntimeResource getParent() {
return parent;
}
/**
* Get path pattern for matching purposes.
*
* @return Path pattern.
*/
public PathPattern getPathPattern() {
return pathPattern;
}
/**
* Get full regular expression of this runtime resource prefixed by regular expression of parent if present.
*
* @return Full resource regular expression.
*/
public String getFullPathRegex() {
if (parent == null) {
return regex;
} else {
return parent.getRegex() + regex;
}
}
/**
* Return parent {@link Resource resources} of {@link Resource resources} from this runtime resource. The returned list
* is ordered so that the position of the parent resource in the returned list is the same as position of its child resource
* in list returned by {@link #getResources()}. Simply said the order of lists returned
* from {@code getParentResources()} and {@link #getResources()} from parent-child point of view is the same. If the resource
* has no parent then the element {@code null} is in the list.
*
* @return Parent resource list with resources if this runtime resource is child resource or {@code null} elements if
* this runtime resource is the parent resource.
*/
public List getParentResources() {
return Lists.transform(resources, new Function() {
@Override
public Resource apply(Resource child) {
return (child == null) ? null : child.getParent();
}
});
}
/**
* Get resources creating this runtime resource.
*
* @return List of resources with same path regular expression which this resource is based on.
*/
public List getResources() {
return resources;
}
@Override
public void accept(ResourceModelVisitor visitor) {
visitor.visitRuntimeResource(this);
}
@Override
public List extends ResourceModelComponent> getComponents() {
return getChildRuntimeResources();
}
}