Package org.eclipse.jst.jsp.ui.internal.validation

Source Code of org.eclipse.jst.jsp.ui.internal.validation.JSPContentSourceValidator

/*******************************************************************************
* Copyright (c) 2007 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
*******************************************************************************/
package org.eclipse.jst.jsp.ui.internal.validation;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jst.jsp.core.internal.contentproperties.JSPFContentProperties;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
import org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;
import org.eclipse.jst.jsp.ui.internal.Logger;
import org.eclipse.wst.html.core.internal.document.HTMLDocumentTypeConstants;
import org.eclipse.wst.html.core.internal.validate.HTMLValidationAdapterFactory;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.FileBufferModelManager;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
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.validate.ValidationAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.ProjectConfiguration;
import org.eclipse.wst.validation.internal.ValidationConfiguration;
import org.eclipse.wst.validation.internal.ValidationRegistryReader;
import org.eclipse.wst.validation.internal.core.Message;
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.xml.core.internal.document.DocumentTypeAdapter;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Text;

/**
* Source validator for JSP content. This validator currently only validates
* html content in jsp.
*/
public class JSPContentSourceValidator extends JSPContentValidator implements ISourceValidator {
  /*
   * Most of this class was copied from the ISourceValidator aspects of
   * html.ui's HTMLValidator
   */
  private IDocument fDocument;
  private boolean fEnableSourceValidation;
  private IContentType fJSPFContentType = null;

  public void connect(IDocument document) {
    fDocument = document;

    // special checks to see source validation should really execute
    IFile file = null;
    IStructuredModel model = null;
    try {
      model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
      if (model != null) {
        String baseLocation = model.getBaseLocation();
        // The baseLocation may be a path on disk or relative to the
        // workspace root. Don't translate on-disk paths to
        // in-workspace resources.
        IPath basePath = new Path(baseLocation);
        if (basePath.segmentCount() > 1) {
          file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
          /*
           * If the IFile doesn't exist, make sure it's not returned
           */
          if (!file.exists())
            file = null;
        }
      }
    }
    finally {
      if (model != null) {
        model.releaseFromRead();
      }
    }
    fEnableSourceValidation = (file != null && isBatchValidatorPreferenceEnabled(file) && shouldValidate(file) && fragmentCheck(file));
  }

  public void disconnect(IDocument document) {
    fDocument = null;
  }

  /**
   * This validate call is for the ISourceValidator partial document
   * validation approach
   *
   * @param dirtyRegion
   * @param helper
   * @param reporter
   * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
   */
  public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
    if (helper == null || fDocument == null || !fEnableSourceValidation)
      return;

    if ((reporter != null) && (reporter.isCancelled() == true)) {
      throw new OperationCanceledException();
    }

    IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
    if (model == null)
      return; // error

