package org.objectstyle.wolips.wodclipse.core.validation; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import jp.aonir.fuzzyxml.FuzzyXMLDocument; import jp.aonir.fuzzyxml.FuzzyXMLElement; import jp.aonir.fuzzyxml.FuzzyXMLNode; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.JavaModelException; import org.objectstyle.wolips.bindings.Activator; import org.objectstyle.wolips.bindings.preferences.PreferenceConstants; import org.objectstyle.wolips.bindings.wod.HtmlElementName; import org.objectstyle.wolips.bindings.wod.IWodElement; import org.objectstyle.wolips.bindings.wod.IWodModel; import org.objectstyle.wolips.bindings.wod.SimpleWodBinding; import org.objectstyle.wolips.bindings.wod.WodBindingValueProblem; import org.objectstyle.wolips.bindings.wod.WodProblem; import org.objectstyle.wolips.locate.LocateException; import org.objectstyle.wolips.variables.BuildProperties; import org.objectstyle.wolips.wodclipse.core.completion.HtmlCacheEntry; import org.objectstyle.wolips.wodclipse.core.completion.WodCacheEntry; import org.objectstyle.wolips.wodclipse.core.completion.WodParserCache; import org.objectstyle.wolips.wodclipse.core.util.FuzzyXMLWodElement; import org.objectstyle.wolips.wodclipse.core.util.WodHtmlUtils; public class TemplateValidator { private BuildProperties _buildProperties; private WodParserCache _cache; private Set<FuzzyXMLElement> _woElements; public TemplateValidator(WodParserCache cache) { _cache = cache; _buildProperties = (BuildProperties)cache.getProject().getAdapter(BuildProperties.class); } /** * Validates the HTML document. * @throws Exception */ public void validate(FuzzyXMLDocument doc) throws Exception { visitDocument(doc, true); } public void visitDocument(FuzzyXMLDocument doc, boolean validate) throws Exception { if (doc != null) { _woElements = new HashSet<FuzzyXMLElement>(); final List<InlineWodProblem> inlineProblems = new LinkedList<InlineWodProblem>(); FuzzyXMLElement rootElement = doc.getDocumentElement(); //FuzzyXMLElement rootElement = (FuzzyXMLElement) XPath.selectSingleNode(doc.getDocumentElement(), "*"); visitElement(rootElement, inlineProblems, validate); if (validate) { HtmlCacheEntry htmlCacheEntry = _cache.getHtmlEntry(); htmlCacheEntry.getHtmlElementCache().clearCache(); WodCacheEntry wodCacheEntry = _cache.getWodEntry(); IFile wodFile = wodCacheEntry.getFile(); IWodModel wodModel = wodCacheEntry.getModel(); for (FuzzyXMLElement woElement : _woElements) { String woElementName = woElement.getAttributeValue("name"); int startOffset = woElement.getOffset() + woElement.getNameOffset() + 1; int endOffset = startOffset + woElement.getNameLength() - 1; HtmlElementName elementName = new HtmlElementName(htmlCacheEntry.getFile(), woElementName, startOffset, endOffset); htmlCacheEntry.getHtmlElementCache().addHtmlElement(elementName); if (wodModel != null) { IWodElement wodElement = wodModel.getElementNamed(woElementName); if (wodElement == null) { WodProblem undefinedElement = new WodBindingValueProblem(wodElement, new SimpleWodBinding(null, "name", null), "name", "The element '" + woElementName + "' is not defined in " + wodFile.getName(), null, -1, false); inlineProblems.add(new InlineWodProblem(woElement, undefinedElement, _cache)); } } } for (InlineWodProblem wodProblem : inlineProblems) { wodProblem.createProblemMarkers(); } } } } private void visitElement(FuzzyXMLElement element, List<InlineWodProblem> inlineProblems, boolean validate) throws CoreException { if (element == null) { return; } String elementName = element.getName(); if (WodHtmlUtils.isInline(elementName)) { if (validate) { IWodElement wodElement = new FuzzyXMLWodElement(element, _buildProperties); if (wodElement != null) { boolean validateBindingValues = Activator.getDefault().getPluginPreferences().getBoolean(PreferenceConstants.VALIDATE_BINDING_VALUES); //String invalidOGNLSeverity = Activator.getDefault().getPluginPreferences().getString(PreferenceConstants.INVALID_OGNL_SEVERITY_KEY); List<WodProblem> wodProblems = new LinkedList<WodProblem>(); try { wodElement.fillInProblems(_cache.getJavaProject(), _cache.getComponentType(), validateBindingValues, wodProblems, WodParserCache.getTypeCache(), _cache.getHtmlEntry().getHtmlElementCache()); inlineProblems.add(new InlineWodProblem(element, wodProblems, _cache)); } catch (JavaModelException e) { try { WodParserCache.getTypeCache().clearCacheForType(_cache.getComponentType()); } catch (LocateException e1) { e1.printStackTrace(); } } catch (Throwable t) { Activator activator = Activator.getDefault(); if (activator != null) { activator.log(t); } } } } } else if (WodHtmlUtils.isWOTag(elementName)) { String webobjectName = element.getAttributeValue("name"); if (webobjectName == null) { if (validate) { inlineProblems.add(new InlineWodProblem(element, "webobject tag missing 'name' attribute", false, _cache)); } } else { _woElements.add(element); if (validate && element.getAttributes().length > 1) { inlineProblems.add(new InlineWodProblem(element, "webobject tags should only have a 'name' attribute", true, _cache)); } } } else { // System.out.println("TemplateValidator.validateElement: " + elementName); } FuzzyXMLNode[] nodes = element.getChildren(); for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof FuzzyXMLElement) { visitElement((FuzzyXMLElement) nodes[i], inlineProblems, validate); } } } }