View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/MelatiConfig.java,v $
3    * $Revision: 1.60 $
4    *
5    * Copyright (C) 2000 Tim Joyce
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Tim Joyce <timj At paneris.org>
42   *     http://paneris.org/
43   *     68 Sandbanks Rd, Poole, Dorset. BH14 8BY. UK
44   */
45  
46  package org.melati;
47  
48  import java.io.FileNotFoundException;
49  import java.io.IOException;
50  import java.util.List;
51  import java.util.Properties;
52  import java.util.Vector;
53  
54  import org.melati.login.AccessHandler;
55  import org.melati.poem.PoemLocale;
56  import org.melati.poem.util.EnumUtils;
57  import org.melati.servlet.FormDataAdaptorFactory;
58  import org.melati.template.ClassNameTempletLoader;
59  import org.melati.template.ServletTemplateEngine;
60  import org.melati.template.SimpleDateAdaptor;
61  import org.melati.template.TemplateEngine;
62  import org.melati.template.TempletLoader;
63  import org.melati.template.YMDDateAdaptor;
64  import org.melati.template.YMDHMSTimestampAdaptor;
65  import org.melati.util.ConfigException;
66  import org.melati.util.HttpHeader;
67  import org.melati.util.PropertiesUtils;
68  
69  /**
70   * A MelatiConfig loads and provides access to the configuration parameters for
71   * melati. These are held in <TT>org.melati.MelatiConfig.properties</TT>.
72   */
73  public class MelatiConfig {
74  
75    private Properties configuration = null;
76    /** The properties file name. */
77    private String propertiesName = "org.melati.MelatiConfig";
78  
79    private AccessHandler accessHandler = null;
80    private FormDataAdaptorFactory fdaFactory = null;
81    private TempletLoader templetLoader = null;
82    private TemplateEngine templateEngine = null;
83    private static PoemLocale poemLocale = null;
84    private Vector<String> preferredCharsets = null; 
85    private String javascriptLibraryURL = null;
86    private String staticURL = null;
87    private String templatePath = null;
88    private static String loginPageServletClassName = "org.melati.login.Login";
89    private static String logoutPageServletClassName = "org.melati.login.Logout";
90  
91    private static String realPath = null;
92    
93    /**
94     * Allows creation of a <code>MelatiConfig</code> with default config
95     * params.
96     */
97    public MelatiConfig() {
98      try {
99        configuration =
100         PropertiesUtils.fromResource(getClass(), propertiesName + ".properties");
101     }
102     catch (FileNotFoundException e) {
103       configuration = new Properties();
104       // TimJ: i think that if we don't have a properties file, it is pretty fatal
105       // TimP: Naah
106     }
107     catch (IOException e) {
108       throw new ConfigException("The file " + propertiesName + ".properties" +
109                                 " could not be read." +
110                                 " Full Error: " + e.toString());
111     }
112     init(propertiesName);
113   }
114 
115   /**
116    * Allows creation of a <code>MelatiConfig</code> with a specified
117    * properties file.
118    * 
119    * @param propertiesName
120    *        the name of a properties file
121    */
122   public MelatiConfig(String propertiesName) {
123     this.propertiesName = propertiesName;
124     try {
125       configuration =
126         PropertiesUtils.fromResource(getClass(), propertiesName + ".properties");
127     }
128     catch (FileNotFoundException e) {
129       throw new ConfigException("The file " + propertiesName + "properties" +
130                                 " could not be found." +
131                                 " Is it in your CLASSPATH?  Full Error: " +
132                                 e.toString());
133     }
134     catch (IOException e) {
135       throw new ConfigException("The file " + propertiesName + ".properties" +
136                                 " could not be read." +
137                                 " Full Error: " + e.toString());
138     }
139     init(propertiesName);
140   }
141 
142   /**
143    * Constructor from a given Properties object.
144    * @param properties the properties object to look in 
145    */
146   public MelatiConfig(Properties properties) {
147     configuration = properties;
148     init(propertiesName);
149   }
150 
151   @SuppressWarnings("unchecked")
152   void init(String propertiesNameIn) {
153     this.propertiesName = propertiesNameIn;
154     String pref = propertiesName + ".";
155     
156     String accessHandlerProp              = pref + "accessHandler";
157     String fdaFactoryProp                 = pref + "formDataAdaptorFactory";
158     String templetLoaderProp              = pref + "templetLoader";
159     String templateEngineProp             = pref + "templateEngine";
160     String templatePathProp               = pref + "templatePath";
161     String javascriptLibraryURLProp       = pref + "javascriptLibraryURL";
162     String staticURLProp                  = pref + "staticURL";
163     String melatiLocaleProp               = pref + "locale";
164     String preferredCharsetsProp          = pref + "preferredCharsets";
165     String loginPageServletClassNameProp  = pref + "loginPageServletClassName";
166     String logoutPageServletClassNameProp = pref + "logoutPageServletClassName";
167 
168     try {
169       setAccessHandler((AccessHandler)PropertiesUtils.
170           instanceOfNamedClass(
171               configuration,
172               accessHandlerProp,
173               "org.melati.login.AccessHandler",
174               "org.melati.login.OpenAccessHandler"));
175 
176       setFdaFactory((FormDataAdaptorFactory)PropertiesUtils.
177           instanceOfNamedClass(
178                        configuration,
179                        fdaFactoryProp,
180                        "org.melati.servlet.FormDataAdaptorFactory",
181                        "org.melati.servlet.MemoryFormDataAdaptorFactory"));
182 
183       String templetLoaderClassName =  (String)configuration.get(templetLoaderProp);
184       if(templetLoaderClassName == null || 
185          templetLoaderClassName.equals("org.melati.template.ClassNameTempletLoader")) {
186         setTempletLoader(ClassNameTempletLoader.getInstance());
187       } else
188         setTempletLoader((TempletLoader)PropertiesUtils.
189           instanceOfNamedClass(
190                           configuration,
191                           templetLoaderProp,
192                           "org.melati.template.TempletLoader",
193                           "org.melati.template.ClassNameTempletLoader"));
194 
195       setTemplateEngine((TemplateEngine)PropertiesUtils.
196           instanceOfNamedClass(
197                            configuration,
198                            templateEngineProp,
199                            "org.melati.template.TemplateEngine",
200                            "org.melati.template.NoTemplateEngine"));
201 
202       String languageTag = PropertiesUtils.getOrDefault(configuration,
203                                                         melatiLocaleProp,
204                                                         "en-gb");
205 
206       setPoemiLocale(PoemLocale.fromLanguageTag(languageTag));
207       if (poemLocale == null)
208           throw new ConfigException(languageTag +
209                               " is not a valid language tag for " +
210                               melatiLocaleProp);
211 
212       // This is a fancy way of splitting, trimming and checking for
213       // errors such as spaces within fields. 
214       // It reflects the fact that the config file format 
215       // is like a quoteless Http header field.
216       setPreferredCharsets(
217         EnumUtils.vectorOf(
218             new HttpHeader(PropertiesUtils.getOrDefault(
219                                configuration,
220                                preferredCharsetsProp,
221                                "ISO-8859-1, UTF-8, UTF-16")).wordIterator()));
222 
223       setJavascriptLibraryURL(PropertiesUtils.getOrDefault(
224               configuration,
225               javascriptLibraryURLProp,
226               "/melati-static/admin/"));
227 
228       setStaticURL(PropertiesUtils.getOrDefault(
229               configuration, 
230               staticURLProp,
231               "/melati-static/"
232               ));
233 
234       setTemplatePath(PropertiesUtils.getOrDefault(configuration,
235           templatePathProp, "."));
236 
237       setLoginPageServletClassName(PropertiesUtils.getOrDefault(configuration,
238           loginPageServletClassNameProp, loginPageServletClassName));
239 
240       setLogoutPageServletClassName(PropertiesUtils.getOrDefault(configuration,
241           logoutPageServletClassNameProp, logoutPageServletClassName));
242     }
243     catch (Exception e) {
244       throw new ConfigException("Melati could not be configured because: " +
245                                 e.toString(), e);
246     }
247 
248   }
249 
250   /**
251    * @return {@link ServletTemplateEngine} in use.
252    */
253   public ServletTemplateEngine getServletTemplateEngine() {
254     return (ServletTemplateEngine)templateEngine;
255   }
256 
257   /**
258    * @return {@link TemplateEngine} in use.
259    */
260   public TemplateEngine getTemplateEngine() {
261     return templateEngine;
262   }
263 
264   /**
265    * Set the {@link TemplateEngine} to use.
266    * 
267    * @param templateEngine
268    *        a {@link TemplateEngine}
269    */
270   public void setTemplateEngine(TemplateEngine templateEngine) {
271     this.templateEngine = templateEngine;
272   }
273 
274   /**
275    * @return the configured {@link AccessHandler}
276    */
277   public AccessHandler getAccessHandler() {
278     return accessHandler;
279   }
280 
281   /**
282    * Set the <code>AccessHandler</code> for use by this Melati.
283    * 
284    * @param accessHandler
285    *        a {@link AccessHandler}
286    */
287   public void setAccessHandler(AccessHandler accessHandler) {
288     this.accessHandler = accessHandler;
289   }
290 
291   /**
292    * @return the configured {@link TempletLoader}
293    */
294   public TempletLoader getTempletLoader() {
295     return templetLoader;
296   }
297 
298   /**
299    * Set the {@link TempletLoader} for use by this Melati.
300    * 
301    * @param templetLoader
302    *        a {@link TempletLoader}
303    */
304   public void setTempletLoader(TempletLoader templetLoader) {
305     this.templetLoader = templetLoader;
306   }
307 
308   /**
309    * @return the configured {@link FormDataAdaptorFactory}
310    */
311   public FormDataAdaptorFactory getFormDataAdaptorFactory() {
312     return fdaFactory;
313   }
314 
315   /**
316    * Set the {@link FormDataAdaptorFactory} for use by this Melati.
317    * 
318    * @param fdaf
319    *        a {@link FormDataAdaptorFactory}
320    */
321   public void setFormDataAdaptorFactory(FormDataAdaptorFactory fdaf) {
322     fdaFactory = fdaf;
323   }
324 
325   /**
326    * @return the location of javascript for this site.
327    */
328   public String getJavascriptLibraryURL() {
329     return javascriptLibraryURL;
330   }
331 
332   /**
333    * Set the <code>JavascriptLibraryURL</code> for use by this Melati.
334    * 
335    * @param url
336    *        a URL to the directory containing the JavaScript for this site
337    */
338   public void setJavascriptLibraryURL(String url) {
339     this.javascriptLibraryURL = url;
340   }
341 
342   /**
343    * Normally set to <code>melati-static</code>.
344    * 
345    * @return the location of static content for this site.
346    */
347   public String getStaticURL() {
348     return staticURL;
349   }
350 
351   /**
352    * Set the <code>StaticURL</code> for use by this Melati.
353    * 
354    * @param url
355    *        a URL to the directory containing the static content
356    */
357   public void setStaticURL(String url) {
358     this.staticURL = url;
359   }
360 
361   /**
362    * @return the location of templates.
363    */
364   public String getTemplatePath() {
365     return templatePath;
366   }
367 
368   /**
369    * @param templatePath
370    *        The templatePath to set.
371    */
372   public void setTemplatePath(String templatePath) {
373     this.templatePath = templatePath;
374   }
375 
376   /**
377    * @return the class name of the logout servlet
378    */
379   public static String getLogoutPageServletClassName() {
380     return logoutPageServletClassName;
381   }
382 
383   /**
384    * @param logoutPageServletClassName
385    *        The logoutPageServletClassName to set.
386    */
387   public static void setLogoutPageServletClassName(
388       String logoutPageServletClassName) {
389     MelatiConfig.logoutPageServletClassName = logoutPageServletClassName;
390   }
391 
392   /**
393    * @return the class name of the login servlet
394    */
395   public static String getLoginPageServletClassName() {
396     return loginPageServletClassName;
397   }
398 
399   /**
400    * @param loginPageServletClassName
401    *        The loginPageServletClassName to set.
402    */
403   public static void setLoginPageServletClassName(
404       String loginPageServletClassName) {
405     MelatiConfig.loginPageServletClassName = loginPageServletClassName;
406   }
407 
408   /**
409    * @return The configured locale, defaults to British English melati locale.
410    */
411   public static PoemLocale getPoemLocale() {
412     if (poemLocale == null)
413       poemLocale = PoemLocale.HERE;
414     return poemLocale;
415   }
416 
417   /**
418    * @param poemLocale
419    *        The PoemLocale to set.
420    */
421   public void setPoemiLocale(PoemLocale poemLocale) {
422     MelatiConfig.poemLocale = poemLocale;
423   }
424 
425 
426   /**
427    * Return the set encodings that the server prefers and supports.
428    * 
429    * @return List of encoding names or aliases.
430    */
431   public List<String> getPreferredCharsets() {
432     return preferredCharsets;
433   }
434 
435   /**
436    * @param preferredCharsets
437    *        The preferredCharsets to set.
438    */
439   public void setPreferredCharsets(Vector<String> preferredCharsets) {
440     this.preferredCharsets = preferredCharsets;
441   }
442 
443   /**
444    * @return Returns the fdaFactory.
445    */
446   public FormDataAdaptorFactory getFdaFactory() {
447     return fdaFactory;
448   }
449 
450   /**
451    * @param fdaFactory
452    *        The fdaFactory to set.
453    */
454   public void setFdaFactory(FormDataAdaptorFactory fdaFactory) {
455     this.fdaFactory = fdaFactory;
456   }
457   
458   //
459   // Non configurable but here to make them available in a template context.
460   //
461   
462   /**
463    * Called from within templets using 
464    * <code>
465    * #set $yearField = $melati.Config.YMDDateAdaptor.yearField($field)
466    * </code>
467    * idiom.
468    * Perhaps this should be elsewhere.
469    * @return the adaptor for rendering dates as drop-downs.
470    */
471   public static YMDDateAdaptor getYMDDateAdaptor() {
472     return YMDDateAdaptor.it;
473   }
474 
475   /**
476    * Called from within templets using 
477    * <code>
478    * #set $secondField = $melati.Config.YMDHMSTimestampAdaptor.secondField($field)
479    * </code>
480    * idiom.
481    * Perhaps this should be elsewhere.
482    * @return the adaptor for rendering timestamps as drop-downs.
483    */
484   public static YMDHMSTimestampAdaptor getYMDHMSTimestampAdaptor() {
485     return YMDHMSTimestampAdaptor.getIt();
486   }
487 
488   /**
489    * Called from within templets.
490    * Perhaps this should be elsewhere.
491    * @return the adaptor for rendering dates as normal.
492    */
493   public static SimpleDateAdaptor getSimpleDateAdaptor() {
494     return SimpleDateAdaptor.it;
495   }
496 
497   /**
498    * @param realPathP the path to set 
499    */
500   public void setRealPath(String realPathP) {
501     realPath = realPathP;
502   }
503   /**
504    * @return the real path, if set null otherwise
505    */
506   public String getRealPath() {
507     return realPath;
508   }
509 
510 }