    try {

      IDOMDocument document = null;
      if (model instanceof IDOMModel) {
        document = ((IDOMModel) model).getDocument();
      }

      if (document == null || !hasHTMLFeature(document))
        return; // ignore

      ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument);
      if (fb == null)
        return;

      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fb.getLocation());
      if (file == null || !file.exists())
        return;

      // this will be the wrong region if it's Text (instead of Element)
      // we don't know how to validate Text
      IndexedRegion ir = getCoveringNode(dirtyRegion); // model.getIndexedRegion(dirtyRegion.getOffset());
      if (ir instanceof Text) {
        while (ir != null && ir instanceof Text) {
          // it's assumed that this gets the IndexedRegion to
          // the right of the end offset
          ir = model.getIndexedRegion(ir.getEndOffset());
        }
      }

      if (ir instanceof INodeNotifier) {

        INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
        ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir);
        if (adapter == null)
          return; // error

        if (reporter != null) {
          HTMLValidationReporter rep = null;
          rep = getReporter(reporter, file, (IDOMModel) model);
          rep.clear();
          adapter.setReporter(rep);

          Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, file.getFullPath().toString().substring(1));
          reporter.displaySubtask(this, mess);
        }
        adapter.validate(ir);
      }
    }
    finally {
      if (model != null)
        model.releaseFromRead();
    }
  }

  private IndexedRegion getCoveringNode(IRegion dirtyRegion) {

    IndexedRegion largestRegion = null;
    if (fDocument instanceof IStructuredDocument) {
      IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument).getStructuredDocumentRegions(dirtyRegion.getOffset(), dirtyRegion.getLength());
      largestRegion = getLargest(regions);
    }
    return largestRegion;
  }

  private IndexedRegion getLargest(IStructuredDocumentRegion[] sdRegions) {

    if (sdRegions == null || sdRegions.length == 0)
      return null;

    IndexedRegion currentLargest = getCorrespondingNode(sdRegions[0]);
    for (int i = 0; i < sdRegions.length; i++) {
      if (!sdRegions[i].isDeleted()) {
        IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);

        if (currentLargest instanceof Text)
          currentLargest = corresponding;

        if (corresponding != null) {
          if (!(corresponding instanceof Text)) {
            if (corresponding.getStartOffset() <= currentLargest.getStartOffset() && corresponding.getEndOffset() >= currentLargest.getEndOffset())
              currentLargest = corresponding;
          }
        }

      }
    }
    return currentLargest;
  }

  protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
    IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
    IndexedRegion indexedRegion = null;
    try {
      if (sModel != null)
        indexedRegion = sModel.getIndexedRegion(sdRegion.getStart());
    }
    finally {
      if (sModel != null)
        sModel.releaseFromRead();
    }
    return indexedRegion;
  }

  private boolean hasHTMLFeature(IDOMDocument document) {
    DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
    if (adapter == null)
      return false;
    return adapter.hasFeature(HTMLDocumentTypeConstants.HTML);
  }

  private HTMLValidationReporter getReporter(IReporter reporter, IFile file, IDOMModel model) {
    return new HTMLValidationReporter(this, reporter, file, model);
  }

  /**
   * Gets current validation configuration based on current project (which
   * is based on current document) or global configuration if project does
   * not override
   *
   * @return ValidationConfiguration
   */
  private ValidationConfiguration getValidationConfiguration(IFile file) {
    ValidationConfiguration configuration = null;
    if (file != null) {
      IProject project = file.getProject();
      if (project != null) {
        try {
          ProjectConfiguration projectConfiguration = ConfigurationManager.getManager().getProjectConfiguration(project);
          configuration = projectConfiguration;
          if (projectConfiguration == null || projectConfiguration.useGlobalPreference()) {
            configuration = ConfigurationManager.getManager().getGlobalConfiguration();
          }
        }
        catch (InvocationTargetException e) {
          Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
        }
      }
    }

    return configuration;
  }

  /**
   * Checks if validator is enabled according in Validation preferences
   *
   * @param vmd
   * @return
   */
  private boolean isBatchValidatorPreferenceEnabled(IFile file) {
    if (file == null) {
      return true;
    }

    boolean enabled = true;
    ValidationConfiguration configuration = getValidationConfiguration(file);
    if (configuration != null) {
      org.eclipse.wst.validation.internal.ValidatorMetaData metadata = ValidationRegistryReader.getReader().getValidatorMetaData(JSPContentValidator.class.getName());
      if (metadata != null) {
        if (!configuration.isBuildEnabled(metadata) && !configuration.isManualEnabled(metadata))
          enabled = false;
      }
    }
    return enabled;
  }

  /**
   * Checks if file is a jsp fragment or not. If so, check if the fragment
   * should be validated or not.
   *
   * @param file
   *            Assumes shouldValidate was already called on file so it
   *            should not be null and does exist
   * @return false if file is a fragment and it should not be validated,
   *         true otherwise
   */
  private boolean fragmentCheck(IFile file) {
    // copied from JSPValidator
    boolean shouldValidate = true;
    // quick check to see if this is possibly a jsp fragment
    if (getJSPFContentType().isAssociatedWith(file.getName())) {
      // get preference for validate jsp fragments
      boolean shouldValidateFragments = Boolean.valueOf(JSPFContentProperties.getProperty(JSPFContentProperties.VALIDATE_FRAGMENTS, file, true)).booleanValue();
      /*
       * if jsp fragments should not be validated, check if file is
       * really jsp fragment
       */
      if (!shouldValidateFragments) {
        boolean isFragment = isFragment(file);
        shouldValidate = !isFragment;
      }
    }
    return shouldValidate;
  }

  /**
   * Determines if file is jsp fragment or not (does a deep, indepth check,
   * looking into contents of file)
   *
   * @param file
   *            assumes file is not null and exists
   * @return true if file is jsp fragment, false otherwise
   */
  private boolean isFragment(IFile file) {
    // copied from JSPValidator
    boolean isFragment = false;
    InputStream is = null;
    try {
      IContentDescription contentDescription = file.getContentDescription();
      // it can be null
      if (contentDescription == null) {
        is = file.getContents();
        contentDescription = Platform.getContentTypeManager().getDescriptionFor(is, file.getName(), new QualifiedName[]{IContentDescription.CHARSET});
      }
      if (contentDescription != null) {
        String fileCtId = contentDescription.getContentType().getId();
        isFragment = (fileCtId != null && ContentTypeIdForJSP.ContentTypeID_JSPFRAGMENT.equals(fileCtId));
      }
    }
    catch (IOException e) {
      // ignore, assume it's invalid JSP
    }
    catch (CoreException e) {
      // ignore, assume it's invalid JSP
    }
    finally {
      // must close input stream in case others need it
      if (is != null)
        try {
          is.close();
        }
        catch (Exception e) {
          // not sure how to recover at this point
        }
    }
    return isFragment;
  }

  private boolean shouldValidate(IFile file) {
    // copied from JSPValidator
    IResource resource = file;
    do {
      if (resource.isDerived() || resource.isTeamPrivateMember() || !resource.isAccessible() || resource.getName().charAt(0) == '.') {
        return false;
      }
      resource = resource.getParent();
    }
    while ((resource.getType() & IResource.PROJECT) == 0);
    return true;
  }

  /**
   * Returns JSP fragment content type
   *
   * @return jspf content type
   */
  private IContentType getJSPFContentType() {
    // copied from JSPValidator
    if (fJSPFContentType == null) {
      fJSPFContentType = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSPFRAGMENT);
    }
    return fJSPFContentType;
  }
}
TOP

Related Classes of org.eclipse.jst.jsp.ui.internal.validation.JSPContentSourceValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.