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.log.Log;
033: import com.caucho.util.L10N;
034: import com.caucho.vfs.Path;
035: import com.caucho.xml.QName;
036:
037: import javax.servlet.jsp.tagext.TagInfo;
038: import java.io.IOException;
039: import java.util.HashMap;
040: import java.util.logging.Logger;
041:
042: /**
043: * Stores the information for the .tags
044: */
045: public class ParseTagManager {
046: static final L10N L = new L10N(ParseTagManager.class);
047: private static final Logger log = Log.open(ParseTagManager.class);
048:
049: private JspResourceManager _resourceManager;
050: private TaglibManager _taglibManager;
051: private TagFileManager _tagFileManager;
052:
053: private HashMap<QName, TagInfo> _tagMap = new HashMap<QName, TagInfo>();
054: private HashMap<String, Taglib> _taglibMap = new HashMap<String, Taglib>();
055:
056: public ParseTagManager(JspResourceManager resourceManager,
057: TaglibManager taglibManager, TagFileManager tagFileManager)
058: throws JspParseException, IOException {
059: _resourceManager = resourceManager;
060: _taglibManager = taglibManager;
061:
062: _tagFileManager = tagFileManager;
063: }
064:
065: /**
066: * Analyzes the tag.
067: */
068: public synchronized AnalyzedTag analyzeTag(Class cl) {
069: return _taglibManager.analyzeTag(cl);
070: }
071:
072: /**
073: * Returns the tag with the given qname.
074: */
075: public synchronized TagInfo getTag(QName qname)
076: throws JspParseException {
077: TagInfo tag = getTagImpl(qname);
078:
079: if (tag instanceof TagInfoImpl)
080: ((TagInfoImpl) tag).validate();
081:
082: return tag;
083: }
084:
085: /**
086: * Returns the tag with the given qname.
087: */
088: private TagInfo getTagImpl(QName qname) throws JspParseException {
089: TagInfo tag = _tagMap.get(qname);
090:
091: if (tag != null)
092: return tag;
093:
094: tag = _tagFileManager.getTag(qname.getPrefix(), qname
095: .getLocalName(), qname.getNamespaceURI());
096: _tagMap.put(qname, tag);
097:
098: if (tag != null)
099: return tag;
100:
101: Taglib taglib = addTaglib(qname);
102: if (taglib == null)
103: return null;
104:
105: String name = qname.getName();
106: String tail = qname.getLocalName();
107:
108: if (qname.getNamespaceURI() == null) {
109: int p = name.lastIndexOf(':');
110:
111: if (p < 0)
112: return null;
113:
114: tail = name.substring(p + 1);
115: }
116:
117: if (taglib != null)
118: tag = taglib.getTag(tail);
119:
120: if (tag == null) {
121: String tagLocation = taglib.getTagFilePath(tail);
122: Path path = taglib.getPath();
123:
124: if (path != null && tagLocation != null) {
125: path = path.lookup(tagLocation);
126:
127: tag = _tagFileManager.getTag(path, qname.getPrefix(),
128: tagLocation);
129:
130: if (tag != null) {
131: return tag;
132: }
133: }
134:
135: if (tagLocation != null) {
136: tag = _tagFileManager.getTag(qname.getPrefix(),
137: tagLocation);
138:
139: if (tag == null)
140: throw new JspParseException(
141: L
142: .l(
143: "'{0}' is an unknown tag-file in tag library '{1}'.",
144: tagLocation, taglib
145: .getURI()));
146: }
147: }
148:
149: if (tag == null)
150: throw new JspParseException(L.l(
151: "'{0}' is an unknown tag in tag library '{1}'.",
152: tail, taglib.getURI()));
153:
154: _tagMap.put(qname, tag);
155:
156: return tag;
157: }
158:
159: /**
160: * Returns the tag with the given qname.
161: */
162: public synchronized Class getTagClass(QName qname) throws Exception {
163: TagInfo tagInfo = getTag(qname);
164:
165: if (tagInfo == null)
166: return null;
167:
168: String className = tagInfo.getTagClassName();
169:
170: if (className != null)
171: return _tagFileManager.loadClass(className);
172: else
173: return null;
174: }
175:
176: public synchronized Taglib addTaglib(QName qname)
177: throws JspParseException {
178: String prefix = qname.getPrefix();
179:
180: Taglib taglib = (Taglib) _taglibMap.get(prefix);
181: if (_taglibMap.get(prefix) != null)
182: return taglib;
183:
184: String uri = qname.getNamespace();
185:
186: taglib = addTaglib(prefix, uri);
187:
188: _taglibMap.put(prefix, taglib);
189:
190: return taglib;
191: }
192:
193: /**
194: * Lookup and add a taglib based on a prefix and uri
195: */
196: public synchronized Taglib addTaglib(String prefix, String uri)
197: throws JspParseException {
198: Taglib taglib = null;
199:
200: boolean hasTld = false;
201:
202: if (uri == null)
203: return null;
204: else if (uri.startsWith("urn:jsptagdir:")) {
205: String tagDir = uri.substring("urn:jsptagdir:".length());
206:
207: taglib = addTaglibDir(prefix, tagDir);
208: hasTld = true;
209:
210: if (taglib == null) {
211: throw error(L
212: .l(
213: "'{0}' has no matching tag. The taglib uri must match a <uri> element in a taglib.tld.",
214: uri));
215: }
216: } else {
217: if (uri.startsWith("urn:jsptld:")) {
218: hasTld = true;
219: uri = uri.substring("urn:jsptld:".length());
220: }
221:
222: String location = uri;
223:
224: taglib = _taglibManager.getTaglib(prefix, uri, location);
225:
226: if (hasTld && taglib == null) {
227: throw error(L
228: .l(
229: "'{0}' has no matching tag. The taglib uri must match a <uri> element in a taglib.tld.",
230: uri));
231: }
232: }
233:
234: return taglib;
235: }
236:
237: /**
238: * Adds a taglib.
239: */
240: public synchronized Taglib addTaglibDir(String prefix, String dir)
241: throws JspParseException {
242: return _taglibManager.getTaglibDir(prefix, dir);
243: }
244:
245: /**
246: * Adds a taglib.
247: */
248: public synchronized Taglib addTaglib(String prefix, String uri,
249: String location) throws JspParseException {
250: Taglib taglib = _taglibManager.getTaglib(prefix, uri, location);
251:
252: return addTaglib(taglib);
253: }
254:
255: private Taglib addTaglib(Taglib taglib) throws JspParseException {
256: if (taglib == null)
257: return null;
258:
259: taglib = taglib.copy();
260:
261: for (Taglib oldTaglib : _taglibMap.values()) {
262: if (oldTaglib != null) {
263: oldTaglib.addTaglib(taglib);
264: taglib.addTaglib(oldTaglib);
265: }
266: }
267:
268: _taglibMap.put(taglib.getPrefixString(), taglib);
269:
270: return taglib;
271: }
272:
273: public boolean hasTags() {
274: return _taglibMap != null && _taglibMap.size() > 1;
275: }
276:
277: public JspParseException error(String message) {
278: return new JspParseException(message);
279: }
280: }
|