/*******************************************************************************
 * Copyright (c) 2001, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.jst.jsp.core.internal.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsp.core.internal.JSPCoreMessages;
import org.eclipse.jst.jsp.core.internal.JSPCorePlugin;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.preferences.JSPCorePreferenceNames;
import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport;
import org.eclipse.jst.jsp.core.taglib.ITaglibRecord;
import org.eclipse.jst.jsp.core.taglib.TaglibIndex;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.html.core.internal.contentmodel.JSP20Namespace;
import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames;
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.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
import org.eclipse.wst.sse.core.utils.StringUtils;
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.IValidator;

import com.ibm.icu.text.Collator;

/**
 * Checks for: - duplicate taglib prefix values and reserved taglib prefix
 * values in the same file
 */
public class JSPDirectiveValidator extends JSPValidator {
	private static Collator collator = Collator.getInstance(Locale.US);

	private static final boolean DEBUG = Boolean.valueOf(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspvalidator")).booleanValue(); //$NON-NLS-1$

	private IValidator fMessageOriginator;
	private IEclipsePreferences fPreferences = null;

	private IPreferencesService fPreferencesService = null;
	private HashMap fPrefixValueRegionToDocumentRegionMap = new HashMap();
	private IJavaProject fProject = null;
	private HashMap fReservedPrefixes = new HashMap();
	private IScopeContext[] fScopes = null;
	private int fSeverityIncludeFileMissing = -1;
	private int fSeverityIncludeFileNotSpecified = -1;
	private int fSeveritySuperClassNotFound = -1;
	private int fSeverityTagdirUnresolvableURI = -1;
	private int fSeverityTaglibDuplicatePrefixWithDifferentURIs = -1;

	private int fSeverityTaglibDuplicatePrefixWithSameURIs = -1;
	private int fSeverityTaglibMissingPrefix = -1;

	private int fSeverityTaglibMissingURI = -1;


	private int fSeverityTaglibUnresolvableURI = -1;

	private HashMap fTaglibPrefixesInUse = new HashMap();

	public JSPDirectiveValidator() {
		initReservedPrefixes();
		fMessageOriginator = this;
	}

	public JSPDirectiveValidator(IValidator validator) {
		initReservedPrefixes();
		this.fMessageOriginator = validator;
	}

	public void cleanup(IReporter reporter) {
		super.cleanup(reporter);
		fTaglibPrefixesInUse.clear();
		fPrefixValueRegionToDocumentRegionMap.clear();
	}

	private void collectTaglibPrefix(IStructuredDocumentRegion documentRegion, ITextRegion valueRegion, String taglibPrefix) {
		fPrefixValueRegionToDocumentRegionMap.put(valueRegion, documentRegion);

		Object o = fTaglibPrefixesInUse.get(taglibPrefix);
		if (o == null) {
			// prefix doesn't exist, remember it
			fTaglibPrefixesInUse.put(taglibPrefix, valueRegion);
		}
		else {
			List regionList = null;
			// already a List
			if (o instanceof List) {
				regionList = (List) o;
			}
			/*
			 * a single value region, create a new List and add previous
			 * valueRegion
			 */
			else {
				regionList = new ArrayList();
				regionList.add(o);
				fTaglibPrefixesInUse.put(taglibPrefix, regionList);
			}
			regionList.add(valueRegion);
		}
	}

	int getMessageSeverity(String key) {
		int sev = fPreferencesService.getInt(JSPCorePlugin.getDefault().getBundle().getSymbolicName(), key, IMessage.NORMAL_SEVERITY, fScopes);
		switch (sev) {
			case ValidationMessage.ERROR :
				return IMessage.HIGH_SEVERITY;
			case ValidationMessage.WARNING :
				return IMessage.NORMAL_SEVERITY;
			case ValidationMessage.INFORMATION :
				return IMessage.LOW_SEVERITY;
			case ValidationMessage.IGNORE :
				return ValidationMessage.IGNORE;
		}
		return IMessage.NORMAL_SEVERITY;
	}
	private void initReservedPrefixes() {
		fReservedPrefixes.put("jsp", ""); //$NON-NLS-1$ //$NON-NLS-2$
		fReservedPrefixes.put("jspx", ""); //$NON-NLS-1$ //$NON-NLS-2$
		fReservedPrefixes.put("java", ""); //$NON-NLS-1$ //$NON-NLS-2$
		fReservedPrefixes.put("javax", ""); //$NON-NLS-1$ //$NON-NLS-2$ 
		fReservedPrefixes.put("servlet", ""); //$NON-NLS-1$ //$NON-NLS-2$ 
		fReservedPrefixes.put("sun", ""); //$NON-NLS-1$ //$NON-NLS-2$ 
		fReservedPrefixes.put("sunw", ""); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	private boolean isReservedTaglibPrefix(String name) {
		return fReservedPrefixes.get(name) != null;
	}
	
	private void loadPreferences(IFile file) {
		String bundleName = JSPCorePlugin.getDefault().getBundle().getSymbolicName();
		fPreferencesService = Platform.getPreferencesService();
		if (file != null && file.isAccessible()) {
			ProjectScope projectScope = new ProjectScope(file.getProject());
			if (projectScope.getNode(bundleName).getBoolean(JSPCorePreferenceNames.USE_PROJECT_SETTINGS, false)) {
				fScopes = new IScopeContext[]{projectScope, new InstanceScope(), new DefaultScope()};
			}
		}
		fScopes = new IScopeContext[]{new InstanceScope(), new DefaultScope()};

		fSeverityIncludeFileMissing = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_INCLUDE_FILE_NOT_FOUND);
		fSeverityIncludeFileNotSpecified = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_INCLUDE_NO_FILE_SPECIFIED);
		fSeverityTaglibDuplicatePrefixWithDifferentURIs = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_DIFFERENT_URIS);
		fSeverityTaglibDuplicatePrefixWithSameURIs = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_SAME_URIS);
		fSeverityTaglibMissingPrefix = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_MISSING_PREFIX);
		fSeverityTaglibMissingURI = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_MISSING_URI_OR_TAGDIR);
		fSeverityTaglibUnresolvableURI = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_UNRESOLVABLE_URI_OR_TAGDIR);
		fSeverityTagdirUnresolvableURI = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_UNRESOLVABLE_URI_OR_TAGDIR);
		fSeveritySuperClassNotFound = getMessageSeverity(JSPCorePreferenceNames.VALIDATION_DIRECTIVE_PAGE_SUPERCLASS_NOT_FOUND);

	}
	
	protected void performValidation(IFile f, IReporter reporter, IStructuredDocument sDoc) {
		loadPreferences(f);
		
		
		setProject(f.getProject());
		/*
		 * when validating an entire file need to clear dupes or else you're
		 * comparing between files
		 */
		fPrefixValueRegionToDocumentRegionMap.clear();
		fTaglibPrefixesInUse.clear();

		// iterate all document regions
		IStructuredDocumentRegion region = sDoc.getFirstStructuredDocumentRegion();
		while (region != null && !reporter.isCancelled()) {
			// only checking directives
			if (region.getType() == DOMJSPRegionContexts.JSP_DIRECTIVE_NAME) {
				processDirective(reporter, f, sDoc, region);
			}
			region = region.getNext();
		}

		if (!reporter.isCancelled()) {
			reportTaglibDuplicatePrefixes(f, reporter, sDoc);
		}

		fPrefixValueRegionToDocumentRegionMap.clear();
		fTaglibPrefixesInUse.clear();
		setProject(null);
		unloadPreferences();
	}

	private void processDirective(IReporter reporter, IFile file, IStructuredDocument sDoc, IStructuredDocumentRegion documentRegion) {
		String directiveName = getDirectiveName(documentRegion);
		// we only care about taglib directive
		if (directiveName.equals("taglib")) { //$NON-NLS-1$
			processTaglibDirective(reporter, file, sDoc, documentRegion);
		}
		else if (directiveName.equals("include")) { //$NON-NLS-1$
			processIncludeDirective(reporter, file, sDoc, documentRegion);
		}
		else if (directiveName.equals("page")) { //$NON-NLS-1$
			processPageDirective(reporter, file, sDoc, documentRegion);
		}
	}

	private void processIncludeDirective(IReporter reporter, IFile file, IStructuredDocument sDoc, IStructuredDocumentRegion documentRegion) {
		ITextRegion fileValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_FILE);
		if (fileValueRegion != null) {
			// file specified
			String fileValue = documentRegion.getText(fileValueRegion);
			fileValue = StringUtils.stripQuotes(fileValue);

			if (fileValue.length() == 0 && fSeverityIncludeFileNotSpecified != ValidationMessage.IGNORE) {
				// file value is specified but empty
				String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP11Namespace.ATTR_NAME_FILE);
				LocalizedMessage message = new LocalizedMessage(fSeverityIncludeFileNotSpecified, msgText, file);
				int start = documentRegion.getStartOffset(fileValueRegion);
				int length = fileValueRegion.getTextLength();
				int lineNo = sDoc.getLineOfOffset(start);
				message.setLineNo(lineNo);
				message.setOffset(start);
				message.setLength(length);

				reporter.addMessage(fMessageOriginator, message);
			}
			else if (fSeverityIncludeFileMissing != ValidationMessage.IGNORE) {
				IPath testPath = FacetModuleCoreSupport.resolve(file.getFullPath(), fileValue);
				if (testPath.segmentCount() > 1) {
					IFile testFile = file.getWorkspace().getRoot().getFile(testPath);
					if (!testFile.isAccessible()) {
						// File not found
						String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_4, new String[]{fileValue, testPath.toString()});
						LocalizedMessage message = new LocalizedMessage(fSeverityIncludeFileMissing, msgText, file);
						int start = documentRegion.getStartOffset(fileValueRegion);
						int length = fileValueRegion.getTextLength();
						int lineNo = sDoc.getLineOfOffset(start);
						message.setLineNo(lineNo);
						message.setOffset(start);
						message.setLength(length);

						reporter.addMessage(fMessageOriginator, message);
					}
				}
			}
		}
		else if (fSeverityIncludeFileNotSpecified != ValidationMessage.IGNORE) {
			// file is not specified at all
			String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP11Namespace.ATTR_NAME_FILE);
			LocalizedMessage message = new LocalizedMessage(fSeverityIncludeFileNotSpecified, msgText, file);
			int start = documentRegion.getStartOffset();
			int length = documentRegion.getTextLength();
			int lineNo = sDoc.getLineOfOffset(start);
			message.setLineNo(lineNo);
			message.setOffset(start);
			message.setLength(length);

			reporter.addMessage(fMessageOriginator, message);
		}
	}

	/**
	 * @param reporter
	 * @param file
	 * @param doc
	 * @param documentRegion
	 */
	private void processPageDirective(IReporter reporter, IFile file, IStructuredDocument doc, IStructuredDocumentRegion documentRegion) {
		ITextRegion superclassValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_EXTENDS);
		if (superclassValueRegion != null) {
			// file specified
			String superclassName = documentRegion.getText(superclassValueRegion);
			superclassName = StringUtils.stripQuotes(superclassName);

			IType superClass = null;
			if (superclassName != null && superclassName.length() > 0 && fProject != null && fProject.exists()) {
				try {
					superClass = fProject.findType(superclassName.trim(), new NullProgressMonitor());
				}
				catch (JavaModelException e) {
					Logger.logException(e);
				}
			}

			if (superClass == null && fSeveritySuperClassNotFound != ValidationMessage.IGNORE) {
				// file value is specified but empty
				String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_8, superclassName);
				LocalizedMessage message = new LocalizedMessage(fSeveritySuperClassNotFound, msgText, file);
				int start = documentRegion.getStartOffset(superclassValueRegion);
				int length = superclassValueRegion.getTextLength();
				int lineNo = doc.getLineOfOffset(start);
				message.setLineNo(lineNo);
				message.setOffset(start);
				message.setLength(length);

				reporter.addMessage(fMessageOriginator, message);
			}
		}
	}

	private void processTaglibDirective(IReporter reporter, IFile file, IStructuredDocument sDoc, IStructuredDocumentRegion documentRegion) {
		ITextRegion prefixValueRegion = null;
		ITextRegion uriValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_URI);
		ITextRegion tagdirValueRegion = getAttributeValueRegion(documentRegion, JSP20Namespace.ATTR_NAME_TAGDIR);
		if (uriValueRegion != null) {
			// URI is specified
			String uri = documentRegion.getText(uriValueRegion);

			if (file != null) {
				uri = StringUtils.stripQuotes(uri);
				if (uri.length() > 0) {
					ITaglibRecord tld = TaglibIndex.resolve(file.getFullPath().toString(), uri, false);
					if (tld == null && fSeverityTaglibUnresolvableURI != ValidationMessage.IGNORE) {
						// URI specified but does not resolve
						String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_1, uri);
						LocalizedMessage message = new LocalizedMessage(fSeverityTaglibUnresolvableURI, msgText, file);
						int start = documentRegion.getStartOffset(uriValueRegion);
						int length = uriValueRegion.getTextLength();
						int lineNo = sDoc.getLineOfOffset(start);
						message.setLineNo(lineNo);
						message.setOffset(start);
						message.setLength(length);

						message.setAttribute("PROBLEM_ID", new Integer(611));

						reporter.addMessage(fMessageOriginator, message);
					}
				}
				else if (fSeverityTaglibMissingURI != ValidationMessage.IGNORE) {
					// URI specified but empty string
					String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP11Namespace.ATTR_NAME_URI);
					LocalizedMessage message = new LocalizedMessage(fSeverityTaglibMissingURI, msgText, file);
					int start = documentRegion.getStartOffset(uriValueRegion);
					int length = uriValueRegion.getTextLength();
					int lineNo = sDoc.getLineOfOffset(start);
					message.setLineNo(lineNo);
					message.setOffset(start);
					message.setLength(length);

					reporter.addMessage(fMessageOriginator, message);
				}
			}
		}
		else if (tagdirValueRegion != null) {
			// URI is specified
			String tagdir = documentRegion.getText(tagdirValueRegion);

			if (file != null) {
				tagdir = StringUtils.stripQuotes(tagdir);
				if (tagdir.length() <= 0 && fSeverityTaglibMissingURI != ValidationMessage.IGNORE) {
					// tagdir specified but empty string
					String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP20Namespace.ATTR_NAME_TAGDIR);
					LocalizedMessage message = new LocalizedMessage(fSeverityTaglibMissingURI, msgText, file);
					int start = documentRegion.getStartOffset(tagdirValueRegion);
					int length = tagdirValueRegion.getTextLength();
					int lineNo = sDoc.getLineOfOffset(start);
					message.setLineNo(lineNo);
					message.setOffset(start);
					message.setLength(length);

					reporter.addMessage(fMessageOriginator, message);
				}
				else if (TaglibIndex.resolve(file.getFullPath().toString(), tagdir, false) == null && fSeverityTagdirUnresolvableURI != ValidationMessage.IGNORE) {
					// URI specified but does not resolve
					String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_1, tagdir);
					LocalizedMessage message = new LocalizedMessage(fSeverityTaglibUnresolvableURI, msgText, file);
					int start = documentRegion.getStartOffset(tagdirValueRegion);
					int length = tagdirValueRegion.getTextLength();
					int lineNo = sDoc.getLineOfOffset(start);
					message.setLineNo(lineNo);
					message.setOffset(start);
					message.setLength(length);

					reporter.addMessage(fMessageOriginator, message);
				}
			}
		}
		else if (fSeverityTaglibMissingURI != ValidationMessage.IGNORE) {
			// URI not specified or empty string
			String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_7, new String[]{JSP20Namespace.ATTR_NAME_TAGDIR, JSP11Namespace.ATTR_NAME_URI});
			LocalizedMessage message = new LocalizedMessage(fSeverityTaglibMissingURI, msgText, file);
			int start = documentRegion.getStartOffset();
			int length = documentRegion.getTextLength();
			int lineNo = sDoc.getLineOfOffset(start);
			message.setLineNo(lineNo);
			message.setOffset(start);
			message.setLength(length);

			reporter.addMessage(fMessageOriginator, message);
		}

		prefixValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_PREFIX);
		if (prefixValueRegion != null) {
			// prefix specified
			String taglibPrefix = documentRegion.getText(prefixValueRegion);
			taglibPrefix = StringUtils.stripQuotes(taglibPrefix);

			collectTaglibPrefix(documentRegion, prefixValueRegion, taglibPrefix);

			if (isReservedTaglibPrefix(taglibPrefix)) {
				// prefix is a reserved prefix
				String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_0, taglibPrefix);
				int sev = IMessage.HIGH_SEVERITY;
				LocalizedMessage message = (file == null ? new LocalizedMessage(sev, msgText) : new LocalizedMessage(sev, msgText, file));
				int start = documentRegion.getStartOffset(prefixValueRegion);
				int length = prefixValueRegion.getTextLength();
				int lineNo = sDoc.getLineOfOffset(start);
				message.setLineNo(lineNo);
				message.setOffset(start);
				message.setLength(length);

				reporter.addMessage(fMessageOriginator, message);
			}
			if (taglibPrefix.length() == 0 && fSeverityTaglibMissingPrefix != ValidationMessage.IGNORE) {
				// prefix is specified but empty
				String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP11Namespace.ATTR_NAME_PREFIX);
				LocalizedMessage message = new LocalizedMessage(fSeverityTaglibMissingPrefix, msgText, file);
				int start = documentRegion.getStartOffset(prefixValueRegion);
				int length = prefixValueRegion.getTextLength();
				int lineNo = sDoc.getLineOfOffset(start);
				message.setLineNo(lineNo);
				message.setOffset(start);
				message.setLength(length);

				reporter.addMessage(fMessageOriginator, message);
			}
		}
		else if (fSeverityTaglibMissingPrefix != ValidationMessage.IGNORE) {
			// prefix is not specified
			String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_3, JSP11Namespace.ATTR_NAME_PREFIX);
			LocalizedMessage message = new LocalizedMessage(fSeverityTaglibMissingPrefix, msgText, file);
			int start = documentRegion.getStartOffset();
			int length = documentRegion.getTextLength();
			int lineNo = sDoc.getLineOfOffset(start);
			message.setLineNo(lineNo);
			message.setOffset(start);
			message.setLength(length);

			reporter.addMessage(fMessageOriginator, message);
		}
	}

	private void reportTaglibDuplicatePrefixes(IFile file, IReporter reporter, IStructuredDocument document) {
		if (fSeverityTaglibDuplicatePrefixWithDifferentURIs == ValidationMessage.IGNORE && fSeverityTaglibDuplicatePrefixWithSameURIs == ValidationMessage.IGNORE)
			return;

		String[] prefixes = (String[]) fTaglibPrefixesInUse.keySet().toArray(new String[0]);
		for (int prefixNumber = 0; prefixNumber < prefixes.length; prefixNumber++) {
			int severity = fSeverityTaglibDuplicatePrefixWithSameURIs;

			Object o = fTaglibPrefixesInUse.get(prefixes[prefixNumber]);
			/*
			 * Only care if it's a List (because there was more than one
			 * directive with that prefix) and if we're supposed to report
			 * duplicates
			 */
			if (o instanceof List) {
				List valueRegions = (List) o;
				String uri = null;
				for (int regionNumber = 0; regionNumber < valueRegions.size(); regionNumber++) {
					IStructuredDocumentRegion documentRegion = (IStructuredDocumentRegion) fPrefixValueRegionToDocumentRegionMap.get(valueRegions.get(regionNumber));
					ITextRegion uriValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_URI);
					if (uriValueRegion == null) {
						uriValueRegion = getAttributeValueRegion(documentRegion, JSP20Namespace.ATTR_NAME_TAGDIR);
					}
					if (uriValueRegion != null) {
						String uri2 = StringUtils.stripQuotes(documentRegion.getText(uriValueRegion));
						if (uri == null) {
							uri = uri2;
						}
						else {
							if (collator.compare(uri, uri2) != 0) {
								severity = fSeverityTaglibDuplicatePrefixWithDifferentURIs;
							}
						}
					}
				}

				String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_2, prefixes[prefixNumber]); //$NON-NLS-2$ //$NON-NLS-1$

				// Report an error in all directives using this prefix
				for (int regionNumber = 0; regionNumber < valueRegions.size(); regionNumber++) {

					ITextRegion valueRegion = (ITextRegion) valueRegions.get(regionNumber);
					IStructuredDocumentRegion documentRegion = (IStructuredDocumentRegion) fPrefixValueRegionToDocumentRegionMap.get(valueRegion);
					LocalizedMessage message = (file == null ? new LocalizedMessage(severity, msgText) : new LocalizedMessage(severity, msgText, file));

					// if there's a message, there was an error found
					int start = documentRegion.getStartOffset(valueRegion);
					int length = valueRegion.getTextLength();
					int lineNo = document.getLineOfOffset(start);
					message.setLineNo(lineNo);
					message.setOffset(start);
					message.setLength(length);

					reporter.addMessage(fMessageOriginator, message);
				}
			}
		}
	}

	/**
	 * @param project
	 */
	private void setProject(IProject project) {
		boolean useProject = false;
		if (project != null) {
			fProject = JavaCore.create(project);
			fPreferences = new ProjectScope(fProject.getProject()).getNode(JSPCorePlugin.getDefault().getBundle().getSymbolicName());
			useProject = fPreferences.getBoolean(HTMLCorePreferenceNames.USE_PROJECT_SETTINGS, false);
		}
		else {
			fProject = null;
		}

		if (!useProject) {
			fPreferences = new InstanceScope().getNode(JSPCorePlugin.getDefault().getBundle().getSymbolicName());
		}
	}

	private void unloadPreferences() {
		fPreferencesService = null;
		fScopes = null;
	}

	/**
	 * batch validation call
	 */
	protected void validateFile(IFile f, IReporter reporter) {
		if (DEBUG) {
			Logger.log(Logger.INFO, getClass().getName() + " validating: " + f); //$NON-NLS-1$
		}

		IStructuredModel sModel = null;
		try {
			sModel = StructuredModelManager.getModelManager().getModelForRead(f);
			if (sModel != null && !reporter.isCancelled()) {
				performValidation(f, reporter, sModel.getStructuredDocument());
			}
		}
		catch (Exception e) {
			Logger.logException(e);
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
	}
}
