/******************************************************************************* * * Copyright 2010 Alexandru Craciun, and individual contributors as indicated * by the @authors tag. * * This 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; either version 3 of * the License, or (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. ******************************************************************************/ package org.netxilia.jaxrs.html; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; @Produces("text/html") @Provider public class HTMLProvider implements MessageBodyWriter<ModelAndView<?>> { public static final String NETXILIA_REDIRECT_COOKIE = "nx.redirect"; @Context private HttpServletResponse response; @Context private HttpServletRequest request; private String modelAttributeName = "model"; private List<IHTMLProviderInterceptor<?>> interceptors; public List<IHTMLProviderInterceptor<?>> getInterceptors() { return interceptors; } public void setInterceptors(List<IHTMLProviderInterceptor<?>> interceptors) { this.interceptors = interceptors; } @Override public long getSize(ModelAndView<?> t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) { return -1; } @Override public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) { // there should be only one html provider and different mappers. // TODO does it make sense to check with the mapper here? return true; } /** * The name of the request attribute will contain the object returned by the resource's method call. * * @return */ public String getModelAttributeName() { return modelAttributeName; } public void setModelAttributeName(String modelAttributeName) { this.modelAttributeName = modelAttributeName; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void writeTo(ModelAndView<?> modelAndView, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, final OutputStream os) throws IOException { try { httpHeaders.putSingle(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE, mediaType.toString() + ";charset=UTF-8"); if (interceptors != null) { for (IHTMLProviderInterceptor<?> interceptor : interceptors) { interceptor.intercept((ModelAndView) modelAndView, request); } } RequestDispatcher dispatcher = request.getRequestDispatcher(modelAndView.getView()); if (dispatcher == null) { throw new IOException("Cannot find the JSP page [" + modelAndView.getView() + "]"); } HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request); wrappedRequest.setAttribute(modelAttributeName, modelAndView.getModel()); dispatcher.forward(wrappedRequest, response); } catch (Exception e) { throw new IOException(e); } } }