Package org.eclipse.php.internal.ui.editor.validation

Source Code of org.eclipse.php.internal.ui.editor.validation.PhpReconcilingStrategy

/*******************************************************************************
* Copyright (c) 2009 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
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.ui.editor.validation;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.ui.text.IProblemRequestorExtension;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.php.internal.core.PHPCorePlugin;
import org.eclipse.php.internal.core.PHPVersion;
import org.eclipse.php.internal.core.ast.nodes.ASTParser;
import org.eclipse.php.internal.core.ast.nodes.Program;
import org.eclipse.php.internal.core.ast.util.Util;
import org.eclipse.php.internal.core.project.ProjectOptions;
import org.eclipse.php.internal.ui.PHPUiPlugin;
import org.eclipse.php.internal.ui.editor.ASTProvider;
import org.eclipse.php.internal.ui.editor.IPhpScriptReconcilingListener;
import org.eclipse.php.internal.ui.editor.PHPStructuredEditor;
import org.eclipse.php.ui.editor.SharedASTProvider;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
import org.eclipse.wst.validation.internal.core.ValidationException;
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.IDOMModel;

/**
* "As You Type" validation for PHP content This class reconciles php content to
* the DLTK model
*/
public class PhpReconcilingStrategy implements IValidator, ISourceValidator {

  /**
   * @since 3.3.1
   */
  public static final String ID = "org.eclipse.php.ui.internal.validation.phpreconciler"; //$NON-NLS-1$
  private IEditorPart fEditor;
  private IDocumentProvider fDocumentProvider;
  private IProgressMonitor fProgressMonitor;
  private IPhpScriptReconcilingListener fJavaReconcilingListener;
  private boolean fIsScriptReconcilingListener;
  private boolean fNotify = true;
  private IDocument document;

  public void connect(IDocument document) {
    this.document = document;
  }

  public void install(IValidationContext helper) {

    IEditorInput fEditorInput = findEditor(helper);

    fDocumentProvider = DLTKUIPlugin.getDefault()
        .getSourceModuleDocumentProvider();

    fEditor = getEditor(fEditorInput);

    fIsScriptReconcilingListener = fEditor instanceof IPhpScriptReconcilingListener;
    if (fIsScriptReconcilingListener) {
      fJavaReconcilingListener = (IPhpScriptReconcilingListener) fEditor;
    }
  }

  private IEditorPart getEditor(final IEditorInput editorInput) {
    final IEditorPart editor[] = new IEditorPart[1];
    Display.getDefault().syncExec(new Runnable() { // needs UI thread to
          // retrieve active page
          public void run() {
            IWorkbenchPage activePage = DLTKUIPlugin
                .getActivePage();
            if (activePage != null) {
              if (editorInput != null) {
                editor[0] = activePage.findEditor(editorInput);
              } else {
                editor[0] = activePage.getActiveEditor(); // workaround
                // for
                // external
                // files
                // editor
              }
            }
          }
        });
    return editor[0];
  }

  private IEditorInput findEditor(IValidationContext helper) {
    String[] delta = helper.getURIs();
    if (delta.length > 0) {
      // get the file, model and document:
      IFile file = getFile(delta[0]);
      if (file == null) {
        return null;
      }
      org.eclipse.ui.part.FileEditorInput fileEditorInput = new org.eclipse.ui.part.FileEditorInput(
          file);
      return fileEditorInput;
    }
    return null;
  }

