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.controller;
17  
18  import java.net.URI;
19  
20  import javax.annotation.security.RolesAllowed;
21  import javax.ws.rs.FormParam;
22  import javax.ws.rs.GET;
23  import javax.ws.rs.POST;
24  import javax.ws.rs.Path;
25  import javax.ws.rs.PathParam;
26  import javax.ws.rs.Produces;
27  import javax.ws.rs.core.Context;
28  import javax.ws.rs.core.MediaType;
29  import javax.ws.rs.core.Response;
30  import javax.ws.rs.core.Response.Status;
31  import javax.ws.rs.core.UriInfo;
32  
33  import org.apache.commons.lang3.StringUtils;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import de.smartics.properties.admin.domain.model.ConfigurationProperty;
38  import de.smartics.properties.admin.domain.model.ManagedApplication;
39  import de.smartics.properties.admin.domain.model.Paths;
40  import de.smartics.properties.admin.domain.model.Roles;
41  import de.smartics.properties.api.config.domain.ConfigControl;
42  import de.smartics.properties.api.config.domain.ConfigurationPropertiesManagement;
43  import de.smartics.properties.api.config.domain.DescribedProperty;
44  import de.smartics.properties.api.config.domain.ValidatedProperty;
45  import de.smartics.properties.api.core.domain.PropertyDescriptor;
46  import de.smartics.properties.api.core.domain.PropertyDescriptorRegistry;
47  import de.smartics.properties.api.core.domain.PropertyValidationException;
48  import de.smartics.properties.api.core.domain.PropertyValueConversionException;
49  import de.smartics.properties.api.core.domain.ReadOnlyPropertyException;
50  import de.smartics.properties.api.core.security.PropertyValueSecurity;
51  
52  /**
53   * Provides access to properties used by the application.
54   */
55  @Path("")
56  @RolesAllowed(Roles.VIEW)
57  public class PropertyResource
58  {
59    // ********************************* Fields *********************************
60  
61    // --- constants ------------------------------------------------------------
62  
63    /**
64     * Reference to the logger for this class.
65     */
66    private static final Logger LOG = LoggerFactory
67        .getLogger(PropertyResource.class);
68  
69    // --- members --------------------------------------------------------------
70  
71    /**
72     * Helper to construct paths.
73     */
74    @Context
75    private UriInfo uriInfo;
76  
77    // ****************************** Initializer *******************************
78  
79    // ****************************** Constructors ******************************
80  
81    // ****************************** Inner Classes *****************************
82  
83    // ********************************* Methods ********************************
84  
85    // --- init -----------------------------------------------------------------
86  
87    // --- get&set --------------------------------------------------------------
88  
89    // --- business -------------------------------------------------------------
90  
91    /**
92     * Returns the property value for a given property key.
93     *
94     * @param configurationKey the configuration key.
95     * @param propertyKey the key to the requested property.
96     * @return the string representation.
97     */
98    @GET
99    @Path(Paths.PATH_PROPERTY_VALUE)
100   @Produces(MediaType.TEXT_PLAIN)
101   public Response getAsText(
102       @PathParam(Paths.PARAM_CONFIGURATION_KEY) final String configurationKey,
103       @PathParam(Paths.PARAM_PROPERTY_KEY) final String propertyKey)
104   {
105     final PropertyDescriptor descriptor = fetchPropertyDescriptor(propertyKey);
106     if (descriptor == null && propertyKey.endsWith(".xml"))
107     {
108       return getAsDotXml(configurationKey,
109           propertyKey.substring(0, propertyKey.length() - 4));
110     }
111     else if (descriptor == null)
112     {
113       final Response response = Response.status(Status.NOT_FOUND).build();
114       return response;
115     }
116 
117     final ConfigurationProperty resource =
118         fetchValidatedProperty(configurationKey, propertyKey);
119     final String value = String.valueOf(resource.getPropertyValue());
120 
121     final Response response = Response.ok().entity(value).build();
122     return response;
123   }
124 
125   private PropertyDescriptor fetchPropertyDescriptor(final String propertyKey)
126   {
127     final ManagedApplication app = ManagedApplication.getApplication();
128     final PropertyDescriptorRegistry registry = app.getDescriptorRegistry();
129     final PropertyDescriptor descriptor = registry.get(propertyKey);
130     return descriptor;
131   }
132 
133   /**
134    * Returns the property value for a given property key.
135    *
136    * @param configurationKey the configuration.
137    * @param propertyKey the key to the requested property.
138    * @return the HTML representation.
139    */
140   @GET
141   @Path(Paths.PATH_PROPERTY_VALUE)
142   @Produces(MediaType.TEXT_HTML)
143   public Response getAsHtml(
144       @PathParam(Paths.PARAM_CONFIGURATION_KEY) final String configurationKey,
145       @PathParam(Paths.PARAM_PROPERTY_KEY) final String propertyKey)
146   {
147     final PropertyDescriptor descriptor = fetchPropertyDescriptor(propertyKey);
148     if (descriptor == null && propertyKey.endsWith(".xml"))
149     {
150       return getAsDotXml(configurationKey,
151           propertyKey.substring(0, propertyKey.length() - 4));
152     }
153     else if (descriptor == null)
154     {
155       final Response response = Response.status(Status.NOT_FOUND).build();
156       return response;
157     }
158 
159     final ConfigurationProperty resource =
160         fetchValidatedProperty(configurationKey, propertyKey);
161 
162     final Response response = Response.ok().entity(resource).build();
163     return response;
164   }
165 
166   private ConfigurationProperty fetchValidatedProperty(
167       final String configurationKey, final String propertyKey)
168   {
169     if (LOG.isDebugEnabled())
170     {
171       LOG.debug("Fetching value from configuration {} with key {}.",
172           configurationKey, propertyKey);
173     }
174 
175     final ManagedApplication app = ManagedApplication.getApplication();
176     final ConfigurationPropertiesManagement configuration =
177         app.getConfiguration(configurationKey);
178     final PropertyDescriptor descriptor =
179         configuration.getDescriptor(propertyKey);
180     try
181     {
182       final ValidatedProperty property =
183           configuration.getValidatedProperty(propertyKey, null);
184       final ConfigurationProperty resource =
185           new ConfigurationProperty(configurationKey, propertyKey, descriptor,
186               property);
187       return resource;
188     }
189     catch (final PropertyValueConversionException e)
190     {
191       final ConfigurationProperty resource =
192           createSimpleProperty(configurationKey, propertyKey, configuration,
193               descriptor);
194       return resource;
195     }
196     catch (final PropertyValidationException e)
197     {
198       final ConfigurationProperty resource =
199           createSimpleProperty(configurationKey, propertyKey, configuration,
200               descriptor);
201       return resource;
202     }
203   }
204 
205   private ConfigurationProperty createSimpleProperty(
206       final String configurationKey, final String propertyKey,
207       final ConfigurationPropertiesManagement configuration,
208       final PropertyDescriptor descriptor)
209   {
210     final DescribedProperty property =
211         configuration.getProperty(propertyKey, null);
212     final ConfigurationProperty resource =
213         new ConfigurationProperty(configurationKey, propertyKey, descriptor,
214             property);
215     return resource;
216   }
217 
218   /**
219    * Changes the property value and returns the representation of the changed
220    * property.
221    *
222    * @param configurationKey the configuration .
223    * @param propertyKey the key to the requested property.
224    * @param propertyValue the new value to set.
225    * @return the HTML representation.
226    * @throws PropertyValidationException if the {@code propertyValue} is not
227    *           successfully validated.
228    * @throws ReadOnlyPropertyException if the property referenced by
229    *           {@code propertyKey} is read-only and therefore cannot be changed.
230    */
231   @POST
232   @Path(Paths.PATH_PROPERTY_VALUE)
233   @Produces(MediaType.TEXT_HTML)
234   @RolesAllowed(Roles.EDIT_PROPERTY)
235   public Response postAsHtml(
236       @PathParam(Paths.PARAM_CONFIGURATION_KEY) final String configurationKey,
237       @PathParam(Paths.PARAM_PROPERTY_KEY) final String propertyKey,
238       @FormParam(Paths.PARAM_VALUE) final String propertyValue)
239     throws PropertyValidationException, ReadOnlyPropertyException
240   {
241     try
242     {
243       ConfigControl.get().setAdminMode(true);
244 
245       final ConfigurationProperty configProperty =
246           create(configurationKey, propertyKey, propertyValue);
247 
248       final URI self = uriInfo.getRequestUriBuilder().build();
249       final Response response =
250           Response.seeOther(self).entity(configProperty).build();
251 
252       return response;
253     }
254     finally
255     {
256       ConfigControl.get().setAdminMode(false);
257     }
258   }
259 
260   private ConfigurationProperty create(final String configurationKey,
261       final String propertyKey, final String propertyValue)
262   {
263     final ManagedApplication app = ManagedApplication.getApplication();
264     final ConfigurationPropertiesManagement configuration =
265         app.getConfiguration(configurationKey);
266     final PropertyDescriptor descriptor =
267         configuration.getDescriptor(propertyKey);
268 
269     if (StringUtils.isEmpty(propertyValue))
270     {
271       configuration.setProperty(descriptor.getKey(), null);
272     }
273     else
274     {
275       if (descriptor.isSecured())
276       {
277         final PropertyValueSecurity security = app.getSecurity();
278         final String securedValue = security.encrypt(descriptor, propertyValue);
279         configuration.validate(descriptor, securedValue);
280       }
281       else
282       {
283         configuration.validate(descriptor, propertyValue);
284       }
285       configuration.setProperty(descriptor.getKey(), propertyValue);
286     }
287 
288     final ValidatedProperty property =
289         configuration.getValidatedProperty(propertyKey, null);
290     final ConfigurationProperty configProperty =
291         new ConfigurationProperty(configurationKey, propertyKey, descriptor,
292             property);
293     return configProperty;
294   }
295 
296   /**
297    * Returns the property value for a given property key in its SDoc XML
298    * representation.
299    *
300    * @param configurationKey the configuration .
301    * @param propertyKey the key to the requested property.
302    * @return the HTML representation.
303    */
304   @GET
305   @Path(Paths.PATH_PROPERTY_VALUE + ".xml")
306   @Produces(MediaType.WILDCARD)
307   public Response getAsDotXml(
308       @PathParam(Paths.PARAM_CONFIGURATION_KEY) final String configurationKey,
309       @PathParam(Paths.PARAM_PROPERTY_KEY) final String propertyKey)
310   {
311     final Response response = getAsXml(configurationKey, propertyKey);
312     return response;
313   }
314 
315   /**
316    * Returns the property value for a given property key in its SDoc XML
317    * representation.
318    *
319    * @param configurationKey the configuration .
320    * @param propertyKey the key to the requested property.
321    * @return the HTML representation.
322    */
323   @GET
324   @Path(Paths.PATH_PROPERTY_VALUE)
325   @Produces({ MediaType.APPLICATION_XML, MediaType.TEXT_XML })
326   public Response getAsXml(
327       @PathParam(Paths.PARAM_CONFIGURATION_KEY) final String configurationKey,
328       @PathParam(Paths.PARAM_PROPERTY_KEY) final String propertyKey)
329   {
330     final PropertyDescriptor descriptor = fetchPropertyDescriptor(propertyKey);
331 
332     if (descriptor == null)
333     {
334       final Response response = Response.status(Status.NOT_FOUND).build();
335       return response;
336     }
337 
338     final ConfigurationProperty resource =
339         fetchValidatedProperty(configurationKey, propertyKey);
340 
341     final Response response =
342         Response.ok().type(MediaType.TEXT_XML_TYPE).entity(resource).build();
343     return response;
344   }
345 
346   // --- object basics --------------------------------------------------------
347 
348 }