001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsp;
031:
032: import com.caucho.config.types.FileSetType;
033: import com.caucho.jsp.cfg.TldFunction;
034: import com.caucho.jsp.cfg.TldTaglib;
035: import com.caucho.loader.DynamicClassLoader;
036: import com.caucho.server.util.CauchoSystem;
037: import com.caucho.server.webapp.WebApp;
038: import com.caucho.util.L10N;
039: import com.caucho.vfs.Path;
040: import com.caucho.vfs.Vfs;
041:
042: import java.io.IOException;
043: import java.lang.reflect.Method;
044: import java.util.ArrayList;
045: import java.util.HashMap;
046: import java.util.logging.Logger;
047:
048: /**
049: * Stores the entire information for a tag library.
050: */
051: public class TaglibManager {
052: static final L10N L = new L10N(TaglibManager.class);
053: private static final Logger log = Logger
054: .getLogger(TaglibManager.class.getName());
055:
056: private JspResourceManager _resourceManager;
057: private WebApp _webApp;
058:
059: private TldManager _tldManager;
060:
061: private String _tldDir;
062: private FileSetType _tldFileSet;
063:
064: private TagFileManager _tagFileManager;
065:
066: private HashMap<String, String> _uriLocationMap = new HashMap<String, String>();
067: private HashMap<String, TldTaglib> _tldMap = new HashMap<String, TldTaglib>();
068: private HashMap<String, Taglib> _taglibMap = new HashMap<String, Taglib>();
069: private HashMap<String, Taglib> _taglibDirMap = new HashMap<String, Taglib>();
070:
071: private TagAnalyzer _tagAnalyzer = new TagAnalyzer();
072:
073: private volatile boolean _isInit;
074:
075: public TaglibManager(JspResourceManager resourceManager,
076: WebApp webApp, TagFileManager tagFileManager)
077: throws JspParseException, IOException {
078: _resourceManager = resourceManager;
079: _webApp = webApp;
080:
081: _tldManager = TldManager.create(resourceManager, webApp);
082: _tagFileManager = tagFileManager;
083:
084: if (webApp != null)
085: webApp.getJspApplicationContext().setTaglibManager(this );
086: }
087:
088: /**
089: * Sets the webApp.
090: */
091: void setWebApp(WebApp webApp) {
092: _webApp = webApp;
093: }
094:
095: public void setTldDir(String tldDir) {
096: _tldDir = tldDir;
097: }
098:
099: public void setTldFileSet(FileSetType fileSet) {
100: _tldManager.setTldFileSet(fileSet);
101: }
102:
103: /**
104: * Adds a URI to location map.
105: */
106: public void addLocationMap(String uri, String location) {
107: _uriLocationMap.put(uri, location);
108: }
109:
110: /**
111: * Loads all the .tld files in the WEB-INF and the META-INF for
112: * the entire classpath.
113: */
114: public synchronized void init() throws JspParseException,
115: IOException {
116: if (_isInit)
117: return;
118: _isInit = true;
119: }
120:
121: /**
122: * Analyze tag.
123: */
124: AnalyzedTag analyzeTag(Class cl) {
125: AnalyzedTag tag = _tagAnalyzer.analyze(cl);
126:
127: return tag;
128: }
129:
130: /**
131: * Returns the taglib with the given prefix and uri.
132: */
133: public synchronized Taglib getTaglib(String prefix, String uri,
134: String location) throws JspParseException {
135: if (JspParser.JSP_NS.equals(uri))
136: return null;
137: else if (prefix != null && prefix.startsWith("jsp")) {
138: throw new JspParseException(L.l(
139: "tag prefix '{0}' may not start with 'jsp'.",
140: prefix));
141: }
142:
143: try {
144: init();
145: } catch (IOException e) {
146: throw new JspParseException(e);
147: }
148:
149: Taglib taglib = _taglibMap.get(uri);
150:
151: if (taglib != null)
152: return taglib;
153:
154: // jsp/188u
155: String mapLocation = _uriLocationMap.get(uri);
156:
157: if (mapLocation != null)
158: location = mapLocation;
159:
160: taglib = readTaglib(prefix, uri, location);
161:
162: if (taglib != null)
163: _taglibMap.put(uri, taglib);
164:
165: return taglib;
166: }
167:
168: /**
169: * Returns the taglib with the given prefix and uri.
170: */
171: public synchronized Taglib getTaglibDir(String prefix, String dir)
172: throws JspParseException {
173: try {
174: init();
175: } catch (IOException e) {
176: throw new JspParseException(e);
177: }
178:
179: Taglib taglib = _taglibDirMap.get(dir);
180:
181: if (taglib != null)
182: return taglib;
183:
184: TldTaglib tldTaglib = new TldTaglib();
185:
186: taglib = new Taglib(prefix, "urn:jsptagdir:" + dir, tldTaglib,
187: _tagFileManager);
188:
189: if (taglib != null)
190: _taglibDirMap.put(dir, taglib);
191:
192: return taglib;
193: }
194:
195: /**
196: * Returns the taglib with the given prefix and uri.
197: */
198: public void addTaglibFunctions(HashMap<String, Method> functionMap,
199: String prefix, String uri) throws JspParseException {
200: Taglib taglib = getTaglib(prefix, uri, uri);
201:
202: if (taglib == null)
203: return;
204:
205: ArrayList<TldFunction> functions = taglib.getFunctionList();
206:
207: for (int i = 0; i < functions.size(); i++) {
208: TldFunction function = functions.get(i);
209:
210: String name = prefix + ":" + function.getName();
211:
212: functionMap.put(name, function.getMethod());
213: }
214: }
215:
216: /**
217: * Returns the taglib with the given prefix and uri.
218: */
219: private Taglib readTaglib(String prefix, String uri, String location)
220: throws JspParseException {
221: try {
222: TldTaglib tldTaglib = _tldMap.get(uri);
223:
224: if (tldTaglib != null) {
225: } else {
226: String mapLocation = _uriLocationMap.get(uri);
227:
228: if ((location == null || location.equals(""))
229: && (mapLocation == null || mapLocation
230: .equals("")))
231: return null;
232:
233: tldTaglib = _tldManager.parseTld(uri, mapLocation,
234: location);
235:
236: _tldMap.put(uri, tldTaglib);
237: }
238:
239: if (tldTaglib != null) {
240: if (tldTaglib.getConfigException() != null)
241: throw JspParseException.create(tldTaglib
242: .getConfigException());
243:
244: return new Taglib(prefix, uri, tldTaglib,
245: _tagFileManager);
246: } else
247: return null;
248: } catch (JspParseException e) {
249: throw e;
250: } catch (Exception e) {
251: throw new JspParseException(e);
252: }
253: }
254:
255: /**
256: * Finds the path to the jar specified by the location.
257: *
258: * @param appDir the webApp directory
259: * @param location the tag-location specified in the web.xml
260: *
261: * @return the found jar or null
262: */
263: private Path findJar(String location) {
264: Path path;
265:
266: if (location.startsWith("file:"))
267: path = Vfs.lookup(location);
268: else if (location.startsWith("/"))
269: path = _resourceManager.resolvePath("." + location);
270: else
271: path = _resourceManager.resolvePath(location);
272:
273: if (path.exists())
274: return path;
275:
276: DynamicClassLoader loader;
277: loader = (DynamicClassLoader) Thread.currentThread()
278: .getContextClassLoader();
279: String classPath = loader.getClassPath();
280: char sep = CauchoSystem.getPathSeparatorChar();
281:
282: int head = 0;
283: int tail = 0;
284:
285: while ((tail = classPath.indexOf(sep, head)) >= 0) {
286: String sub = classPath.substring(head, tail);
287:
288: path = Vfs.lookup(sub);
289:
290: if (sub.endsWith(location) && path.exists())
291: return path;
292:
293: head = tail + 1;
294: }
295:
296: if (classPath.length() <= head)
297: return null;
298:
299: String sub = classPath.substring(head);
300:
301: path = Vfs.lookup(sub);
302:
303: if (sub.endsWith(location) && path.exists())
304: return path;
305: else
306: return null;
307: }
308: }
|