KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > facelets > impl > DefaultFacelet


1 /**
2  * Licensed under the Common Development and Distribution License,
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://www.sun.com/cddl/
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */

14
15 package com.sun.facelets.impl;
16
17 import java.io.Externalizable JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.io.ObjectInput JavaDoc;
20 import java.io.ObjectOutput JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.text.DateFormat JavaDoc;
23 import java.text.SimpleDateFormat JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.WeakHashMap JavaDoc;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32
33 import javax.el.ELException;
34 import javax.el.ExpressionFactory;
35 import javax.faces.FacesException;
36 import javax.faces.component.UIComponent;
37 import javax.faces.context.FacesContext;
38
39 import com.sun.facelets.Facelet;
40 import com.sun.facelets.FaceletContext;
41 import com.sun.facelets.FaceletException;
42 import com.sun.facelets.FaceletHandler;
43 import com.sun.facelets.tag.jsf.ComponentSupport;
44
45 /**
46  * Default Facelet implementation.
47  *
48  * @author Jacob Hookom
49  * @version $Id: DefaultFacelet.java,v 1.9 2006/04/03 05:10:38 jhook Exp $
50  */

51 final class DefaultFacelet extends Facelet {
52
53     private final Logger JavaDoc log = Logger.getLogger("facelets.facelet");
54
55     private final static String JavaDoc APPLIED_KEY = "com.sun.facelets.APPLIED";
56
57     private final String JavaDoc alias;
58
59     private final ExpressionFactory elFactory;
60
61     private final DefaultFaceletFactory factory;
62
63     private final long createTime;
64
65     private final long refreshPeriod;
66
67     private final Map JavaDoc relativePaths;
68
69     private final FaceletHandler root;
70
71     private final URL JavaDoc src;
72
73     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el,
74             URL JavaDoc src, String JavaDoc alias, FaceletHandler root) {
75         this.factory = factory;
76         this.elFactory = el;
77         this.src = src;
78         this.root = root;
79         this.alias = alias;
80         this.createTime = System.currentTimeMillis();
81         this.refreshPeriod = this.factory.getRefreshPeriod();
82         this.relativePaths = new WeakHashMap JavaDoc();
83     }
84
85     /**
86      * @see com.sun.facelets.Facelet#apply(javax.faces.context.FacesContext,
87      * javax.faces.component.UIComponent)
88      */

89     public void apply(FacesContext facesContext, UIComponent parent)
90             throws IOException JavaDoc, FacesException, FaceletException, ELException {
91         DefaultFaceletContext ctx = new DefaultFaceletContext(facesContext,
92                 this);
93         this.refresh(parent);
94         ComponentSupport.markForDeletion(parent);
95         this.root.apply(ctx, parent);
96         ComponentSupport.finalizeForDeletion(parent);
97         this.markApplied(parent);
98     }
99
100     private final void refresh(UIComponent c) {
101         if (this.refreshPeriod > 0) {
102
103             // finally remove any children marked as deleted
104
int sz = c.getChildCount();
105             if (sz > 0) {
106                 UIComponent cc = null;
107                 List JavaDoc cl = c.getChildren();
108                 ApplyToken token;
109                 while (--sz >= 0) {
110                     cc = (UIComponent) cl.get(sz);
111                     if (!cc.isTransient()) {
112                         token = (ApplyToken) cc.getAttributes().get(APPLIED_KEY);
113                         if (token != null && token.time < this.createTime
114                                 && token.alias.equals(this.alias)) {
115                             if (log.isLoggable(Level.INFO)) {
116                                 DateFormat JavaDoc df = SimpleDateFormat.getTimeInstance();
117                                 log.info("Facelet[" + this.alias
118                                         + "] was modified @ "
119                                         + df.format(new Date JavaDoc(this.createTime))
120                                         + ", flushing component applied @ "
121                                         + df.format(new Date JavaDoc(token.time)));
122                             }
123                             cl.remove(sz);
124                         }
125                     }
126                 }
127             }
128
129             // remove any facets marked as deleted
130
if (c.getFacets().size() > 0) {
131                 Collection JavaDoc col = c.getFacets().values();
132                 UIComponent fc;
133                 ApplyToken token;
134                 for (Iterator JavaDoc itr = col.iterator(); itr.hasNext();) {
135                     fc = (UIComponent) itr.next();
136                     if (!fc.isTransient()) {
137                         token = (ApplyToken) fc.getAttributes().get(APPLIED_KEY);
138                         if (token != null && token.time < this.createTime
139                                 && token.alias.equals(this.alias)) {
140                             if (log.isLoggable(Level.INFO)) {
141                                 DateFormat JavaDoc df = SimpleDateFormat.getTimeInstance();
142                                 log.info("Facelet[" + this.alias
143                                         + "] was modified @ "
144                                         + df.format(new Date JavaDoc(this.createTime))
145                                         + ", flushing component applied @ "
146                                         + df.format(new Date JavaDoc(token.time)));
147                             }
148                             itr.remove();
149                         }
150                     }
151                 }
152             }
153         }
154     }
155
156     private final void markApplied(UIComponent parent) {
157         if (this.refreshPeriod > 0) {
158             Iterator JavaDoc itr = parent.getFacetsAndChildren();
159             UIComponent c;
160             Map JavaDoc attr;
161             ApplyToken token = new ApplyToken(this.alias, System
162                     .currentTimeMillis()
163                     + this.refreshPeriod);
164             while (itr.hasNext()) {
165                 c = (UIComponent) itr.next();
166                 if (!c.isTransient()) {
167                     attr = c.getAttributes();
168                     if (!attr.containsKey(APPLIED_KEY)) {
169                         attr.put(APPLIED_KEY, token);
170                     }
171                 }
172             }
173         }
174     }
175
176     /**
177      * Return the alias name for error messages and logging
178      *
179      * @return alias name
180      */

