View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.jspf.impl;
21  
22  import org.apache.james.jspf.core.LogEnabled;
23  import org.apache.james.jspf.core.Logger;
24  import org.apache.james.jspf.core.exceptions.PermErrorException;
25  import org.apache.james.jspf.parser.TermsFactory;
26  import org.apache.james.jspf.terms.Configuration;
27  import org.apache.james.jspf.terms.ConfigurationEnabled;
28  import org.apache.james.jspf.wiring.WiringService;
29  import org.apache.james.jspf.wiring.WiringServiceException;
30  import org.apache.james.jspf.wiring.WiringServiceTable;
31  
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.util.ArrayList;
35  import java.util.Collection;
36  import java.util.Collections;
37  import java.util.Properties;
38  
39  /**
40   * The default implementation of the TermsFactory
41   */
42  public class DefaultTermsFactory implements TermsFactory {
43      
44      private String termFile = "org/apache/james/jspf/parser/jspf.default.terms";
45      
46      private Collection mechanismsCollection;
47  
48      private Collection modifiersCollection;
49  
50      private Logger log;
51      
52      private WiringService wiringService;
53  
54      public DefaultTermsFactory(Logger log) {
55          this.log = log;
56          this.wiringService = new WiringServiceTable();
57          ((WiringServiceTable) this.wiringService).put(LogEnabled.class, log);
58          init();
59      }
60  
61      public DefaultTermsFactory(Logger log, WiringService wiringService) {
62          this.log = log;
63          this.wiringService = wiringService;
64          init();
65      }
66  
67      /**
68       * Initialize the factory and the services
69       */
70      private void init() {
71          try {
72              InputStream is = Thread.currentThread().getContextClassLoader()
73                      .getResourceAsStream(termFile);
74              if (is == null) {
75                  throw new NullPointerException("Unable to find the "+termFile+" resource in the classpath");
76              }
77              Properties p = new Properties();
78              p.load(is);
79              String mechs = p.getProperty("mechanisms");
80              String mods = p.getProperty("modifiers");
81              String[] classes;
82              classes = mechs.split(",");
83              Class[] knownMechanisms = new Class[classes.length];
84              for (int i = 0; i < classes.length; i++) {
85                  log.debug("Add following class as known mechanismn: "
86                          + classes[i]);
87                  knownMechanisms[i] = Thread.currentThread()
88                          .getContextClassLoader().loadClass(classes[i]);
89              }
90              mechanismsCollection = createTermDefinitionCollection(knownMechanisms);
91              classes = mods.split(",");
92              Class[] knownModifiers = new Class[classes.length];
93              for (int i = 0; i < classes.length; i++) {
94                  log.debug("Add following class as known modifier: "
95                          + classes[i]);
96                  knownModifiers[i] = Thread.currentThread()
97                          .getContextClassLoader().loadClass(classes[i]);
98              }
99              modifiersCollection = createTermDefinitionCollection(knownModifiers);
100     
101         } catch (IOException e) {
102             throw new IllegalStateException(
103                     "Term configuration cannot be found");
104         } catch (ClassNotFoundException e) {
105             throw new IllegalStateException(
106                     "One configured class cannot be found");
107         }
108     }
109 
110 
111     /**
112      * Create a collection of term definitions supported by this factory.
113      * 
114      * @param classes
115      *            classes to analyze
116      * @param staticFieldName
117      *            static field to concatenate
118      * @return map <Class,Pattern>
119      */
120     private Collection createTermDefinitionCollection(Class[] classes) {
121         Collection l = new ArrayList();
122         for (int j = 0; j < classes.length; j++) {
123             try {
124                 l.add(new DefaultTermDefinition(classes[j]));
125             } catch (Exception e) {
126                 log.debug("Unable to create the term collection", e);
127                 throw new IllegalStateException(
128                         "Unable to create the term collection");
129             }
130         }
131         return Collections.synchronizedCollection(l);
132     }
133 
134 
135     /**
136      * @see org.apache.james.jspf.parser.TermsFactory#createTerm(java.lang.Class, org.apache.james.jspf.terms.Configuration)
137      */
138     public Object createTerm(Class termDef, Configuration subres) throws PermErrorException, InstantiationException {
139         try {
140             Object term = termDef.newInstance();
141             
142             try {
143                 wiringService.wire(term);
144             } catch (WiringServiceException e) {
145                 throw new InstantiationException(
146                         "Unexpected error adding dependencies to term: " + e.getMessage());
147             }
148 
149             if (term instanceof ConfigurationEnabled) {
150                 if (subres == null || subres.groupCount() == 0) {
151                     ((ConfigurationEnabled) term).config(null);
152                 } else {
153                     ((ConfigurationEnabled) term).config(subres);
154                 }
155             }
156             return term;
157         } catch (IllegalAccessException e) {
158             throw new InstantiationException(
159                     "Unexpected error creating term: " + e.getMessage());
160         }
161     }
162 
163 
164     /**
165      * @see org.apache.james.jspf.parser.TermsFactory#getMechanismsCollection()
166      */
167     public Collection getMechanismsCollection() {
168         return mechanismsCollection;
169     }
170 
171 
172     /**
173      * @see org.apache.james.jspf.parser.TermsFactory#getModifiersCollection()
174      */
175     public Collection getModifiersCollection() {
176         return modifiersCollection;
177     }
178 
179 }