Package org.eclipse.php.internal.debug.ui.breakpoint.provider

Source Code of org.eclipse.php.internal.debug.ui.breakpoint.provider.DefaultPHPBreakpointProvider

/*******************************************************************************
* 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.debug.ui.breakpoint.provider;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.php.internal.core.documentModel.partitioner.PHPPartitionTypes;
import org.eclipse.php.internal.core.documentModel.partitioner.PHPStructuredTextPartitioner;
import org.eclipse.php.internal.debug.core.model.PHPConditionalBreakpoint;
import org.eclipse.php.internal.debug.ui.Logger;
import org.eclipse.php.internal.debug.ui.PHPDebugUIMessages;
import org.eclipse.php.internal.debug.ui.PHPDebugUIPlugin;
import org.eclipse.php.internal.ui.editor.input.IPlatformIndependentPathEditorInput;
import org.eclipse.php.internal.ui.editor.input.NonExistingPHPFileEditorInput;
import org.eclipse.php.internal.ui.util.StatusLineMessageTimerManager;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.wst.sse.ui.internal.StructuredResourceMarkerAnnotationModel;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;

import com.ibm.icu.text.MessageFormat;

public class DefaultPHPBreakpointProvider implements IPHPBreakpointProvider,
    IExecutableExtension {

  public IStatus addBreakpoint(IDocument document, IEditorInput input,
      int lineNumber, int offset) throws CoreException {

    // check if there is a valid position to set breakpoint
    int pos = getValidPosition(document, lineNumber);

    // calculate the line number here so both workspace files AND externals
    // will get it
    try {
      lineNumber = document.getLineOfOffset(pos) + 1;
    } catch (BadLocationException e) {
      Logger.logException(e);
      return new Status(IStatus.ERROR, PHPDebugUIPlugin.getID(),
          PHPDebugUIMessages.DefaultPHPBreakpointProvider_0);
    }

    IStatus status = null;
    IBreakpoint point = null;
    if (pos >= 0) {

      IResource resource = getResourceFromInput(input);

      Map<String, String> attributes = new HashMap<String, String>();
      ISourceModule modelElement = DLTKUIPlugin
          .getEditorInputModelElement(input);

      if (modelElement != null) {
        attributes.put(IMarker.LOCATION, modelElement.getPath()
            .toString());
      }

      // Calculate secondary ID
      String secondaryId = null;
      if (input instanceof IFileEditorInput) {
        IFileEditorInput fileEditorInput = (IFileEditorInput) input;
        if (fileEditorInput.getFile().isLinked()) {
          secondaryId = fileEditorInput.getFile().getRawLocation()
              .toString();
        }
      } else if (input instanceof IURIEditorInput
          || (input instanceof NonExistingPHPFileEditorInput)) {

        if (input instanceof IPlatformIndependentPathEditorInput) {
          secondaryId = ((IPlatformIndependentPathEditorInput) input)
              .getPath();
        } else if (input instanceof IURIEditorInput) {
          secondaryId = URIUtil.toPath(
              ((IURIEditorInput) input).getURI()).toOSString();
        } else {
          secondaryId = ((NonExistingPHPFileEditorInput) input)
              .getPath(input).toString();
        }

      } else if (input instanceof IStorageEditorInput) {
        IStorage storage = ((IStorageEditorInput) input).getStorage();
        if (storage instanceof IModelElement) {
          IModelElement element = (IModelElement) storage;
          secondaryId = EnvironmentPathUtils.getFile(element)
              .getFullPath().toPortableString();
        }
      }

      if (secondaryId != null) {
        attributes
            .put(StructuredResourceMarkerAnnotationModel.SECONDARY_ID_KEY,
                secondaryId);
      }

      if (findBreakpointMarker(secondaryId, resource, lineNumber) == null) {
        IRegion region = null;
        int charStart = -1;
        int charEnd = -1;
        try {
          region = document.getLineInformationOfOffset(pos);
          charStart = region.getOffset();
          charEnd = charStart + region.getLength();
        } catch (BadLocationException e) {
          PHPDebugUIPlugin.log(e);
        }
        point = createBreakpoint(input, resource, lineNumber,
            charStart, charEnd, attributes);
      }
    }

    if (point == null) {
      showErrorMessage();
    }

    if (status == null) {
      status = new Status(IStatus.OK, PHPDebugUIPlugin.getID(),
          IStatus.OK, MessageFormat.format(
              PHPDebugUIMessages.BreakpointCreated_1,
              new Object[] {}), null);
    }
    return status;
  }

  protected void showErrorMessage() {
    // hide message after one second:
    StatusLineMessageTimerManager.setErrorMessage(
        PHPDebugUIMessages.ErrorCreatingBreakpoint_1, 1000, true);
  }

  protected IMarker findBreakpointMarker(String secondaryId,
      IResource resource, int lineNumber) throws CoreException {
    IMarker[] breakpoints = resource.findMarkers(
        IBreakpoint.LINE_BREAKPOINT_MARKER, true, IResource.DEPTH_ZERO);
    for (IMarker breakpoint : breakpoints) {
      if (breakpoint.getAttribute(IMarker.LINE_NUMBER).equals(
          Integer.valueOf(lineNumber))
          && (secondaryId == null || secondaryId
              .equals(breakpoint
                  .getAttribute(StructuredResourceMarkerAnnotationModel.SECONDARY_ID_KEY)))) {
        return breakpoint;
      }
    }
    return null;
  }

  @Override
  public IBreakpoint createBreakpoint(IEditorInput input, IResource resource,
      int lineNumber, int charStart, int charEnd,
      Map<String, String> attributes) throws CoreException {
    return new PHPConditionalBreakpoint(resource, lineNumber, charStart,
        charEnd, attributes);
  }

  public IResource getResource(IEditorInput input) {
    return getResourceFromInput(input);
  }

  private IResource getResourceFromInput(IEditorInput input) {
    IResource resource = (IResource) input.getAdapter(IFile.class);
    if (resource == null || !resource.exists()) {
      // for non-workspace resources - use workspace root for storing
      // breakpoints
      resource = ResourcesPlugin.getWorkspace().getRoot();
    }
    return resource;
  }

  /**
   * Finds a valid position somewhere on lineNumber in document, idoc, where a
   * breakpoint can be set and returns that position. -1 is returned if a
   * position could not be found.
   *
   * @param idoc
   * @param editorLineNumber
   * @return position to set breakpoint or -1 if no position could be found
   */
  public static int getValidPosition(IDocument idoc, int editorLineNumber) {
    int result = -1;
    if (idoc != null) {

      int startOffset = 0;
      int endOffset = 0;
      try {
        String partitionType = null;
        IRegion line;
        String linePart;
        boolean phpPartitionVisited = false;

        do {
          line = idoc.getLineInformation(editorLineNumber - 1);
          startOffset = line.getOffset();
          endOffset = Math.max(line.getOffset(), line.getOffset()
              + line.getLength());

          ITypedRegion[] partitions = null;

          partitions = idoc.computePartitioning(startOffset,
              endOffset - startOffset);

          for (int i = 0; i < partitions.length; ++i) {
            partitionType = partitions[i].getType();
            if (partitionType.equals(PHPPartitionTypes.PHP_DEFAULT)) {
              phpPartitionVisited = true;
              startOffset = partitions[i].getOffset();
              linePart = idoc.get(startOffset,
                  partitions[i].getLength()).trim();
              if (Pattern.matches(".*[a-zA-Z0-0_]+.*", linePart) //$NON-NLS-1$
                  && !linePart.trim().toLowerCase()
                      .equals("<?php")) { //$NON-NLS-1$
                result = startOffset;
                break;
              }
            }
          }
          ++editorLineNumber;
        } while ((!phpPartitionVisited || PHPStructuredTextPartitioner
            .isPHPPartitionType(partitionType)) && result == -1);
      } catch (BadLocationException e) {
        result = -1;
      }
    }
    return result;
  }

  /**
   * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
   *      java.lang.String, java.lang.Object)
   */
  public void setInitializationData(IConfigurationElement config,
      String propertyName, Object data) {
    // not used
  }

  public void setSourceEditingTextTools(ISourceEditingTextTools tools) {
    // not used
  }

}
TOP

Related Classes of org.eclipse.php.internal.debug.ui.breakpoint.provider.DefaultPHPBreakpointProvider

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.