diff options
author | nitind | 2005-02-15 06:42:31 +0000 |
---|---|---|
committer | nitind | 2005-02-15 06:42:31 +0000 |
commit | 49418459edc208867da7d93559584ceaad2cd927 (patch) | |
tree | 27e32edf4ab6db8c8f03d5c33e183672893f84ac /bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld | |
parent | 969bea5e6d02a7056ca613412a4a9fd4d9f3e61d (diff) | |
download | webtools.sourceediting-49418459edc208867da7d93559584ceaad2cd927.tar.gz webtools.sourceediting-49418459edc208867da7d93559584ceaad2cd927.tar.xz webtools.sourceediting-49418459edc208867da7d93559584ceaad2cd927.zip |
move to internals
Diffstat (limited to 'bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld')
3 files changed, 1632 insertions, 0 deletions
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java new file mode 100644 index 0000000000..3106ba8f81 --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java @@ -0,0 +1,668 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.core.internal.contentmodel.tld; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP11TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP12TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP20TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDDocument; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDFunction; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDInitParam; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDListener; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDValidator; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDVariable; +import org.eclipse.jst.jsp.core.internal.Logger; +import org.eclipse.jst.jsp.core.internal.contentmodel.ITaglibRecord; +import org.eclipse.jst.jsp.core.internal.contentmodel.JarRecord; +import org.eclipse.jst.jsp.core.internal.contentmodel.TLDRecord; +import org.eclipse.jst.jsp.core.internal.contentmodel.URLRecord; +import org.eclipse.jst.jsp.core.internal.util.DocumentProvider; +import org.eclipse.wst.common.contentmodel.CMAttributeDeclaration; +import org.eclipse.wst.common.contentmodel.CMDocument; +import org.eclipse.wst.common.contentmodel.CMElementDeclaration; +import org.eclipse.wst.common.contentmodel.factory.CMDocumentFactory; +import org.eclipse.wst.sse.core.util.JarUtilities; +import org.eclipse.wst.xml.uriresolver.util.URIHelper; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * CMDocumentBuilder for Taglib Descriptors + * + * Returns namespace-less CMDocuments for a taglib descriptor, loading it + * directly from a file or extracted from a JAR archive. Content Model objects + * will implement the TLDCMDocument, TLDElementDeclaration, and + * TLDAttributeDeclaration interfaces for extended properties. + */ +public class CMDocumentFactoryTLD implements CMDocumentFactory { + + static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/tldcmdocument/factory")); //$NON-NLS-1$ //$NON-NLS-2$ + + /** + * CMDocumentFactoryTLD constructor comment. + */ + public CMDocumentFactoryTLD() { + super(); + } + + /** + * NOT API + * + * @param baselocation + * @param input + * @return + */ + public CMDocument buildCMDocument(String baselocation, InputStream input) { + DocumentProvider provider = new DocumentProvider(); + provider.setValidating(false); + provider.setRootElementName(JSP11TLDNames.TAGLIB); + provider.setInputStream(input); + if (baselocation != null) + provider.setBaseReference(baselocation); + return loadDocument(baselocation, provider.getRootElement()); + } + + /** + * @param fileName + * @return + */ + private CMDocument buildCMDocumentFromDirectory(File directory) { + if (_debug) { + System.out.println("not implemented: tagdir loading for " + directory.getAbsolutePath()); + } + return null; + } + + /** + * NOT API + * + * @param fileName + * @return + */ + protected CMDocument buildCMDocumentFromFile(String fileName) { + // load the taglib descriptor file + DocumentProvider provider = new DocumentProvider(); + provider.setValidating(false); + provider.setBaseReference(fileName); + provider.setRootElementName(JSP11TLDNames.TAGLIB); + provider.setFileName(fileName); + Node rootElement = provider.getRootElement(); + return loadDocument(fileName, rootElement); + } + + /** + * Builds a CMDocument assuming the JSP v1.1 default path + * + * @param jarFileName - + * the name of the containing JAR file + */ + protected CMDocument buildCMDocumentFromJar(String jarFileName) { + // load the taglib descriptor file + return buildCMDocumentFromJar(jarFileName, JarUtilities.JSP11_TAGLIB); + } + + /** + * Builds a CMDocument + * + * @param jarFileName - + * the name of the containing JAR file + * @param contentFileName - + * the path within the JAR for a valid taglib descriptor + */ + protected CMDocument buildCMDocumentFromJar(String jarFileName, String contentFileName) { + // load the taglib descriptor file + DocumentProvider provider = new DocumentProvider(); + provider.setValidating(false); + provider.setBaseReference(jarFileName); + provider.setRootElementName(JSP11TLDNames.TAGLIB); + provider.setJarFileName(jarFileName); + provider.setFileName(contentFileName); + CMDocument document = loadDocument("jar:file://" + jarFileName + "!" + contentFileName, provider.getRootElement()); //$NON-NLS-1$ //$NON-NLS-2$ + // TODO: Add the tags declared in META-INF/tags, see JSP 2.0 section + // 8.4.1 + return document; + } + + protected CMAttributeDeclaration createAttributeDeclaration(CMDocument document, Node attrNode) { + CMAttributeDeclarationImpl attr = new CMAttributeDeclarationImpl(document); + + Node child = attrNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + if (child.getNodeName().equals(JSP11TLDNames.NAME) && child.hasChildNodes()) { + attr.setNodeName(getContainedText(child)); + } + else if (child.getNodeName().equals(JSP12TLDNames.DESCRIPTION) && child.hasChildNodes()) { + attr.setDescription(getContainedText(child)); + } + else if (child.getNodeName().equals(JSP11TLDNames.ID) && child.hasChildNodes()) { + attr.setId(getContainedText(child)); + } + else if (child.getNodeName().equals(JSP11TLDNames.REQUIRED) && child.hasChildNodes()) { + attr.setRequiredString(getContainedText(child)); + } + else if (child.getNodeName().equals(JSP11TLDNames.RTEXPRVALUE) && child.hasChildNodes()) { + attr.setRtexprvalue(getContainedText(child)); + } + else if (child.getNodeName().equals(JSP20TLDNames.FRAGMENT) && child.hasChildNodes()) { + attr.setFragment(Boolean.valueOf(getContainedText(child)).booleanValue()); + } + } + child = child.getNextSibling(); + } + + return attr; + } + + /** + * Builds a CMDocument from a taglib descriptor + * + * @param uri - + * the location of a valid taglib descriptor + */ + public CMDocument createCMDocument(String uri) { + CMDocument result = null; + URL url = null; + try { + url = new URL(uri); + } + catch (MalformedURLException e) { + result = createCMDocumentFromFile(uri); + } + if (result == null && url != null) { + InputStream istream = null; + if (url.getProtocol().equals("file")) { //$NON-NLS-1$ + result = createCMDocumentFromFile(url.getFile()); + } + else { + try { + istream = url.openStream(); + result = buildCMDocument(url.toExternalForm(), istream); + } + catch (Exception t) { + // Logger.log(Logger.INFO, "Exception creating content + // model: could not load TLD contents from URI " + uri + " + // :" + t); + } + } + try { + if (istream != null) + istream.close(); + } + catch (IOException e1) { + // don't care + } + } + if (result == null) + result = new CMDocumentImpl(); + return result; + } + + /** + * @param fileName + * @return + */ + private CMDocument createCMDocumentFromFile(String fileName) { + CMDocument result = null; + File file = new File(fileName); + try { + if (file.isDirectory()) { + result = buildCMDocumentFromDirectory(file); + } + } + catch (SecurityException e) { + result = null; + } + if (result == null) { + if (fileName.endsWith(".jar")) { //$NON-NLS-1$ + result = buildCMDocumentFromJar(fileName); + } + else { + result = buildCMDocumentFromFile(fileName); + } + } + return result; + } + + protected CMElementDeclaration createElementDeclaration(CMDocument cmdocument, Element tagFileNode, String path) { + CMElementDeclarationImpl ed = new CMElementDeclarationImpl(cmdocument); + boolean hasName = false; + + // load information declared within the .tld + Node child = tagFileNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.DESCRIPTION) && child.hasChildNodes()) { + ed.setDescription(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.DISPLAY_NAME) && child.hasChildNodes()) { + ed.setDisplayName(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.EXAMPLE) && child.hasChildNodes()) { + ed.setExample(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.ICON) && child.hasChildNodes()) { + ed.setSmallIcon(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.NAME) && child.hasChildNodes()) { + ed.setNodeName(getContainedText(child)); + hasName = ed.getNodeName().trim().length() > 0; + } + else if (nodeName.equals(JSP20TLDNames.PATH) && child.hasChildNodes()) { + ed.setPath(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.TAG_EXTENSION)) { + ed.getExtensions().add(child); + } + } + child = child.getNextSibling(); + } + if (hasName) { + // load information declared within the .tag(x) file + // JSP2_TODO: implement for JSP 2.0 + return ed; + } + return null; + } + + protected CMElementDeclaration createElementDeclaration(CMDocument document, Node tagNode) { + CMElementDeclarationImpl ed = new CMElementDeclarationImpl(document); + + Node child = tagNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + // tag information + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP11TLDNames.NAME) && child.hasChildNodes()) { + ed.setNodeName(getContainedText(child)); + } + else if ((nodeName.equals(JSP11TLDNames.TAGCLASS) || nodeName.equals(JSP12TLDNames.TAG_CLASS)) && child.hasChildNodes()) { + ed.setTagclass(getContainedText(child)); + } + else if ((nodeName.equals(JSP11TLDNames.TEICLASS) || nodeName.equals(JSP12TLDNames.TEI_CLASS)) && child.hasChildNodes()) { + ed.setTeiclass(getContainedText(child)); + } + else if ((nodeName.equals(JSP11TLDNames.BODYCONTENT) || nodeName.equals(JSP12TLDNames.BODY_CONTENT)) && child.hasChildNodes()) { + String bodycontent = getContainedText(child); + // Apparently, Apache Tomcat is not case sensitive about + // these values + if (bodycontent.equalsIgnoreCase(JSP11TLDNames.CONTENT_JSP)) + ed.setBodycontent(JSP11TLDNames.CONTENT_JSP); + else if (bodycontent.equalsIgnoreCase(JSP11TLDNames.CONTENT_TAGDEPENDENT)) + ed.setBodycontent(JSP11TLDNames.CONTENT_TAGDEPENDENT); + else if (bodycontent.equalsIgnoreCase(JSP11TLDNames.CONTENT_EMPTY)) + ed.setBodycontent(JSP11TLDNames.CONTENT_EMPTY); + else if (bodycontent.equalsIgnoreCase(JSP20TLDNames.CONTENT_SCRIPTLESS)) + ed.setBodycontent(JSP20TLDNames.CONTENT_SCRIPTLESS); + } + // info (1.1 only) or description (1.2 only) + else if ((nodeName.equals(JSP11TLDNames.INFO) || nodeName.equals(JSP12TLDNames.DESCRIPTION)) && child.hasChildNodes()) { + // ed.setDescription(getContainedText(child)); + ed.setDescription(getContainedText(child)); + } + // attributes + else if (nodeName.equals(JSP11TLDNames.ATTRIBUTE)) { + CMAttributeDeclaration attr = createAttributeDeclaration(document, child); + ed.attributes.setNamedItem(attr.getAttrName(), attr); + } + // variables + else if (nodeName.equals(JSP12TLDNames.VARIABLE)) { + ed.getVariables().add(createVariable(child)); + } + else if (nodeName.equals(JSP12TLDNames.LARGE_ICON) && child.hasChildNodes()) { + ed.setLargeIcon(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.SMALL_ICON) && child.hasChildNodes()) { + ed.setSmallIcon(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.TAG_EXTENSION) && child.getNodeType() == Node.ELEMENT_NODE) { + ed.getExtensions().add(child); + } + } + child = child.getNextSibling(); + } + return ed; + } + + protected TLDFunction createFunction(CMDocument document, Node functionNode) { + TLDFunctionImpl function = new TLDFunctionImpl(document); + boolean hasName = false; + + Node child = functionNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + // tag information + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.DESCRIPTION) && child.hasChildNodes()) { + function.setDescription(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.DISPLAY_NAME) && child.hasChildNodes()) { + function.setName(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.EXAMPLE) && child.hasChildNodes()) { + function.setExample(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.FUNCTION_CLASS) && child.hasChildNodes()) { + function.setClassName(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.FUNCTION_EXTENSION) && child.hasChildNodes()) { + function.getExtensions().add(child); + } + else if (nodeName.equals(JSP20TLDNames.FUNCTION_SIGNATURE) && child.hasChildNodes()) { + function.setSignature(getContainedText(child)); + } + else if (nodeName.equals(JSP20TLDNames.ICON) && child.hasChildNodes()) { + function.setIcon(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.NAME) && child.hasChildNodes()) { + function.setName(getContainedText(child)); + hasName = function.getName().trim().length() > 0; + } + } + child = child.getNextSibling(); + } + if (hasName) { + return function; + } + return null; + } + + protected TLDInitParam createInitParam(Node initParamNode) { + TLDInitParamImpl initParam = new TLDInitParamImpl(); + Node child = initParamNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.VALIDATOR_PARAM_NAME) && child.hasChildNodes()) { + initParam.setName(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VALIDATOR_PARAM_VALUE) && child.hasChildNodes()) { + initParam.setValue(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.DESCRIPTION) && child.hasChildNodes()) { + initParam.setDescription(getContainedText(child)); + } + } + child = child.getNextSibling(); + } + return initParam; + } + + protected TLDListener createListener(Node listenerNode) { + TLDListenerImpl listener = new TLDListenerImpl(); + Node child = listenerNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.LISTENER_CLASS) && child.hasChildNodes()) { + listener.setListenerClass(getContainedText(child)); + } + } + child = child.getNextSibling(); + } + return listener; + } + + protected TLDValidator createValidator(Node validatorNode) { + TLDValidatorImpl validator = new TLDValidatorImpl(); + Node child = validatorNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.VALIDATOR_CLASS) && child.hasChildNodes()) { + validator.setValidatorClass(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VALIDATOR_INIT_PARAM) && child.hasChildNodes()) { + validator.getInitParams().add(createInitParam(child)); + } + } + child = child.getNextSibling(); + } + return validator; + } + + protected TLDVariable createVariable(Node variableNode) { + TLDVariableImpl variable = new TLDVariableImpl(); + Node child = variableNode.getFirstChild(); + while (child != null) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + if (nodeName.equals(JSP12TLDNames.VARIABLE_CLASS) && child.hasChildNodes()) { + variable.setVariableClass(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VARIABLE_DECLARE) && child.hasChildNodes()) { + variable.setDeclareString(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VARIABLE_NAME_FROM_ATTRIBUTE) && child.hasChildNodes()) { + variable.setNameFromAttribute(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VARIABLE_NAME_GIVEN) && child.hasChildNodes()) { + variable.setNameGiven(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.VARIABLE_SCOPE) && child.hasChildNodes()) { + variable.setScope(getContainedText(child)); + } + else if (nodeName.equals(JSP12TLDNames.DESCRIPTION) && child.hasChildNodes()) { + variable.setDescription(getContainedText(child)); + } + } + child = child.getNextSibling(); + } + return variable; + } + + protected String getContainedText(Node parent) { + NodeList children = parent.getChildNodes(); + if (children.getLength() == 1) { + return children.item(0).getNodeValue().trim(); + } + StringBuffer s = new StringBuffer(); + Node child = parent.getFirstChild(); + while (child != null) { + s.append(child.getNodeValue()); + child = child.getNextSibling(); + } + return s.toString().trim(); + } + + public boolean isBuilderForGrammar(String grammarFileName) { + String fileName = grammarFileName.toLowerCase(); + return fileName.endsWith(".tld") || fileName.endsWith(".jar"); //$NON-NLS-2$//$NON-NLS-1$ + } + + private CMDocument loadDocument(String baseLocation, Node taglib) { + Node root = taglib; + + // create the CMDocument + CMDocumentImpl document = new CMDocumentImpl(); + document.setBaseLocation(baseLocation); + + if (root == null) { + if (_debug) { + System.out.println("null \"taglib\" element for TLD " + baseLocation); + } + return document; + } + + // populate the CMDocument + Node child = root.getFirstChild(); + while (child != null) { + if (child.getNodeType() != Node.ELEMENT_NODE) { + child = child.getNextSibling(); + continue; + } + String nodeName = child.getNodeName(); + // tag + if (nodeName.equals(JSP11TLDNames.TAG)) { + CMElementDeclaration ed = createElementDeclaration(document, child); + if (ed != null) { + document.fElements.setNamedItem(ed.getNodeName(), ed); + } + } + // tag-file + else if (nodeName.equals(JSP20TLDNames.TAG_FILE) && child.getNodeType() == Node.ELEMENT_NODE && child.hasChildNodes()) { + Element tagFileElement = (Element) child; + String path = tagFileElement.getAttribute(JSP20TLDNames.PATH); + + CMElementDeclarationImpl ed = (CMElementDeclarationImpl) createElementDeclaration(document, tagFileElement, path); + if (ed != null) { + document.fElements.setNamedItem(ed.getNodeName(), ed); + } + } + // other one-of-a-kind children + // JSP version + else if ((nodeName.equals(JSP11TLDNames.JSPVERSION) || nodeName.equals(JSP12TLDNames.JSP_VERSION)) && child.hasChildNodes()) { + document.setJspversion(getContainedText(child)); + } + // tag library version + else if ((nodeName.equals(JSP11TLDNames.TLIBVERSION) || nodeName.equals(JSP12TLDNames.TLIB_VERSION)) && child.hasChildNodes()) { + document.setTlibversion(getContainedText(child)); + } + // short name + else if ((nodeName.equals(JSP11TLDNames.SHORTNAME) || nodeName.equals(JSP12TLDNames.SHORT_NAME)) && child.hasChildNodes()) { + document.setShortname(getContainedText(child)); + } + // URI/URN + else if ((nodeName.equals(JSP11TLDNames.URI) || nodeName.equals(JSP11TLDNames.URN)) && child.hasChildNodes()) { //$NON-NLS-1$ + document.setUri(getContainedText(child)); + } + // info + else if (nodeName.equals(JSP11TLDNames.INFO) && child.hasChildNodes()) { + document.setInfo(getContainedText(child)); + } + // New JSP 1.2 + // description + else if (nodeName.equals(JSP12TLDNames.DESCRIPTION)) { + document.setDescription(getContainedText(child)); + } + // display name + else if (nodeName.equals(JSP12TLDNames.DISPLAY_NAME) && child.hasChildNodes()) { + document.setDisplayName(getContainedText(child)); + } + // large icon + else if (nodeName.equals(JSP12TLDNames.LARGE_ICON) && child.hasChildNodes()) { + document.setLargeIcon(getContainedText(child)); + } + // small icon + else if (nodeName.equals(JSP12TLDNames.SMALL_ICON) && child.hasChildNodes()) { + document.setSmallIcon(getContainedText(child)); + } + // validator + else if (nodeName.equals(JSP12TLDNames.VALIDATOR)) { + document.setValidator(createValidator(child)); + } + // listener + else if (nodeName.equals(JSP12TLDNames.LISTENER)) { + document.getListeners().add(createListener(child)); + } + else if (nodeName.equals(JSP20TLDNames.FUNCTION)) { + TLDFunction function = createFunction(document, child); + if (function != null) { + document.getListeners().add(function); + } + } + else if (nodeName.equals(JSP20TLDNames.TAGLIB_EXTENSION)) { + document.getExtensions().add(child); + } + + child = child.getNextSibling(); + } + return document; + } + + /** + * @param reference + * @return + */ + public CMDocument createCMDocument(ITaglibRecord reference) { + CMDocumentImpl document = null; + switch (reference.getRecordType()) { + case (ITaglibRecord.TLD) : { + TLDRecord record = (TLDRecord) reference; + document = (CMDocumentImpl) buildCMDocumentFromFile(record.getLocation().toString()); + if (_debug && document != null && document.getElements().getLength() == 0) { + System.out.println("failure parsing " + record.getLocation()); + } + + if (document.getSmallIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getSmallIcon(), record.getLocation().toString(), "/"); + document.setProperty(JSP12TLDNames.SMALL_ICON, "file:" + iconPath); + } + if (document.getLargeIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getLargeIcon(), record.getLocation().toString(), "/"); + document.setProperty(JSP12TLDNames.LARGE_ICON, "file:" + iconPath); + } + } + break; + case (ITaglibRecord.JAR) : { + JarRecord record = (JarRecord) reference; + document = (CMDocumentImpl) buildCMDocumentFromJar(record.getLocation().toString()); + if (document.getSmallIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getSmallIcon(), record.getLocation().toString() + "!META-INF/", "/"); + document.setProperty(JSP12TLDNames.SMALL_ICON, "jar:file:" + iconPath); + } + if (document.getLargeIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getLargeIcon(), record.getLocation().toString() + "!META-INF/", "/"); + document.setProperty(JSP12TLDNames.LARGE_ICON, "jar:file:" + iconPath); + } + if (document != null && document.getElements().getLength() == 0) { + System.out.println("failure parsing " + record.getLocation()); + } + } + break; + case (ITaglibRecord.TAGDIR) : { + // TagDirRecord record = (TagDirRecord) reference; + // document = + // buildCMDocumentFromDirectory(record.getLocation().toFile()); + } + break; + case (ITaglibRecord.URL) : { + URLRecord record = (URLRecord) reference; + InputStream urlContents = null; + try { + urlContents = record.getURL().openStream(); + document = (CMDocumentImpl) buildCMDocument(record.getBaseLocation(), urlContents); + if (document.getSmallIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getSmallIcon(), record.getURL().toString(), "/"); + document.setProperty(JSP12TLDNames.SMALL_ICON, iconPath); + } + if (document.getLargeIcon() != null) { + String iconPath = URIHelper.normalize(((TLDDocument) document).getLargeIcon(), record.getURL().toString(), "/"); + document.setProperty(JSP12TLDNames.LARGE_ICON, iconPath); + } + } + catch (IOException e) { + Logger.logException(e); + } + finally { + if (urlContents != null) { + try { + urlContents.close(); + } + catch (IOException e) { + } + } + } + } + break; + } + return document; + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java new file mode 100644 index 0000000000..460d0923af --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java @@ -0,0 +1,919 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.core.internal.contentmodel.tld; + + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.content.IContentDescription; +import org.eclipse.jst.jsp.core.JSP12Namespace; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP11TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP12TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.JSP20TLDNames; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDDocument; +import org.eclipse.jst.jsp.core.contentmodel.tld.TLDElementDeclaration; +import org.eclipse.jst.jsp.core.contentmodel.tld.URIResolverProvider; +import org.eclipse.jst.jsp.core.internal.Logger; +import org.eclipse.jst.jsp.core.internal.contentmodel.ITaglibRecord; +import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController; +import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibIndex; +import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser; +import org.eclipse.wst.common.contentmodel.CMDocument; +import org.eclipse.wst.common.contentmodel.CMNamedNodeMap; +import org.eclipse.wst.common.uriresolver.URIResolverPlugin; +import org.eclipse.wst.sse.core.parser.BlockMarker; +import org.eclipse.wst.sse.core.parser.StructuredDocumentRegionHandler; +import org.eclipse.wst.sse.core.parser.StructuredDocumentRegionHandlerExtension; +import org.eclipse.wst.sse.core.text.IStructuredDocument; +import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion; +import org.eclipse.wst.sse.core.text.ITextRegion; +import org.eclipse.wst.sse.core.text.ITextRegionList; +import org.eclipse.wst.sse.core.util.Assert; +import org.eclipse.wst.sse.core.util.Debug; +import org.eclipse.wst.sse.core.util.StringUtils; +import org.eclipse.wst.xml.core.jsp.model.parser.temp.XMLJSPRegionContexts; +import org.eclipse.wst.xml.core.parser.XMLRegionContext; +import org.eclipse.wst.xml.uriresolver.util.URIHelper; + +public class TLDCMDocumentManager { + + protected class DirectiveStructuredDocumentRegionHandler implements StructuredDocumentRegionHandler, StructuredDocumentRegionHandlerExtension { + + /** + * Adds a block tagname (fully namespace qualified) into the list of + * block tag names for the parser. The marker + * IStructuredDocumentRegion along with position cues during reparses + * allow the JSPSourceParser to enable/ignore the tags as blocks. + */ + protected void addBlockTag(String tagnameNS, IStructuredDocumentRegion marker) { + if (getParser() == null) + return; + if (getParser().getBlockMarker(tagnameNS) == null) { + getParser().addBlockMarker(new BlockMarker(tagnameNS, marker, XMLRegionContext.BLOCK_TEXT, true, false)); + if (_debug) { + System.out.println("TLDCMDocumentManager added block marker: " + tagnameNS + "@" + marker.getStartOffset()); //$NON-NLS-2$//$NON-NLS-1$ + } + } + } + + /** + * Enables a TLD owning the given prefix loaded from the given URI at + * the anchorStructuredDocumentRegion. The list of + * additionalCMDocuments will claim to not know any of its tags at + * positions earlier than that IStructuredDocumentRegion's position. + * + * For taglib directives, the taglib is the anchor while taglibs + * registered through include directives use the parent document's + * include directive as their anchor. + * + * @param prefix + * @param uri + * @param anchorStructuredDocumentRegion + */ + protected void enableTaglibFromURI(String prefix, String uri, IStructuredDocumentRegion anchorStructuredDocumentRegion) { + if (prefix == null || uri == null || bannedPrefixes.contains(prefix)) + return; + // Try to load the CMDocument for this URI + CMDocument tld = getCMDocument(uri); + if (tld == null || !(tld instanceof TLDDocument)) { + if (_debug) { + System.out.println("TLDCMDocumentManager failed to create a CMDocument for " + uri); //$NON-NLS-1$ + } + return; + } + CMNamedNodeMap elements = tld.getElements(); + // Go through the CMDocument for any tags that must be marked as + // block tags + // starting at the anchoring IStructuredDocumentRegion. As the + // document is edited and the + // IStructuredDocumentRegion moved around, the block tag + // enablement will automatically follow + // it. + for (int i = 0; i < elements.getLength(); i++) { + TLDElementDeclaration ed = (TLDElementDeclaration) elements.item(i); + if (ed.getBodycontent() == JSP12TLDNames.CONTENT_TAGDEPENDENT) + addBlockTag(prefix + ":" + ed.getNodeName(), anchorStructuredDocumentRegion); //$NON-NLS-1$ + } + // Since modifications to StructuredDocumentRegions adjacent to a + // taglib directive can cause + // that IStructuredDocumentRegion to be reported, filter out any + // duplicated URIs. When the + // taglib is actually modified, a full rebuild will occur and no + // duplicates + // will/should be found. + List trackers = getTaglibTrackers(); + for (int i = 0; i < trackers.size(); i++) { + TaglibTracker tracker = (TaglibTracker) trackers.get(i); + if (tracker.getPrefix().equals(prefix) && tracker.getURI().equals(uri)) { + return; + } + } + if (_debug) { + System.out.println("TLDCMDocumentManager registered a tracker for " + uri + " with prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$ + } + getTaglibTrackers().add(new TaglibTracker(uri, prefix, tld, anchorStructuredDocumentRegion)); + } + + /** + * Enables a TLD owning the given prefix loaded from the given URI at + * the anchorStructuredDocumentRegion. The list of + * additionalCMDocuments will claim to not know any of its tags at + * positions earlier than that IStructuredDocumentRegion's position. + * + * For taglib directives, the taglib is the anchor while taglibs + * registered through include directives use the parent document's + * include directive as their anchor. + * + * @param prefix + * @param uri + * @param taglibStructuredDocumentRegion + */ + protected void enableTagsInDir(String prefix, String tagdir, IStructuredDocumentRegion taglibStructuredDocumentRegion) { + if (prefix == null || tagdir == null || bannedPrefixes.contains(prefix)) + return; + if (_debug) { + System.out.println("TLDCMDocumentManager enabling tags from directory" + tagdir + " for prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$ + } + // Try to load the CMDocument for this URI + CMDocument tld = getImplicitCMDocument(tagdir); + if (tld == null || !(tld instanceof TLDDocument)) + return; + CMNamedNodeMap elements = tld.getElements(); + // Go through the CMDocument for any tags that must be marked as + // block tags + // starting at the anchoring IStructuredDocumentRegion. As the + // document is edited and the + // IStructuredDocumentRegion moved around, the block tag + // enablement will automatically follow + // it. + for (int i = 0; i < elements.getLength(); i++) { + TLDElementDeclaration ed = (TLDElementDeclaration) elements.item(i); + if (ed.getBodycontent() == JSP12TLDNames.CONTENT_TAGDEPENDENT) + addBlockTag(prefix + ":" + ed.getNodeName(), taglibStructuredDocumentRegion); //$NON-NLS-1$ + } + // Since modifications to StructuredDocumentRegions adjacent to a + // taglib directive can cause + // that IStructuredDocumentRegion to be reported, filter out any + // duplicated URIs. When the + // taglib is actually modified, a full rebuild will occur and no + // duplicates + // will/should be found. + List trackers = getTaglibTrackers(); + for (int i = 0; i < trackers.size(); i++) { + TaglibTracker tracker = (TaglibTracker) trackers.get(i); + if (tracker.getPrefix().equals(prefix) && tracker.getURI().equals(tagdir)) { + return; + } + } + if (_debug) { + System.out.println("TLDCMDocumentManager registered a tracker for directory" + tagdir + " with prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$ + } + getTaglibTrackers().add(new TaglibTracker(tagdir, prefix, tld, taglibStructuredDocumentRegion)); + } + + public void nodeParsed(IStructuredDocumentRegion aCoreStructuredDocumentRegion) { + // could test > 1, but since we only care if there are 8 (<%@, + // taglib, uri, =, where, prefix, =, what) [or 4 for includes] + if (aCoreStructuredDocumentRegion.getNumberOfRegions() > 4 && aCoreStructuredDocumentRegion.getRegions().get(1).getType() == XMLJSPRegionContexts.JSP_DIRECTIVE_NAME) { + ITextRegion name = aCoreStructuredDocumentRegion.getRegions().get(1); + try { + if (getParser() == null) { + Logger.log(Logger.WARNING, "Warning: parser text was requested by " + getClass().getName() + " but none was available; taglib support disabled"); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + boolean taglibDetected = false; + boolean taglibDirectiveDetected = false; + boolean includeDetected = false; + boolean includeDirectiveDetected = false; + int startOffset = aCoreStructuredDocumentRegion.getStartOffset(name); + int textLength = name.getTextLength(); + + if (getParser() != null) { + taglibDetected = getParser().regionMatches(startOffset, textLength, JSP12TLDNames.TAGLIB); + taglibDirectiveDetected = getParser().regionMatches(startOffset, textLength, JSP12Namespace.ElementName.DIRECTIVE_TAGLIB); + includeDetected = getParser().regionMatches(startOffset, textLength, JSP12TLDNames.INCLUDE); + includeDirectiveDetected = getParser().regionMatches(startOffset, textLength, JSP12Namespace.ElementName.DIRECTIVE_INCLUDE); + } + else { + // old fashioned way + String directiveName = getParser().getText(startOffset, textLength); + taglibDetected = directiveName.equals(JSP12TLDNames.TAGLIB); + taglibDirectiveDetected = directiveName.equals(JSP12Namespace.ElementName.DIRECTIVE_TAGLIB); + includeDetected = directiveName.equals(JSP12TLDNames.INCLUDE); + includeDirectiveDetected = directiveName.equals(JSP12Namespace.ElementName.DIRECTIVE_INCLUDE); + } + if (taglibDetected || taglibDirectiveDetected) { + processTaglib(aCoreStructuredDocumentRegion); + } + else if (includeDetected || includeDirectiveDetected) { + processInclude(aCoreStructuredDocumentRegion); + } + } + } + catch (StringIndexOutOfBoundsException sioobExc) { + // do nothing + } + } + // could test > 1, but since we only care if there are 5 (<, + // jsp:root, xmlns:prefix, =, where) + else if (aCoreStructuredDocumentRegion.getNumberOfRegions() > 4 && aCoreStructuredDocumentRegion.getRegions().get(1).getType() == XMLJSPRegionContexts.JSP_ROOT_TAG_NAME) { + if (getParser() == null) { + Logger.log(Logger.WARNING, "Warning: parser text was requested by " + getClass().getName() + " but none was available; taglib support disabled"); //$NON-NLS-1$ //$NON-NLS-2$ + } + else { + processJSPRoot(aCoreStructuredDocumentRegion); + } + } + } + + protected void processInclude(IStructuredDocumentRegion aCoreStructuredDocumentRegion) { + processInclude(aCoreStructuredDocumentRegion, aCoreStructuredDocumentRegion, getParser()); + } + + /** + * Process an include directive found by the textSource parser and + * anchor any taglibs found within at the + * anchorStructuredDocumentRegion. Includes use the including file as + * the point of reference, not necessarily the "top" file. + */ + protected void processInclude(IStructuredDocumentRegion includeStructuredDocumentRegion, IStructuredDocumentRegion anchorStructuredDocumentRegion, JSPSourceParser textSource) { + ITextRegionList regions = includeStructuredDocumentRegion.getRegions(); + String includedFile = null; + boolean isFilename = false; + try { + for (int i = 0; i < regions.size(); i++) { + ITextRegion region = regions.get(i); + if (region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_NAME) { + if (textSource.getText(includeStructuredDocumentRegion.getStartOffset(region), region.getTextLength()).equals(JSP12TLDNames.FILE)) { + isFilename = true; + } + else { + isFilename = false; + } + } + else if (isFilename && region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_VALUE) { + includedFile = textSource.getText(includeStructuredDocumentRegion.getStartOffset(region), region.getTextLength()); + isFilename = false; + } + } + } + catch (StringIndexOutOfBoundsException sioobExc) { + // nothing to be done + includedFile = null; + } + if (includedFile != null) { + IPath root = TaglibIndex.getContextRoot(getCurrentBaseLocation()); + IPath fileLocation = new Path(URIHelper.normalize(StringUtils.strip(includedFile).trim(), getCurrentBaseLocation().toString(), root.toString())); + // check for "loops" + if (!getIncludes().contains(fileLocation) && fileLocation != null && !fileLocation.equals(getCurrentBaseLocation())) { + getIncludes().push(fileLocation); + if (getParser() != null) + new IncludeHelper(anchorStructuredDocumentRegion, getParser()).parse(fileLocation.toString()); + else + Logger.log(Logger.WARNING, "Warning: parser text was requested by " + getClass().getName() + " but none was available; taglib support disabled"); //$NON-NLS-1$ //$NON-NLS-2$ + getIncludes().pop(); + } + else { + if (Debug.debugTokenizer) + System.out.println("LOOP IN @INCLUDES FOUND: " + fileLocation); //$NON-NLS-1$ + } + } + } + + // Pulls the URI and prefix from the given jsp:root + // IStructuredDocumentRegion and + // makes sure the tags are known. + protected void processJSPRoot(IStructuredDocumentRegion jspRootStructuredDocumentRegion) { + processJSPRoot(jspRootStructuredDocumentRegion, jspRootStructuredDocumentRegion, getParser()); + } + + protected void processJSPRoot(IStructuredDocumentRegion taglibStructuredDocumentRegion, IStructuredDocumentRegion anchorStructuredDocumentRegion, JSPSourceParser textSource) { + ITextRegionList regions = taglibStructuredDocumentRegion.getRegions(); + String uri = null; + String prefix = null; + boolean taglib = false; + try { + for (int i = 0; i < regions.size(); i++) { + ITextRegion region = regions.get(i); + if (region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_NAME) { + String name = textSource.getText(taglibStructuredDocumentRegion.getStartOffset(region), region.getTextLength()); + if (name.startsWith(XMLNS)) { //$NON-NLS-1$ + prefix = name.substring(XMLNS_LENGTH); + if (!bannedPrefixes.contains(prefix)) + taglib = true; + } + else { + prefix = null; + taglib = false; + } + } + else if (taglib && region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_VALUE) { + uri = textSource.getText(taglibStructuredDocumentRegion.getStartOffset(region), region.getTextLength()); + if (uri != null && prefix != null && (StringUtils.strip(uri).length() > 0) && (StringUtils.strip(prefix).length() > 0)) { + if (anchorStructuredDocumentRegion == null) + enableTaglibFromURI(StringUtils.strip(prefix), StringUtils.strip(uri), taglibStructuredDocumentRegion); + else + enableTaglibFromURI(StringUtils.strip(prefix), StringUtils.strip(uri), anchorStructuredDocumentRegion); + uri = null; + prefix = null; + } + } + } + } + catch (StringIndexOutOfBoundsException sioobExc) { + // nothing to be done + uri = null; + prefix = null; + } + } + + protected void processTaglib(IStructuredDocumentRegion taglibStructuredDocumentRegion) { + processTaglib(taglibStructuredDocumentRegion, taglibStructuredDocumentRegion, getParser()); + } + + /** + * Pulls the URI and prefix from the given taglib directive + * IStructuredDocumentRegion and makes sure the tags are known. + */ + protected void processTaglib(IStructuredDocumentRegion taglibStructuredDocumentRegion, IStructuredDocumentRegion anchorStructuredDocumentRegion, JSPSourceParser textSource) { + ITextRegionList regions = taglibStructuredDocumentRegion.getRegions(); + String uri = null; + String prefix = null; + String tagdir = null; + String attrName = null; + try { + for (int i = 0; i < regions.size(); i++) { + ITextRegion region = regions.get(i); + // remember attribute name + int startOffset = taglibStructuredDocumentRegion.getStartOffset(region); + int textLength = region.getTextLength(); + if (region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_NAME) { + // String name = textSource.getText(startOffset, + // textLength); + if (textSource.regionMatches(startOffset, textLength, JSP11TLDNames.PREFIX)) { + attrName = JSP11TLDNames.PREFIX; + } + else if (textSource.regionMatches(startOffset, textLength, JSP12TLDNames.URI)) { + attrName = JSP11TLDNames.URI; + } + else if (textSource.regionMatches(startOffset, textLength, JSP20TLDNames.TAGDIR)) { + attrName = JSP20TLDNames.TAGDIR; + } + else { + attrName = null; + } + } + // process value + else if (region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_VALUE) { + if (JSP11TLDNames.PREFIX.equals(attrName)) + prefix = textSource.getText(startOffset, textLength); + else if (JSP11TLDNames.URI.equals(attrName)) + uri = textSource.getText(startOffset, textLength); + else if (JSP20TLDNames.TAGDIR.equals(attrName)) + tagdir = textSource.getText(startOffset, textLength); + } + } + } + catch (StringIndexOutOfBoundsException sioobExc) { + // nothing to be done + uri = null; + prefix = null; + } + if (uri != null && prefix != null && (StringUtils.strip(uri).length() > 0) && (StringUtils.strip(prefix).length() > 0)) { + if (anchorStructuredDocumentRegion == null) + enableTaglibFromURI(StringUtils.strip(prefix), StringUtils.strip(uri), taglibStructuredDocumentRegion); + else + enableTaglibFromURI(StringUtils.strip(prefix), StringUtils.strip(uri), anchorStructuredDocumentRegion); + } + else if (tagdir != null && prefix != null && (StringUtils.strip(tagdir).length() > 0) && (StringUtils.strip(prefix).length() > 0)) { + if (anchorStructuredDocumentRegion == null) + enableTagsInDir(StringUtils.strip(prefix), StringUtils.strip(tagdir), taglibStructuredDocumentRegion); + else + enableTagsInDir(StringUtils.strip(prefix), StringUtils.strip(tagdir), anchorStructuredDocumentRegion); + } + } + + private void resetBlockTags() { + if (getParser() == null) + return; + Iterator names = getParser().getBlockMarkers().iterator(); + while (names.hasNext()) { + BlockMarker marker = (BlockMarker) names.next(); + if (!marker.isGlobal() && marker.getContext() == XMLRegionContext.BLOCK_TEXT) { + if (_debug) { + System.out.println("TLDCMDocumentManager removing block tag named: " + marker.getTagName()); //$NON-NLS-1$ + } + names.remove(); + } + } + } + + public void resetNodes() { + if (Debug.debugTaglibs) + System.out.println(getClass().getName() + ": resetting"); //$NON-NLS-1$ + getIncludes().clear(); + resetBlockTags(); + resetTaglibTrackers(); + } + + public void setStructuredDocument(IStructuredDocument newDocument) { + Assert.isTrue(newDocument != null, "null document"); + Assert.isTrue(newDocument.getParser() != null, "null document parser"); + Assert.isTrue(newDocument.getParser() instanceof JSPSourceParser, "can only listen to document with a JSPSourceParser"); + getSourceParser().removeStructuredDocumentRegionHandler(this); + setSourceParser((JSPSourceParser) newDocument.getParser()); + getSourceParser().addStructuredDocumentRegionHandler(this); + } + } + + protected class IncludeHelper extends DirectiveStructuredDocumentRegionHandler { + protected IStructuredDocumentRegion fAnchor = null; + protected JSPSourceParser fLocalParser = null; + protected JSPSourceParser fParentParser = null; + + public IncludeHelper(IStructuredDocumentRegion anchor, JSPSourceParser rootParser) { + super(); + fAnchor = anchor; + fParentParser = rootParser; + } + + private String detectCharset(IFile file) { + if (file.getType() == IResource.FILE && file.isAccessible()) { + IContentDescription d = null; + try { + // optimized description lookup, might not succeed + d = file.getContentDescription(); + if (d != null) + return d.getCharset(); + } + catch (CoreException e) { + // should not be possible given the accessible and file + // type + // check above + } + InputStream contents = null; + try { + contents = file.getContents(); + IContentDescription description = Platform.getContentTypeManager().getDescriptionFor(contents, file.getName(), new QualifiedName[]{IContentDescription.CHARSET}); + if (description != null) { + return description.getCharset(); + } + } + catch (IOException e) { + // will try to cleanup in finally + } + catch (CoreException e) { + Logger.logException(e); + } + finally { + if (contents != null) { + try { + contents.close(); + } + catch (Exception e) { + // not sure how to recover at this point + } + } + } + } + return ResourcesPlugin.getEncoding(); + } + + protected String getContents(String fileName) { + StringBuffer s = new StringBuffer(); + IFile iFile = FileBuffers.getWorkspaceFileAtLocation(new Path(fileName)); + if (iFile != null && iFile.exists()) { + String charset = detectCharset(iFile); + InputStream contents = null; + try { + contents = iFile.getContents(); + Reader reader = new InputStreamReader(contents, charset); + char[] readBuffer = new char[2048]; + int n = reader.read(readBuffer); + while (n > 0) { + s.append(readBuffer, 0, n); + n = reader.read(readBuffer); + } + } + catch (Exception e) { + if (Debug.debugStructuredDocument) + Logger.log(Logger.WARNING, "An exception occured while scanning " + fileName, e); //$NON-NLS-1$ + } + finally { + try { + if (contents != null) { + contents.close(); + } + } + catch (Exception e) { + // nothing to do + } + } + } + else { + int c = 0; + int length = 0; + int count = 0; + File file = null; + FileInputStream fis = null; + try { + file = new File(fileName); + length = (int) file.length(); + fis = new FileInputStream(file); + while (((c = fis.read()) >= 0) && (count < length)) { + count++; + s.append((char) c); + } + } + catch (FileNotFoundException e) { + if (Debug.debugStructuredDocument) + System.out.println("File not found : \"" + fileName + "\""); //$NON-NLS-2$//$NON-NLS-1$ + } + catch (ArrayIndexOutOfBoundsException e) { + if (Debug.debugStructuredDocument) + System.out.println("Usage wrong: specify inputfile"); //$NON-NLS-1$ + //$NON-NLS-1$ + } + catch (IOException e) { + if (Debug.debugStructuredDocument) + System.out.println("An I/O error occured while scanning :"); //$NON-NLS-1$ + //$NON-NLS-1$ + } + catch (Exception e) { + if (Debug.debugStructuredDocument) + e.printStackTrace(); + } + finally { + try { + if (fis != null) { + fis.close(); + } + } + catch (Exception e) { + // nothing to do + } + } + } + return s.toString(); + } + + public void nodeParsed(IStructuredDocumentRegion aCoreStructuredDocumentRegion) { + // could test > 1, but since we only care if there are 8 (<%@, + // taglib, uri, =, where, prefix, =, what) + if (aCoreStructuredDocumentRegion.getNumberOfRegions() > 1 && aCoreStructuredDocumentRegion.getRegions().get(1).getType() == XMLJSPRegionContexts.JSP_DIRECTIVE_NAME) { + ITextRegion name = aCoreStructuredDocumentRegion.getRegions().get(1); + try { + String directiveName = fLocalParser.getText(aCoreStructuredDocumentRegion.getStartOffset(name), name.getTextLength()); + if (directiveName.equals(JSP12TLDNames.TAGLIB) || directiveName.equals(JSP12Namespace.ElementName.DIRECTIVE_TAGLIB)) { + processTaglib(aCoreStructuredDocumentRegion, fAnchor, fLocalParser); + } + if (directiveName.equals(JSP12TLDNames.INCLUDE) || directiveName.equals(JSP12Namespace.ElementName.DIRECTIVE_INCLUDE)) { + processInclude(aCoreStructuredDocumentRegion, fAnchor, fLocalParser); + } + } + catch (StringIndexOutOfBoundsException sioobExc) { + // do nothing + } + } + // could test > 1, but since we only care if there are 5 (<, + // jsp:root, xmlns:prefix, =, where) + else if (aCoreStructuredDocumentRegion.getNumberOfRegions() > 4 && aCoreStructuredDocumentRegion.getRegions().get(1).getType() == XMLJSPRegionContexts.JSP_ROOT_TAG_NAME) { + processJSPRoot(aCoreStructuredDocumentRegion, fAnchor, fLocalParser); + } + } + + public void parse(String filename) { + JSPSourceParser p = new JSPSourceParser(); + fLocalParser = p; + List blockTags = fParentParser.getBlockMarkers(); + String includedFilename = filename; + File baseFile = FileBuffers.getSystemFileAtLocation(new Path(includedFilename)); + try { + if (baseFile != null) + includedFilename = baseFile.getCanonicalPath(); + } + catch (IOException e) { + } + String s = getContents(includedFilename); + fLocalParser.addStructuredDocumentRegionHandler(this); + fLocalParser.reset(s); + for (int i = 0; i < blockTags.size(); i++) { + BlockMarker marker = (BlockMarker) blockTags.get(i); + fLocalParser.addBlockMarker(new BlockMarker(marker.getTagName(), null, marker.getContext(), marker.isCaseSensitive())); + } + // force parse + fLocalParser.getDocumentRegions(); + fLocalParser = null; + } + + public void resetNodes() { + } + + } + + static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/tldcmdocument/manager")); //$NON-NLS-1$ //$NON-NLS-2$ + + // will hold the prefixes banned by the specification; taglibs may not use + // them + protected static List bannedPrefixes = null; + static final String XMLNS = "xmlns:"; //$NON-NLS-1$ + static final int XMLNS_LENGTH = XMLNS.length(); + + static { + bannedPrefixes = new ArrayList(7); + bannedPrefixes.add("jsp"); //$NON-NLS-1$ + bannedPrefixes.add("jspx"); //$NON-NLS-1$ + bannedPrefixes.add("java"); //$NON-NLS-1$ + bannedPrefixes.add("javax"); //$NON-NLS-1$ + bannedPrefixes.add("servlet"); //$NON-NLS-1$ + bannedPrefixes.add("sun"); //$NON-NLS-1$ + bannedPrefixes.add("sunw"); //$NON-NLS-1$ + } + + private CMDocumentFactoryTLD fCMDocumentBuilder = null; + private DirectiveStructuredDocumentRegionHandler fDirectiveHandler = null; + private Hashtable fDocuments = null; + private Stack fIncludes = null; + + private JSPSourceParser fParser = null; + + // trivial hand edit to remove unused variable private URIResolverProvider + // fResolverProvider = null; + + private List fTaglibTrackers = null; + + public TLDCMDocumentManager() { + super(); + } + + public void clearCache() { + if (_debug) { + System.out.println("TLDCMDocumentManager cleared its CMDocument cache"); //$NON-NLS-1$ + } + getDocuments().clear(); + } + + /** + * Return the CMDocument at the uri (cached) + */ + protected CMDocument getCMDocument(String uri) { + if (uri == null || uri.length() == 0) + return null; + String reference = uri; + /** + * JSP 1.2 Specification, section 5.2.2 jsp-1_2-fcs-spec.pdf, page 87 + */ + String URNprefix = "urn:jsptld:"; //$NON-NLS-1$ + if (reference.startsWith(URNprefix)) { + /** + * @see section 7.3.2 + */ + if (reference.length() > URNprefix.length()) + reference = reference.substring(11); + } + else { + /** + * @see section 7.3.6 + */ + } + CMDocument doc = (CMDocument) getDocuments().get(reference); + if (doc == null) { + doc = loadTaglib(reference); + if (doc != null) + getDocuments().put(reference, doc); + } + return doc; + } + + /** + * Gets the cMDocumentBuilder. + * + * @return Returns a CMDocumentFactoryTLD, since it has more builder + * methods + */ + protected CMDocumentFactoryTLD getCMDocumentBuilder() { + if (fCMDocumentBuilder == null) + fCMDocumentBuilder = new CMDocumentFactoryTLD(); + return fCMDocumentBuilder; + } + + public List getCMDocumentTrackers(int offset) { + List validDocs = new ArrayList(); + Iterator alldocs = getTaglibTrackers().iterator(); + while (alldocs.hasNext()) { + TaglibTracker aTracker = (TaglibTracker) alldocs.next(); + if (aTracker.getStructuredDocumentRegion().getStartOffset() < offset || offset < 0) { + validDocs.add(aTracker); + } + } + return validDocs; + } + + public List getCMDocumentTrackers(String prefix, int offset) { + List validDocs = new ArrayList(); + Iterator alldocs = getTaglibTrackers().iterator(); + while (alldocs.hasNext()) { + TaglibTracker aTracker = (TaglibTracker) alldocs.next(); + if ((aTracker.getStructuredDocumentRegion().getStartOffset() < offset || offset < 0) && aTracker.getPrefix().equals(prefix)) { + validDocs.add(aTracker); + } + } + return validDocs; + } + + /** + * + * @return java.lang.String + */ + IPath getCurrentBaseLocation() { + IPath baseLocation = null; + if (!getIncludes().isEmpty()) { + baseLocation = (IPath) getIncludes().peek(); + } + else { + IPath path = TaglibController.getFileBuffer(this).getLocation(); + if (path.toFile().exists()) + baseLocation = path; + else + baseLocation = ResourcesPlugin.getWorkspace().getRoot().getFile(path).getLocation(); + } + return baseLocation; + } + + protected DirectiveStructuredDocumentRegionHandler getDirectiveStructuredDocumentRegionHandler() { + if (fDirectiveHandler == null) + fDirectiveHandler = new DirectiveStructuredDocumentRegionHandler(); + return fDirectiveHandler; + } + + /** + * Gets the documents. + * + * @return Returns a Hashtable + */ + public Hashtable getDocuments() { + if (fDocuments == null) + fDocuments = new Hashtable(); + return fDocuments; + } + + /** + * Return the CMDocument at the tagdir (cached) + */ + protected CMDocument getImplicitCMDocument(String tagdir) { + if (tagdir == null || tagdir.length() == 0) + return null; + String reference = tagdir; + /** + * JSP 1.2 Specification, section 5.2.2 jsp-1_2-fcs-spec.pdf, page 87 + */ + String URNprefix = "urn:jsptld:"; //$NON-NLS-1$ + if (reference.startsWith(URNprefix)) { + /** + * @see section 7.3.2 + */ + if (reference.length() > URNprefix.length()) + reference = reference.substring(11); + } + else { + /** + * @see section 7.3.6 + */ + } + CMDocument doc = (CMDocument) getDocuments().get(reference); + if (doc == null) { + doc = loadTagDir(reference); + if (doc != null) + getDocuments().put(reference, doc); + } + return doc; + } + + /** + * Gets the includes. + * + * @return Returns a Stack + */ + protected Stack getIncludes() { + if (fIncludes == null) + fIncludes = new Stack(); + return fIncludes; + } + + JSPSourceParser getParser() { + return fParser; + } + + /** + * @deprecated + */ + public URIResolverProvider getResolverProvider() { + return null; + } + + public JSPSourceParser getSourceParser() { + return fParser; + } + + public StructuredDocumentRegionHandler getStructuredDocumentRegionHandler() { + return getDirectiveStructuredDocumentRegionHandler(); + } + + /** + * + * @return java.util.List + */ + public List getTaglibTrackers() { + if (fTaglibTrackers == null) + fTaglibTrackers = new ArrayList(); + return fTaglibTrackers; + } + + /** + * Loads the tags from the specified URI. It must point to a URL of valid + * tag files to work. + */ + protected CMDocument loadTagDir(String uri) { + ITaglibRecord reference = TaglibIndex.resolve(getCurrentBaseLocation().toString(), uri, false); + if (reference != null) { + CMDocument document = getCMDocumentBuilder().createCMDocument(reference); + if (document != null) { + return document; + } + } + // JSP2_TODO: implement for JSP 2.0 + String location = URIResolverPlugin.createResolver().resolve(getCurrentBaseLocation().toString(), null, uri); + if (location == null) + return null; + if (_debug) { + System.out.println("Loading tags from dir" + uri + " at " + location); //$NON-NLS-2$//$NON-NLS-1$ + } + return getCMDocumentBuilder().createCMDocument(location); + } + + /** + * Loads the taglib from the specified URI. It must point to a valid + * taglib descriptor or valid JAR file to work. + */ + protected CMDocument loadTaglib(String uri) { + CMDocument document = null; + ITaglibRecord reference = TaglibIndex.resolve(TaglibController.getFileBuffer(this).getLocation().toString(), uri, false); + if (reference != null) { + document = getCMDocumentBuilder().createCMDocument(reference); + } + else { + String location = URIResolverPlugin.createResolver().resolve(getCurrentBaseLocation().toString(), null, uri); + if (location != null) { + if (_debug) { + System.out.println("Loading tags from " + uri + " at " + location); //$NON-NLS-2$//$NON-NLS-1$ + } + document = getCMDocumentBuilder().createCMDocument(location); + } + } + return document; + } + + protected void resetTaglibTrackers() { + if (_debug) { + System.out.println("TLDCMDocumentManager cleared its taglib trackers\n"); //$NON-NLS-1$ + } + getTaglibTrackers().clear(); + } + + public void setSourceParser(JSPSourceParser parser) { + if (fParser != null) + fParser.removeStructuredDocumentRegionHandler(getStructuredDocumentRegionHandler()); + fParser = parser; + if (fParser != null) + fParser.addStructuredDocumentRegionHandler(getStructuredDocumentRegionHandler()); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TaglibTracker.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TaglibTracker.java new file mode 100644 index 0000000000..8a9885f437 --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TaglibTracker.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.core.internal.contentmodel.tld; + + + +import org.eclipse.jst.jsp.core.internal.contentmodel.CMDocumentWrapperImpl; +import org.eclipse.wst.common.contentmodel.CMDocument; +import org.eclipse.wst.sse.core.contentmodel.CMDocumentTracker; +import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion; + +/** + * TaglibTracker class + */ +public class TaglibTracker extends CMDocumentWrapperImpl implements CMDocumentTracker { + + private IStructuredDocumentRegion fStructuredDocumentRegion; + + public TaglibTracker(String newURI, String newPrefix, CMDocument tld, IStructuredDocumentRegion aStructuredDocumentRegion) { + super(newURI, newPrefix, tld); + fStructuredDocumentRegion = aStructuredDocumentRegion; + } + + /** + * + * @return com.ibm.sed.structuredDocument.IStructuredDocumentRegion + */ + public IStructuredDocumentRegion getStructuredDocumentRegion() { + return fStructuredDocumentRegion; + } + + public String toString() { + if (getStructuredDocumentRegion() != null) + return getPrefix() + "@" + getStructuredDocumentRegion().getStartOffset(); //$NON-NLS-1$ + return super.toString(); + } +}
\ No newline at end of file |