Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornitind2005-02-15 06:42:31 +0000
committernitind2005-02-15 06:42:31 +0000
commit49418459edc208867da7d93559584ceaad2cd927 (patch)
tree27e32edf4ab6db8c8f03d5c33e183672893f84ac /bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld
parent969bea5e6d02a7056ca613412a4a9fd4d9f3e61d (diff)
downloadwebtools.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')
-rw-r--r--bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java668
-rw-r--r--bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java919
-rw-r--r--bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TaglibTracker.java45
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

Back to the top