View Javadoc

1   /**
2    * This file is part of the equanda project.
3    *
4    * The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7    *
8    * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
9    * ANY KIND, either express or implied. See the License for the specific language governing rights and
10   * limitations under the License.
11   *
12   * Alternatively, the contents of this file may be used under the terms of
13   * either the GNU General Public License Version 2 or later (the "GPL"), or
14   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15   * in which case the provisions of the GPL or the LGPL are applicable instead
16   * of those above. If you wish to allow use of your version of this file only
17   * under the terms of either the GPL or the LGPL, and not to allow others to
18   * use your version of this file under the terms of the MPL, indicate your
19   * decision by deleting the provisions above and replace them with the notice
20   * and other provisions required by the GPL or the LGPL. If you do not delete
21   * the provisions above, a recipient may use your version of this file under
22   * the terms of any one of the MPL, the GPL or the LGPL.
23   */
24  
25  package org.equanda.tapestry5.bindings;
26  
27  import org.apache.tapestry5.Binding;
28  
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.lang.annotation.Annotation;
32  import java.net.URL;
33  import java.util.Enumeration;
34  import java.util.Map;
35  import java.util.concurrent.ConcurrentHashMap;
36  import java.util.jar.Manifest;
37  
38  /**
39   * Binding prefix which allows you to get a value from a manifest file. As multiple files may contain a value for the
40   * same key, the first encountered is used.
41   *
42   * @author <a href="mailto:joachim@progs.be">Joachim Van der Auwera</a>
43   */
44  public class ManifestBindingPrefix
45      implements Binding
46  {
47      private static final Map<String, String> CACHE = new ConcurrentHashMap<String, String>();
48      private String expression;
49  
50      public ManifestBindingPrefix( String expression )
51      {
52          this.expression = expression;
53      }
54  
55      public Object get()
56      {
57          try
58          {
59              // first try to get the value from the cache (these things don't really change at runtime after all)
60              String res = CACHE.get( expression );
61              if ( res != null ) return res;
62  
63              ClassLoader cl = Thread.currentThread().getContextClassLoader();
64              if ( null == cl ) cl = this.getClass().getClassLoader();
65  
66              Enumeration<URL> urls = cl.getResources( "META-INF/MANIFEST.MF" );
67  
68              while ( null == res && urls.hasMoreElements() )
69              {
70                  URL url = urls.nextElement();
71                  res = get( url );
72              }
73              if ( res != null ) CACHE.put( expression, res );
74              return res;
75          }
76          catch ( Exception ex )
77          {
78              return null;
79          }
80      }
81  
82      private String get( URL url )
83          throws IOException
84      {
85          InputStream in = null;
86          try
87          {
88              in = url.openStream();
89              Manifest mf = new Manifest( in );
90              return mf.getMainAttributes().getValue( expression );
91          }
92          finally
93          {
94              if ( null != in ) in.close();
95          }
96      }
97  
98      @SuppressWarnings( "unchecked" )
99      public Class getBindingType()
100     {
101         return String.class;
102     }
103 
104     public boolean isInvariant()
105     {
106         return false;
107     }
108 
109     public void set( Object value )
110     {
111         // do nothing
112     }
113 
114     public <T extends Annotation> T getAnnotation( Class<T> annotationClass )
115     {
116         return null;
117     }
118 }