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  package org.apache.myfaces.view.facelets.compiler;
20  
21  import java.io.IOException;
22  import java.net.URL;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.logging.Logger;
29  
30  import javax.el.ELException;
31  import javax.el.ExpressionFactory;
32  import javax.faces.FacesException;
33  import javax.faces.context.FacesContext;
34  import javax.faces.view.facelets.FaceletException;
35  import javax.faces.view.facelets.FaceletHandler;
36  import javax.faces.view.facelets.TagDecorator;
37  
38  import org.apache.myfaces.config.element.FaceletsProcessing;
39  import org.apache.myfaces.view.facelets.tag.BaseMultipleTagDecorator;
40  import org.apache.myfaces.view.facelets.tag.BaseTagDecorator;
41  import org.apache.myfaces.view.facelets.tag.CompositeTagDecorator;
42  import org.apache.myfaces.view.facelets.tag.CompositeTagLibrary;
43  import org.apache.myfaces.view.facelets.tag.TagLibrary;
44  import org.apache.myfaces.view.facelets.tag.jsf.html.DefaultTagDecorator;
45  import org.apache.myfaces.view.facelets.util.ParameterCheck;
46  import org.apache.myfaces.view.facelets.util.ReflectionUtil;
47  
48  /**
49   * A Compiler instance may handle compiling multiple sources
50   * 
51   * @author Jacob Hookom
52   * @version $Id$
53   */
54  public abstract class Compiler
55  {
56  
57      //protected final static Logger log = Logger.getLogger("facelets.compiler");
58      protected final static Logger log = Logger.getLogger(Compiler.class.getName());
59  
60      public final static String EXPRESSION_FACTORY = "compiler.ExpressionFactory";
61  
62      private static final TagLibrary EMPTY_LIBRARY = new CompositeTagLibrary(new TagLibrary[0]);
63  
64      private boolean validating = false;
65  
66      private boolean trimmingWhitespace = false;
67  
68      private boolean trimmingComments = false;
69  
70      private final List<TagLibrary> libraries = new ArrayList<TagLibrary>();
71  
72      private final List<TagDecorator> decorators = new ArrayList<TagDecorator>();
73  
74      private final Map<String, String> features = new HashMap<String, String>();
75  
76      private boolean developmentProjectStage = false;
77  
78      private Collection<FaceletsProcessing> faceletsProcessingConfigurations;
79  
80      /**
81       * 
82       */
83      public Compiler()
84      {
85  
86      }
87  
88      public final FaceletHandler compile(URL src, String alias) throws IOException, FaceletException, ELException,
89              FacesException
90      {
91          return this.doCompile(src, alias);
92      }
93      
94      public final FaceletHandler compileViewMetadata(URL src, String alias)
95              throws IOException, FaceletException, ELException, FacesException
96      {
97          return this.doCompileViewMetadata(src, alias);
98      }
99      
100     public final FaceletHandler compileCompositeComponentMetadata(URL src, String alias)
101             throws IOException, FaceletException, ELException, FacesException
102     {
103         return this.doCompileCompositeComponentMetadata(src, alias);
104     }
105     
106     public final FaceletHandler compileComponent(
107         String taglibURI, String tagName, Map<String,Object> attributes)
108     {
109         return this.doCompileComponent(taglibURI, tagName, attributes);
110     }
111 
112     protected abstract FaceletHandler doCompile(URL src, String alias)
113             throws IOException, FaceletException, ELException, FacesException;
114 
115     protected abstract FaceletHandler doCompileViewMetadata(URL src, String alias)
116             throws IOException, FaceletException, ELException, FacesException;
117     
118     protected abstract FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
119             throws IOException, FaceletException, ELException, FacesException;
120     
121     protected abstract FaceletHandler doCompileComponent(
122         String taglibURI, String tagName, Map<String,Object> attributes);
123 
124     public final TagDecorator createTagDecorator()
125     {
126         if (this.decorators.size() > 0)
127         {
128             return new BaseMultipleTagDecorator(new DefaultTagDecorator(), 
129                 new CompositeTagDecorator(this.decorators.toArray(
130                     new TagDecorator[this.decorators.size()])));
131         }
132         // JSF 2.2 has always enabled the default tag decorator.
133         return new BaseTagDecorator(new DefaultTagDecorator());
134         //return EMPTY_DECORATOR;
135     }
136 
137     public final void addTagDecorator(TagDecorator decorator)
138     {
139         ParameterCheck.notNull("decorator", decorator);
140         if (!this.decorators.contains(decorator))
141         {
142             this.decorators.add(decorator);
143         }
144     }
145 
146     public final ExpressionFactory createExpressionFactory()
147     {
148         ExpressionFactory el = null;
149         el = (ExpressionFactory) this.featureInstance(EXPRESSION_FACTORY);
150         if (el == null)
151         {
152             try
153             {
154                 el = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
155                 if (el == null)
156                 {
157                     log.warning("No default ExpressionFactory from Faces Implementation, "
158                                 + "attempting to load from Feature["
159                                 + EXPRESSION_FACTORY + "]");
160                 }
161             }
162             catch (Exception e)
163             {
164                 // do nothing
165             }
166         }
167         
168         return el;
169     }
170 
171     private final Object featureInstance(String name)
172     {
173         String type = (String) this.features.get(name);
174         if (type != null)
175         {
176             try
177             {
178                 return ReflectionUtil.forName(type).newInstance();
179             }
180             catch (Throwable t)
181             {
182                 throw new FaceletException("Could not instantiate feature[" + name + "]: " + type);
183             }
184         }
185         return null;
186     }
187 
188     public final TagLibrary createTagLibrary()
189     {
190         if (this.libraries.size() > 0)
191         {
192             return new CompositeTagLibrary(this.libraries.toArray(new TagLibrary[this.libraries.size()]));
193         }
194         return EMPTY_LIBRARY;
195     }
196 
197     public final void addTagLibrary(TagLibrary library)
198     {
199         ParameterCheck.notNull("library", library);
200         if (!this.libraries.contains(library))
201         {
202             this.libraries.add(library);
203         }
204     }
205 
206     public final void setFeature(String name, String value)
207     {
208         this.features.put(name, value);
209     }
210 
211     public final String getFeature(String name)
212     {
213         return (String) this.features.get(name);
214     }
215 
216     public final boolean isTrimmingComments()
217     {
218         return this.trimmingComments;
219     }
220 
221     public final void setTrimmingComments(boolean trimmingComments)
222     {
223         this.trimmingComments = trimmingComments;
224     }
225 
226     public final boolean isTrimmingWhitespace()
227     {
228         return this.trimmingWhitespace;
229     }
230 
231     public final void setTrimmingWhitespace(boolean trimmingWhitespace)
232     {
233         this.trimmingWhitespace = trimmingWhitespace;
234     }
235 
236     public final boolean isValidating()
237     {
238         return this.validating;
239     }
240 
241     public final void setValidating(boolean validating)
242     {
243         this.validating = validating;
244     }
245     
246     public final boolean isDevelopmentProjectStage()
247     {
248         return this.developmentProjectStage;
249     }
250     
251     public final void setDevelopmentProjectStage(boolean developmentProjectStage)
252     {
253         this.developmentProjectStage = developmentProjectStage;
254     }
255 
256     /**
257      * 
258      * @since 2.1.0
259      * @return
260      */
261     public Collection<FaceletsProcessing> getFaceletsProcessingConfigurations()
262     {
263         return faceletsProcessingConfigurations;
264     }
265 
266     /**
267      * 
268      * @since 2.1.0
269      * @param faceletsProcessingConfigurations 
270      */
271     public void setFaceletsProcessingConfigurations(
272             Collection<FaceletsProcessing> faceletsProcessingConfigurations)
273     {
274         this.faceletsProcessingConfigurations = faceletsProcessingConfigurations;
275     }
276 }
277