  /**
   * Performs the reconcile and returns the AST if it was computed.
   *
   * @param unit
   *            the compilation unit
   * @param initialReconcile
   *            <code>true</code> if this is the initial reconcile
   * @return the AST or <code>null</code> if none
   * @throws JavaModelException
   *             if the original Java element does not exist
   * @since 3.4
   */
  private Program reconcile(ISourceModule unit, boolean initialReconcile)
      throws ModelException {
    /* fix for missing cancel flag communication */
    IProblemRequestorExtension extension = getProblemRequestorExtension();
    if (extension != null) {
      extension.setProgressMonitor(fProgressMonitor);
      extension.setIsActive(true);
    }

    try {
      final ASTProvider astProvider = PHPUiPlugin.getDefault()
          .getASTProvider();

      synchronized (unit) {
        unit.reconcile(true, null, fProgressMonitor);
      }

      // read DOM AST from provider if avaiable
      Program createdAST = astProvider.getAST(unit,
          SharedASTProvider.WAIT_NO, fProgressMonitor);
      if (astProvider.isActive(unit) && createdAST != null) {
        return createdAST;
      }

      if (initialReconcile || astProvider.isActive(unit)) {
        PHPVersion phpVersion = ProjectOptions.getPhpVersion(unit
            .getScriptProject().getProject());
        ASTParser newParser = ASTParser.newParser(phpVersion, unit);
        createdAST = newParser.createAST(null);
        if (createdAST != null && document != null) {
          createdAST.setSourceModule(unit);
          createdAST.setSourceRange(0, document.getLength());
          createdAST.setLineEndTable(Util.lineEndTable(document));
        }
        return createdAST;
      }

    } catch (OperationCanceledException ex) {
      Assert.isTrue(fProgressMonitor == null
          || fProgressMonitor.isCanceled());

    } catch (Exception e) {
      throw new ModelException(e, IStatus.ERROR);

    } finally {
      /* fix for missing cancel flag communication */
      if (extension != null) {
        extension.setProgressMonitor(null);
        extension.setIsActive(false);
      }
    }

    return null;
  }

  public void validate(IValidationContext helper, IReporter reporter)
      throws ValidationException {
    validate(null, helper, reporter);
  }

  public void validate(IRegion dirtyRegion, IValidationContext helper,
      IReporter reporter) {

    // install editors
    if (fEditor == null) {
      install(helper);
      if (fEditor == null) {
        return;
      }
    }

    if (!(fEditor instanceof PHPStructuredEditor)) {
      return;
    }

    final IModelElement modelElement = ((PHPStructuredEditor) fEditor)
        .getModelElement();
    if (modelElement instanceof ISourceModule) {

      final Program ast[] = new Program[1];
      try {
        SafeRunner.run(new ISafeRunnable() {
          public void run() throws ModelException {
            ast[0] = reconcile((ISourceModule) modelElement, true);
          }

          public void handleException(Throwable ex) {
            IStatus status = new Status(IStatus.ERROR,
                PHPUiPlugin.ID, IStatus.OK,
                "Error in php Core during reconcile", ex); //$NON-NLS-1$
            PHPCorePlugin.getDefault().getLog().log(status);
          }
        });
      } finally {
        // Always notify listeners, see
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=55969 for the
        // final solution
        try {
          if (fIsScriptReconcilingListener) {
            IProgressMonitor pm = fProgressMonitor;
            if (pm == null)
              pm = new NullProgressMonitor();
            fJavaReconcilingListener.reconciled(ast[0], !fNotify,
                pm);
          }
        } finally {
          fNotify = true;
        }
      }
    }
  }

  /**
   * @param delta
   *            the IFileDelta containing the file name to get
   * @return the IFile
   */
  public IFile getFile(String delta) {
    try {
      return ResourcesPlugin.getWorkspace().getRoot()
          .getFile(new Path(delta));
    } catch (Exception e) {
    }
    return null;
  }

  /**
   *
   * @param file
   *            the file to get the model for
   * @return the file's XMLModel
   */
  protected IDOMModel getModelForResource(IFile file) {
    IStructuredModel model = null;
    IModelManager manager = StructuredModelManager.getModelManager();

    try {
      model = manager.getModelForRead(file);
      // TODO.. HTML validator tries again to get a model a 2nd way
    } catch (Exception e) {
      // e.printStackTrace();
    }
    return model instanceof IDOMModel ? (IDOMModel) model : null;
  }

  private IProblemRequestorExtension getProblemRequestorExtension() {
    IAnnotationModel model = fDocumentProvider.getAnnotationModel(fEditor
        .getEditorInput());
    if (model instanceof IProblemRequestorExtension)
      return (IProblemRequestorExtension) model;
    return null;
  }

  public void notifyListeners(boolean notify) {
    fNotify = notify;
  }

  public void cleanup(IReporter reporter) {
  }

  public void disconnect(IDocument document) {
    this.document = null;
  }
}
TOP

Related Classes of org.eclipse.php.internal.ui.editor.validation.PhpReconcilingStrategy

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.