1/*2 * $Id: LocaleDbDefinitionDAO.java 831448 2009-10-30 20:39:52Z apetrelli $3 *4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122package org.apache.tiles.test.db;
2324import java.sql.ResultSet;
25import java.sql.SQLException;
26import java.util.List;
27import java.util.Locale;
28import java.util.Map;
2930import org.apache.tiles.Attribute;
31import org.apache.tiles.Definition;
32import org.apache.tiles.definition.dao.DefinitionDAO;
33import org.apache.tiles.util.LocaleUtil;
34import org.springframework.jdbc.core.RowMapper;
35import org.springframework.jdbc.core.support.JdbcDaoSupport;
3637/***38 * Stub definition DAO to demonstrate that Tiles definitions can be stored in a39 * Database.40 *41 * @version $Rev: 831448 $ $Date: 2009-10-30 21:39:52 +0100 (ven, 30 ott 2009) $42 */43publicclassLocaleDbDefinitionDAOextends JdbcDaoSupport implements
44 DefinitionDAO<Locale> {
4546/***47 * Selects a customization by its name.48 */49privatestaticfinal String SELECT_CUSTOMIZATION_BY_NAME_SQL =
50"select ID, PARENT_ID, NAME from CUSTOMIZATION "51 + "where NAME = ? ";
5253/***54 * Selects a customization by its Id.55 */56privatestaticfinal String SELECT_CUSTOMIZATION_BY_ID_SQL =
57"select ID, PARENT_ID, NAME from CUSTOMIZATION "58 + "where ID = ? ";
5960/***61 * Selects a definition by its name and a customization Id.62 */63privatestaticfinal String SELECT_DEFINITION_SQL =
64"select ID, PARENT_NAME, NAME, PREPARER, TEMPLATE from DEFINITION "65 + "where NAME = ? and CUSTOMIZATION_ID = ? ";
6667/***68 * Selects attributes of a definition, given the definition Id.69 */70privatestaticfinal String SELECT_ATTRIBUTES_SQL =
71"select ID, NAME, TYPE, VALUE, CASCADE_ATTRIBUTE from ATTRIBUTE "72 + "where DEFINITION_ID = ? ";
7374/***75 * Maps a row of a {@link ResultSet} to a {@link Definition}.76 */77privatefinal DefinitionRowMapper definitionRowMapper = new DefinitionRowMapper();
7879/*** {@inheritDoc} */80 @SuppressWarnings("unchecked")
81public Definition getDefinition(String name, Locale locale) {
82 List<Map<String, Object>> customizations = null;
83 Long customizationId = null, parentCustomizationId = null;
84do {
85 customizations = getJdbcTemplate().queryForList(
86 SELECT_CUSTOMIZATION_BY_NAME_SQL,
87new Object[] { locale.toString() });
88if (!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());
9697return getDefinition(name, customizationId, parentCustomizationId,
98 locale);
99 }
100101/*** {@inheritDoc} */102public Map<String, Definition> getDefinitions(Locale locale) {
103thrownew UnsupportedOperationException(
104"Currently the 'getDefinitions' method is not supported");
105 }
106107/***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")
117protected DbDefinition getDefinition(String name, Long baseCustomizationId,
118 Long baseParentCustomizationId, Locale locale) {
119 DbDefinition definition = null;
120 Long customizationId = baseCustomizationId;
121 Long parentCustomizationId = baseParentCustomizationId;
122 List<DbDefinition> definitions = null;
123boolean finished = false;
124do {
125 definitions = getJdbcTemplate()
126 .query(SELECT_DEFINITION_SQL,
127new Object[] { name, customizationId },
128 definitionRowMapper);
129if (definitions.isEmpty()) {
130if (parentCustomizationId != null) {
131 Map<String, Object> customization = getJdbcTemplate().queryForMap(
132 SELECT_CUSTOMIZATION_BY_ID_SQL,
133new 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);
144145if (definition != null) {
146 AttributeRowMapper attributeRowMapper = new AttributeRowMapper(definition);
147 getJdbcTemplate().query(SELECT_ATTRIBUTES_SQL,
148new Object[] { definition.getId() }, attributeRowMapper);
149 }
150return definition;
151 }
152153/***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 */160privatestatic Long numberToLong(Number number) {
161 Long retValue = null;
162if (number != null) {
163 retValue = number.longValue();
164 }
165return retValue;
166 }
167168/***169 * A definition with the new property "id".170 */171privatestaticclass DbDefinition extends Definition {
172173/***174 * The id of the definition.175 */176private Long id;
177178/***179 * The default constructor.180 */181public DbDefinition() {
182super();
183 }
184185/***186 * Returns the Id of the definition.187 *188 * @return The id.189 */190public Long getId() {
191return id;
192 }
193194/***195 * Sets the id of the definition.196 *197 * @param id The id to set198 */199publicvoid setId(Long id) {
200this.id = id;
201 }
202203 }
204205/***206 * Maps a row of a {@link ResultSet} to a {@link Definition}.207 */208privatestaticfinalclass DefinitionRowMapper implements RowMapper {
209210/*** {@inheritDoc} */211public 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"));
219return definition;
220 }
221222 }
223224/***225 * Maps a row of a {@link ResultSet} to an {@link Attribute}. It stores the226 * attributes directly in their definition.227 */228privatestaticfinalclass AttributeRowMapper implements RowMapper {
229230/***231 * The definition in which the attributes will be stored.232 */233private Definition definition;
234235/***236 * Constructor.237 *238 * @param definition The definition in which the attributes will be239 * stored.240 */241private AttributeRowMapper(Definition definition) {
242this.definition = definition;
243 }
244245/*** {@inheritDoc} */246public 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"));
252return attribute;
253 }
254255 }
256 }