View Javadoc

1   /*
2    * Copyright 2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.admin.resources.representation.share;
17  
18  import java.io.OutputStream;
19  
20  import javax.ws.rs.core.MediaType;
21  import javax.ws.rs.core.MultivaluedMap;
22  import javax.ws.rs.core.UriInfo;
23  
24  import de.smartics.properties.admin.resources.representation.html.share.HtmlPathHelper;
25  import de.smartics.properties.utils.HtmlUtils;
26  import de.smartics.resteasy.hypermedia.renderer.LinkDescriptor;
27  import de.smartics.resteasy.hypermedia.renderer.LocalizationProvider;
28  import de.smartics.resteasy.hypermedia.renderer.RepresentationRenderer;
29  import de.smartics.resteasy.hypermedia.renderer.ResourceContext;
30  import de.smartics.resteasy.hypermedia.resources.Resources;
31  
32  /**
33   * Base implementation for document renderers.
34   *
35   * @param <T> the type of the resource the renderer is rendering representations
36   *          for.
37   */
38  public abstract class AbstractRepresentationRenderer<T> implements
39      RepresentationRenderer<T>
40  {
41    // ********************************* Fields *********************************
42  
43    // --- constants ------------------------------------------------------------
44  
45    // --- members --------------------------------------------------------------
46  
47    /**
48     * The context information for representation renderers.
49     */
50    private final ResourceContext context;
51  
52    /**
53     * The original stream to write to.
54     */
55    protected final OutputStream entityStream;
56  
57    /**
58     * The character encoding to use to render the output.
59     */
60    protected final String characterEncoding;
61  
62    /**
63     * Helper to localize application specific resources.
64     */
65    protected final HtmlPathHelper pathHelper;
66  
67    /**
68     * The factory to create link descriptors.
69     */
70    protected final LinkDescriptorFactory linkDescriptorFactory;
71  
72    /**
73     * The helper to create the breadcrumbs.
74     */
75    protected final BreadcrumbHelper breadcrumb;
76  
77    /**
78     * Utilities to deal with HTML.
79     */
80    protected final HtmlUtils htmlUtils;
81  
82    // ****************************** Initializer *******************************
83  
84    // ****************************** Constructors ******************************
85  
86    /**
87     * Default constructor using a stream.
88     *
89     * @param context the context information to render the representation.
90     * @param characterEncoding the character encoding to use to render the
91     *          output.
92     * @param entityStream the stream to write to.
93     * @param method the method to select the service method of the resource.
94     */
95    protected AbstractRepresentationRenderer(final ResourceContext context,
96        final String characterEncoding, final OutputStream entityStream,
97        final String method)
98    {
99      this.context = context;
100     this.characterEncoding = characterEncoding;
101     this.entityStream = entityStream;
102     this.pathHelper = new HtmlPathHelper(context.getUriInfo());
103 
104     this.linkDescriptorFactory = createLinkDescriptorFactory();
105     this.breadcrumb = new BreadcrumbHelper(linkDescriptorFactory, method);
106     this.htmlUtils = new HtmlUtils(characterEncoding);
107   }
108 
109   // ****************************** Inner Classes *****************************
110 
111   // ********************************* Methods ********************************
112 
113   // --- init -----------------------------------------------------------------
114 
115   private LinkDescriptorFactory createLinkDescriptorFactory()
116   {
117     final LocalizationProvider provider = context.getL7nProvider();
118     final UriInfo uriInfo = context.getUriInfo();
119     final LinkDescriptorFactory factory =
120         new LinkDescriptorFactory(uriInfo, provider);
121     return factory;
122   }
123 
124   // --- get&set --------------------------------------------------------------
125 
126   // --- business -------------------------------------------------------------
127 
128   @Override
129   public void render()
130   {
131     httpHeader();
132     httpBody();
133 
134     close();
135   }
136 
137   private void httpHeader()
138   {
139     final MediaType mediaType = context.getMediaType();
140     final MultivaluedMap<String, Object> httpHeaders = context.getHttpHeaders();
141     if (httpHeaders != null)
142     {
143       httpHeaders.add("Content-Type", mediaType + "; charset="
144                                       + characterEncoding);
145       renderApplicationStateHttpHeader(httpHeaders);
146     }
147   }
148 
149   private void renderApplicationStateHttpHeader(
150       final MultivaluedMap<String, Object> httpHeaders)
151   {
152     final Resources discovery = context.getDiscovery();
153     for (final LinkDescriptor link : discovery.links())
154     {
155       renderHttpHeaderLink(httpHeaders, link);
156     }
157 
158     renderAdditionalHttpHeader(httpHeaders);
159   }
160 
161   /**
162    * Hook to override in subclasses to add additional HTTP headers.
163    *
164    * @param httpHeaders the headers to add to.
165    */
166   protected void renderAdditionalHttpHeader(
167       final MultivaluedMap<String, Object> httpHeaders)
168   {
169   }
170 
171   /**
172    * Renders a link in the HTTP header.
173    *
174    * @param httpHeaders the headers to add to.
175    * @param link the link to add.
176    */
177   protected final void renderHttpHeaderLink(
178       final MultivaluedMap<String, Object> httpHeaders,
179       final LinkDescriptor link)
180   {
181     // TODO: Add additional properties of link if present
182     final String rel = link.getRel();
183     final String href = link.getHref();
184 
185     final String header = "<" + href + ">; rel=\"" + rel + '"';
186     httpHeaders.add("Link", header);
187   }
188 
189   /**
190    * Redners the HTTP body.
191    */
192   protected abstract void httpBody();
193 
194   /**
195    * Releases any resources held by the renderer.
196    */
197   protected abstract void close();
198 
199   // --- object basics --------------------------------------------------------
200 
201 }