View Javadoc

1   /*
2    * $Id: Constants.java,v 1.18 2011/06/16 09:29:40 jbmeslin Exp $
3    */
4   package org.rcfaces.core.internal;
5   
6   import java.io.IOException;
7   import java.io.InputStream;
8   import java.net.URL;
9   import java.util.Arrays;
10  import java.util.Enumeration;
11  import java.util.HashSet;
12  import java.util.Locale;
13  import java.util.Set;
14  import java.util.StringTokenizer;
15  import java.util.jar.Attributes;
16  import java.util.jar.Manifest;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  import org.rcfaces.core.component.capability.IAsyncRenderModeCapability;
21  import org.rcfaces.core.internal.component.ComponentsFactory;
22  import org.rcfaces.core.internal.component.IFactory;
23  import org.rcfaces.core.internal.resource.IResourceLoaderFactory;
24  import org.rcfaces.core.internal.util.Delay;
25  
26  /**
27   * 
28   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
29   * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:40 $
30   */
31  public class Constants {
32      private static final String REVISION = "$Revision: 1.18 $";
33  
34      private static final Log LOG = LogFactory.getLog(Constants.class);
35  
36      private static final String CONSTANT_PREFIX;
37      static {
38          Package _package = Constants.class.getPackage();
39  
40          String name = _package.getName();
41          if (name.endsWith(".internal")) {
42              name = name.substring(0, name.lastIndexOf('.'));
43          }
44  
45          CONSTANT_PREFIX = name;
46      }
47  
48      private static final String BUILDER_VERSION = null;
49  
50      public static final boolean READ_ONLY_COLLECTION_LOCK_ENABLED = true;
51  
52      public static final boolean TEMPLATE_ENGINE_SUPPORT = true;
53  
54      public static final boolean COMPONENT_DEFAULT_PROPERTIES_SUPPORT = true;
55  
56      public static final boolean RESOURCE_CONTENT_VERSION_SUPPORT = true;
57  
58      public static final boolean RESOURCE_CONTENT_PROXY_SUPPORT = true;
59  
60      public static final boolean CACHED_COMPONENT_ITERATOR = false;
61  
62      public static final boolean STATED_COMPONENT_CHILDREN_LIST = false;
63  
64      public static final boolean ENCODE_URI = false;
65  
66      public static final boolean HASH_SUPPORT = true;
67  
68      public static final boolean ETAG_SUPPORT = true;
69  
70      public static final boolean GZIP_SUPPORT_DEFAULT_VALUE = true;
71  
72      public static final boolean MYFACES_INPUT_BROADCAST_BUG = true;
73  
74      /**
75       * Collection can be converted to DataModel (JSF spec extension)
76       */
77      public static final boolean COLLECTION_DATAMODEL_SUPPORT = true;
78  
79      /**
80       * Adaptable object can be converted to DataModel (JSF spec extension)
81       */
82      public static final boolean ADAPTABLE_DATAMODEL_SUPPORT = true;
83  
84      public static final long DEFAULT_EXPIRATION_DELAY = Delay.WEEK;
85  
86      public static final long DEFAULT_VERSIONED_EXPIRATION_DELAY = Delay.YEAR;
87  
88      public static final int VERSIONED_URI_HASHCODE_MAX_SIZE = 64;
89  
90      private static final String RCFACES_VERSION_SYSTEM_PARAMETER = "rcfaces.core.version";
91  
92      public static final String SAVE_STATE_FIELD_MARKER_SYSTEM_PARAMETER = "rcfaces.core.stateFieldMarker";
93  
94      public static final String SAVE_STATE_FIELD_MARKER_PARAMETER = getPackagePrefix()
95              + ".SAVE_STATE_FIELD_MARKER";
96  
97      public static final boolean CLIENT_LOCALE_SUPPORT_DEFAULT_VALUE = true;
98  
99      public static final String[] RESOURCE_VERSION_DIGEST_ALGORITHMS = {
100             "SHA-512", "SHA-256", "SHA-1" };
101 
102     public static final String[] ETAG_DIGEST_ALGORITHMS = { "SHA-512",
103             "SHA-256", "SHA-1" };
104 
105     public static final String[] SERIALISATION_HASH_ALGORITHMS = { "SHA-512",
106             "SHA-256", "SHA-1" };
107 
108     public static final String[] HASH_DIGEST_ALGORITHMS = { "MD5" };
109 
110     public static final boolean BASIC_CONTENT_WEAK_CACHE_ENABLED = true;
111 
112     public static final int BASIC_CONTENT_CACHE_SIZE = 256;
113 
114     private static final String version;
115     static {
116         if (BUILDER_VERSION != null) {
117             version = BUILDER_VERSION;
118 
119         } else {
120             version = searchVersion(Constants.class,
121                     RCFACES_VERSION_SYSTEM_PARAMETER, "RCFaces Core");
122         }
123 
124         LOG.info("RCFaces CORE version '" + version + "'");
125     }
126 
127     private static final IFactory defaultFactory;
128 
129     public static final IResourceLoaderFactory IMAGE_LOADER_FACTORY = null;
130 
131     public static final boolean CACHED_LOCALE_FORMATS = true;
132 
133     /**
134      * <code>false</code> Optimize for CPU <code>true</code>Optimize for Memory
135      */
136     public static final boolean COMPACTED_PROPERTY_NAME = false;
137 
138     public static final boolean LOCKED_CLIENT_ATTRIBUTES_DEFAULT_VALUE = false;
139 
140     private static final String FACELET_CLASSNAME = "com.sun.facelets.Facelet";
141 
142     public static final int DEFAULT_ASYNC_MODE = IAsyncRenderModeCapability.NONE_ASYNC_RENDER_MODE;
143 
144     public static final int ENABLE_ASYNC_MODE_VALUE = IAsyncRenderModeCapability.BUFFER_ASYNC_RENDER_MODE;
145 
146     public static final boolean FACELETS_SUPPORT = true;
147 
148     public static final boolean ADAPT_SELECT_ITEMS = true;
149 
150     public static final Locale REPOSITORY_DEFAULT_LOCALE = Locale.ENGLISH;
151 
152     public static final boolean VERIFY_VARIABLE_SYNTAX = false;
153 
154     private static final boolean VERIFY_IMPLEMENTATION = true;
155 
156     public static final int MINIMUM_GZIP_BUFFER_SIZE = 128;
157 
158     public static final int CONTENT_STORAGE_CACHE_SIZE = 512;
159 
160     static {
161         LOG.info("READ_ONLY_COLLECTION_LOCK_ENABLED="
162                 + READ_ONLY_COLLECTION_LOCK_ENABLED);
163 
164         LOG.info("LOCKED_CLIENT_ATTRIBUTES_DEFAULT_VALUE="
165                 + LOCKED_CLIENT_ATTRIBUTES_DEFAULT_VALUE);
166 
167         LOG.info("TEMPLATE_ENGINE_SUPPORT=" + TEMPLATE_ENGINE_SUPPORT);
168 
169         LOG.info("RESOURCE_CONTENT_VERSION_SUPPORT="
170                 + RESOURCE_CONTENT_VERSION_SUPPORT);
171 
172         LOG.info("STATED_COMPONENT_CHILDREN_LIST="
173                 + STATED_COMPONENT_CHILDREN_LIST);
174 
175         LOG.info("CACHED_COMPONENT_ITERATOR=" + CACHED_COMPONENT_ITERATOR);
176 
177         LOG.info("CACHED_LOCALE_FORMATS=" + CACHED_LOCALE_FORMATS);
178 
179         LOG.info("COMPACTED_PROPERTY_NAME=" + COMPACTED_PROPERTY_NAME);
180 
181         LOG.info("ETAG_SUPPORT=" + ETAG_SUPPORT + " (algorithms: "
182                 + Arrays.asList(ETAG_DIGEST_ALGORITHMS) + ")");
183 
184         LOG.info("HASH_SUPPORT=" + HASH_SUPPORT + " (algorithms: "
185                 + Arrays.asList(HASH_DIGEST_ALGORITHMS) + ")");
186 
187         LOG.info("SERIALISATION_HASH_ALGORITHMS="
188                 + Arrays.asList(SERIALISATION_HASH_ALGORITHMS));
189 
190         LOG.info("GZIP_SUPPORT_DEFAULT_VALUE=" + GZIP_SUPPORT_DEFAULT_VALUE);
191 
192         LOG.info("DEFAULT_EXPIRATION_DELAY=" + DEFAULT_EXPIRATION_DELAY + " ("
193                 + Delay.format(DEFAULT_EXPIRATION_DELAY) + ")");
194 
195         LOG.info("DEFAULT_VERSIONED_EXPIRATION_DELAY="
196                 + DEFAULT_VERSIONED_EXPIRATION_DELAY + " ("
197                 + Delay.format(DEFAULT_VERSIONED_EXPIRATION_DELAY) + ")");
198 
199         LOG.info("CLIENT_LOCALE_SUPPORT_DEFAULT_VALUE="
200                 + CLIENT_LOCALE_SUPPORT_DEFAULT_VALUE);
201 
202         LOG.info("VERSIONED_URI_HASHCODE_MAX_SIZE="
203                 + VERSIONED_URI_HASHCODE_MAX_SIZE);
204 
205         LOG.info("REPOSITORY_DEFAULT_LOCALE=" + REPOSITORY_DEFAULT_LOCALE);
206 
207         LOG.info("CONTENT_STORAGE_CACHE_SIZE=" + CONTENT_STORAGE_CACHE_SIZE);
208 
209         LOG.info("FACELETS_SUPPORT=" + FACELETS_SUPPORT);
210 
211         switch (DEFAULT_ASYNC_MODE) {
212         case IAsyncRenderModeCapability.TREE_ASYNC_RENDER_MODE:
213             LOG.info("DEFAULT_ASYNC_MODE=tree");
214             break;
215 
216         case IAsyncRenderModeCapability.BUFFER_ASYNC_RENDER_MODE:
217             LOG.info("DEFAULT_ASYNC_MODE=buffer");
218             break;
219 
220         default:
221             LOG.info("DEFAULT_ASYNC_MODE=none");
222             break;
223         }
224 
225         switch (ENABLE_ASYNC_MODE_VALUE) {
226         case IAsyncRenderModeCapability.TREE_ASYNC_RENDER_MODE:
227             LOG.info("ENABLE_ASYNC_MODE_VALUE=tree");
228             break;
229 
230         case IAsyncRenderModeCapability.BUFFER_ASYNC_RENDER_MODE:
231             LOG.info("ENABLE_ASYNC_MODE_VALUE=buffer");
232             break;
233 
234         default:
235             LOG.info("ENABLE_ASYNC_MODE_VALUE=unknown");
236             break;
237         }
238 
239         defaultFactory = ComponentsFactory.getCameliaFactory(null);
240         LOG.info("Default components factory: " + defaultFactory.getName());
241     }
242 
243     public static final String getPackagePrefix() {
244         return CONSTANT_PREFIX;
245     }
246 
247     public static IFactory getCameliaFactory() {
248         return defaultFactory;
249     }
250 
251     public static String getVersion() {
252         return version;
253     }
254 
255     public static final String searchVersion(Class clazz,
256             String systemParameter, String versionName) {
257 
258         try {
259             String version = System.getProperty(systemParameter);
260             if (version != null) {
261                 if ("now".equalsIgnoreCase(version)) {
262                     version = "0." + String.valueOf(System.currentTimeMillis());
263 
264                     try {
265                         System.setProperty(systemParameter, version);
266 
267                     } catch (Throwable th2) {
268                         LOG.debug(th2);
269                     }
270 
271                     LOG.info(versionName
272                             + " version: DEVELOPMENT MODE (Use fake version: "
273                             + version + ")");
274 
275                 } else {
276                     LOG.info(versionName + " version setted by property: "
277                             + version);
278                 }
279 
280                 return version;
281             }
282 
283         } catch (Throwable th) {
284             // Un probleme de sécurité peut-etre !
285             LOG.debug(th);
286         }
287 
288         Package clazzPackage = clazz.getPackage();
289         if (clazzPackage != null) {
290             try {
291                 String implementationTitle = clazzPackage
292                         .getImplementationTitle();
293                 if (implementationTitle != null) {
294                     verifyImplementationTitle(implementationTitle);
295                 }
296 
297                 String version = clazzPackage.getImplementationVersion();
298                 if (version != null) {
299                     LOG.info(versionName + " version: " + version);
300 
301                     return version;
302                 }
303 
304             } catch (Throwable th) {
305                 LOG.error("Can not get " + versionName
306                         + " version by package API ! ("
307                         + clazzPackage.getName() + ")", th);
308             }
309         }
310 
311         String version = "0." + String.valueOf(System.currentTimeMillis());
312         LOG.error("Version of " + versionName
313                 + " can not be determined ! (Use the fake version: " + version
314                 + ")");
315 
316         return version;
317     }
318 
319     private static void verifyImplementationTitle(String implementationTitle) {
320         if (Constants.VERIFY_IMPLEMENTATION == false) {
321             return;
322         }
323 
324         LOG.debug("Check for implementation title '" + implementationTitle
325                 + "' uniqueness.");
326 
327         try {
328             Enumeration enumeration = Constants.class.getClassLoader()
329                     .getResources("META-INF/MANIFEST.MF");
330 
331             Set resources = new HashSet(2);
332 
333             for (; enumeration.hasMoreElements();) {
334                 URL url = (URL) enumeration.nextElement();
335 
336                 InputStream inputStream = url.openStream();
337                 if (inputStream == null) {
338                     LOG.debug("No input stream for url '" + url + "'.");
339                     continue;
340                 }
341 
342                 try {
343                     Manifest manifest = new Manifest(inputStream);
344 
345                     String jarImplementationTitle = (String) manifest
346                             .getMainAttributes().get(
347                                     Attributes.Name.IMPLEMENTATION_TITLE);
348 
349                     if (implementationTitle.equals(jarImplementationTitle) == false) {
350                         continue;
351                     }
352 
353                     resources.add(url);
354 
355                     LOG.debug("Implementation title detected '"
356                             + implementationTitle + "' => " + url);
357 
358                 } catch (IOException ex) {
359                     LOG.error("Can not load manifest '" + url + "'", ex);
360 
361                 } finally {
362                     try {
363                         inputStream.close();
364 
365                     } catch (IOException ex) {
366                         LOG.error(ex);
367                     }
368                 }
369             }
370 
371             LOG.debug("Count of implementation title '" + implementationTitle
372                     + "' = " + resources.size());
373 
374             if (resources.size() > 1) {
375                 throw new IllegalStateException(
376                         "More than one definition of implementation title '"
377                                 + implementationTitle + "' !");
378             }
379 
380         } catch (IOException e) {
381             LOG.error("Can not search manifest for implementation title '"
382                     + implementationTitle + "'.", e);
383         }
384     }
385 
386     public static final String getBuildId(String version) {
387         StringTokenizer st = new StringTokenizer(version, ".");
388         if (st.countTokens() < 4) {
389             return version;
390         }
391 
392         st.nextToken();
393         st.nextToken();
394         st.nextToken();
395 
396         return st.nextToken("\n\r\t ");
397     }
398 }