package tk.eclipse.plugin.jspeditor.editors; import java.util.HashMap; import java.util.List; import jp.aonir.fuzzyxml.FuzzyXMLAttribute; import jp.aonir.fuzzyxml.FuzzyXMLDocument; import jp.aonir.fuzzyxml.FuzzyXMLElement; import jp.aonir.fuzzyxml.FuzzyXMLNode; import jp.aonir.fuzzyxml.XPath; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import tk.eclipse.plugin.htmleditor.HTMLPlugin; import tk.eclipse.plugin.htmleditor.HTMLUtil; import tk.eclipse.plugin.htmleditor.ICustomTagValidator; import tk.eclipse.plugin.htmleditor.ICustomTagValidatorContributer; import tk.eclipse.plugin.htmleditor.assist.AttributeInfo; import tk.eclipse.plugin.htmleditor.assist.TagInfo; import tk.eclipse.plugin.htmleditor.editors.HTMLValidator; /** * The JSP Validator that is called by <code>JSPSourceEditor</code>. * <p> * This validator validates the JSP document using FuzzyXML API, * and reports following errors. * <ul> * <li>TLDs are not extst</li> * <li>taglibs are not defined</li> * <li>required attributes of taglibs are not specified</li> * </ul> * * @author Naoki Takezoe * @author Tom Wickham-Jones */ public class JSPValidator extends HTMLValidator implements IJSPValidationMarkerCreator { private JSPInfo info; /** * The constructor. * * @param file */ public JSPValidator(IFile file){ super(file); } /** * The constructor. * * @param file * @param info */ public JSPValidator(IFile file, JSPInfo info){ super(file); this.info = info; } @Override protected void validateDocument(FuzzyXMLDocument doc){ if(doc!=null){ if(this.info==null){ this.info = JSPInfo.getJSPInfo(getFile(), getContent()); } validateElement((FuzzyXMLElement)XPath.selectSingleNode(doc.getDocumentElement(),"*")); } } @Override protected boolean validateUsingFuzzyXML() { return true; } @Override protected boolean validateUsingTidy() { return false; } private void validateElement(FuzzyXMLElement element){ if(element==null){ return; } if(element.getName().indexOf(":") > 0){ String[] dim = element.getName().split(":"); if(dim.length==1){ // I can't judge that this case is marked an error... } else { String prefix = dim[0]; // String tagName = dim[1]; String uri = info.getTaglibUri(prefix); ICustomTagValidator validator = null; if(uri!=null){ ICustomTagValidatorContributer contributer = HTMLPlugin.getDefault().getCustomTagValidatorContributer(uri); if(contributer!=null){ validator = contributer.getConverter(dim[1]); } if(validator!=null){ HashMap<String, String> attrMap = new HashMap<String, String>(); FuzzyXMLAttribute[] attrs = element.getAttributes(); for(int i=0;i<attrs.length;i++){ attrMap.put(attrs[i].getName(),attrs[i].getValue()); } validator.validate(this, attrMap,element,info); return; } } if(!prefix.equals("jsp")){ TLDInfo tld = getTLDInfo(prefix); if(tld==null){ // tld does not exist. addElementMarker(element,"Validation.NoTLD",prefix); } else if(tld.getUri()!=null || tld.getTagdir()!=null){ TagInfo tagInfo = getTagInfo(tld,element.getName()); if(tagInfo==null){ // taglib does not exist. addElementMarker(element,"Validation.NoCustomTag",element.getName()); } else { AttributeInfo[] attrs = tagInfo.getAttributeInfo(); for(int i=0;i<attrs.length;i++){ if(attrs[i].isRequired() && !element.hasAttribute(attrs[i].getAttributeName())){ // check jsp:attribute boolean findAttribute = false; FuzzyXMLNode[] nodes = element.getChildren(); for(int j=0;j<nodes.length;j++){ if(nodes[j] instanceof FuzzyXMLElement && ((FuzzyXMLElement)nodes[j]).getName().equals("jsp:attribute")){ FuzzyXMLAttribute attr = ((FuzzyXMLElement)nodes[j]).getAttributeNode("name"); if(attr!=null && attr.getValue().equals(attrs[i].getAttributeName())){ findAttribute = true; break; } } } // required attributes wasn't specified. if(!findAttribute){ addElementMarker(element,"Validation.RequiredAttr",attrs[i].getAttributeName()); } } } } } } } } FuzzyXMLNode[] nodes = element.getChildren(); for(int i=0;i<nodes.length;i++){ if(nodes[i] instanceof FuzzyXMLElement){ validateElement((FuzzyXMLElement)nodes[i]); } } } private TLDInfo getTLDInfo(String prefix){ TLDInfo[] tlds = info.getTLDInfo(); for(int i=0;i<tlds.length;i++){ if(tlds[i].getPrefix().equals(prefix)){ return tlds[i]; } } return null; } private TagInfo getTagInfo(TLDInfo tld,String tagName){ List list = tld.getTagInfo(); // boolean tagFound = false; for(int j=0;j<list.size();j++){ TagInfo tagInfo = (TagInfo)list.get(j); if(tagInfo.getTagName().equals(tagName)){ return tagInfo; } } return null; } private void addElementMarker(FuzzyXMLElement element,String key,String value){ // create message String message = HTMLPlugin.createMessage( HTMLPlugin.getResourceString(key),new String[]{value}); int offset = element.getOffset()+1; HTMLUtil.addMarker(getFile(), IMarker.SEVERITY_ERROR, getLineAtOffset(offset), offset ,element.getName().length(), message); } public void addMarker( int severity, int offset, int length, String message) { HTMLUtil.addMarker(getFile(), severity, getLineAtOffset(offset), offset , length, message); } /* * Call any contributed JSP filter extensions * @since 2.0.5 */ @Override protected String filterContents( String jspContents, IFile file) { IJSPFilter[] jspFilters = HTMLPlugin.getDefault().getJSPFilters(); for ( int i = 0; i < jspFilters.length; i++) { jspContents = jspFilters[i].filterJSP(jspContents, file); } return jspContents; } }