This project has retired. For details please refer to its Attic page.
LocaleDbDefinitionDAO xref
View Javadoc

1   /*
2    * $Id: LocaleDbDefinitionDAO.java 1297705 2012-03-06 20:44:30Z nlebas $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.tiles.test.db;
23  
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.util.List;
27  import java.util.Locale;
28  import java.util.Map;
29  
30  import org.apache.tiles.Attribute;
31  import org.apache.tiles.Definition;
32  import org.apache.tiles.definition.dao.DefinitionDAO;
33  import org.apache.tiles.request.locale.LocaleUtil;
34  import org.springframework.jdbc.core.RowMapper;
35  import org.springframework.jdbc.core.support.JdbcDaoSupport;
36  
37  /**
38   * Stub definition DAO to demonstrate that Tiles definitions can be stored in a
39   * Database.
40   *
41   * @version $Rev: 1297705 $ $Date: 2012-03-07 07:44:30 +1100 (Wed, 07 Mar 2012) $
42   */
43  public class LocaleDbDefinitionDAO extends JdbcDaoSupport implements
44          DefinitionDAO<Locale> {
45  
46      /**
47       * Selects a customization by its name.
48       */
49      private static final String SELECT_CUSTOMIZATION_BY_NAME_SQL =
50          "select ID, PARENT_ID, NAME from CUSTOMIZATION "
51              + "where NAME = ? ";
52  
53      /**
54       * Selects a customization by its Id.
55       */
56      private static final String SELECT_CUSTOMIZATION_BY_ID_SQL =
57          "select ID, PARENT_ID, NAME from CUSTOMIZATION "
58              + "where ID = ? ";
59  
60      /**
61       * Selects a definition by its name and a customization Id.
62       */
63      private static final String SELECT_DEFINITION_SQL =
64          "select ID, PARENT_NAME, NAME, PREPARER, TEMPLATE from DEFINITION "
65              + "where NAME = ? and CUSTOMIZATION_ID = ? ";
66  
67      /**
68       * Selects attributes of a definition, given the definition Id.
69       */
70      private static final String SELECT_ATTRIBUTES_SQL =
71          "select ID, NAME, TYPE, VALUE, CASCADE_ATTRIBUTE from ATTRIBUTE "
72              + "where DEFINITION_ID = ? ";
73  
74      /**
75       * Maps a row of a {@link ResultSet} to a {@link Definition}.
76       */
77      private final DefinitionRowMapper definitionRowMapper = new DefinitionRowMapper();
78  
79      /** {@inheritDoc} */
80      @SuppressWarnings("unchecked")
81      public Definition getDefinition(String name, Locale locale) {
82          List<Map<String, Object>> customizations = null;
83          Long customizationId = null, parentCustomizationId = null;
84          do {
85              customizations = getJdbcTemplate().queryForList(
86                      SELECT_CUSTOMIZATION_BY_NAME_SQL,
87                      new Object[] { locale.toString() });
88              if (!customizations.isEmpty()) {
89                  Map<String, Object> customization = customizations.get(0);
90                  customizationId = ((Number) customization.get("ID")).longValue();
91                  parentCustomizationId = numberToLong((Number) customization.get("PARENT_ID"));
92              } else {
93                  locale = LocaleUtil.getParentLocale(locale);
94              }
95          } while (customizations.isEmpty());
96  
97          return getDefinition(name, customizationId, parentCustomizationId,
98                  locale);
99      }
100 
101     /** {@inheritDoc} */
102     public Map<String, Definition> getDefinitions(Locale locale) {
103         throw new UnsupportedOperationException(
104                 "Currently the 'getDefinitions' method is not supported");
105     }
106 
107     /**
108      * Loads a definition from the DB.
109      *
110      * @param name The name of the definition.
111      * @param baseCustomizationId The id of the customization item.
112      * @param baseParentCustomizationId The id of the parent customization item.
113      * @param locale The locale.
114      * @return The definition.
115      */
116     @SuppressWarnings("unchecked")
117     protected DbDefinition getDefinition(String name, Long baseCustomizationId,
118             Long baseParentCustomizationId, @SuppressWarnings("unused") Locale locale) {
119         DbDefinition definition = null;
120         Long customizationId = baseCustomizationId;
121         Long parentCustomizationId = baseParentCustomizationId;
122         List<DbDefinition> definitions = null;
123         boolean finished = false;
124         do {
125             definitions = getJdbcTemplate()
126                     .query(SELECT_DEFINITION_SQL,
127                             new Object[] { name, customizationId },
128                             definitionRowMapper);
129             if (definitions.isEmpty()) {
130                 if (parentCustomizationId != null) {
131                     Map<String, Object> customization = getJdbcTemplate().queryForMap(
132                             SELECT_CUSTOMIZATION_BY_ID_SQL,
133                             new Object[] { parentCustomizationId });
134                     customizationId = ((Number) customization.get("ID")).longValue();
135                     parentCustomizationId = numberToLong((Number) customization.get("PARENT_ID"));
136                 } else {
137                     finished = true;
138                 }
139             } else {
140                 definition = definitions.get(0);
141                 finished = true;
142             }
143         } while (!finished);
144 
145         if (definition != null) {
146             AttributeRowMapper attributeRowMapper = new AttributeRowMapper(definition);
147             getJdbcTemplate().query(SELECT_ATTRIBUTES_SQL,
148                     new Object[] { definition.getId() }, attributeRowMapper);
149         }
150         return definition;
151     }
152 
153     /**
154      * Returns a {@link Long} object only if the number is not null.
155      *
156      * @param number The number to convert.
157      * @return The number converted into {@link Long} if not null,
158      * <code>null</code> otherwise.
159      */
160     private static Long numberToLong(Number number) {
161         Long retValue = null;
162         if (number != null) {
163             retValue = number.longValue();
164         }
165         return retValue;
166     }
167 
168     /**
169      * A definition with the new property "id".
170      */
171     private static class DbDefinition extends Definition {
172 
173         /**
174          * The id of the definition.
175          */
176         private Long id;
177 
178         /**
179          * The default constructor.
180          */
181         public DbDefinition() {
182             super();
183         }
184 
185         /**
186          * Returns the Id of the definition.
187          *
188          * @return The id.
189          */
190         public Long getId() {
191             return id;
192         }
193 
194         /**
195          * Sets the id of the definition.
196          *
197          * @param id The id to set
198          */
199         public void setId(Long id) {
200             this.id = id;
201         }
202 
203     }
204 
205     /**
206      * Maps a row of a {@link ResultSet} to a {@link Definition}.
207      */
208     private static final class DefinitionRowMapper implements RowMapper {
209 
210         /** {@inheritDoc} */
211         public Object mapRow(ResultSet rs, int row) throws SQLException {
212             DbDefinition definition = new DbDefinition();
213             definition.setId(numberToLong((Number) rs.getObject("ID")));
214             definition.setName(rs.getString("NAME"));
215             definition.setTemplateAttribute(Attribute
216                     .createTemplateAttribute(rs.getString("TEMPLATE")));
217             definition.setPreparer(rs.getString("PREPARER"));
218             definition.setExtends(rs.getString("PARENT_NAME"));
219             return definition;
220         }
221 
222     }
223 
224     /**
225      * Maps a row of a {@link ResultSet} to an {@link Attribute}. It stores the
226      * attributes directly in their definition.
227      */
228     private static final class AttributeRowMapper implements RowMapper {
229 
230         /**
231          * The definition in which the attributes will be stored.
232          */
233         private Definition definition;
234 
235         /**
236          * Constructor.
237          *
238          * @param definition The definition in which the attributes will be
239          * stored.
240          */
241         private AttributeRowMapper(Definition definition) {
242             this.definition = definition;
243         }
244 
245         /** {@inheritDoc} */
246         public Object mapRow(ResultSet rs, int row) throws SQLException {
247             Attribute attribute = new Attribute();
248             attribute.setRenderer(rs.getString("TYPE"));
249             attribute.setValue(rs.getString("VALUE"));
250             definition.putAttribute(rs.getString("NAME"), attribute, rs
251                     .getBoolean("CASCADE_ATTRIBUTE"));
252             return attribute;
253         }
254 
255     }
256 }