| package org.eclipse.jst.jsf.facelet.ui.internal.validation; |
| |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.runtime.content.IContentTypeManager; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.Namespace; |
| import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver; |
| import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory; |
| import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext; |
| import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory; |
| import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; |
| import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry; |
| import org.eclipse.jst.jsf.facelet.core.internal.util.ViewUtil; |
| import org.eclipse.jst.jsf.facelet.ui.internal.FaceletUiPlugin; |
| import org.eclipse.jst.jsf.validation.internal.IJSFViewValidator; |
| import org.eclipse.jst.jsf.validation.internal.JSFValidatorFactory; |
| import org.eclipse.jst.jsf.validation.internal.ValidationPreferences; |
| import org.eclipse.jst.jsf.validation.internal.facelet.FaceletDiagnosticFactory; |
| import org.eclipse.wst.sse.core.StructuredModelManager; |
| import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; |
| import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; |
| import org.eclipse.wst.validation.AbstractValidator; |
| import org.eclipse.wst.validation.ValidationResult; |
| import org.eclipse.wst.validation.ValidationState; |
| import org.eclipse.wst.validation.internal.core.ValidationException; |
| import org.eclipse.wst.validation.internal.operations.LocalizedMessage; |
| import org.eclipse.wst.validation.internal.provisional.core.IMessage; |
| import org.eclipse.wst.validation.internal.provisional.core.IReporter; |
| import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; |
| import org.eclipse.wst.validation.internal.provisional.core.IValidator; |
| import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| /** |
| * The Facelet HTML file validator. |
| * |
| * @author cbateman |
| * |
| */ |
| public class HTMLValidator extends AbstractValidator implements IValidator |
| { |
| private FaceletDiagnosticFactory _diagnosticFactory = new FaceletDiagnosticFactory(); |
| /** |
| * @param helper |
| * @return no rule, null |
| */ |
| public ISchedulingRule getSchedulingRule(final IValidationContext helper) |
| { |
| // no rule... |
| return null; |
| } |
| |
| /** |
| * @param helper |
| * @param reporter |
| * @return status of this validation |
| * @throws ValidationException |
| */ |
| public IStatus validateInJob(final IValidationContext helper, |
| final IReporter reporter) throws ValidationException |
| { |
| IStatus status = Status.OK_STATUS; |
| try |
| { |
| validate(helper, reporter); |
| } |
| catch (final ValidationException e) |
| { |
| status = new Status(IStatus.ERROR, FaceletUiPlugin.PLUGIN_ID, |
| IStatus.ERROR, e.getLocalizedMessage(), e); |
| } |
| return status; |
| |
| } |
| |
| public void cleanup(final IReporter reporter) |
| { |
| // do nothing |
| } |
| |
| @Override |
| public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor){ |
| ValidationResult vr = new ValidationResult(); |
| if (resource == null || !(resource instanceof IFile)) { |
| return vr; |
| } |
| IFile currentFile = (IFile) resource; |
| if (shouldValidate(currentFile)) { |
| validateFile(currentFile, vr.getReporter(monitor)); |
| } |
| return vr; |
| } |
| |
| public void validate(final IValidationContext helper, |
| final IReporter reporter) throws ValidationException |
| { |
| final String[] uris = helper.getURIs(); |
| final IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); |
| if (uris.length > 0) |
| { |
| IFile currentFile = null; |
| |
| for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) |
| { |
| currentFile = wsRoot.getFile(new Path(uris[i])); |
| if (currentFile != null && currentFile.exists()) |
| { |
| if (shouldValidate(currentFile)) |
| { |
| final int percent = (i * 100) / uris.length + 1; |
| final IMessage message = new LocalizedMessage( |
| IMessage.LOW_SEVERITY, percent + "% " + uris[i]); |
| reporter.displaySubtask(this, message); |
| |
| validateFile(currentFile, reporter); |
| } |
| } |
| } |
| } |
| |
| } |
| |
| private void validateFile(final IFile file, final IReporter reporter) |
| { |
| final IJSFViewValidator validator = JSFValidatorFactory |
| .createDefaultXMLValidator(); |
| final ValidationPreferences prefs = new ValidationPreferences( |
| JSFCorePlugin.getDefault().getPreferenceStore()); |
| prefs.load(); |
| |
| IStructuredModel model = null; |
| try |
| { |
| model = StructuredModelManager.getModelManager().getModelForRead( |
| file); |
| |
| final ValidationReporter jsfReporter = new ValidationReporter(this, |
| reporter, file, prefs, model); |
| validator.validateView(file, jsfReporter); |
| // TODO: break off into composite strategies |
| validateFaceletHtml(file, jsfReporter); |
| } |
| catch (final CoreException e) |
| { |
| JSFCorePlugin.log("Error validating JSF", e); |
| } |
| catch (final IOException e) |
| { |
| JSFCorePlugin.log("Error validating JSF", e); |
| } |
| finally |
| { |
| if (null != model) |
| { |
| model.releaseFromRead(); |
| } |
| } |
| } |
| |
| private void validateFaceletHtml(final IFile file, |
| final ValidationReporter reporter) |
| { |
| IStructuredModel model = null; |
| try |
| { |
| model = StructuredModelManager.getModelManager().getModelForRead( |
| file); |
| |
| final IStructuredDocument structuredDoc = model |
| .getStructuredDocument(); |
| |
| validateDocument(structuredDoc, reporter, file.getProject()); |
| } |
| catch (final CoreException e) |
| { |
| JSFCorePlugin.log("Error validating JSF", e); |
| } |
| catch (final IOException e) |
| { |
| JSFCorePlugin.log("Error validating JSF", e); |
| } |
| finally |
| { |
| if (null != model) |
| { |
| model.releaseFromRead(); |
| } |
| } |
| } |
| |
| private void validateDocument(IStructuredDocument structuredDoc, |
| final ValidationReporter reporter, IProject project) |
| { |
| validateRoot(structuredDoc, reporter, project); |
| } |
| |
| private void validateRoot(IStructuredDocument structuredDoc, |
| ValidationReporter reporter, IProject project) |
| { |
| final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE |
| .getContext(structuredDoc, -1); |
| final IDOMContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE |
| .getDOMContextResolver(context); |
| final Document document = resolver.getDOMDocument(); |
| Element rootElement = document.getDocumentElement(); |
| |
| if ("html".equals(rootElement.getNodeName())) |
| { |
| final Set<Attr> declaredNamespaces = ViewUtil |
| .getDeclaredNamespaces(rootElement.getAttributes()); |
| final ITagRegistry tagRegistry = ViewUtil |
| .getHtmlTagRegistry(project); |
| final Collection<? extends Namespace> namespaces; |
| if (tagRegistry != null) |
| { |
| namespaces = tagRegistry.getAllTagLibraries(); |
| } |
| else |
| { |
| // unexpected |
| namespaces = Collections.EMPTY_SET; |
| JSFCorePlugin.log(IStatus.ERROR, "Program Error: HTML tag registry not found"); //$NON-NLS-1$ |
| } |
| |
| for (final Attr attr : declaredNamespaces) |
| { |
| // only validate prefix declarations |
| if (attr.getPrefix() != null && attr instanceof IDOMAttr) |
| { |
| final String declaredUri = attr.getValue(); |
| String findUri = null; |
| SEARCH_NAMESPACES: for (final Namespace ns : namespaces) |
| { |
| if (ns.getNSUri().equals(declaredUri)) |
| { |
| findUri = ns.getNSUri(); |
| break SEARCH_NAMESPACES; |
| } |
| } |
| |
| if (findUri == null) |
| { |
| final Diagnostic diag = _diagnosticFactory.create_CANNOT_FIND_FACELET_TAGLIB(declaredUri); |
| final IDOMAttr domAttr = (IDOMAttr) attr; |
| reporter.report(diag, domAttr.getValueRegionStartOffset(), domAttr |
| .getValue().length()); |
| } |
| } |
| } |
| } |
| } |
| |
| private boolean shouldValidate(final IFile model) |
| { |
| final IContentTypeManager manager = Platform.getContentTypeManager(); |
| final IContentType contentType = manager |
| .getContentType("org.eclipse.wst.html.core.htmlsource"); |
| return (contentType.isAssociatedWith(model.getName())) |
| && ViewUtil.isFaceletVDLFile(model); |
| } |
| } |