KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > jsfext > layout > xml > XMLLayoutDefinitionManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.tools.jsfext.layout.xml;
24
25 import com.sun.enterprise.tools.jsfext.layout.LayoutDefinitionManager;
26 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutDefinition;
27 import com.sun.enterprise.tools.jsfext.util.Util;
28 import com.sun.enterprise.tools.jsfext.util.ClasspathEntityResolver;
29
30 import java.io.File JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.OutputStreamWriter JavaDoc;
34 import java.io.PrintWriter JavaDoc;
35 import java.io.UnsupportedEncodingException JavaDoc;
36 import java.lang.reflect.InvocationTargetException JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38 import java.net.URL JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Map JavaDoc;
41
42 import javax.faces.context.FacesContext;
43
44 import org.xml.sax.EntityResolver JavaDoc;
45 import org.xml.sax.ErrorHandler JavaDoc;
46 import org.xml.sax.InputSource JavaDoc;
47 import org.xml.sax.SAXException JavaDoc;
48 import org.xml.sax.SAXParseException JavaDoc;
49
50
51 /**
52  * <p> This class is a concrete implmentation of the abstract class
53  * {@link LayoutDefinitionManager}. It obtains {@link LayoutDefinition}
54  * objects by interpreting the <code>key</code> passed to
55  * {@link #getLayoutDefinition(String)} as a path to an XML file
56  * describing the {@link LayoutDefinition}. It will first attempt to
57  * resolve this path from the document root of the ServletContext or
58  * PortletCotnext. If that fails, it will attempt to use the Classloader
59  * to resolve it.</p>
60  *
61  * <p> Locating the dtd for the XML file is done in a similar manner. It
62  * will first attempt to locate the dtd relative to the ServletContext
63  * (or PortletContext) root. If that fails it will attempt to use the
64  * ClassLoader to resolve it. Optionally a different EntityResolver may
65  * be supplied to provide a custom way of locating the dtd, this is done
66  * via {@link #setEntityResolver}.</p>
67  *
68  * <p> This class is a singleton. This means modifications to this class
69  * effect all threads using this class. This includes setting
70  * EntityResolvers and ErrorHandlers. These values only need to be set
71  * once to remain in effect as long as the JVM is running.</p>
72  *
73  * @author Ken Paulsen (ken.paulsen@sun.com)
74  */

