/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.api.handlers; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.core.Response.ResponseBuilder; import org.apache.wink.common.internal.ResponseImpl.ResponseBuilderImpl; import org.apache.wink.server.handlers.MessageContext; import org.apache.wink.server.internal.handlers.CheckLocationHeaderHandler; import org.apache.wink.server.internal.handlers.SearchResult; import org.apache.wink.server.utils.LinkBuilders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.context.support.WebApplicationContextUtils; import com.abiquo.api.util.AbiquoLinkBuildersFactory; import com.abiquo.api.util.IRESTBuilder; import com.abiquo.model.transport.AcceptedRequestDto; import com.abiquo.model.transport.MovedPermanentlyDto; import com.abiquo.model.transport.SeeOtherDto; import com.abiquo.model.transport.SingleResourceTransportDto; import com.abiquo.model.transport.WrapperDto; import com.google.common.collect.Iterables; public class RESTHandler extends CheckLocationHeaderHandler { protected Class<IRESTBuilder> REST_BUILDER_INTERFACE = IRESTBuilder.class; private static final Logger LOGGER = LoggerFactory.getLogger(RESTHandler.class); @Override public void handleRequest(final MessageContext context) { LinkBuilders builder = new AbiquoLinkBuildersFactory(context); context.getAttributes().remove(LinkBuilders.class.getName()); context.setAttribute(LinkBuilders.class, builder); SearchResult searchResult = context.getAttribute(SearchResult.class); Object[] parameters = searchResult.getInvocationParameters(); Collection<Object> newParameters = new ArrayList<Object>(); if (parameters != null && parameters.length > 0) { for (Object parameter : parameters) { if (parameter instanceof LinkBuilders) { newParameters.add(builder); } else { newParameters.add(parameter); } } } searchResult .setInvocationParameters(newParameters.toArray(new Object[newParameters.size()])); context.setAttribute(SearchResult.class, searchResult); createRESTBuilder(context, builder); } @Override public void handleResponse(final MessageContext context) throws Throwable { if (context.getResponseStatusCode() == HttpServletResponse.SC_OK && context.getResponseEntity() != null && context.getResponseEntity() instanceof SeeOtherDto) { SeeOtherDto dto = (SeeOtherDto) context.getResponseEntity(); ResponseBuilder builder = new ResponseBuilderImpl(); builder.location(new URI(dto.getLocation())); builder.status(HttpServletResponse.SC_SEE_OTHER); context.setResponseStatusCode(HttpServletResponse.SC_SEE_OTHER); context.setResponseEntity(builder.build()); } // If the entity is the appropriate we return a 202 else if (context.getResponseStatusCode() == HttpServletResponse.SC_OK && context.getResponseEntity() != null && context.getResponseEntity() instanceof AcceptedRequestDto) { context.setResponseStatusCode(HttpServletResponse.SC_ACCEPTED); } else if (context.getResponseStatusCode() == HttpServletResponse.SC_OK && context.getResponseEntity() != null && context.getResponseEntity() instanceof MovedPermanentlyDto) { context.setResponseStatusCode(HttpServletResponse.SC_MOVED_PERMANENTLY); ResponseBuilder builder = new ResponseBuilderImpl(); builder.location(new URI(((MovedPermanentlyDto) context.getResponseEntity()) .getLocation().getHref())); builder.entity(context.getResponseEntity()); builder.status(HttpServletResponse.SC_MOVED_PERMANENTLY); context.setResponseEntity(builder.build()); } else if (context.getResponseStatusCode() == HttpServletResponse.SC_OK && RequestMethod.valueOf(context.getRequest().getMethod()) == RequestMethod.POST) { context.setResponseStatusCode(HttpServletResponse.SC_CREATED); Object entity = context.getResponseEntity(); if (entity instanceof SingleResourceTransportDto) { SingleResourceTransportDto resource = (SingleResourceTransportDto) entity; ResponseBuilder builder = new ResponseBuilderImpl(); if (!(entity instanceof WrapperDto)) { if (resource.getEditLink() != null) { builder.location(new URI(resource.getEditLink().getHref())); } else { LOGGER.warn("The object returned by the POST " + "operation does not have an edit link"); } } builder.entity(resource); builder.status(HttpServletResponse.SC_CREATED); context.setResponseEntity(builder.build()); } } super.handleRequest(context); } protected void createRESTBuilder(final MessageContext context, final LinkBuilders linksProcessor) { ServletContext servletContext = context.getAttribute(ServletContext.class); Map<String, IRESTBuilder> beans = WebApplicationContextUtils.getWebApplicationContext(servletContext).getBeansOfType( IRESTBuilder.class); IRESTBuilder builder = Iterables.get(beans.values(), 0); context.setAttribute(REST_BUILDER_INTERFACE, builder.injectProcessor(linksProcessor)); } }