/*
* Copyright 2011 cruxframework.org
*
* 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.cruxframework.crux.core.server.rest.core.registry;
import java.util.ArrayList;
import java.util.List;
import org.cruxframework.crux.core.server.rest.core.MediaType;
import org.cruxframework.crux.core.server.rest.core.dispatch.ResourceMethod;
import org.cruxframework.crux.core.server.rest.spi.AmbiguousServiceException;
import org.cruxframework.crux.core.server.rest.spi.HttpRequest;
import org.cruxframework.crux.core.server.rest.spi.InternalServerErrorException;
import org.cruxframework.crux.core.server.rest.spi.MethodNotAllowedException;
import org.cruxframework.crux.core.server.rest.spi.NotAcceptableException;
import org.cruxframework.crux.core.server.rest.spi.NotFoundException;
/**
*
* @author Thiago da Rosa de Bustamante
*
*/
public class Segment
{
private List<ResourceMethod> methods = new ArrayList<ResourceMethod>();
protected boolean isEmpty()
{
return methods.size() == 0;
}
protected ResourceMethod match(String httpMethod, HttpRequest request)
{
// MediaType contentType = request.getHttpHeaders().getMediaType();
List<MediaType> accepts = request.getHttpHeaders().getAcceptableMediaTypes();
if (!isResponseMediaTypeAllowed(accepts))
{
throw new NotAcceptableException("No match for accept header");
}
ResourceMethod invoker = null;
for (ResourceMethod rm : methods)
{
if (rm.getHttpMethod() != null && rm.getHttpMethod().equals(httpMethod))
{
if (invoker != null)
{
throw new InternalServerErrorException("More than one method is bound to the same REST operation (URI + Method Type)", "Error processing requested operation.");
}
invoker = rm;
}
}
if (invoker == null)
{
if (methods == null || methods.size() == 0)
{
throw new NotFoundException("Could not find resource for full path: " + request.getUri().getRequestUri());
}
throw new MethodNotAllowedException("No resource method found for " + httpMethod);
}
return invoker;
}
protected void addMethod(ResourceMethod invoker)
{
for (ResourceMethod res : methods)
{
if (res.getHttpMethod() != null && res.getHttpMethod().equals(invoker.getHttpMethod()))
{
throw new AmbiguousServiceException("Ambiguous service methods. Methods ["+invoker.getMethod().getName()+"] " +
"and ["+res.getMethod().getName()+"], declared on class ["+invoker.getResourceClass().getCanonicalName()+"] tries to serve" +
" the same rest path and HTTP method.");
}
}
methods.add(invoker);
}
protected boolean isResponseMediaTypeAllowed(List<MediaType> accepts)
{
boolean responseMediaTypeAllowed = false;
if (accepts == null || accepts.isEmpty())
{ // assumes accepts '*' if not informed
responseMediaTypeAllowed = true;
}
else
{
for (MediaType accept : accepts)
{
if (MediaType.APPLICATION_JSON_TYPE.isCompatible(accept))
{
responseMediaTypeAllowed = true;
break;
}
}
}
return responseMediaTypeAllowed;
}
}