package tk.eclipse.plugin.jspeditor.editors; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import jp.aonir.fuzzyxml.FuzzyXMLAttribute; import jp.aonir.fuzzyxml.FuzzyXMLDocument; import jp.aonir.fuzzyxml.FuzzyXMLElement; import jp.aonir.fuzzyxml.FuzzyXMLNode; import jp.aonir.fuzzyxml.FuzzyXMLParser; import jp.aonir.fuzzyxml.XPath; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import tk.eclipse.plugin.htmleditor.HTMLPlugin; import tk.eclipse.plugin.htmleditor.HTMLProjectParams; import tk.eclipse.plugin.htmleditor.HTMLUtil; /** * This class has informations about JSP like following: * <ul> * <li>information about taglib directive</li> * </ul> */ public class JSPInfo { private static Map<IFile, JSPInfoCache> _jspInfoMap = new HashMap<IFile, JSPInfoCache>(); private static class JSPInfoCache { private JSPInfo jspInfo; private long timestamp; } private ArrayList<TLDInfo> _tldInfoList = new ArrayList<TLDInfo>(); private FuzzyXMLDocument _doc; // Regular expressions // private Pattern pagePattern = Pattern.compile("<%@\\s*page\\s+(.+?)%>",Pattern.DOTALL); private Pattern _taglibPattern = Pattern.compile("<%@\\s*taglib\\s+(.+?)%>",Pattern.DOTALL); private Pattern _uriPattern = Pattern.compile("uri\\s*=\\s*\"(.+?)\""); private Pattern _tagdirPattern = Pattern.compile("tagdir\\s*=\\s*\"(.+?)\""); private Pattern _prefixPattern = Pattern.compile("prefix\\s*=\\s*\"(.+?)\""); private Pattern _includePattern = Pattern.compile("<%@\\s*include\\s+(.+?)%>",Pattern.DOTALL); private Pattern _filePattern = Pattern.compile("file\\s*=\\s*\"(.+?)\""); public static JSPInfo getJSPInfo(IFile file, String source){ JSPInfoCache cache = _jspInfoMap.get(file); if(cache!=null){ if(file.getLocalTimeStamp()==cache.timestamp){ return cache.jspInfo; } } JSPInfo info = new JSPInfo(file, source); cache = new JSPInfoCache(); cache.jspInfo = info; cache.timestamp = file.getLocalTimeStamp(); _jspInfoMap.put(file, cache); return info; } /** * The constructor. * * @param input IFileEditorInput * @param source JSP */ private JSPInfo(IFile file, String source){ this(file, source, true); } public FuzzyXMLDocument getDocument(){ return this._doc; } /** * The constructor. * * @param input IFileEditorInput * @param source JSP * @param include use include configuration of web.xml */ private JSPInfo(IFile file, String source, boolean include) { super(); try { // load project preference HTMLProjectParams params = new HTMLProjectParams(file.getProject()); String webapproot = params.getRoot(); // processing for include direcive IContainer basedir = file.getProject(); if (!webapproot.equals("") && !webapproot.equals("/")) { basedir = basedir.getFolder(new Path(webapproot)); } Matcher matcher = _includePattern.matcher(source); while (matcher.find()) { String content = matcher.group(1); String fileInc = getAttribute(content, _filePattern); if(fileInc==null){ continue; } // taglibInsertIndex = matcher.end(); // Lecture du fichier inclus puis extraction de ses TLDs IFile incJspFile = null; if(fileInc.startsWith("/")){ incJspFile = basedir.getFile(new Path(fileInc)); } else { incJspFile = file.getParent().getFile(new Path(fileInc)); } try { if(incJspFile!=null && incJspFile.exists()){ String contents = new String(HTMLUtil.readStream(incJspFile.getContents())); JSPInfo info = new JSPInfo(incJspFile, contents); TLDInfo[] tldInfos = info.getTLDInfo(); for (int i = 0; i < tldInfos.length; i++) { _tldInfoList.add(tldInfos[i]); } } } catch (IOException ioe) { HTMLPlugin.logException(ioe); } catch (CoreException ce) { HTMLPlugin.logException(ce); } } // getting page directove // matcher = pagePattern.matcher(source); // while(matcher.find()){ // taglibInsertIndex = matcher.end(); // } // getting taglib directive matcher = _taglibPattern.matcher(source); while(matcher.find()){ // parsing taglib directive String content = matcher.group(1); String tagdir = getAttribute(content, _tagdirPattern); if(tagdir != null){ String prefix = getAttribute(content,_prefixPattern); TLDInfo info = TLDInfo.getTLDInfoFromTagdir(file,prefix,tagdir); if(info!=null){ _tldInfoList.add(info); } } else { String uri = getAttribute(content,_uriPattern); String prefix = getAttribute(content,_prefixPattern); // creation TLDInfo // taglibInsertIndex = matcher.end(); TLDInfo info = TLDInfo.getTLDInfo(file,prefix,uri); if(info!=null){ _tldInfoList.add(info); } } } // getting TLDs from xmlns try { this._doc = new FuzzyXMLParser(false).parse(HTMLUtil.scriptlet2space(source,false)); FuzzyXMLElement root = (FuzzyXMLElement)XPath.selectSingleNode(_doc.getDocumentElement(),"*"); if(root!=null){ FuzzyXMLAttribute[] attrs = root.getAttributes(); for(int i=0;i<attrs.length;i++){ if(attrs[i].getName().startsWith("xmlns:")){ String[] dim = attrs[i].getName().split(":"); if(dim.length > 1){ TLDInfo info = null; String value = attrs[i].getValue(); if(value.startsWith("urn:jsptagdir:")){ value = value.replaceFirst("^urn:jsptagdir:", ""); info = TLDInfo.getTLDInfoFromTagdir(file,dim[1],value); } else if(value.startsWith("urn:jsptld:")){ value = value.replaceFirst("^urn:jsptld:", ""); info = TLDInfo.getTLDInfo(file,dim[1],value); } else { info = TLDInfo.getTLDInfo(file,dim[1],value); } if(info!=null){ _tldInfoList.add(info); } } } } } } catch(Exception ex){ HTMLPlugin.logException(ex); } // getting TLDs from included JSP defined in web.xml try { if(include){ IPath path = new Path(webapproot).append("/WEB-INF/web.xml"); IFile webXML = file.getProject().getFile(path); if(webXML!=null && webXML.exists()){ FuzzyXMLDocument doc = new FuzzyXMLParser(false).parse(webXML.getContents()); FuzzyXMLNode[] nodes = HTMLUtil.selectXPathNodes(doc.getDocumentElement(), "/web-app/jsp-config/jsp-property-group[url-pattern='*.jsp']"); for(int i=0;i<nodes.length;i++){ FuzzyXMLNode[] includes = HTMLUtil.selectXPathNodes((FuzzyXMLElement)nodes[i],"/include-prelude|/include-coda"); for(int j=0;j<includes.length;j++){ IFile incFile = basedir.getFile(new Path(((FuzzyXMLElement)includes[j]).getValue())); if(incFile!=null && incFile.exists()){ String contents = new String(HTMLUtil.readStream(incFile.getContents())); JSPInfo info = new JSPInfo(incFile, contents, false); TLDInfo[] tldInfos = info.getTLDInfo(); for (int k = 0; k < tldInfos.length; k++) { _tldInfoList.add(tldInfos[k]); } } } } } } } catch(Exception ex){ HTMLPlugin.logException(ex); } } catch(Exception ex){ HTMLPlugin.logException(ex); } } private String getAttribute(String source,Pattern pattern){ Matcher matcher = pattern.matcher(source); if(matcher.find()){ return matcher.group(1); } return null; } // public void addTaglibDirective(IDocument doc,String prefix,String uri){ // try { // doc.replace(taglibInsertIndex,0,"\n<%@ taglib uri=\""+uri+"\" prefix=\""+prefix+"\" %>"); // } catch(Exception ex){ // HTMLPlugin.logException(ex); // } // } public String getTaglibUri(String prefix){ String uri = null; TLDInfo[] tlds = getTLDInfo(); for(int i=0;i<tlds.length;i++){ if(tlds[i].getPrefix().equals(prefix)){ uri = tlds[i].getTaglibUri(); break; } } return uri; } /** * Returns an array of TLDInfo. * * @return an array of TLDInfo. */ public TLDInfo[] getTLDInfo(){ return _tldInfoList.toArray(new TLDInfo[_tldInfoList.size()]); } }