📄 taglibfactory.java
字号:
String nsuri, String localName, String qName, Attributes atts) { if ("uri".equals(qName)) { buf = new StringBuffer(); } } public void characters(char[] chars, int off, int len) { if (buf != null) { buf.append(chars, off, len); } } public void endElement(String nsuri, String localName, String qName) { if ("uri".equals(qName)) { uri = buf.toString().trim(); buf = null; } } } private static void parseXml(InputStream in, String url, DefaultHandler handler) throws ParserConfigurationException, IOException, SAXException { InputSource is = new InputSource(); is.setByteStream(in); is.setSystemId(url); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(false); factory.setValidating(true); XMLReader reader = factory.newSAXParser().getXMLReader(); reader.setEntityResolver(new LocalTaglibDtds()); reader.setContentHandler(handler); reader.parse(is); } private static final class Taglib implements TemplateHashModel { private Map tags; Taglib() { } public TemplateModel get(String key) { return (TagTransformModel) tags.get(key); } public boolean isEmpty() { return false; } boolean load(String uri, ServletContext ctx, Map locations) throws ParserConfigurationException, IOException, SAXException, TemplateModelException { String[] tldPath = getTldPath(uri, locations); if(logger.isDebugEnabled()) { if(tldPath == null) { logger.debug("Loading taglib " + uri + " from location null"); } else { logger.debug("Loading taglib " + uri + " from location " + tldPath[0] + (tldPath[1] != null ? "!" + tldPath[1] : "")); } } tags = loadTaglib(tldPath, ctx); if(tags != null) { locations.remove(uri); return true; } else { return false; } } } private static final Map loadTaglib(String[] tldPath, ServletContext ctx) throws ParserConfigurationException, IOException, SAXException, TemplateModelException { if (tldPath == null) { return null; } String filePath = tldPath[0]; TldParser tldParser = new TldParser(); InputStream in = ctx.getResourceAsStream(filePath); if(in == null) { throw new TemplateModelException("Could not find webapp resource " + filePath); } String url = ctx.getResource(filePath).toExternalForm(); try { String jarPath = tldPath[1]; if(jarPath != null) { ZipInputStream zin = new ZipInputStream(in); for(;;) { ZipEntry ze = zin.getNextEntry(); if(ze == null) { throw new TemplateModelException("Could not find JAR entry " + jarPath + " inside webapp resource " + filePath); } String zname = ze.getName(); if(zname.equals(jarPath)) { parseXml(zin, "jar:" + url + "!" + zname, tldParser); break; } } } else { parseXml(in, url, tldParser); } } finally { in.close(); } EventForwarding eventForwarding = EventForwarding.getInstance(ctx); if(eventForwarding != null) { eventForwarding.addListeners(tldParser.getListeners()); } else if(tldParser.getListeners().size() > 0) { throw new TemplateModelException( "Event listeners specified in the TLD could not be " + " registered since the web application doesn't have a" + " listener of class " + EventForwarding.class.getName() + ". To remedy this, add this element to web.xml:\n" + "| <listener>\n" + "| <listener-class>" + EventForwarding.class.getName() + "</listener-class>\n" + "| </listener>"); } return tldParser.getTags(); } private static final String[] getTldPath(String uri, Map locations) { String[] path = (String[])locations.get(uri); // If location was explicitly defined in web.xml, or discovered in a // JAR file, use it. (Hopefully this is 99% of the cases) if(path != null) { return path; } // If there was no explicit mapping in web.xml, but URI is a // ROOT_REL_URI, return it (JSP.7.6.3.2) if(uri.startsWith("/")) { path = new String[2]; path[0] = uri; if(uri.endsWith(".jar") || uri.endsWith(".zip")) { path[1] = "META-INF/taglib.tld"; } return path; } return null; } private static String resolveRelativeUri(String uri) throws TemplateModelException { // Absolute and root-relative URIs are left as they are. if(uri.startsWith("/") || uri.indexOf("://") != -1) { return uri; } // Otherwise it is a NOROOT_REL_URI, and has to be resolved relative // to current page... We have to obtain the request object to know what // is the URL of the current page (this assumes there's a // HttpRequestHashModel under name FreemarkerServlet.KEY_REQUEST in the // environment...) (JSP.7.6.3.2) TemplateModel reqHash = Environment.getCurrentEnvironment().getVariable( FreemarkerServlet.KEY_REQUEST_PRIVATE); if(reqHash instanceof HttpRequestHashModel) { HttpServletRequest req = ((HttpRequestHashModel)reqHash).getRequest(); String pi = req.getPathInfo(); String reqPath = req.getServletPath(); if(reqPath == null) { reqPath = ""; } reqPath += (pi == null ? "" : pi); // We don't care about paths with ".." in them. If the container // wishes to resolve them on its own, let it be. int lastSlash = reqPath.lastIndexOf('/'); if(lastSlash != -1) { return reqPath.substring(0, lastSlash + 1) + uri; } else { return '/' + uri; } } throw new TemplateModelException( "Can't resolve relative URI " + uri + " as request URL information is unavailable."); } private static final class TldParser extends DefaultHandler { private final Map tags = new HashMap(); private final List listeners = new ArrayList(); private Locator locator; private StringBuffer buf; private String tagName; private String tagClass; Map getTags() { return tags; } List getListeners() { return listeners; } public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startElement( String nsuri, String localName, String qName, Attributes atts) { if ("name".equals(qName) || "tagclass".equals(qName) || "tag-class".equals(qName) || "listener-class".equals(qName)) { buf = new StringBuffer(); } } public void characters(char[] chars, int off, int len) { if (buf != null) { buf.append(chars, off, len); } } public void endElement(String nsuri, String localName, String qName) throws SAXParseException { if ("name".equals(qName)) { if(tagName == null) { tagName = buf.toString().trim(); } buf = null; } else if ("tagclass".equals(qName) || "tag-class".equals(qName)) { tagClass = buf.toString().trim(); buf = null; } else if ("tag".equals(qName)) { try { tags.put( tagName, new TagTransformModel(ClassUtil.forName(tagClass))); tagName = null; tagClass = null; } catch (IntrospectionException e) { throw new SAXParseException( "Can't introspect tag class " + tagClass, locator, e); } catch (ClassNotFoundException e) { throw new SAXParseException( "Can't find tag class " + tagClass, locator, e); } } else if ("listener-class".equals(qName)) { String listenerClass = buf.toString().trim(); buf = null; try { listeners.add(ClassUtil.forName(listenerClass).newInstance()); } catch(Exception e) { throw new SAXParseException( "Can't instantiate listener class " + listenerClass, locator, e); } } } } private static final Map dtds = new HashMap(); static { // JSP taglib 2.0 dtds.put("http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd", "web-jsptaglibrary_2_0.xsd"); // JSP taglib 1.2 dtds.put("-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN", "web-jsptaglibrary_1_2.dtd"); dtds.put("http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd", "web-jsptaglibrary_1_2.dtd"); // JSP taglib 1.1 dtds.put("-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN", "web-jsptaglibrary_1_1.dtd"); dtds.put("http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd", "web-jsptaglibrary_1_1.dtd"); // Servlet 2.4 dtds.put("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd", "web-app_2_4.xsd"); // Servlet 2.3 dtds.put("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", "web-app_2_3.dtd"); dtds.put("http://java.sun.com/dtd/web-app_2_3.dtd", "web-app_2_3.dtd"); // Servlet 2.2 dtds.put("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", "web-app_2_2.dtd"); dtds.put("http://java.sun.com/j2ee/dtds/web-app_2_2.dtd", "web-app_2_2.dtd"); } private static final class LocalTaglibDtds implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) { String resourceName = (String)dtds.get(publicId); if(resourceName == null) { resourceName = (String)dtds.get(systemId); } InputStream resourceStream; if(resourceName != null) { resourceStream = getClass().getResourceAsStream(resourceName); } else { // Fake an empty stream for unknown DTDs resourceStream = new ByteArrayInputStream(new byte[0]); } InputSource is = new InputSource(); is.setPublicId(publicId); is.setSystemId(systemId); is.setByteStream(resourceStream); return is; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -