/projects/netbeans-7.3/web.core.syntax/src/org/netbeans/modules/web/core/syntax/JspSyntaxSupport.java
Java | 973 lines | 689 code | 96 blank | 188 comment | 196 complexity | 6698d3aced1a116a42225b3514de5799 MD5 | raw file
- /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * Contributor(s):
- *
- * The Original Software is NetBeans. The Initial Developer of the Original
- * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
- * Microsystems, Inc. All Rights Reserved.
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- */
- package org.netbeans.modules.web.core.syntax;
- import java.io.File;
- import java.util.*;
- import java.net.URL;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javax.swing.text.BadLocationException;
- import javax.swing.text.Document;
- import javax.swing.text.EditorKit;
- import javax.swing.text.JTextComponent;
- import javax.servlet.jsp.tagext.*;
- import org.netbeans.api.lexer.Language;
- import org.netbeans.api.lexer.TokenHierarchy;
- import org.netbeans.api.lexer.TokenSequence;
- import org.netbeans.modules.web.core.syntax.completion.api.JspCompletionItem;
- import org.netbeans.modules.web.core.syntax.deprecated.ELTokenContext;
- import org.netbeans.modules.web.core.syntax.deprecated.JspDirectiveTokenContext;
- import org.netbeans.modules.web.core.syntax.deprecated.JspMultiTokenContext;
- import org.netbeans.modules.web.core.syntax.deprecated.JspTagTokenContext;
- import org.netbeans.modules.web.core.api.JspContextInfo;
- import org.netbeans.modules.web.jsps.parserapi.JspParserAPI.JspOpenInfo;
- import org.netbeans.spi.editor.completion.CompletionItem;
- import org.openide.filesystems.FileAttributeEvent;
- import org.openide.filesystems.FileChangeListener;
- import org.openide.filesystems.FileEvent;
- import org.openide.filesystems.FileObject;
- import org.openide.filesystems.FileRenameEvent;
- import org.openide.loaders.DataObject;
- import org.netbeans.modules.web.jsps.parserapi.JspParserAPI;
- import org.netbeans.modules.web.jsps.parserapi.PageInfo;
- import org.netbeans.editor.*;
- import org.netbeans.editor.ext.ExtSyntaxSupport;
- import org.netbeans.editor.ext.java.JavaTokenContext;
- import org.netbeans.modules.editor.NbEditorUtilities;
- import org.netbeans.modules.html.editor.api.completion.HtmlCompletionItem;
- import org.openide.filesystems.FileUtil;
- import org.openide.modules.InstalledFileLocator;
- import org.openide.text.CloneableEditorSupport;
- import org.openide.util.WeakListeners;
- /**
- *
- * @author Petr Jiricka, Petr Nejedly
- * @author Marek.Fukala@Sun.COM
- */
- public class JspSyntaxSupport extends ExtSyntaxSupport implements FileChangeListener {
- /** ErrorManager shared by whole module (package) for logging */
- static final Logger err =
- Logger.getLogger("org.netbeans.modules.web.jspsyntax"); // NOI18N
- /* Constants for various contexts in the text from the point of
- view of JSP completion.*/
- /** Completion context for JSP tags (standard or custom) */
- public static final int TAG_COMPLETION_CONTEXT = 1;
- /** Completion context for JSP end tags (standard or custom) */
- public static final int ENDTAG_COMPLETION_CONTEXT = 2;
- /** Completion context for JSP directives */
- public static final int DIRECTIVE_COMPLETION_CONTEXT = 3;
- /** Completion context for JSP comments */
- public static final int COMMENT_COMPLETION_CONTEXT = 4;
- /** Completion context for other JSP text - such as body of custom tags
- * with TAG_DEPENDENT body content. */
- public static final int TEXT_COMPLETION_CONTEXT = 5;
- /** Completion context for the content language */
- public static final int CONTENTL_COMPLETION_CONTEXT = 6;
- /** Completion context for the scripting language */
- public static final int SCRIPTINGL_COMPLETION_CONTEXT = 7;
- /** Completion context for error */
- public static final int ERROR_COMPLETION_CONTEXT = 8;
- /** Completion context for expression language */
- public static final int EL_COMPLETION_CONTEXT = 9;
- private static final String STANDARD_JSP_PREFIX = "jsp"; // NOI18N
- /** Data for completion: TreeMap for standard JSP tags
- * (tag name, array of attributes). */
- private static TagInfo[] standardJspTagDatas;
- private static TagInfo[] standardTagTagDatas;
- /** Data for completion, when the jsp page is in XML syntax
- **/
- private static TagInfo[] xmlJspTagDatas;
- /** Data for completion, when the tag file is in XML syntax
- **/
- private static TagInfo[] xmlTagFileTagDatas;
- /** Data for completion: TreeMap for JSP directives
- * (directive name, array of attributes). */
- private static TagInfo[] directiveJspData;
- private static TagInfo[] directiveTagFileData;
- /** Mapping the URI of tag library -> URL where the help files are.
- */
- private static HashMap helpMap = null;
- private static final TokenID[] JSP_BRACKET_SKIP_TOKENS = new TokenID[] {
- JavaTokenContext.LINE_COMMENT,
- JavaTokenContext.BLOCK_COMMENT,
- JavaTokenContext.CHAR_LITERAL,
- JavaTokenContext.STRING_LITERAL,
- JspTagTokenContext.ATTR_VALUE,
- JspTagTokenContext.COMMENT
- };
- protected FileObject fobj;
- /** Special bracket finder is used when caret is in JSP context */
- private boolean useCustomBracketFinder = true;
- /** Creates new JspSyntaxSupport */
- public static synchronized JspSyntaxSupport get(Document doc) {
- JspSyntaxSupport sup = (JspSyntaxSupport)doc.getProperty(JspSyntaxSupport.class);
- if(sup == null) {
- sup = new JspSyntaxSupport((BaseDocument)doc);
- doc.putProperty(JspSyntaxSupport.class, sup);
- }
- return sup;
- }
- public JspSyntaxSupport(BaseDocument doc) {
- super(doc);
- fobj = null;
- if (doc != null){
- initFileObject();
- }
- }
- private void initFileObject() {
- DataObject dobj = NbEditorUtilities.getDataObject(getDocument());
- if(dobj != null) {
- fobj = NbEditorUtilities.getDataObject(getDocument()).getPrimaryFile();
- fobj.addFileChangeListener(WeakListeners.create(FileChangeListener.class, this, fobj));
- }
- }
- public String[] getImports(){
- JspParserAPI.ParseResult pre = getParseResult();
- if (pre != null){
- PageInfo pi = pre.getPageInfo();
- if(pi == null) {
- //report error but do not break the entire CC
- err.log(Level.WARNING, null, new NullPointerException("PageInfo obtained from JspParserAPI.ParseResult is null"));
- return null;
- }
- List<String> imports = pi.getImports();
- return imports.toArray(new String[imports.size()]);
- }
- return null;
- }
- public boolean isXmlSyntax(){
- JspContextInfo jspCO = JspContextInfo.getContextInfo(fobj);
- if(jspCO == null) {
- return false;
- }
- JspOpenInfo jspOpenInfo = jspCO.getCachedOpenInfo(fobj, false);
- if(jspOpenInfo == null) {
- return false;
- }
- return jspOpenInfo.isXmlSyntax();
- }
- protected JspParserAPI.ParseResult getParseResult() {
- JspParserAPI.ParseResult result = JspUtils.getCachedParseResult(fobj, true, false);
- if (result == null) {
- result = JspUtils.getCachedParseResult(fobj, false, false);
- }
- return result;
- }
- /** Returns a map of prefix -> URI that maps tag libraries on prefixes.
- * For the XML syntax this mapping may only be approximate.
- */
- protected Map getPrefixMapper() {
- // PENDING - must also take xmlPrefixMapper into account
- JspParserAPI.ParseResult result = getParseResult();
- Map prefixMapper = null;
- if (result != null && result.getPageInfo() != null) {
- //if (result.isParsingSuccess()) {
- // PENDING - can we somehow get incomplete parsed information ?
- if (result.getPageInfo().getXMLPrefixMapper().size() > 0) {
- prefixMapper = result.getPageInfo().getApproxXmlPrefixMapper();
- if (prefixMapper.size() == 0){
- prefixMapper = result.getPageInfo().getXMLPrefixMapper();
- }
- prefixMapper.putAll(result.getPageInfo().getJspPrefixMapper());
- } else {
- prefixMapper = result.getPageInfo().getJspPrefixMapper();
- }
- //}
- }
- return prefixMapper;
- }
- private Map getTagLibraries(boolean requiresFresh) {
- //refresh tag libraries mappings - this call causes the WebAppParseSupport to refresh taglibs mapping
- getTagLibraryMappings();
- //if requiresFresh force the parser to update the parse information for the file
- JspParserAPI.ParseResult result = JspUtils.getCachedParseResult(fobj, false, requiresFresh, requiresFresh);
- if (result != null) {
- PageInfo pi = result.getPageInfo();
- if(pi == null) {
- //report error but do not break the entire CC
- err.log(Level.INFO, null, new NullPointerException("PageInfo obtained from JspParserAPI.ParseResult is null"));
- return null;
- } else {
- return pi.getTagLibraries();
- }
- }
- return null; //an error
- }
- private TagInfo[] getSortedTagInfos(TagInfo[] tinfos) {
- Arrays.sort(tinfos, new Comparator() {
- public int compare(Object o1, Object o2) {
- TagInfo ti1 = (TagInfo)o1;
- TagInfo ti2 = (TagInfo)o2;
- String tname1 = (ti1.getDisplayName() == null ? ti1.getTagName() : ti1.getDisplayName());
- String tname2 = (ti2.getDisplayName() == null ? ti2.getTagName() : ti2.getDisplayName());
- if(tname1 == null || tname2 == null) return 0;
- return tname1.compareTo(tname2);
- }
- @Override
- public boolean equals(Object o) {
- return o.equals(this);
- }
- });
- return tinfos;
- }
- private TagLibraryInfo getTagLibrary(String prefix, boolean requiresFresh) {
- Map mapper = getPrefixMapper();
- if (mapper != null) {
- Object uri = mapper.get(prefix);
- if (uri != null) {
- Map taglibs = getTagLibraries(requiresFresh);
- if (taglibs != null) {
- return (TagLibraryInfo)taglibs.get(uri);
- }
- }
- }
- return null;
- }
- @Override
- protected SyntaxSupport createSyntaxSupport(Class syntaxSupportClass) {
- SyntaxSupport support = super.createSyntaxSupport(syntaxSupportClass);
- if (support != null)
- return support;
- EditorKit kit;
- // try the content language support
- kit = CloneableEditorSupport.getEditorKit("text/html"); //NOI18N
- if (kit instanceof BaseKit) {
- support = ((BaseKit)kit).createSyntaxSupport(getDocument());
- if (support != null)
- return support;
- }
- // try the scripting language support
- kit = CloneableEditorSupport.getEditorKit("text/x-java"); //NOI18N
- if (kit instanceof BaseKit) {
- support = ((BaseKit)kit).createSyntaxSupport(getDocument());
- if (support != null)
- return support;
- }
- return null;
- }
- /** This method decides what kind of completion (html, java, jsp-tag, ...) should be opened
- * or whether the completion window should be closed if it is opened.
- */
- @Override
- public int checkCompletion(JTextComponent target, String typedText, boolean visible ) {
- char first = typedText.charAt(0); //get typed char
- TokenItem item = null; //get token on the cursor
- try{
- item = getItemAtOrBefore(target.getCaret().getDot());
- }catch(BadLocationException e) {
- return COMPLETION_HIDE;
- }
- if (item == null) return COMPLETION_HIDE;
- TokenContextPath tcp = item.getTokenContextPath();
- if(tcp.contains(JavaTokenContext.contextPath)) {
- return COMPLETION_CANCEL; //the JavaCompletionProvider handles this
- }
- //JSP tag or directive
- if(tcp.contains(JspTagTokenContext.contextPath)) {
- //need to distinguish tag/end_tag/directive - search back throught the token chain for <%@ , </ or < tokens
- TokenItem tracking = item;
- //the maxBacktrace number says how far back we are willing to look for
- //the start tag tokens <%, </ and < (simply the JSP tag or directive beginning).
- //There may happen a situation when user starts to write a tag that the a large
- //part of the document behind the cursor is recognized as a jsp tag.
- //In such a case typing somewhere in the end of this 'badly' recognized block
- //would slow down the typing rapidy due to the backtracking oven a long token chain.
- //
- //So we suppose that tag has less than 20 attributes (and one attribute-value pair consumes 4 tokens)
- int maxBacktrace = 20 * 4;
- do {
- //test whether the token is not an error token
- if(tracking.getTokenID() == JspTagTokenContext.ERROR) return COMPLETION_HIDE;
- String image = tracking.getImage();
- //System.out.println("tracking: " + tracking);
- //this is a case when use types %> which is recognized as a JspTagToken, but before that there are java tokens
- if(image.equals("%>")) return COMPLETION_HIDE;
- if(tracking.getImage().startsWith("<%")) {
- //we are in a directive
- if (err.isLoggable(Level.FINE)) err.log(Level.FINE, "DIRECTIVE_COMPLETION_CONTEXT"); // NOI18N
- //open completion also in such a case: <%=|
- if( !visible && first == '=' && tracking.getImage().equals("<%")) return COMPLETION_POPUP;
- if( !visible && first == '%' || first == '@' || first == ' ' ) return COMPLETION_POPUP;
- if( visible && first == '=' || first == '>' ) return COMPLETION_HIDE;
- return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL;
- }
- if(tracking.getImage().equals("<")) {
- //we are in a tag
- if (err.isLoggable(Level.FINE)) err.log(Level.FINE, "TAG_COMPLETION_CONTEXT"); // NOI18N
- if( !visible && first == ' ' || first == ':' ) return COMPLETION_POPUP;
- if( visible && first == '>' ) return COMPLETION_HIDE;
- return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL;
- }
- if(tracking.getImage().equals("</")) {
- //we are in an end tag
- if (err.isLoggable(Level.FINE)) err.log(Level.FINE, "ENDTAG_COMPLETION_CONTEXT"); // NOI18N
- if( visible && first == '>' ) return COMPLETION_HIDE;
- return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL;
- }
- //test whether we are still in the tag context
- if(!tracking.getTokenContextPath().contains(JspTagTokenContext.contextPath)) {
- if (err.isLoggable(Level.FINE)) err.log(Level.FINE, "We are out of jsp tag without finding any tag start token!");
- break;
- }
- if(tracking.getImage().equals(">")) {
- try {
- //check if the cursor is behind an open tag
- SyntaxElement se = getElementChain(tracking.getOffset());
- if(se != null && (se instanceof SyntaxElement.Tag)) {
- return COMPLETION_POPUP;
- }
- }catch(BadLocationException e) {
- //do nothing
- }
- return COMPLETION_HIDE;
- }
- //search previous token
- tracking = tracking.getPrevious();
- } while((maxBacktrace-- > 0) && (tracking != null));
- }//eof JSP tag
- if(tcp.contains(ELTokenContext.contextPath)) {
- if(first == '.') {
- return COMPLETION_POPUP;
- }
- }
- return COMPLETION_HIDE;
- }
- /** Returns offset where the next offset after this offset starts. */
- private final int getTokenEnd( TokenItem item ) {
- if (item == null)
- return 0; //getDocument().getLength();
- return item.getOffset() + item.getImage().length();
- }
- /** Filters list of strings so only strings starting
- * with a given prefix are returned in the new List. */
- public static final List<Object> filterList(List<? extends Object> toFilter, String prefix) {
- List<Object> newList = new ArrayList<Object>();
- Object item;
- for (int i = 0; i < toFilter.size(); i++) {
- item = toFilter.get(i);
- String txt;
- if (item instanceof TagInfo)
- txt = ((TagInfo)item).getTagName();
- else if (item instanceof TagAttributeInfo)
- txt = ((TagAttributeInfo)item).getName();
- else
- txt = (String)item;
- if (txt != null && txt.startsWith(prefix)) {
- newList.add(item);
- }
- }
- return newList;
- }
- /** Filters list of strings so only strings starting
- * with a given prefix are returned in the new List. */
- public static final List<String> filterStrings(List<String> toFilter, String prefix) {
- List<String> newList = new ArrayList<String>();
- for(String val : toFilter) {
- if(val.startsWith(prefix)) {
- newList.add(val);
- }
- }
- return newList;
- }
- /** Gets all 'jsp prefixes' whose 'string prefix' matches complPrefix as a list of Strings. */
- public final List<Object> getTagPrefixes(String complPrefix) {
- return filterList(getAllTagPrefixes(), complPrefix);
- }
- /** Gets all tags whose 'string prefix' matches complPrefix as a list of Strings.
- * Assumes that complPrefix also includes the 'jsp prefix'.
- */
- public final List getTags(String complPrefix) {
- int colonIndex = complPrefix.indexOf(":"); // NOI18N
- if (colonIndex == -1)
- throw new IllegalArgumentException();
- return getTags(complPrefix.substring(0, colonIndex),
- complPrefix.substring(colonIndex + 1));
- }
- /** Gets all tags whose 'string prefix' matches complPrefix and whose 'jsp prefix'
- * is tagPrefix as a list of Strings.
- * Assumes that complPrefix does not include the 'jsp prefix'.
- */
- public final List getTags(String tagPrefix, String complPrefix) {
- return filterList(getAllTags(tagPrefix, true), complPrefix);
- }
- /** Gets attributes for tag whose prefix + name
- * is tagPrefixName as a list of Strings.
- * The attribute's 'string prefix' must match complPrefix.
- */
- public final List getTagAttributes(String tagPrefixName, String complPrefix) {
- int colonIndex = tagPrefixName.indexOf(":"); // NOI18N
- if (colonIndex == -1)
- throw new IllegalArgumentException();
- return getTagAttributes(tagPrefixName.substring(0, colonIndex),
- tagPrefixName.substring(colonIndex + 1), complPrefix);
- }
- /** Gets attributes for tag whose 'jsp prefix'
- * is tagPrefix and whose tag name is tagName as a list of Strings.
- * The attribute's 'string prefix' must match complPrefix.
- */
- protected final List getTagAttributes(String tagPrefix, String tagName, String complPrefix) {
- return filterList(getAllTagAttributes(tagPrefix, tagName), complPrefix);
- }
- /** Gets all directives whose 'string prefix' matches complPrefix as a list of Strings. */
- public final List getDirectives(String complPrefix) {
- return filterList(getAllDirectives(), complPrefix);
- }
- /** Gets attributes for directive <code>directive</code> as a list of Strings.
- * The attribute's 'string prefix' must match complPrefix. */
- public final List getDirectiveAttributes(String directive, String complPrefix) {
- return filterList(getAllDirectiveAttributes(directive), complPrefix);
- }
- /**
- * Returns a list of strings - prefixes available in this support context (JSP file).
- */
- protected List getAllTagPrefixes() {
- List items = new ArrayList();
- // jsp: prefix
- items.add(STANDARD_JSP_PREFIX);
- Map mapper = getPrefixMapper();
- if (mapper != null) {
- // sort it
- TreeSet ts = new TreeSet();
- ts.addAll(mapper.keySet());
- ts.remove("jsp"); // remove jsp prefix when is declared in xml syntax
- items.addAll(ts);
- }
- // prefixes for tag libraries
- /* TagLibParseSupport support = (dobj == null) ?
- null : (TagLibParseSupport)dobj.getCookie(TagLibParseSupport.class);
- if (support != null) {
- // add all prefixes from the support
- TagLibParseSupport.TagLibData[] tagLibData = support.getTagLibEditorData().getTagLibData();
- for (int i = 0; i < tagLibData.length; i++)
- items.add(tagLibData[i].getPrefix());
- }
- */
- return items;
- }
- /** This method merges tagInfos of tags and file tags from a tagLibrary.
- * @param tagLibrary
- * @return array of TagInfo of all tags and tag files from the library
- * or an empty array of if there is not any tag or tagfile defined in the library.
- */
- private TagInfo[] getAllTagInfos(TagLibraryInfo tagLibrary) {
- // if there is not any tag or file tag, then the empty array is returned
- TagInfo[] allTags = new TagInfo[0];
- if (tagLibrary != null) {
- int tagInfosLength = 0;
- int tagAllInfosLength = 0;
- TagInfo[] tagInfos = tagLibrary.getTags();
- TagFileInfo[] tagFileInfos = tagLibrary.getTagFiles();
- if (tagInfos != null) { // it can be null, when the jsp parser finished unexpectedly
- tagInfosLength = tagInfos.length;
- tagAllInfosLength = tagInfosLength;
- }
- if (tagFileInfos != null) { // it can be null, when the jsp parser finished unexpectedly
- tagAllInfosLength = tagAllInfosLength + tagFileInfos.length;
- }
- allTags = new TagInfo[tagAllInfosLength];
- if (tagInfos != null) {
- for (int i = 0; i < tagInfosLength; i++) {
- allTags[i] = tagInfos[i];
- }
- }
- if (tagFileInfos != null) {
- for (int i = 0; i < tagFileInfos.length; i++) {
- allTags[tagInfosLength + i] = tagFileInfos[i].getTagInfo();
- }
- }
- }
- return allTags;
- }
- /** Returns a list of strings - tag names available for a particular prefix.
- */
- protected List getAllTags(String prefix, boolean requiresFresh) {
- List items = new ArrayList();
- // standard JSP tags (jsp:)
- initCompletionData();
- if (STANDARD_JSP_PREFIX.equals(prefix)) {
- TagInfo[] stanTagDatas = getTagInfos();
- for (int i=0; i<stanTagDatas.length; i++) {
- items.add(stanTagDatas[i]);
- }
- }
- TagLibraryInfo info = getTagLibrary(prefix, requiresFresh);
- TagInfo[] tags = null;
- if (info != null) {
- tags = getAllTagInfos(info);
- }
- if (tags != null) {
- tags = getSortedTagInfos(tags);
- String url = (String)helpMap.get(info.getURI());
- if (url != null && !url.equals("")){
- for (int i = 0; i < tags.length; i++) {
- items.add(new TagInfo(tags[i].getTagName(),
- tags[i].getTagClassName(), tags[i].getBodyContent(),
- url + tags[i].getTagName() + ".html#tag-start-" + tags[i].getTagName()
- + "#tag-end-" + tags[i].getTagName(), info,
- tags[i].getTagExtraInfo(), tags[i].getAttributes(),
- tags[i].getDisplayName(), tags[i].getSmallIcon(), tags[i].getLargeIcon(),
- tags[i].getTagVariableInfos(), tags[i].hasDynamicAttributes()));
- }
- } else {
- for (int i = 0; i < tags.length; i++) {
- items.add(tags[i]);
- }
- }
- }
- return items;
- }
- /** Should be overriden ny subclasses to support JSP 1.1.
- * Returns a list of strings - attribute names available for a particular prefix and tag name.
- */
- protected List getAllTagAttributes(String prefix, String tag) {
- List items = new ArrayList();
- // attributes for standard JSP tags (jsp:)
- initCompletionData();
- if (STANDARD_JSP_PREFIX.equals(prefix)) {
- TagInfo[] stanTagDatas = getTagInfos();
- for (int i=0; i<stanTagDatas.length; i++) {
- if (stanTagDatas[i].getTagName().equals(tag)) {
- TagAttributeInfo[] attrs = stanTagDatas[i].getAttributes();
- for (int j=0; j<attrs.length; j++)
- items.add(attrs[j]);
- break;
- }
- }
- }
- TagLibraryInfo info = getTagLibrary(prefix, true);
- if (info != null) {
- TagInfo tagInfo = info.getTag(tag);
- if (tagInfo == null) {
- TagFileInfo tagFile = info.getTagFile(tag);
- if (tagFile != null) {
- tagInfo = tagFile.getTagInfo();
- }
- }
- if (tagInfo != null) {
- TagAttributeInfo[] attributes = tagInfo.getAttributes();
- String url = (String)helpMap.get(tagInfo.getTagLibrary().getURI());
- if (url != null && !url.equals("")){
- for (int i = 0; i < attributes.length; i++) {
- items.add(new TagAttributeInfo(attributes[i].getName(),
- attributes[i].isRequired(),
- url + tagInfo.getTagName() + ".html#attribute-start-" + attributes[i].getName()
- + "#attribute-end-" + attributes[i].getName(),
- attributes[i].canBeRequestTime(),
- attributes[i].isFragment()));
- }
- } else {
- for (int i = 0; i < attributes.length; i++)
- items.add(attributes[i]);
- }
- }
- }
- return items;
- }
- /** Should be overriden ny subclasses to support JSP 1.1. */
- protected List<TagInfo> getAllDirectives() {
- initCompletionData();
- List<TagInfo> items = new ArrayList<TagInfo>();
- //Is xml syntax? => return nothing.
- if (isXmlSyntax()) return items;
- TagInfo[] directiveData;
- if(NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE))
- directiveData = directiveTagFileData;
- else {
- directiveData = directiveJspData;
- }
- for (int i = 0; i < directiveData.length; i++){
- items.add(directiveData[i]);
- }
- return items;
- }
- /** Should be overriden ny subclasses to support JSP 1.1. */
- protected List getAllDirectiveAttributes(String directive) {
- initCompletionData();
- List items = new ArrayList();
- //Is xml syntax? => return nothing.
- if (isXmlSyntax()) return items;
- TagInfo[] directiveData;
- if(NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE))
- directiveData = directiveTagFileData;
- else
- directiveData = directiveJspData;
- for (int i=0; i<directiveData.length; i++) {
- if (directiveData[i].getTagName().equals(directive)) {
- TagAttributeInfo[] attrs = directiveData[i].getAttributes();
- for (int j=0; j<attrs.length; j++)
- items.add(attrs[j]);
- break;
- }
- }
- return items;
- }
- public PageInfo.BeanData[] getBeanData() {
- JspParserAPI.ParseResult result = getParseResult();
- if (result != null) {
- PageInfo pageInfo = result.getPageInfo();
- //pageInfo can be null in some cases when the parser cannot parse
- //the webmodule or the page itself
- if(pageInfo != null) {
- return pageInfo.getBeans();
- }
- }
- /*TagLibParseSupport support = (dobj == null) ?
- null : (TagLibParseSupport)dobj.getCookie(TagLibParseSupport.class);
- return support.getTagLibEditorData().getBeanData();*/
- return null;
- }
- public boolean isErrorPage() {
- JspParserAPI.ParseResult result = getParseResult();
- if (result != null) {
- if (result.getPageInfo() != null)
- return result.getPageInfo().isErrorPage();
- }
- /*TagLibParseSupport support = (dobj == null) ?
- null : (TagLibParseSupport)dobj.getCookie(TagLibParseSupport.class);
- return support.getTagLibEditorData().isErrorPage ();*/
- return false;
- }
- /**
- * The mapping of the 'global' tag library URI to the location
- * (resource path) of the TLD associated with that tag library.
- * The location is returned as a String array:
- * [0] The location
- * [1] If the location is a jar file, this is the location
- * of the tld.
- */
- public Map getTagLibraryMappings() {
- if (fobj == null) {
- return null;
- }
- return JspUtils.getTaglibMap(fobj);
- }
- private static void initHelp(){
- if (helpMap == null){
- String url="";
- File f = InstalledFileLocator.getDefault().locate("docs/jstl11-doc.zip", "org.netbeans.modules.web.core.syntax", false); //NoI18N
- if (f != null){
- try {
- URL urll = f.toURL();
- urll = FileUtil.getArchiveRoot(urll);
- url = urll.toString();
- } catch (java.net.MalformedURLException e){
- err.log(Level.WARNING, null, e);
- // nothing to do
- }
- }
- helpMap = new HashMap();
- // The URI from the tld file URL, where are the files for the library
- helpMap.put("http://java.sun.com/jsp/jstl/core", url + "c/");
- helpMap.put("http://java.sun.com/jstl/core", url + "c/");
- helpMap.put("http://java.sun.com/jstl/core_rt", url + "c_rt/");
- helpMap.put("http://java.sun.com/jsp/jstl/fmt", url + "fmt/");
- helpMap.put("http://java.sun.com/jstl/fmt", url + "fmt/");
- helpMap.put("http://java.sun.com/jstl/fmt_rt", url + "fmt_rt/");
- helpMap.put("http://java.sun.com/jsp/jstl/functions", url + "fn/");
- helpMap.put("http://java.sun.com/jstl/functions", url + "fn/");
- helpMap.put("http://jakarta.apache.org/taglibs/standard/permittedTaglibs", url+"permittedTaglibs/");
- helpMap.put("http://jakarta.apache.org/taglibs/standard/scriptfree", url+ "scriptfree/");
- helpMap.put("http://java.sun.com/jsp/jstl/sql", url + "sql/");
- helpMap.put("http://java.sun.com/jstl/sql", url + "sql/");
- helpMap.put("http://java.sun.com/jstl/sql_rt", url + "sql_rt/");
- helpMap.put("http://java.sun.com/jsp/jstl/xml", url + "x/");
- helpMap.put("http://java.sun.com/jstl/xml", url + "x/");
- helpMap.put("http://java.sun.com/jstl/xml_rt", url + "x_rt/");
- f = InstalledFileLocator.getDefault().locate("docs/jsf12-tlddoc.zip", "org.netbeans.modules.web.core.syntax", false); //NoI18N
- if (f != null){
- try {
- URL urll = f.toURL();
- urll = FileUtil.getArchiveRoot(urll);
- url = urll.toString();
- helpMap.put("http://java.sun.com/jsf/html", url + "h/");
- helpMap.put("http://java.sun.com/jsf/core", url + "f/");
- } catch (java.net.MalformedURLException e){
- err.log(Level.WARNING, null, e);
- // nothing to do
- }
- }
- f = InstalledFileLocator.getDefault().locate("docs/struts-tags.zip", "org.netbeans.modules.web.core.syntax", false);
- if (f != null){
- try {
- URL urll = f.toURL();
- urll = FileUtil.getArchiveRoot(urll);
- url = urll.toString();
- helpMap.put("http://jakarta.apache.org/struts/tags-bean", url + "bean/");
- helpMap.put("http://struts.apache.org/tags-bean", url + "bean/");
- helpMap.put("/WEB-INF/struts-bean.tld", url + "bean/");
- helpMap.put("http://jakarta.apache.org/struts/tags-html", url + "html/");
- helpMap.put("http://struts.apache.org/tags-html", url + "html/");
- helpMap.put("/WEB-INF/struts-html.tld", url + "html/");
- helpMap.put("http://jakarta.apache.org/struts/tags-logic", url + "logic/");
- helpMap.put("http://struts.apache.org/tags-logic", url + "logic/");
- helpMap.put("/WEB-INF/struts-logic.tld", url + "logic/");
- helpMap.put("http://jakarta.apache.org/struts/tags-nested", url + "nested/");
- helpMap.put("http://struts.apache.org/tags-nested", url + "nested/");
- helpMap.put("/WEB-INF/struts-nested.tld", url + "nested/");
- helpMap.put("http://jakarta.apache.org/struts/tags-tiles", url + "tiles/");
- helpMap.put("http://struts.apache.org/tags-tiles", url + "tiles/");
- helpMap.put("/WEB-INF/struts-tiles.tld", url + "tiles/");
- } catch (java.net.MalformedURLException e){
- err.log(Level.WARNING, null, e);
- // nothing to do
- }
- }
- }
- }
- private static void initCompletionData() {
- if (helpMap == null)
- initHelp();
- String url = ""; // NOI18N
- if (directiveJspData == null){
- directiveJspData = new TagInfo[] {
- new TagInfo("include", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref209.html#1003408#8975", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("file", true, url + "syntaxref209.html#16836#10636", false)}), // NOI18N
- new TagInfo("page", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref2010.html", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("autoFlush", false, url+"syntaxref2010.html#15673#15675", false), // NOI18N
- new TagAttributeInfo("buffer", false, url+"syntaxref2010.html#15671#15673", false), // NOI18N
- new TagAttributeInfo("contentType", false, url+"syntaxref2010.html#15683#1001361", false), // NOI18N
- new TagAttributeInfo("errorPage", false, url+"syntaxref2010.html#15679#15681", false), // NOI18N
- new TagAttributeInfo("extends", false, url+"syntaxref2010.html#15665#16862", false), // NOI18N
- new TagAttributeInfo("import", false, url+"syntaxref2010.html#16862#15669", false), // NOI18N
- new TagAttributeInfo("info", false, url+"syntaxref2010.html#15677#15679", false), // NOI18N
- new TagAttributeInfo("isELIgnored", false, url+"syntaxref2010.html#1011216#18865", false), // NOI18N
- new TagAttributeInfo("isErrorPage", false, url+"syntaxref2010.html#15681#15683", false), // NOI18N
- new TagAttributeInfo("isThreadSafe", false, url+"syntaxref2010.html#15675#15677", false), // NOI18N
- new TagAttributeInfo("language", false, url+"syntaxref2010.html#15663#15665", false), // NOI18N
- new TagAttributeInfo("pageEncoding", false, url+"syntaxref2010.html#1001361#1011216", false), // NOI18N
- new TagAttributeInfo("session", false, url+"syntaxref2010.html#15669#15671", false)}), // NOI18N
- new TagInfo("taglib", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref2012.html#1003416#1002041", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("prefix", true, url+"syntaxref2012.html#1011290#1002041", false), // NOI18N
- new TagAttributeInfo("uri", false, url+"syntaxref2012.html#10721#1011294", false), // NOI18N
- new TagAttributeInfo("tagdir", false, url + "syntaxref2012.html#1011294#1011290", false)}) // NOI18N
- };
- }
- if (directiveTagFileData == null){
- directiveTagFileData = new TagInfo[]{
- new TagInfo("attribute", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref208.html", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("description", false, url + "syntaxref208.html#1004672", false), // NOI18N
- new TagAttributeInfo("fragment", false, url + "syntaxref208.html#1004657#1004666", false), // NOI18N
- new TagAttributeInfo("name", true, url + "syntaxref208.html#1004648#1004655", false), // NOI18N
- new TagAttributeInfo("required", false, url + "syntaxref208.html#1004655#1004657", false), // NOI18N
- new TagAttributeInfo("rtexprvalue", false, url + "syntaxref208.html#1004666#1004669", false), // NOI18N
- new TagAttributeInfo("type", false, url + "syntaxref208.html#1004669#1004672", false)}), // NOI18N
- directiveJspData[0],
- new TagInfo("tag", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2011.html", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("body-content", false, url + "syntaxref2011.html#1005164#005172", false), // NOI18N
- new TagAttributeInfo("description", false, url + "syntaxref2011.html#1005196#1005198", false), // NOI18N
- new TagAttributeInfo("display-name", false, url + "syntaxref2011.html#1005161#1005164", false), // NOI18N
- new TagAttributeInfo("dynamic-attributes", false, url + "syntaxref2011.html#005172#1005190", false), // NOI18N
- new TagAttributeInfo("example", false, url + "syntaxref2011.html#1005198#1005201", false), // NOI18N
- new TagAttributeInfo("import", false, url + "syntaxref2011.html#1005203#1005209", false), // NOI18N
- new TagAttributeInfo("isELIgnored", false, url + "syntaxref2011.html#1005214#1005291#1005291", false), // NOI18N
- //new TagAttributeInfo("isScriptingEnabled", false, url + "syntaxref2011.html#", false), // NOI18N
- new TagAttributeInfo("large-icon", false, url + "syntaxref2011.html#1005193#1005196", false), // NOI18N
- new TagAttributeInfo("language", false, url + "syntaxref2011.html#1005201#1005203", false), // NOI18N
- new TagAttributeInfo("pageEncoding", false, url + "syntaxref2011.html#1005209#1005214", false), // NOI18N
- new TagAttributeInfo("small-icon", false, url + "syntaxref2011.html#1005190#1005193", false)}), // NOI18N
- directiveJspData[2],
- new TagInfo("variable", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2013.html#15694#1003563", null, null, // NOI18N
- new TagAttributeInfo[] { new TagAttributeInfo("alias", false, url + "syntaxref2013.html#1005914#1005956", false), // NOI18N
- new TagAttributeInfo("declare", false, url + "syntaxref2013.html#1006001#1006019", false), // NOI18N
- new TagAttributeInfo("description", false, url + "syntaxref2013.html#1005991#1003563", false), // NOI18N
- new TagAttributeInfo("name-given", false, url + "syntaxref2013.html#1003561#1005914", false), // NOI18N
- new TagAttributeInfo("scope", false, url + "syntaxref2013.html#1006019#1005991", false), // NOI18N
- new TagAttributeInfo("variable-class", false, url + "syntaxref2013.html#1005956#1006001", false)}) // NOI18N
- };
- }
- if (standardJspTagDatas == null) {
- final String helpFiles = "docs/syntaxref20.zip"; //NoI18N
- File f = InstalledFileLocator.getDefault().locate(helpFiles, "org.netbeans.modules.web.core.syntax", true); //NoI18N
- if (f != null){
- try {
- URL urll = f.toURL();
- urll = FileUtil.getArchiveRoot(urll);
- url = urll.toString();
- } catch (java.net.MalformedURLException e){
- err.log(Level.WARNING, null, e);
- // nothing to do
- }
- }
- standardJspTagDatas = new TagInfo[] {
- new TagInfo("attribute", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2014.html", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2014.html#1003581#1006483", false), // NOI18N
- new TagAttributeInfo("trim", false, url + "syntaxref2014.html#1006483#1003583", false)}), // NOI18N
- new TagInfo("body", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2015.html#1006731#1003768", // NOI18N
- null, null, new TagAttributeInfo[]{}),
- new TagInfo("element", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2016.html#1003696#1003708", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2016.html#1003706#1003708", false)}), // NOI18N
- new TagInfo("expression", null, TagInfo.BODY_CONTENT_JSP, url+"syntaxref205.html#1004353#11268", // NOI18N
- null, null, new TagAttributeInfo[] {}),
- new TagInfo("fallback", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#11583#19029", // NOI18N
- null, null, new TagAttributeInfo[] {}),
- new TagInfo("forward", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2018.html#1003349#15708", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("page", true, url + "syntaxref2018.html#15704#15708", true)}), // NOI18N
- new TagInfo("getProperty", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2019.html#8820#9201", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2019.html#15748#10919", false), // NOI18N
- new TagAttributeInfo("property", true, url + "syntaxref2019.html#10919#19482", false)}), // NOI18N
- new TagInfo("include", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2020.html#8828#9228", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("flush", true, url + "syntaxref2020.html#17145#18376", false), // NOI18N
- new TagAttributeInfo("page", true, url + "syntaxref2020.html#10930#17145", true)}), // NOI18N
- new TagInfo("param", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2023.html#11538#11583", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2023.html#11538#11583", false), // NOI18N
- new TagAttributeInfo("value", true, url + "syntaxref2023.html#11538#11583", true)}), // NOI18N
- new TagInfo("params", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#11538#11583", // NOI18N
- null, null, new TagAttributeInfo[] {}),
- new TagInfo("plugin", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#1004158#19029", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("align", false, url + "syntaxref2023.html#11516#11518", false), // NOI18N
- new TagAttributeInfo("archive", false, url + "syntaxref2023.html#11553#11516", false), // NOI18N
- new TagAttributeInfo("code", true, url + "syntaxref2023.html#11514#11515", false), // NOI18N
- new TagAttributeInfo("codebase", true, url + "syntaxref2023.html#11515#11547", false), // NOI18N
- new TagAttributeInfo("height", false, url + "syntaxref2023.html#11518#11568", false), // NOI18N
- new TagAttributeInfo("hspace", false, url + "syntaxref2023.html#11568#11520", false), // NOI18N
- new TagAttributeInfo("iepluginurl", false, url + "syntaxref2023.html#11526#11538", false),// NOI18N
- new TagAttributeInfo("jreversion", false, url + "syntaxref2023.html#11520#11525", false), // NOI18N
- new TagAttributeInfo("name", false, url + "syntaxref2023.html#11547#11553", false), // NOI18N
- new TagAttributeInfo("nspluginurl", false,url + "syntaxref2023.html#11525#11526", false),// NOI18N
- new TagAttributeInfo("type", true, url + "syntaxref2023.html#10935#11514", false), // NOI18N
- new TagAttributeInfo("vspace", false, url + "syntaxref2023.html#11568#11520", false), // NOI18N
- new TagAttributeInfo("width", false, url + "syntaxref2023.html#11518#11568", false)}), // NOI18N
- new TagInfo("setProperty", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2025.html#8856#9329", // NOI18N
- null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2025.html#17612#1001786", true), // NOI18N
- new TagAttributeInfo("param", false, url + "syntaxref2025.html#9919#20483", false), // NOI18N
- new TagAttributeInfo("property", false, url + "syntaxref2025.html#1001786#9329", false), // NOI18N
- new TagAttributeInfo("value", false, url + "syntaxref2025.html#20483#9329", true)}), // NOI18N
- new TagInfo("text", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2026.html",
- null, n