Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.wink.server.internal.handlers;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.wink.common.internal.registry.metadata.MethodMetadata;
import org.apache.wink.common.internal.uritemplate.UriTemplateMatcher;
import org.apache.wink.server.handlers.HandlersChain;
import org.apache.wink.server.handlers.MessageContext;
import org.apache.wink.server.handlers.RequestHandler;
import org.apache.wink.server.internal.contexts.UriInfoImpl;
import org.apache.wink.server.internal.handlers.SearchResult.AccumulatedData;
import org.apache.wink.server.internal.registry.MethodRecord;
import org.apache.wink.server.internal.registry.ResourceInstance;
import org.apache.wink.server.internal.registry.ResourceRecord;
import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.apache.wink.server.internal.registry.SubResourceInstance;
import org.apache.wink.server.internal.registry.SubResourceMethodRecord;
import org.apache.wink.server.internal.registry.SubResourceRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FindResourceMethodHandler implements RequestHandler {
private boolean isContinuedSearchPolicy;
private static final Logger logger = LoggerFactory.getLogger(FindResourceMethodHandler.class);
public void handleRequest(MessageContext context, HandlersChain chain) throws Throwable {
SearchResult result = context.getAttribute(SearchResult.class);
ResourceInstance resource = result.getResource();
// resource method
if (resource.isExactMatch()) {
logger
.trace("Root resource @Path matches exactly so finding root resource method in {}", //$NON-NLS-1$
resource.getResourceClass().getName());
handleResourceMethod(context, chain);
return;
}
// sub-resource method or locator
UriTemplateMatcher templateMatcher = resource.getMatcher();
String tail = templateMatcher.getTail(false);
if (tail == null) {
tail = ""; //$NON-NLS-1$
}
if (tail.startsWith("/")) { //$NON-NLS-1$
tail = tail.substring(1);
}
logger.trace("Unmatched tail to the URI: {}", tail); //$NON-NLS-1$
// get a sorted list of all the sub-resources (methods and locators)
List subResources = resource.getRecord().getMatchingSubResources(tail);
logger.trace("Possible subresources found: {}", subResources); //$NON-NLS-1$
if (subResources.size() == 0) {
result.setError(new WebApplicationException(Response.Status.NOT_FOUND));
return;
}
// get all the searchable sub-resources
List searchableSubResources = getSearchableSubResources(subResources);
logger.trace("Possible searchable subresources found: {}", searchableSubResources); //$NON-NLS-1$
// save the current data in case we need to role back the information if
// the search fails and we will need to continue to the next
// sub-resource
// (for continued search mode only)
AccumulatedData originalData = result.getData();
// iterate through all sub-resources until a match is found.
// JAX-RS compliance requires to look only at the first sub-resource -
// this will be the case
// unless the search policy is specifically set to "continued search"
for (SubResourceInstance subResourceInstance : searchableSubResources) {
SubResourceRecord subResourceRecord = subResourceInstance.getRecord();
// set a clone of the accumulated data before continuing to the next
// sub-resource
result.setData(originalData.clone());
// handle the sub-resource
if (subResourceRecord instanceof SubResourceMethodRecord) {
handleSubResourceMethod(subResourceInstance, subResources, context, chain);
if (result.isFound()) {
return;
}
} else {
handleSubResourceLocator(subResourceInstance, subResources, context, chain);
// check the result of the recursive call
if (result.isFound()) {
return;
}
}
}
}
private void handleResourceMethod(MessageContext context, HandlersChain chain) throws Throwable {
// if the resource is an exact match to the uri, then this is the
// handling resource,
// and we need to find the dispatch method.
// if no method is found then a RequestMatchingException exception is
// thrown
ResourceRegistry registry = context.getAttribute(ResourceRegistry.class);
SearchResult result = context.getAttribute(SearchResult.class);
ResourceInstance resource = result.getResource();
MethodRecord method = null;
try {
// if no method is found then a RequestMatchingException exception
// is thrown
method = registry.findMethod(resource, context);
} catch (WebApplicationException e) {
// couldn't find a method
result.setError(e);
return;
}
result.setFound(true);
result.setMethod(method);
// continue the chain to invoke the method
if (logger.isTraceEnabled()) {
MethodMetadata metadata = (method == null) ? null : method.getMetadata();
logger.trace("Found root resource method to invoke: {} ", metadata); //$NON-NLS-1$
}
chain.doChain(context);
}
private void handleSubResourceMethod(SubResourceInstance subResourceInstance,
List subResources,
MessageContext context,
HandlersChain chain) throws Throwable {
ResourceRegistry registry = context.getAttribute(ResourceRegistry.class);
SearchResult result = context.getAttribute(SearchResult.class);
ResourceInstance resource = result.getResource();
SubResourceRecord subResourceRecord = subResourceInstance.getRecord();
String pattern = subResourceRecord.getTemplateProcessor().getPatternString();
// dispatch to one of the sub-resource methods.
SubResourceInstance method = null;
try {
// if no method is found then a RequestMatchingException exception
// is thrown
method = registry.findSubResourceMethod(pattern, subResources, resource, context);
} catch (WebApplicationException e) {
// couldn't find a method
result.setError(e);
return;
}
UriTemplateMatcher matcher = method.getMatcher();
saveFoundMethod(result, matcher, method, context);
// continue the chain to invoke the method
if (logger.isTraceEnabled()) {
MethodMetadata metadata = (method == null) ? null : method.getMetadata();
logger.trace("Found subresource method to invoke: {} ", metadata); //$NON-NLS-1$
}
chain.doChain(context);
}
private void handleSubResourceLocator(SubResourceInstance subResourceInstance,
List subResources,
MessageContext context,
HandlersChain chain) throws Throwable {
ResourceRegistry registry = context.getAttribute(ResourceRegistry.class);
SearchResult result = context.getAttribute(SearchResult.class);
UriTemplateMatcher matcher = subResourceInstance.getMatcher();
// // dispatch to the sub-resource locator.
// result.setFound(true);
// result.setMethod(subResourceInstance);
// // save the matched template variables for UriInfo
// matcher.storeVariables(result.getData().getMatchedVariables(),
// false);
// // save the matched uri for UriInfo
// result.getData().addMatchedUri(matcher.getHead(false));
saveFoundMethod(result, matcher, subResourceInstance, context);
// continue the chain to invoke the locator
if (logger.isTraceEnabled()) {
MethodMetadata metadata =
(subResourceInstance == null) ? null : subResourceInstance.getMetadata();
logger.trace("Found subresource locator to invoke: {} ", metadata); //$NON-NLS-1$
}
chain.doChain(context);
// the object returned from the locator is a sub-resource so we must
// continue the search in it
Object subResource = context.getResponseEntity();
if (subResource == null) {
logger.trace("Subresource returned was null so returning a 404 Not Found"); //$NON-NLS-1$
result.setError(new WebApplicationException(Status.NOT_FOUND));
return;
}
ResourceRecord record = registry.getRecord(subResource, false);
ResourceInstance resourceInstance = new ResourceInstance(subResource, record, matcher);
// save the resource for UriInfo
result.getData().getMatchedResources().addFirst(resourceInstance);
// call recursively to search in the sub-resource
result.setFound(false);
logger
.trace("Re-invoking the chain (due to hitting a subresource locator method) with the new subresource instance {}", //$NON-NLS-1$
resourceInstance);
handleRequest(context, chain);
}
private List getSearchableSubResources(List subResources) {
// JAX-RS specification requires that if the first matching sub-resource
// is a method,
// then we must dispatch to one of the sub-resource methods, otherwise
// we should invoke the sub-resource locator.
// but the continued search behavior is to continue searching in all
// matching
// sub-resources
List searchableSubResources = new LinkedList();
if (!isContinuedSearchPolicy) {
// strict behavior - look only at the first method
searchableSubResources.add(subResources.iterator().next());
} else {
// continued search behavior - search through all sub-resources
searchableSubResources.addAll(subResources);
}
return searchableSubResources;
}
private void saveFoundMethod(SearchResult result,
UriTemplateMatcher matcher,
SubResourceInstance method,
MessageContext context) {
result.setFound(true);
result.setMethod(method);
// save the matched template variables for UriInfo
matcher.storeVariables(result.getData().getMatchedVariables(), false);
// save the path segments of the matched path variables.
// the matched "head" is added to the "matched uri's" list to reflect
// the
// most recent match. the difference in the number of segments between
// the uri of the
// previous match and the uri of the current match reflects the number
// of segments that
// the head of the current match contains.
// this is done in this way (instead of just converting the "head" into
// path segments)
// because we want to save the path segments with the matrix parameters,
// and the "head" matched
// part was matched without the matrix parameters, but the
// "matched uri's" list saves the
// path segments with the matrix parameters.
// 1. get the number of segments that were matched up until the current
// match. this will be used as
// the offset into the full path segments list
int offset = result.getData().calculateUriOffset();
// 2. save the current matched uri - it is added as the first uri in the
// list of matched uri's
int headSegmentsCount = result.getData().addMatchedURI(matcher.getHead(false));
List segments = context.getUriInfo().getPathSegments(false);
// 3. save the path segments of the matched variables
matcher.storeVariablesPathSegments(segments, offset, headSegmentsCount, result.getData()
.getMatchedVariablesPathSegments());
// for sub resources with annotated method parameters, we need to reload
// path parameters so that they are injected when invoked
UriInfoImpl uriInfoImpl = context.getAttribute(UriInfoImpl.class);
if (uriInfoImpl != null && matcher.getVariables().size() > 0)
uriInfoImpl.resetPathParameters();
}
public void init(Properties props) {
String property =
props.getProperty(FindRootResourceHandler.SEARCH_POLICY_CONTINUED_SEARCH_KEY);
isContinuedSearchPolicy = Boolean.valueOf(property);
}
}