View Javadoc

1   /*
2    * JaspertReports JSF Plugin Copyright (C) 2011 A. Alonso Dominguez
3    *
4    * This library is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as published by
6    * the Free Software Foundation; either version 2.1 of the License, or (at
7    * your option) any later version. This library is distributed in the hope
8    * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9    * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   *
11   * See the GNU Lesser General Public License for more details. You should have
12   * received a copy of the GNU Lesser General Public License along with this
13   * library; if not, write to the Free Software Foundation, Inc., 59 Temple
14   * Place, Suite 330, Boston, MA 02111-1307 USA A.
15   *
16   * Alonso Dominguez
17   * alonsoft@users.sf.net
18   */
19  package net.sf.jasperreports.jsf.context;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.Enumeration;
27  import java.util.List;
28  
29  import javax.faces.context.ExternalContext;
30  import javax.portlet.PortletContext;
31  import javax.portlet.PortletRequest;
32  import javax.portlet.ResourceRequest;
33  import javax.portlet.ResourceResponse;
34  import net.sf.jasperreports.jsf.Constants;
35  
36  import net.sf.jasperreports.jsf.component.UIReport;
37  import net.sf.jasperreports.jsf.config.Configuration;
38  import net.sf.jasperreports.jsf.renderkit.ReportRenderer;
39  
40  /**
41   * Portlet implementation of the external context helper.
42   *
43   * @author A. Alonso Dominguez
44   */
45  final class PortletContextHelper extends ExternalContextHelper {
46  
47      /**
48       * Protected constructor to prevent instantiation.
49       */
50      protected PortletContextHelper() {
51      }
52  
53      @Override
54      public Collection<ContentType> getAcceptedContentTypes(
55              final ExternalContext context) {
56          if ("2.0".equals(getPortletVersion())) {
57              ResourceRequest request = (ResourceRequest) context.getRequest();
58              Enumeration<String> values = request.getProperties("Accept");
59              List<ContentType> list = new ArrayList<ContentType>();
60              while (values.hasMoreElements()) {
61                  ContentType type = new ContentType(values.nextElement());
62                  list.add(type);
63              }
64              Collections.sort(list);
65              return Collections.unmodifiableList(list);
66          } else {
67              throw new IllegalStateException(
68                      "Only Resource Request/Response state is allowed");
69          }
70      }
71  
72      /**
73       * Creates a <code>ReportRenderRequest</code> based on the data code in the
74       * current ExternalContext.
75       *
76       * @param context the current ExternalContext
77       * @return A representation of the request render request
78       */
79      @Override
80      public ReportRenderRequest restoreReportRequest(
81              final ExternalContext context) {
82          if ("2.0".equals(getPortletVersion())) {
83              final Configuration config = Configuration.getInstance(context);
84              ResourceRequest request = (ResourceRequest) context.getRequest();
85              final String viewId = context.getRequestParameterMap().get(
86                      Constants.PARAM_VIEWID);
87              final String viewState = getViewCacheMap(context).get(viewId);
88  
89              request = new ReportPortletRenderRequest(request,
90                                                       config.getDefaultMapping(),
91                                                       viewId, viewState);
92              context.setRequest(request);
93              return (ReportRenderRequest) request;
94          } else {
95              throw new IllegalStateException(
96                      "Only Resource Request/Response state is allowed");
97          }
98      }
99  
100     /**
101      * Gets the request uri.
102      *
103      * @param context the context
104      * @return the request uri
105      */
106     @Override
107     public String getRequestURI(final ExternalContext context) {
108         if ("2.0".equals(getPortletVersion())) {
109             final ResourceRequest request =
110                     (ResourceRequest) context.getRequest();
111             return request.getResourceID();
112         } else {
113             return null;
114         }
115     }
116 
117     /**
118      * Obtains the server name of the current request.
119      *
120      * @param context the current ExternalContext
121      * @return the server name
122      */
123     @Override
124     public String getRequestServerName(final ExternalContext context) {
125         final PortletRequest request = (PortletRequest) context.getRequest();
126         return request.getServerName();
127     }
128 
129     /**
130      * Obtains the real path name of the resource local to the current context.
131      *
132      * @param context the current ExternalContext
133      * @param name the resource name
134      * @return the resource real path name
135      */
136     @Override
137     public String getResourceRealPath(final ExternalContext context,
138             final String name) {
139         PortletContext ctx = (PortletContext) context.getContext();
140         return ctx.getRealPath(name);
141     }
142 
143     /**
144      * Writes the report headers into the current response using the report
145      * renderer.
146      *
147      * @param context the current ExternalContext
148      * @param renderer the report renderer instance
149      * @param report the report component instance
150      * @throws IOException if any input or output error happens when writing
151      *         the report headers
152      */
153     @Override
154     public void writeHeaders(final ExternalContext context,
155             final ReportRenderer renderer, final UIReport report)
156             throws IOException {
157         if ("2.0".equals(getPortletVersion())) {
158             final ResourceResponse response = (ResourceResponse) context.
159                     getResponse();
160             response.setProperty("Cache-Type", "no-cache");
161             response.setProperty("Expires", "0");
162 
163             if (report.getName() != null) {
164                 response.setProperty("Content-Disposition",
165                                      renderer.encodeContentDisposition(report,
166                                                                        response.
167                         getCharacterEncoding()));
168             }
169         } else {
170             throw new IllegalStateException(
171                     "Only Resource Request/Response state is allowed");
172         }
173     }
174 
175     /**
176      * Writes the report contents into the context response.
177      *
178      * @param context the context
179      * @param contentType the content type
180      * @param data the data
181      * @throws IOException Signals that an I/O exception has occurred.
182      */
183     @Override
184     public void writeResponse(final ExternalContext context,
185             final ContentType contentType, final InputStream stream) 
186     throws IOException {
187         if ("2.0".equals(getPortletVersion())) {
188             final ResourceResponse response = (ResourceResponse) context.
189                     getResponse();
190             response.setContentType(contentType.toString());
191             
192             int contentLength = 0;
193             byte[] data = new byte[BUFFER_SIZE];
194             int bytesRead;
195             while (-1 != (bytesRead = stream.read(data))) {
196             	response.getPortletOutputStream().write(data, 0, bytesRead);
197             	contentLength += bytesRead;
198             }
199             
200             response.setContentLength(contentLength);
201         } else {
202             throw new IllegalStateException(
203                     "Only Resource Request/Response state is allowed");
204         }
205     }
206 }