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

1   /*
2    * $Id: UrlDefinitionsFactory.java 934508 2010-04-15 18:30:51Z apetrelli $
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  package org.apache.tiles.definition;
22  
23  import java.net.URL;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.Map;
28  import java.util.StringTokenizer;
29  
30  import org.apache.tiles.Definition;
31  import org.apache.tiles.context.TilesRequestContext;
32  import org.apache.tiles.definition.dao.DefinitionDAO;
33  import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO;
34  import org.apache.tiles.definition.dao.URLReader;
35  import org.apache.tiles.impl.BasicTilesContainer;
36  import org.apache.tiles.locale.impl.DefaultLocaleResolver;
37  import org.apache.tiles.util.LocaleUtil;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /***
42   * {@link DefinitionsFactory DefinitionsFactory} implementation that manages
43   * Definitions configuration data from URLs, resolving inheritance when the URL
44   * is loaded.
45   * <p/>
46   * <p>
47   * The Definition objects are read from the
48   * {@link org.apache.tiles.definition.digester.DigesterDefinitionsReader
49   * 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 using
54   * {@link ResolvingLocaleUrlDefinitionDAO} as Tiles DAO.
55   */
56  public class UrlDefinitionsFactory extends UnresolvingLocaleDefinitionsFactory
57          implements Refreshable {
58  
59      /***
60       * Compatibility constant.
61       *
62       * @deprecated use {@link DefinitionsFactory#DEFINITIONS_CONFIG} to avoid
63       * namespace collisions.
64       */
65      private static final String LEGACY_DEFINITIONS_CONFIG = "definitions-config";
66  
67      /***
68       * LOG instance for all UrlDefinitionsFactory instances.
69       */
70      private final Logger log = LoggerFactory
71              .getLogger(UrlDefinitionsFactory.class);
72  
73      /***
74       * Contains the URL objects identifying where configuration data is found.
75       *
76       * @deprecated Use {@link URLReader#addSourceURL(URL)}.
77       */
78      protected List<Object> sources;
79  
80      /***
81       * Reader used to get definitions from the sources.
82       *
83       * @deprecated No more used.
84       */
85      protected DefinitionsReader reader;
86  
87      /***
88       * Contains the dates that the URL sources were last modified.
89       *
90       * @deprecated No more used.
91       */
92      protected Map<String, Long> lastModifiedDates;
93  
94      /*** {@inheritDoc} */
95      public synchronized void refresh() {
96          log.debug("Updating Tiles definitions. . .");
97          if (definitionDao instanceof Refreshable) {
98              ((Refreshable) definitionDao).refresh();
99          }
100     }
101 
102 
103     /***
104      * Indicates whether the DefinitionsFactory is out of date and needs to be
105      * reloaded.
106      *
107      * @return If the factory needs refresh.
108      */
109     public boolean refreshRequired() {
110         return (definitionDao instanceof RefreshMonitor)
111                 && ((RefreshMonitor) definitionDao).refreshRequired();
112     }
113 
114     /***
115      * Indicates whether a given context has been processed or not.
116      * <p/>
117      * This method can be used to avoid unnecessary synchronization of the
118      * DefinitionsFactory in multi-threaded situations.  Check the return of
119      * isContextProcessed before synchronizing the object and reading
120      * 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
127     protected boolean isContextProcessed(TilesRequestContext tilesContext) {
128         return true;
129     }
130 
131     /***
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 configuration
136      * source containing definitions.  The source should be a "base" source for
137      * configurations.  Internationalization and Localization properties will be
138      * applied by implementations to discriminate the correct data sources based
139      * on locale.
140      *
141      * @param source The configuration source for definitions.
142      * @throws DefinitionsFactoryException if an invalid source is passed in or
143      *                                     an error occurs resolving the source to an actual data store.
144      * @deprecated Use {@link URLReader#addSourceURL(URL)}.
145      */
146     public void addSource(Object source) {
147         if (source == null) {
148             throw new DefinitionsFactoryException(
149                 "Source object must not be null");
150         }
151 
152         if (!(source instanceof URL)) {
153             throw new DefinitionsFactoryException(
154                 "Source object must be an URL");
155         }
156 
157         if (definitionDao instanceof URLReader) {
158             ((URLReader) definitionDao).addSourceURL((URL) source);
159         }
160     }
161 
162     /***
163      * Creates the default definition DAO, if it has not been specified outside.
164      *
165      * @return The default definition DAO.
166      * @since 2.1.0
167      */
168     protected ResolvingLocaleUrlDefinitionDAO createDefaultDefinitionDAO() {
169         return new ResolvingLocaleUrlDefinitionDAO();
170     }
171 
172     @Override
173     public void init(Map<String, String> params) {
174         super.init(params);
175         setLocaleResolver(new DefaultLocaleResolver());
176         ResolvingLocaleUrlDefinitionDAO dao = createDefaultDefinitionDAO();
177         dao.setApplicationContext(applicationContext);
178         dao.init(params);
179         setDefinitionDAO(dao);
180 
181     }
182 
183     /***
184      * Creates and returns a {@link Definitions} set by reading
185      * 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 the
189      * sources.
190      * @deprecated Let the Definitions Factory use it.
191      */
192     @Deprecated
193     public Definitions readDefinitions() {
194         return new CompatibilityDefinitionsImpl(definitionDao);
195     }
196 
197     /***
198      * Returns the definitions holder object.
199      *
200      * @return The definitions holder.
201      * @deprecated Do not use! Deprecated with no replacement.
202      */
203     @Deprecated
204     protected Definitions getDefinitions() {
205         return new CompatibilityDefinitionsImpl(definitionDao);
206     }
207 
208     /***
209      * Appends locale-specific {@link Definition} objects to an existing
210      * {@link Definitions} set by reading locale-specific versions of
211      * 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
219     protected void addDefinitions(Definitions definitions,
220             TilesRequestContext tilesContext) {
221         Locale locale = localeResolver.resolveLocale(tilesContext);
222         Map<String, Definition> defsMap = definitionDao.getDefinitions(locale);
223         if (defsMap == null) {
224             throw new NullPointerException(
225                     "There are no definitions mapped to locale '"
226                             + locale.toString() + "'");
227         }
228     }
229 
230     /***
231      * Creates a new instance of <code>Definitions</code>. Override this method
232      * 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
238     protected Definitions createDefinitions() {
239         return new CompatibilityDefinitionsImpl(definitionDao);
240     }
241 
242     /***
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)} instead
251      */
252     protected static String concatPostfix(String name, String postfix) {
253         return LocaleUtil.concatPostfix(name, postfix);
254     }
255 
256     /***
257      * Calculate the postfixes along the search path from the base bundle to the
258      * bundle specified by baseName and locale.
259      * Method copied from java.util.ResourceBundle
260      *
261      * @param locale the locale
262      * @return a list of
263      * @deprecated Use {@link LocaleUtil#calculatePostfixes(Locale)} instead.
264      */
265     protected static List<String> calculatePostfixes(Locale locale) {
266         return LocaleUtil.calculatePostfixes(locale);
267     }
268 
269     /***
270      * Derive the resource string from the initialization parameters. If no
271      * parameter {@link DefinitionsFactory#DEFINITIONS_CONFIG} is available,
272      * attempts to retrieve {@link BasicTilesContainer#DEFINITIONS_CONFIG} and
273      * {@link UrlDefinitionsFactory#LEGACY_DEFINITIONS_CONFIG}. If neither are
274      * 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
281     protected String getResourceString(Map<String, String> parms) {
282         String resourceStr = parms.get(DefinitionsFactory.DEFINITIONS_CONFIG);
283         if (resourceStr == null) {
284             resourceStr = parms.get(BasicTilesContainer.DEFINITIONS_CONFIG);
285         }
286         if (resourceStr == null) {
287             resourceStr = parms.get(UrlDefinitionsFactory.LEGACY_DEFINITIONS_CONFIG);
288         }
289         if (resourceStr == null) {
290             resourceStr = "/WEB-INF/tiles.xml";
291         }
292         return resourceStr;
293     }
294 
295     /***
296      * Parse the resourceString into a list of resource paths
297      * which can be loaded by the application context.
298      *
299      * @param resourceString comma seperated resources
300      * @return parsed resources
301      * @deprecated Deprecated without replacement.
302      */
303     @Deprecated
304     protected List<String> getResourceNames(String resourceString) {
305         StringTokenizer tokenizer = new StringTokenizer(resourceString, ",");
306         List<String> filenames = new ArrayList<String>(tokenizer.countTokens());
307         while (tokenizer.hasMoreTokens()) {
308             filenames.add(tokenizer.nextToken().trim());
309         }
310         return filenames;
311     }
312 
313     /***
314      * {@link Definitions} implementation that uses a {@link DefinitionDAO}.
315      *
316      * @since 2.1.0
317      * @deprecated Here only for compatibility reasons.
318      */
319     @Deprecated
320     private static final class CompatibilityDefinitionsImpl implements Definitions {
321 
322         /***
323          * The definition DAO to use.
324          *
325          * @since 2.1.0
326          */
327         private DefinitionDAO<Locale> definitionDao;
328 
329         /***
330          * Constructor.
331          *
332          * @param definitionDao The definition DAO to use.
333          * @since 2.1.0
334          */
335         public CompatibilityDefinitionsImpl(DefinitionDAO<Locale> definitionDao) {
336             this.definitionDao = definitionDao;
337         }
338 
339         /*** {@inheritDoc} */
340         public void addDefinitions(Map<String, Definition> defsMap) {
341             Map<String, Definition> definitions = definitionDao
342                     .getDefinitions(null);
343             if (definitions == null) {
344                 throw new NullPointerException(
345                         "No definitions loaded for default locale");
346             }
347             definitions.putAll(defsMap);
348         }
349 
350         /*** {@inheritDoc} */
351         public void addDefinitions(Map<String, Definition> defsMap,
352                 Locale locale) {
353             Map<String, Definition> definitions = definitionDao
354                     .getDefinitions(locale);
355             if (definitions == null) {
356                 throw new NullPointerException(
357                         "No definitions loaded for locale '"
358                                 + locale.toString() + "'");
359             }
360             definitions.putAll(defsMap);
361         }
362 
363         /*** {@inheritDoc} */
364         public Map<String, Definition> getBaseDefinitions() {
365             return definitionDao.getDefinitions(null);
366         }
367 
368         /*** {@inheritDoc} */
369         public Definition getDefinition(String name) {
370             return definitionDao.getDefinition(name, null);
371         }
372 
373         /*** {@inheritDoc} */
374         public Definition getDefinition(String name, Locale locale) {
375             return definitionDao.getDefinition(name, locale);
376         }
377 
378         /*** {@inheritDoc} */
379         public void reset() {
380             if (definitionDao instanceof Refreshable) {
381                 ((Refreshable) definitionDao).refresh();
382             }
383         }
384 
385         /*** {@inheritDoc} */
386         public void resolveInheritances() {
387             // Does nothing.
388         }
389 
390         /*** {@inheritDoc} */
391         public void resolveInheritances(Locale locale) {
392             // Does nothing.
393         }
394     }
395 }