75 public class XMLLayoutDefinitionManager extends LayoutDefinitionManager {
76
77     /**
78      * <p> Constructor.</p>
79      */

80     protected XMLLayoutDefinitionManager() {
81     super();
82
83     // Set the default XMLError Handler
84
try {
85         setErrorHandler(new XMLErrorHandler(new PrintWriter JavaDoc(
86             new OutputStreamWriter JavaDoc(System.err, "UTF-8"), true)));
87     } catch (UnsupportedEncodingException JavaDoc ex) {
88         throw new RuntimeException JavaDoc(ex);
89     }
90
91     // Set the default EntityResolver
92
setEntityResolver(new ClasspathEntityResolver());
93     }
94
95     /**
96      * <p> This method returns an instance of this LayoutDefinitionManager.
97      * The object returned is a singleton (only 1 instance will be
98      * created per JVM).</p>
99      *
100      * @return <code>XMLLayoutDefinitionManager</code> instance
101      */

102     public static LayoutDefinitionManager getInstance() {
103     if (instance == null) {
104         instance = new XMLLayoutDefinitionManager();
105     }
106     return instance;
107     }
108
109     /**
110      * <p> This method is responsible for finding the requested
111      * {@link LayoutDefinition} for the given <code>key</code>.</p>
112      *
113      * @param key Key identifying the desired {@link LayoutDefinition}
114      *
115      * @return The requested {@link LayoutDefinition}.
116      */

117     public LayoutDefinition getLayoutDefinition(String JavaDoc key) throws IOException JavaDoc {
118     // Remove leading "/" (we'll add it back if needed)
119
while (key.startsWith("/")) {
120         key = key.substring(1);
121     }
122
123     // See if we already have this one.
124
LayoutDefinition ld = (LayoutDefinition) layouts.get(key);
125     if (DEBUG) {
126         // Disable caching
127
ld = null;
128     }
129     if (ld == null) {
130         String JavaDoc baseURI = getBaseURI();
131
132         // Check for XML file in docroot. Use docroot for the baseURI,
133
// and get the full path to the xml file
134
URL JavaDoc ldURL = null;
135         Object JavaDoc ctx = FacesContext.getCurrentInstance().
136         getExternalContext().getContext();
137         String JavaDoc url;
138
139         // The following should work w/ a ServletContext or PortletContext
140
Method JavaDoc method = null;
141         try {
142         method = ctx.getClass().getMethod(
143             "getRealPath", GET_REAL_PATH_ARGS);
144         } catch (NoSuchMethodException JavaDoc ex) {
145         throw new RuntimeException JavaDoc(ex);
146         }
147         try {
148         if (baseURI == null) {
149             baseURI = "file:///"
150             + method.invoke(ctx, new Object JavaDoc [] {"/"});
151         }
152         url = (String JavaDoc) method.invoke(ctx, new Object JavaDoc [] {key});
153         // Don't add the leading '/' back on because it looks a the
154
// root if we do
155
} catch (IllegalAccessException JavaDoc ex) {
156         throw new RuntimeException JavaDoc(ex);
157         } catch (InvocationTargetException JavaDoc ex) {
158         throw new RuntimeException JavaDoc(ex);
159         }
160
161         // Create a URL to the xml file, if file exists
162
if ((url != null) && new File JavaDoc(url).canRead()) {
163         try {
164             ldURL = new URL JavaDoc("file:///" + url);
165         } catch (Exception JavaDoc ex) {
166             throw new RuntimeException JavaDoc(
167             "Unable to create URL: 'file:///" + url
168             + "' while attempting to locate '" + key + "'", ex);
169         }
170         }
171
172         if (ldURL == null) {
173         // Check the classpath for the xml file
174
ClassLoader JavaDoc loader = Util.getClassLoader(key);
175         ldURL = loader.getResource(key);
176         if (ldURL == null) {
177             ldURL = loader.getResource("/"+key);
178             if (ldURL == null) {
179             ldURL = loader.getResource("META-INF/"+key);
180             }
181         }
182         }
183
184         // Make sure we found the url
185
if (ldURL == null) {
186         throw new java.io.FileNotFoundException JavaDoc(
187             "Unable to locate '" + key + "'");
188         }
189
190         // Read the XML file
191
try {
192         ld = new XMLLayoutDefinitionReader(
193             ldURL, getEntityResolver(), getErrorHandler(), baseURI).
194             read();
195         } catch (IOException JavaDoc ex) {
196         throw new RuntimeException JavaDoc("Unable to process '" + ldURL
197             + "'. EntityResolver: '" + getEntityResolver()
198             + "'. ErrorHandler: '" + getErrorHandler()
199             + "'. baseURI: '" + baseURI + "'.", ex);
200         }
201
202         // Cache the LayoutDefinition
203
synchronized (layouts) {
204         layouts.put(key, ld);
205         }
206     }
207     return ld;
208     }
209
210     /**
211      * <p> This returns the LDM's entity resolver, null if not set.</p>
212      *
213      * @return EntityResolver
214      */

215     public EntityResolver getEntityResolver() {
216     return (EntityResolver) getAttribute(ENTITY_RESOLVER);
217     }
218
219     /**
220      * <p> This method sets the LDM's entity resolver.</p>
221      *
222      * @param entityResolver The EntityResolver to use.
223      */

224     public void setEntityResolver(EntityResolver entityResolver) {
225     setAttribute(ENTITY_RESOLVER, entityResolver);
226     }
227
228     /**
229      * <p> This returns the LDM's XML parser ErrorHandler, null if not set.</p>
230      *
231      * @return ErrorHandler
232      */

233     public ErrorHandler JavaDoc getErrorHandler() {
234     return (ErrorHandler JavaDoc) getAttribute(ERROR_HANDLER);
235     }
236
237     /**
238      * <p> This method sets the LDM's ErrorHandler.</p>
239      *
240      * @param errorHandler The ErrorHandler to use.
241      */

242     public void setErrorHandler(ErrorHandler JavaDoc errorHandler) {
243     setAttribute(ERROR_HANDLER, errorHandler);
244     }
245
246     /**
247      * <p> This returns the LDM's XML parser baseURI which will be used to
248      * resolve relative URI's, null if not set.</p>
249      *
250      * @return The base URI as a String
251      */

252     public String JavaDoc getBaseURI() {
253     return (String JavaDoc) getAttribute(BASE_URI);
254     }
255
256     /**
257      * <p> This method sets the LDM's BaseURI.</p>
258      *
259      * @param baseURI The BaseURI to use.
260      */

261     public void setBaseURI(String JavaDoc baseURI) {
262     setAttribute(BASE_URI, baseURI);
263     }
264
265     /**
266      * <p> This class handles XML parser errors.</p>
267      */

268     private static class XMLErrorHandler implements ErrorHandler JavaDoc {
269     /** Error handler output goes here */
270     private PrintWriter JavaDoc out;
271
272     XMLErrorHandler(PrintWriter JavaDoc outWriter) {
273         this.out = outWriter;
274     }
275
276     /**
277      * <p> Returns a string describing parse exception details.</p>
278      */

279     private String JavaDoc getParseExceptionInfo(SAXParseException JavaDoc spe) {
280         String JavaDoc systemId = spe.getSystemId();
281         if (systemId == null) {
282         systemId = "null";
283         }
284         String JavaDoc info = "URI=" + systemId + " Line=" + spe.getLineNumber()
285         + ": " + spe.getMessage();
286         return info;
287     }
288
289     // The following methods are standard SAX ErrorHandler methods.
290
// See SAX documentation for more info.
291

292     public void warning(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
293         out.println("Warning: " + getParseExceptionInfo(spe));
294     }
295
296     public void error(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
297         String JavaDoc message = "Error: " + getParseExceptionInfo(spe);
298         throw new SAXException JavaDoc(message, spe);
299     }
300
301     public void fatalError(SAXParseException JavaDoc spe) throws SAXException JavaDoc {
302         String JavaDoc message = "Fatal Error: " + getParseExceptionInfo(spe);
303         throw new SAXException JavaDoc(message, spe);
304     }
305     }
306
307     /**
308      * <p> Static map of LayoutDefinitionManagers. Normally this will only
309      * contain the default LayoutManager.</p>
310      */

311     private static Map JavaDoc layouts = new HashMap JavaDoc();
312
313     /**
314      * <p> This is used to ensure that only 1 instance of this class is
315      * created (per JVM).</p>
316      */

317     private static LayoutDefinitionManager instance = null;
318
319     /**
320      *
321      */

322     private static final Class JavaDoc [] GET_REAL_PATH_ARGS =
323         new Class JavaDoc[] {String JavaDoc.class};
324
325     /**
326      * <p> This is an attribute key which can be used to provide an
327      * EntityResolver to the XML parser.</p>
328      */

329     public static final String JavaDoc ENTITY_RESOLVER = "entityResolver";
330
331     /**
332      *
333      */

334     public static final String JavaDoc ERROR_HANDLER = "errorHandler";
335
336     /**
337      *
338      */

339     public static final String JavaDoc BASE_URI = "baseURI";
340
341     private static boolean DEBUG =
342     Boolean.getBoolean("com.sun.enterprise.tools.jsfext.DEBUG");
343 }
344
Popular Tags