181     public String JavaDoc getAlias() {
182         return this.alias;
183     }
184
185     /**
186      * Return this Facelet's ExpressionFactory instance
187      *
188      * @return internal ExpressionFactory instance
189      */

190     public ExpressionFactory getExpressionFactory() {
191         return this.elFactory;
192     }
193
194     /**
195      * The time when this Facelet was created, NOT the URL source code
196      *
197      * @return final timestamp of when this Facelet was created
198      */

199     public long getCreateTime() {
200         return this.createTime;
201     }
202
203     /**
204      * Delegates resolution to DefaultFaceletFactory reference. Also, caches
205      * URLs for relative paths.
206      *
207      * @param path
208      * a relative url path
209      * @return URL pointing to destination
210      * @throws IOException
211      * if there is a problem creating the URL for the path specified
212      */

213     private URL JavaDoc getRelativePath(String JavaDoc path) throws IOException JavaDoc {
214         URL JavaDoc url = (URL JavaDoc) this.relativePaths.get(path);
215         if (url == null) {
216             url = this.factory.resolveURL(this.src, path);
217             this.relativePaths.put(path, url);
218         }
219         return url;
220     }
221
222     /**
223      * The URL this Facelet was created from.
224      *
225      * @return the URL this Facelet was created from
226      */

227     public URL JavaDoc getSource() {
228         return this.src;
229     }
230
231     /**
232      * Given the passed FaceletContext, apply our child FaceletHandlers to the
233      * passed parent
234      *
235      * @see FaceletHandler#apply(FaceletContext, UIComponent)
236      * @param ctx
237      * the FaceletContext to use for applying our FaceletHandlers
238      * @param parent
239      * the parent component to apply changes to
240      * @throws IOException
241      * @throws FacesException
242      * @throws FaceletException
243      * @throws ELException
244      */

245     private void include(DefaultFaceletContext ctx, UIComponent parent)
246             throws IOException JavaDoc, FacesException, FaceletException, ELException {
247         this.refresh(parent);
248         this.root.apply(new DefaultFaceletContext(ctx, this), parent);
249         this.markApplied(parent);
250     }
251
252     /**
253      * Used for delegation by the DefaultFaceletContext. First pulls the URL
254      * from {@link #getRelativePath(String) getRelativePath(String)}, then
255      * calls
256      * {@link #include(FaceletContext, UIComponent, URL) include(FaceletContext, UIComponent, URL)}.
257      *
258      * @see FaceletContext#includeFacelet(UIComponent, String)
259      * @param ctx
260      * FaceletContext to pass to the included Facelet
261      * @param parent
262      * UIComponent to apply changes to
263      * @param path
264      * relative path to the desired Facelet from the FaceletContext
265      * @throws IOException
266      * @throws FacesException
267      * @throws FaceletException
268      * @throws ELException
269      */

270     public void include(DefaultFaceletContext ctx, UIComponent parent, String JavaDoc path)
271             throws IOException JavaDoc, FacesException, FaceletException, ELException {
272         URL JavaDoc url = this.getRelativePath(path);
273         this.include(ctx, parent, url);
274     }
275
276     /**
277      * Grabs a DefaultFacelet from referenced DefaultFaceletFacotry
278      *
279      * @see DefaultFaceletFactory#getFacelet(URL)
280      * @param ctx
281      * FaceletContext to pass to the included Facelet
282      * @param parent
283      * UIComponent to apply changes to
284      * @param url
285      * URL source to include Facelet from
286      * @throws IOException
287      * @throws FacesException
288      * @throws FaceletException
289      * @throws ELException
290      */

291     public void include(DefaultFaceletContext ctx, UIComponent parent, URL JavaDoc url)
292             throws IOException JavaDoc, FacesException, FaceletException, ELException {
293         DefaultFacelet f = (DefaultFacelet) this.factory.getFacelet(url);
294         f.include(ctx, parent);
295     }
296
297     private static class ApplyToken implements Externalizable JavaDoc {
298         public String JavaDoc alias;
299
300         public long time;
301
302         public ApplyToken() {
303         }
304
305         public ApplyToken(String JavaDoc alias, long time) {
306             this.alias = alias;
307             this.time = time;
308         }
309
310         public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc,
311                 ClassNotFoundException JavaDoc {
312             this.alias = in.readUTF();
313             this.time = in.readLong();
314         }
315
316         public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
317             out.writeUTF(this.alias);
318             out.writeLong(this.time);
319         }
320     }
321
322     public String JavaDoc toString() {
323         return this.alias;
324     }
325 }
326
Popular Tags