1/*2 * $Id: UrlDefinitionsFactory.java 934508 2010-04-15 18:30:51Z 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 */21package org.apache.tiles.definition;
2223import java.net.URL;
24import java.util.ArrayList;
25import java.util.List;
26import java.util.Locale;
27import java.util.Map;
28import java.util.StringTokenizer;
2930import org.apache.tiles.Definition;
31import org.apache.tiles.context.TilesRequestContext;
32import org.apache.tiles.definition.dao.DefinitionDAO;
33import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO;
34import org.apache.tiles.definition.dao.URLReader;
35import org.apache.tiles.impl.BasicTilesContainer;
36import org.apache.tiles.locale.impl.DefaultLocaleResolver;
37import org.apache.tiles.util.LocaleUtil;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
4041/***42 * {@link DefinitionsFactory DefinitionsFactory} implementation that manages43 * Definitions configuration data from URLs, resolving inheritance when the URL44 * is loaded.45 * <p/>46 * <p>47 * The Definition objects are read from the48 * {@link org.apache.tiles.definition.digester.DigesterDefinitionsReader49 * DigesterDefinitionsReader} class unless another implementation is specified.50 * </p>51 *52 * @version $Rev: 934508 $ $Date: 2010-04-15 20:30:51 +0200 (gio, 15 apr 2010) $53 * @deprecated Use {@link UnresolvingLocaleDefinitionsFactory} and using54 * {@link ResolvingLocaleUrlDefinitionDAO} as Tiles DAO.55 */56publicclassUrlDefinitionsFactoryextendsUnresolvingLocaleDefinitionsFactory57 implements Refreshable {
5859/***60 * Compatibility constant.61 *62 * @deprecated use {@link DefinitionsFactory#DEFINITIONS_CONFIG} to avoid63 * namespace collisions.64 */65privatestaticfinal String LEGACY_DEFINITIONS_CONFIG = "definitions-config";
6667/***68 * LOG instance for all UrlDefinitionsFactory instances.69 */70privatefinal Logger log = LoggerFactory
71 .getLogger(UrlDefinitionsFactory.class);
7273/***74 * Contains the URL objects identifying where configuration data is found.75 *76 * @deprecated Use {@link URLReader#addSourceURL(URL)}.77 */78protected List<Object> sources;
7980/***81 * Reader used to get definitions from the sources.82 *83 * @deprecated No more used.84 */85protectedDefinitionsReader reader;
8687/***88 * Contains the dates that the URL sources were last modified.89 *90 * @deprecated No more used.91 */92protected Map<String, Long> lastModifiedDates;
9394/*** {@inheritDoc} */95publicsynchronizedvoid refresh() {
96 log.debug("Updating Tiles definitions. . .");
97if (definitionDao instanceof Refreshable) {
98 ((Refreshable) definitionDao).refresh();
99 }
100 }
101102103/***104 * Indicates whether the DefinitionsFactory is out of date and needs to be105 * reloaded.106 *107 * @return If the factory needs refresh.108 */109publicboolean refreshRequired() {
110return (definitionDao instanceof RefreshMonitor)
111 && ((RefreshMonitor) definitionDao).refreshRequired();
112 }
113114/***115 * Indicates whether a given context has been processed or not.116 * <p/>117 * This method can be used to avoid unnecessary synchronization of the118 * DefinitionsFactory in multi-threaded situations. Check the return of119 * isContextProcessed before synchronizing the object and reading120 * locale-specific definitions.121 *122 * @param tilesContext The Tiles context to check.123 * @return true if the given context has been processed and false otherwise.124 * @deprecated It always return <code>true</code>.125 */126 @Deprecated
127protectedboolean isContextProcessed(TilesRequestContext tilesContext) {
128returntrue;
129 }
130131/***132 * Adds a source where Definition objects are stored.133 * <p/>134 * Implementations should publish what type of source object they expect.135 * The source should contain enough information to resolve a configuration136 * source containing definitions. The source should be a "base" source for137 * configurations. Internationalization and Localization properties will be138 * applied by implementations to discriminate the correct data sources based139 * on locale.140 *141 * @param source The configuration source for definitions.142 * @throws DefinitionsFactoryException if an invalid source is passed in or143 * an error occurs resolving the source to an actual data store.144 * @deprecated Use {@link URLReader#addSourceURL(URL)}.145 */146publicvoid addSource(Object source) {
147if (source == null) {
148thrownewDefinitionsFactoryException(
149"Source object must not be null");
150 }
151152if (!(source instanceof URL)) {
153thrownewDefinitionsFactoryException(
154"Source object must be an URL");
155 }
156157if (definitionDao instanceof URLReader) {
158 ((URLReader) definitionDao).addSourceURL((URL) source);
159 }
160 }
161162/***163 * Creates the default definition DAO, if it has not been specified outside.164 *165 * @return The default definition DAO.166 * @since 2.1.0167 */168protectedResolvingLocaleUrlDefinitionDAO createDefaultDefinitionDAO() {
169returnnewResolvingLocaleUrlDefinitionDAO();
170 }
171172 @Override
173publicvoid init(Map<String, String> params) {
174super.init(params);
175 setLocaleResolver(newDefaultLocaleResolver());
176ResolvingLocaleUrlDefinitionDAO dao = createDefaultDefinitionDAO();
177 dao.setApplicationContext(applicationContext);
178 dao.init(params);
179 setDefinitionDAO(dao);
180181 }
182183/***184 * Creates and returns a {@link Definitions} set by reading185 * configuration data from the applied sources.186 *187 * @return The definitions holder object, filled with base definitions.188 * @throws DefinitionsFactoryException if an error occurs reading the189 * sources.190 * @deprecated Let the Definitions Factory use it.191 */192 @Deprecated
193publicDefinitions readDefinitions() {
194returnnew CompatibilityDefinitionsImpl(definitionDao);
195 }
196197/***198 * Returns the definitions holder object.199 *200 * @return The definitions holder.201 * @deprecated Do not use! Deprecated with no replacement.202 */203 @Deprecated
204protectedDefinitions getDefinitions() {
205returnnew CompatibilityDefinitionsImpl(definitionDao);
206 }
207208/***209 * Appends locale-specific {@link Definition} objects to an existing210 * {@link Definitions} set by reading locale-specific versions of211 * the applied sources.212 *213 * @param definitions The Definitions object to append to.214 * @param tilesContext The requested locale.215 * @throws DefinitionsFactoryException if an error occurs reading definitions.216 * @deprecated Let the definitions be loaded by a {@link DefinitionDAO}.217 */218 @Deprecated
219protectedvoid addDefinitions(Definitions definitions,
220TilesRequestContext tilesContext) {
221 Locale locale = localeResolver.resolveLocale(tilesContext);
222 Map<String, Definition> defsMap = definitionDao.getDefinitions(locale);
223if (defsMap == null) {
224thrownew NullPointerException(
225"There are no definitions mapped to locale '"226 + locale.toString() + "'");
227 }
228 }
229230/***231 * Creates a new instance of <code>Definitions</code>. Override this method232 * to provide your custom instance of Definitions.233 *234 * @return A new instance of <code>Definitions</code>.235 * @deprecated Do not use! Deprecated with no replacement.236 */237 @Deprecated
238protectedDefinitions createDefinitions() {
239returnnew CompatibilityDefinitionsImpl(definitionDao);
240 }
241242/***243 * Concat postfix to the name. Take care of existing filename extension.244 * Transform the given name "name.ext" to have "name" + "postfix" + "ext".245 * If there is no ext, return "name" + "postfix".246 *247 * @param name Filename.248 * @param postfix Postfix to add.249 * @return Concatenated filename.250 * @deprecated Use {@link LocaleUtil#concatPostfix(String,String)} instead251 */252protectedstatic String concatPostfix(String name, String postfix) {
253return LocaleUtil.concatPostfix(name, postfix);
254 }
255256/***257 * Calculate the postfixes along the search path from the base bundle to the258 * bundle specified by baseName and locale.259 * Method copied from java.util.ResourceBundle260 *261 * @param locale the locale262 * @return a list of263 * @deprecated Use {@link LocaleUtil#calculatePostfixes(Locale)} instead.264 */265protectedstatic List<String> calculatePostfixes(Locale locale) {
266return LocaleUtil.calculatePostfixes(locale);
267 }
268269/***270 * Derive the resource string from the initialization parameters. If no271 * parameter {@link DefinitionsFactory#DEFINITIONS_CONFIG} is available,272 * attempts to retrieve {@link BasicTilesContainer#DEFINITIONS_CONFIG} and273 * {@link UrlDefinitionsFactory#LEGACY_DEFINITIONS_CONFIG}. If neither are274 * available, returns "/WEB-INF/tiles.xml".275 *276 * @param parms The initialization parameters.277 * @return resource string to be parsed.278 * @deprecated Deprecated without replacement.279 */280 @Deprecated
281protected String getResourceString(Map<String, String> parms) {
282 String resourceStr = parms.get(DefinitionsFactory.DEFINITIONS_CONFIG);
283if (resourceStr == null) {
284 resourceStr = parms.get(BasicTilesContainer.DEFINITIONS_CONFIG);
285 }
286if (resourceStr == null) {
287 resourceStr = parms.get(UrlDefinitionsFactory.LEGACY_DEFINITIONS_CONFIG);
288 }
289if (resourceStr == null) {
290 resourceStr = "/WEB-INF/tiles.xml";
291 }
292return resourceStr;
293 }
294295/***296 * Parse the resourceString into a list of resource paths297 * which can be loaded by the application context.298 *299 * @param resourceString comma seperated resources300 * @return parsed resources301 * @deprecated Deprecated without replacement.302 */303 @Deprecated
304protected List<String> getResourceNames(String resourceString) {
305 StringTokenizer tokenizer = new StringTokenizer(resourceString, ",");
306 List<String> filenames = new ArrayList<String>(tokenizer.countTokens());
307while (tokenizer.hasMoreTokens()) {
308 filenames.add(tokenizer.nextToken().trim());
309 }
310return filenames;
311 }
312313/***314 * {@link Definitions} implementation that uses a {@link DefinitionDAO}.315 *316 * @since 2.1.0317 * @deprecated Here only for compatibility reasons.318 */319 @Deprecated
320privatestaticfinalclass CompatibilityDefinitionsImpl implements Definitions {
321322/***323 * The definition DAO to use.324 *325 * @since 2.1.0326 */327private DefinitionDAO<Locale> definitionDao;
328329/***330 * Constructor.331 *332 * @param definitionDao The definition DAO to use.333 * @since 2.1.0334 */335public CompatibilityDefinitionsImpl(DefinitionDAO<Locale> definitionDao) {
336this.definitionDao = definitionDao;
337 }
338339/*** {@inheritDoc} */340publicvoid addDefinitions(Map<String, Definition> defsMap) {
341 Map<String, Definition> definitions = definitionDao
342 .getDefinitions(null);
343if (definitions == null) {
344thrownew NullPointerException(
345"No definitions loaded for default locale");
346 }
347 definitions.putAll(defsMap);
348 }
349350/*** {@inheritDoc} */351publicvoid addDefinitions(Map<String, Definition> defsMap,
352 Locale locale) {
353 Map<String, Definition> definitions = definitionDao
354 .getDefinitions(locale);
355if (definitions == null) {
356thrownew NullPointerException(
357"No definitions loaded for locale '"358 + locale.toString() + "'");
359 }
360 definitions.putAll(defsMap);
361 }
362363/*** {@inheritDoc} */364public Map<String, Definition> getBaseDefinitions() {
365return definitionDao.getDefinitions(null);
366 }
367368/*** {@inheritDoc} */369public Definition getDefinition(String name) {
370return definitionDao.getDefinition(name, null);
371 }
372373/*** {@inheritDoc} */374public Definition getDefinition(String name, Locale locale) {
375return definitionDao.getDefinition(name, locale);
376 }
377378/*** {@inheritDoc} */379publicvoid reset() {
380if (definitionDao instanceof Refreshable) {
381 ((Refreshable) definitionDao).refresh();
382 }
383 }
384385/*** {@inheritDoc} */386publicvoid resolveInheritances() {
387// Does nothing.388 }
389390/*** {@inheritDoc} */391publicvoid resolveInheritances(Locale locale) {
392// Does nothing.393 }
394 }
395 }