View Javadoc

1   /*
2    * Copyright 2012-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.spi.config.ds;
17  
18  import java.sql.Connection;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  
23  import de.smartics.properties.api.config.domain.Property;
24  import de.smartics.properties.api.config.domain.PropertyCollection;
25  import de.smartics.properties.api.config.domain.PropertyLocation;
26  import de.smartics.util.lang.Arguments;
27  
28  /**
29   * Provides access to properties in a data source.
30   */
31  public final class PropertiesStore extends DefaultDataSourceManager implements
32      PropertiesDataSourceAccessor
33  {
34    // ********************************* Fields *********************************
35  
36    // --- constants ------------------------------------------------------------
37  
38    /**
39     * The class version identifier.
40     */
41    private static final long serialVersionUID = 1L;
42  
43    // --- members --------------------------------------------------------------
44  
45    // ****************************** Initializer *******************************
46  
47    // ****************************** Constructors ******************************
48  
49    /**
50     * Default constructor.
51     *
52     * @param builder the builder of manager instance.
53     */
54    protected PropertiesStore(final Builder builder)
55    {
56      super(builder);
57    }
58  
59    // ****************************** Inner Classes *****************************
60  
61    /**
62     * The builder of manager instances.
63     */
64    public static class Builder extends DefaultDataSourceManager.Builder
65    {
66      // ******************************** Fields ********************************
67  
68      // --- constants ----------------------------------------------------------
69  
70      // --- members ------------------------------------------------------------
71  
72      // ***************************** Initializer ******************************
73  
74      // ***************************** Constructors *****************************
75  
76      // ***************************** Inner Classes ****************************
77  
78      // ******************************** Methods *******************************
79  
80      // --- init ---------------------------------------------------------------
81  
82      // --- get&set ------------------------------------------------------------
83  
84      // --- business -----------------------------------------------------------
85  
86      /**
87       * Creates the instance.
88       *
89       * @return the created instance.
90       * @throws NullPointerException if no data source proxy has been provided.
91       */
92      @Override
93      public final PropertiesStore build() throws NullPointerException
94      {
95        Arguments.checkNotNull("dataSourceProxy", dataSourceProxy);
96  
97        return new PropertiesStore(this);
98      }
99  
100     // --- object basics ------------------------------------------------------
101   }
102 
103   // ********************************* Methods ********************************
104 
105   // --- init -----------------------------------------------------------------
106 
107   // --- get&set --------------------------------------------------------------
108 
109   // --- business -------------------------------------------------------------
110 
111   @Override
112   public Property getProperty(final String name)
113     throws IllegalArgumentException, DataSourceException
114   {
115     Arguments.checkNotBlank("name", name); // NOPMD
116 
117     try
118     {
119       final Connection connection =
120           getDataSourceProxy().getDataSource().getConnection();
121 
122       try
123       {
124         final PreparedStatement statement =
125             createGetPropertyStatement(connection);
126         statement.setString(1, name);
127         final ResultSet resultSet = statement.executeQuery();
128         final String value;
129         if (resultSet.next())
130         {
131           value = resultSet.getString(1);
132         }
133         else
134         {
135           value = null;
136         }
137         return new Property(new PropertyLocation(getDataSourceId()), name,
138             value);
139       }
140       finally
141       {
142         connection.close();
143       }
144     }
145     catch (final SQLException e)
146     {
147       final String dataSourceId = getDataSourceId();
148       final String message =
149           String.format("Cannot access property '%s' on data source '%s'.",
150               name, dataSourceId);
151       throw new DataSourceException(message, e, dataSourceId);
152     }
153   }
154 
155   @Override
156   public void setProperty(final String name, final String value)
157     throws IllegalArgumentException, DataSourceException
158   {
159     Arguments.checkNotBlank("name", name);
160 
161     try
162     {
163       final Connection connection =
164           getDataSourceProxy().getDataSource().getConnection();
165 
166       try
167       {
168         final PreparedStatement statement =
169             createSetPropertyStatement(connection);
170         statement.setString(2, name);
171         statement.setString(1, value);
172         statement.executeUpdate();
173       }
174       finally
175       {
176         connection.close();
177       }
178     }
179     catch (final SQLException e)
180     {
181       final String dataSourceId = getDataSourceId();
182       final String message =
183           String.format(
184               "Cannot set property '%s' to value '%s' on data source '%s'.",
185               name, value, dataSourceId);
186       throw new DataSourceException(message, e, dataSourceId);
187     }
188   }
189 
190   @Override
191   public void deleteProperty(final String name)
192     throws IllegalArgumentException, DataSourceException
193   {
194     Arguments.checkNotBlank("name", name);
195 
196     try
197     {
198       final Connection connection =
199           getDataSourceProxy().getDataSource().getConnection();
200 
201       try
202       {
203         final PreparedStatement statement =
204             createDeletePropertyStatement(connection);
205         statement.setString(1, name);
206         statement.executeUpdate();
207       }
208       finally
209       {
210         connection.close();
211       }
212     }
213     catch (final SQLException e)
214     {
215       final String dataSourceId = getDataSourceId();
216       final String message =
217           String.format("Cannot delete property '%s' from data source '%s'.",
218               name, dataSourceId);
219       throw new DataSourceException(message, e, dataSourceId);
220     }
221   }
222 
223   /**
224    * The collection of all properties stored.
225    *
226    * @return the collection of all properties stored.
227    */
228   public PropertyCollection getCollection()
229   {
230     try
231     {
232       final Connection connection =
233           getDataSourceProxy().getDataSource().getConnection();
234 
235       final PreparedStatement statement =
236           createGetPropertiesStatement(connection);
237       final ResultSet resultSet = statement.executeQuery(); // NOPMD
238       final DsPropertyCollection collection =
239           new DsPropertyCollection(getDataSourceId(), connection, resultSet);
240       return collection;
241     }
242     catch (final SQLException e)
243     {
244       final String dataSourceId = getDataSourceId();
245       final String message =
246           String.format("Cannot access properties on data source '%s'.",
247               dataSourceId);
248       throw new DataSourceException(message, e, dataSourceId);
249     }
250   }
251 
252   /**
253    * Checks if a property with the given {@code name} is stored.
254    *
255    * @param name the name of the property to check if it is stored.
256    * @return <code>true</code> if there is a property with that name and a non-
257    *         <code>null</code> value, <code>false</code> otherwise.
258    * @throws IllegalArgumentException if {@code name} is blank.
259    */
260   public boolean containsKey(final String name) throws IllegalArgumentException
261   {
262     final Property property = getProperty(name);
263     return property.getValue() != null;
264   }
265 
266   private PreparedStatement createGetPropertyStatement(
267       final Connection connection) throws SQLException
268   {
269     final String sql =
270         "SELECT " + getValueColumn() + " FROM " + getTable() + " WHERE "
271             + getNameColumn() + " = ?";
272     return connection.prepareStatement(sql);
273   }
274 
275   private PreparedStatement createGetPropertiesStatement(
276       final Connection connection) throws SQLException
277   {
278     final String sql =
279         "SELECT " + getNameColumn() + ", " + getValueColumn() + " FROM "
280             + getTable();
281     return connection.prepareStatement(sql);
282   }
283 
284   private PreparedStatement createSetPropertyStatement(
285       final Connection connection) throws SQLException
286   {
287     final String sql =
288         "UPDATE " + getTable() + " SET " + getValueColumn() + " = ? WHERE "
289             + getNameColumn() + " = ?";
290     return connection.prepareStatement(sql);
291   }
292 
293   private PreparedStatement createDeletePropertyStatement(
294       final Connection connection) throws SQLException
295   {
296     final String sql =
297         "DELETE FROM " + getTable() + " WHERE" + getNameColumn() + " = ? ";
298     return connection.prepareStatement(sql);
299   }
300 
301   // --- object basics --------------------------------------------------------
302 
303 }