Bug 398252 [facelets] Validator is not fully overridable
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.properties b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.properties index 21fb12e..6f38f09 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.properties +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.properties
@@ -2,4 +2,5 @@ EL_Hyperlinkdetector_name=Facelet EL Hyperlink Detector FaceletValidatorMarker=Facelet Validator Bundle-Name.0 = UI Plug-in -Bundle-Vendor.0 = Eclipse.org \ No newline at end of file +Bundle-Vendor.0 = Eclipse.org +extension-point.name = Facelet Validation Override Extension \ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml index 17c268d..05c6432 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml
@@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.2"?> <plugin> + <extension-point id="faceletValidator" name="%extension-point.name" schema="schema/faceletValidator.exsd"/> <extension point="org.eclipse.wst.sse.ui.editorConfiguration"> <sourceViewerConfiguration @@ -85,6 +86,14 @@ <facet id="jst.jsf" version="2.0"> </facet> + <facet + id="jst.jsf" + version="2.1"> + </facet> + <facet + id="jst.jsf" + version="2.2"> + </facet> </rules> </include> <include> @@ -144,4 +153,11 @@ contentType="org.eclipse.wst.html.core.htmlsource"> </modelQueryExtension> </extension> + <extension + point="org.eclipse.jst.jsf.facelet.ui.faceletValidator"> + <validationStrategy + class="org.eclipse.jst.jsf.facelet.ui.internal.validation.DefaultFaceletValidationStrategy" + id="org.eclipse.jst.jsf.facelet.ui.defaultValidationStrategy"> + </validationStrategy> + </extension> </plugin>
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/schema/faceletValidator.exsd b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/schema/faceletValidator.exsd new file mode 100644 index 0000000..70b36f1 --- /dev/null +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/schema/faceletValidator.exsd
@@ -0,0 +1,109 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.eclipse.jst.jsf.facelet.ui" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="org.eclipse.jst.jsf.facelet.ui" id="faceletValidator" name="faceletValidator"/> + </appInfo> + <documentation> + Optional extension to allow third-parties to replace the default facelet validator with their own. + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="validationStrategy"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="validationStrategy"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="org.eclipse.jst.jsf.facelet.ui.internal.validation.AbstractFaceletValidationStrategy:"/> + </appInfo> + </annotation> + </attribute> + <attribute name="id" type="string" use="default" value="Enter default value"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + Internal Provisional. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema>
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/FaceletUiPlugin.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/FaceletUiPlugin.java index 15ed671..99b3386 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/FaceletUiPlugin.java +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/FaceletUiPlugin.java
@@ -1,8 +1,13 @@ package org.eclipse.jst.jsf.facelet.ui.internal; +import java.util.Map; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.jst.jsf.designtime.internal.BasicExtensionFactory; +import org.eclipse.jst.jsf.designtime.internal.BasicExtensionFactory.ExtensionData; import org.eclipse.jst.jsf.designtime.internal.view.model.TagRegistryFactory.TagRegistryFactoryException; +import org.eclipse.jst.jsf.facelet.ui.internal.validation.AbstractFaceletValidationStrategy; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -20,6 +25,9 @@ // The shared instance private static FaceletUiPlugin plugin; + private final Object extensionLock = new Object(); + private BasicExtensionFactory<AbstractFaceletValidationStrategy> faceletValidationStrategyExtension; + /* * (non-Javadoc) * @@ -66,4 +74,15 @@ getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "", e)); } + + public Map<String, ExtensionData<AbstractFaceletValidationStrategy>> getValidationStrategy() + { + synchronized (this.extensionLock) { + if (this.faceletValidationStrategyExtension == null) + { + this.faceletValidationStrategyExtension = new BasicExtensionFactory<AbstractFaceletValidationStrategy>(this.getBundle(), "faceletValidator", "validationStrategy", false); + } + return this.faceletValidationStrategyExtension.getExtensions(); + } + } }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/AbstractFaceletValidationStrategy.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/AbstractFaceletValidationStrategy.java new file mode 100644 index 0000000..1a6253a --- /dev/null +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/AbstractFaceletValidationStrategy.java
@@ -0,0 +1,134 @@ +package org.eclipse.jst.jsf.facelet.ui.internal.validation; + +import java.io.IOException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.core.runtime.content.IContentTypeManager; +import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; +import org.eclipse.jst.jsf.facelet.core.internal.util.ViewUtil; +import org.eclipse.jst.jsf.validation.internal.IJSFViewValidator; +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.validation.internal.provisional.core.IReporter; +import org.eclipse.wst.validation.internal.provisional.core.IValidator; + + +/** + * Strategy that is delegated to from HTMLValidator to do the validation. Allows third-parties to enhance + * or replace the existing strategy. + * + */ +public abstract class AbstractFaceletValidationStrategy { + + /** + * return from getPriority to indicate no priority preference. If any other strategy returns a value higher, then + * a validator returning a smaller value including 0 will be ignored. If all return DONT_CARE then they will + * all be called. + */ + public static final int DONT_CARE = 0; + + /** + * The factory for diagnostics. + */ + protected final FaceletDiagnosticFactory _diagnosticFactory = new FaceletDiagnosticFactory(); + + /** + * If not overriden, returns DONT_CARE. + * + * @return a value indicating the override priority for this strategy. If more than one validation strategy + * exists, then *only* the one that returns the highest positive value will be used. If a strategy returns 0, then + * it is signallying that it does not care. If no strategy returns a value greater than 0, then all strategies will + * be called. Negative values are currently reserved and strategies returning negative values will be treated as though + * they returned 0. + */ + public int getPriority() + { + return DONT_CARE; + } + +// /** +// * @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; +// +// } + + /** + * @param file + * @param reporter + * @param caller + */ + public final void validateFile(final IFile file, final IReporter reporter, final IValidator caller) + { + final ValidationPreferences prefs = new ValidationPreferences( + JSFCorePlugin.getDefault().getPreferenceStore()); + prefs.load(); + + IStructuredModel model = null; + try + { + model = StructuredModelManager.getModelManager().getModelForRead( + file); + + final ValidationReporter jsfReporter = new ValidationReporter(caller, + reporter, file, prefs, model); + doValidate(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(); + } + } + } + + /** + * @param file + * @param jsfReporter + */ + protected abstract void doValidate(final IFile file, IJSFViewValidator.IValidationReporter jsfReporter); + + + /** + * @param model + * @return true validation should be executed against model + */ + public 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); + } +}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/DefaultFaceletValidationStrategy.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/DefaultFaceletValidationStrategy.java new file mode 100644 index 0000000..2ff8549 --- /dev/null +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/DefaultFaceletValidationStrategy.java
@@ -0,0 +1,154 @@ +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.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +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.validation.internal.IJSFViewValidator; +import org.eclipse.jst.jsf.validation.internal.JSFValidatorFactory; +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.xml.core.internal.provisional.document.IDOMAttr; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * The default validation strategy. + * + */ +public class DefaultFaceletValidationStrategy extends AbstractFaceletValidationStrategy { + + @Override + protected void doValidate(final IFile file, final IJSFViewValidator.IValidationReporter jsfReporter) { + final IJSFViewValidator validator = JSFValidatorFactory + .createDefaultXMLValidator(); + + validator.validateView(file, jsfReporter); + validateFaceletHtml(file, jsfReporter); + + } + + /** + * @param file + * @param reporter + */ + protected void validateFaceletHtml(final IFile file, + final IJSFViewValidator.IValidationReporter 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(); + } + } + } + + /** + * @param structuredDoc + * @param reporter + * @param project + */ + protected void validateDocument(IStructuredDocument structuredDoc, + final IJSFViewValidator.IValidationReporter reporter, IProject project) + { + validateRoot(structuredDoc, reporter, project); + } + + /** + * @param structuredDoc + * @param reporter + * @param project + */ + protected void validateRoot(IStructuredDocument structuredDoc, + final IJSFViewValidator.IValidationReporter 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()); + } + } + } + } + } + +}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/HTMLValidator.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/HTMLValidator.java index b3df148..d20d718 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/HTMLValidator.java +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/validation/HTMLValidator.java
@@ -1,41 +1,19 @@ 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 java.util.ArrayList; +import java.util.List; +import java.util.Map; 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.designtime.internal.BasicExtensionFactory.ExtensionData; 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; @@ -45,236 +23,93 @@ 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(); +public class HTMLValidator extends AbstractValidator implements IValidator { /** * @param helper * @return no rule, null */ - public ISchedulingRule getSchedulingRule(final IValidationContext helper) - { + 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) - { + 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)); + public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) { + final ValidationResult vr = new ValidationResult(); + if (resource == null || !(resource instanceof IFile)) { + return vr; } - return vr; - } + IFile currentFile = (IFile) resource; + List<AbstractFaceletValidationStrategy> validationStrategies = getStrategies(currentFile.getProject()); + for (AbstractFaceletValidationStrategy strategy : validationStrategies) { + if (strategy.shouldValidate(currentFile)) { + strategy.validateFile(currentFile, vr.getReporter(monitor), this); + } + } + return vr; + } - public void validate(final IValidationContext helper, - final IReporter reporter) throws ValidationException - { + 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) - { + if (uris.length > 0) { IFile currentFile = null; - for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) - { + 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); + if (currentFile != null && currentFile.exists()) { + List<AbstractFaceletValidationStrategy> validationStrategies = getStrategies(currentFile + .getProject()); + for (AbstractFaceletValidationStrategy strategy : validationStrategies) { + if (strategy.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; + strategy.validateFile(currentFile, reporter, this); } } - - 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); + + private List<AbstractFaceletValidationStrategy> getStrategies(final IProject project) { + Map<String, ExtensionData<AbstractFaceletValidationStrategy>> possibleStrategies = FaceletUiPlugin.getDefault() + .getValidationStrategy(); + List<AbstractFaceletValidationStrategy> strategies = new ArrayList<AbstractFaceletValidationStrategy>( + possibleStrategies.size()); + int maxPriority = 0; + for (final Map.Entry<String, ExtensionData<AbstractFaceletValidationStrategy>> entry : possibleStrategies + .entrySet()) { + AbstractFaceletValidationStrategy instance = entry.getValue().getInstance(project); + if (instance != null) { + + int priority = instance.getPriority(); + if (priority > maxPriority) { + strategies.clear(); + maxPriority = priority; + strategies.add(instance); + } + + if (priority == maxPriority) { + strategies.add(instance); + } + } + } + return strategies; } + }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/templates/templates.properties b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/templates/templates.properties index 1b2b72b..397cad2 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/templates/templates.properties +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/templates/templates.properties
@@ -11,5 +11,5 @@ New_Simple_Facelet_Composition_Page_Description=Creates a new Facelet page for use with a template. New_Facelet_Header.header=<?xml version="1.0" encoding="ISO-8859-1" ?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml">\n<body>\n<div style="width:100%;font-size:36px;line-height:48px;background-color:navy;color:white">My Facelet Application</div>\n</body>\n</html>\n New_Facelet_Footer.footer=<?xml version="1.0" encoding="ISO-8859-1" ?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />\n<title>Insert title here</title>\n</head>\n<body>\n<div style="background-color:navy;width:100%;color:white"></div>\n</body>\n</html>\n -New_Facelet_Template.template=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml"\n xmlns:ui="http://java.sun.com/jsf/facelets">\n<head>\n <title><ui:insert name="title">Default title</ui:insert></title>\n</head>\n\n<body>\n\n<div id="header">\n <ui:insert name="header">\n Header area. See comments below this line in the source.\n <!-- include your header file or uncomment the include below and create header.xhtml in this directory -->\n <!-- <ui:include src="header.xhtml"/> -->\n </ui:insert>\n</div>\n\n\n<div id="content">\n <ui:insert name="content">\n Content area. See comments below this line in the source.\n <!-- include your content file or uncomment the include below and create content.xhtml in this directory -->\n <!-- <div> -->\n <!-- <ui:include src="content.xhtml"/> --> \n <!-- </div> -->\n </ui:insert>\n</div>\n\n<div id="footer">\n <ui:insert name="footer">\n Footer area. See comments below this line in the source.\n <!-- include your header file or uncomment the include below and create footer.xhtml in this directory -->\n <!--<ui:include src="footer.xhtml"/> -->\n </ui:insert>\n</div>\n\n</body>\n\n</html>\n +New_Facelet_Template.template=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml"\n xmlns:ui="http://java.sun.com/jsf/facelets">\n<head>\n <title><ui:insert name="title">Default title</ui:insert></title>\n</head>\n\n<body>\n<ui:debug hotkey="x" rendered="#{initParam['javax.faces.FACELETS_DEVELOPMENT']}"/>\n\n<div id="header">\n <ui:insert name="header">\n Header area. See comments below this line in the source.\n <!-- include your header file or uncomment the include below and create header.xhtml in this directory -->\n <!-- <ui:include src="header.xhtml"/> -->\n </ui:insert>\n</div>\n\n\n<div id="content">\n <ui:insert name="content">\n Content area. See comments below this line in the source.\n <!-- include your content file or uncomment the include below and create content.xhtml in this directory -->\n <!-- <div> -->\n <!-- <ui:include src="content.xhtml"/> --> \n <!-- </div> -->\n </ui:insert>\n</div>\n\n<div id="footer">\n <ui:insert name="footer">\n Footer area. See comments below this line in the source.\n <!-- include your header file or uncomment the include below and create footer.xhtml in this directory -->\n <!--<ui:include src="footer.xhtml"/> -->\n </ui:insert>\n</div>\n\n</body>\n\n</html>\n New_Simple_Facelet_Composition_Page.composition=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n<html xmlns="http://www.w3.org/1999/xhtml"\n xmlns:ui="http://java.sun.com/jsf/facelets"\n xmlns:h="http://java.sun.com/jsf/html"\n xmlns:f="http://java.sun.com/jsf/core">\n\n<ui:composition template="">\n <ui:define name="header">\n Add your header here or delete to use the default\n </ui:define>\n <ui:define name="content">\n Add your content here or delete to use the default\n </ui:define>\n <ui:define name="footer">\n Add your footer here or delete to use the default\n </ui:define>\n</ui:composition>\n</html>