/******************************************************************************* * Copyright (c) 2005, 2009 Zend Technologies. * All rights reserved. This program and the accompanying materials * are the copyright of Zend Technologies and is protected under * copyright laws of the United States. * You must not copy, adapt or redistribute this document for * any use. * *******************************************************************************/ package org.eclipse.php.internal.debug.ui.breakpoint; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IBreakpointManager; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IVerticalRulerInfo; import org.eclipse.jface.viewers.ISelection; import org.eclipse.php.internal.debug.ui.Logger; import org.eclipse.php.internal.ui.editor.PHPStructuredEditor; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.*; import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IDocumentProviderExtension4; import org.eclipse.ui.texteditor.ITextEditor; 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.core.internal.util.Debug; import org.eclipse.wst.sse.ui.internal.SSEUIMessages; import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder; import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools; import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.IBreakpointProvider; /** * Adapter to create the break point. */ public class ScriptLineBreakpointAdapter implements IToggleBreakpointsTarget { protected IVerticalRulerInfo fRulerInfo = null; /* * (non-Javadoc) * * @seeorg.eclipse.debug.ui.actions.IToggleBreakpointsTarget# * canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) { PHPStructuredEditor textEditor = getEditor(part); if (textEditor != null) { return true; } return false; } /* * (non-Javadoc) * * @seeorg.eclipse.debug.ui.actions.IToggleBreakpointsTarget# * canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) { return false; } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget# * canToggleWatchpoints (org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { return false; } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget# * toggleLineBreakpoints (org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { ITextEditor editor = (ITextEditor) part.getAdapter(ITextEditor.class); if (selection instanceof ITextSelection) { ITextSelection textSelection = (ITextSelection) selection; IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput()); int lineNumber = -1; try { lineNumber = document.getLineOfOffset(textSelection.getOffset()); } catch (BadLocationException e) { } if (lineNumber >= 0) { IResource resource = getResource(editor.getEditorInput()); AbstractMarkerAnnotationModel model = getAnnotationModel(editor); IBreakpoint[] breakpoints = getBreakpoints(resource, document, model, lineNumber); if (breakpoints.length > 0) { IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager(); for (int i = 0; i < breakpoints.length; i++) { breakpoints[i].getMarker().delete(); breakpointManager.removeBreakpoint(breakpoints[i], true); } } else { createBreakpoints(editor, lineNumber + 1); } } } } protected String getContentType(ITextEditor editor, IDocument document) { IModelManager mgr = StructuredModelManager.getModelManager(); String contentType = null; IDocumentProvider provider = editor.getDocumentProvider(); if (provider instanceof IDocumentProviderExtension4) { try { IContentType type = ((IDocumentProviderExtension4) provider).getContentType(editor.getEditorInput()); if (type != null) contentType = type.getId(); } catch (CoreException e) { /* * A failure accessing the underlying store really isn't * interesting, although it can be a problem for * IStorageEditorInputs. */ } } if (contentType == null) { IStructuredModel model = null; try { model = mgr.getExistingModelForRead(document); if (model != null) { contentType = model.getContentTypeIdentifier(); } } finally { if (model != null) { model.releaseFromRead(); } } } return contentType; } public static final String getFileExtension(IEditorInput input) { IPath path = null; if (input instanceof IStorageEditorInput) { try { path = ((IStorageEditorInput) input).getStorage().getFullPath(); } catch (CoreException e) { Logger.logException(e); } } if (path != null) { return path.getFileExtension(); } String name = input.getName(); int index = name.lastIndexOf('.'); if (index == -1) return null; if (index == (name.length() - 1)) return ""; //$NON-NLS-1$ return name.substring(index + 1); } protected boolean createBreakpoints(ITextEditor editor, int lineNumber) { /* * Note: we'll always allow processing to continue, even for a "read * only" IStorageEditorInput, for the ActiveScript debugger. But this * means sometimes the ActiveScript provider might get an input from CVS * or something that is not related to debugging. */ IEditorInput input = editor.getEditorInput(); IDocument document = editor.getDocumentProvider().getDocument(input); if (document == null) return false; String contentType = getContentType(editor, document); IBreakpointProvider[] providers = BreakpointProviderBuilder.getInstance().getBreakpointProviders(editor, contentType, getFileExtension(input)); int pos = -1; ISourceEditingTextTools tools = (ISourceEditingTextTools) editor.getAdapter(ISourceEditingTextTools.class); if (tools != null) { pos = tools.getCaretOffset(); } final int n = providers.length; List errors = new ArrayList(0); for (int i = 0; i < n; i++) { try { if (Debug.debugBreakpoints) System.out.println(providers[i].getClass().getName() + " adding breakpoint to line " + lineNumber); //$NON-NLS-1$ IStatus status = providers[i].addBreakpoint(document, input, lineNumber, pos); if (status != null && !status.isOK()) { errors.add(status); } } catch (CoreException e) { errors.add(e.getStatus()); } catch (Exception t) { Logger.logException("exception while adding breakpoint", t); //$NON-NLS-1$ } } IStatus status = null; if (errors.size() > 0) { Shell shell = editor.getSite().getShell(); if (errors.size() > 1) { status = new MultiStatus(SSEUIPlugin.ID, IStatus.OK, (IStatus[]) errors.toArray(new IStatus[0]), SSEUIMessages.ManageBreakpoints_error_adding_message1, null); } else { status = (IStatus) errors.get(0); } if ((status.getSeverity() > IStatus.INFO) || (Platform.inDebugMode() && !status.isOK())) { Platform.getLog(SSEUIPlugin.getDefault().getBundle()).log(status); } /* * Show for conditions more severe than INFO or when no breakpoints * were created */ if (status.getSeverity() > IStatus.INFO || getBreakpoints(getMarkers(editor)).length < 1) { ErrorDialog.openError(shell, SSEUIMessages.ManageBreakpoints_error_adding_title1, status.getMessage(), status); return false; } } return true; } protected IBreakpoint[] getBreakpoints(IMarker[] markers) { IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); List breakpoints = new ArrayList(markers.length); for (int i = 0; i < markers.length; i++) { IBreakpoint breakpoint = manager.getBreakpoint(markers[i]); if (breakpoint != null) { breakpoints.add(breakpoint); } } return (IBreakpoint[]) breakpoints.toArray(new IBreakpoint[0]); } /** * Returns the <code>IDocument</code> of the editor's input. * * @return the document of the editor's input */ protected IDocument getDocument(ITextEditor editor) { IDocumentProvider provider = editor.getDocumentProvider(); return provider.getDocument(editor.getEditorInput()); } /** * Returns all markers which include the ruler's line of activity. * * @return an array of markers which include the ruler's line of activity */ protected IMarker[] getMarkers(ITextEditor editor) { List markers = new ArrayList(); IResource resource = getResource(editor.getEditorInput()); IDocument document = getDocument(editor); AbstractMarkerAnnotationModel annotationModel = getAnnotationModel(editor); if (resource != null && annotationModel != null && resource.exists()) { try { IMarker[] allMarkers = resource.findMarkers(IBreakpoint.BREAKPOINT_MARKER, true, IResource.DEPTH_ZERO); if (allMarkers != null) { for (int i = 0; i < allMarkers.length; i++) { if (includesRulerLine(editor, annotationModel.getMarkerPosition(allMarkers[i]), document)) { markers.add(allMarkers[i]); } } } } catch (CoreException x) { // } } return (IMarker[]) markers.toArray(new IMarker[0]); } /** * Checks whether a position includes the ruler's line of activity. * * @param editor * * @param position * the position to be checked * @param document * the document the position refers to * @return <code>true</code> if the line is included by the given position */ protected boolean includesRulerLine(ITextEditor editor, Position position, IDocument document) { return false; } private IBreakpoint[] getBreakpoints(IResource resource, IDocument document, AbstractMarkerAnnotationModel model, int lineNumber) { List markers = new ArrayList(); if (document != null && resource != null && model != null && resource.exists()) { try { IMarker[] allMarkers = resource.findMarkers(IBreakpoint.LINE_BREAKPOINT_MARKER, true, IResource.DEPTH_ZERO); if (allMarkers != null) { for (int i = 0; i < allMarkers.length; i++) { Position p = model.getMarkerPosition(allMarkers[i]); int markerLine = -1; try { markerLine = document.getLineOfOffset(p.getOffset()); } catch (BadLocationException e1) { } if (markerLine == lineNumber) { markers.add(allMarkers[i]); } } } } catch (CoreException x) { } } IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); List breakpoints = new ArrayList(markers.size()); for (int i = 0; i < markers.size(); i++) { IBreakpoint breakpoint = manager.getBreakpoint((IMarker) markers.get(i)); if (breakpoint != null) { breakpoints.add(breakpoint); } } return (IBreakpoint[]) breakpoints.toArray(new IBreakpoint[0]); } /** * Returns the <code>AbstractMarkerAnnotationModel</code> of the editor's * input. * * @param editor * * @return the marker annotation model */ protected AbstractMarkerAnnotationModel getAnnotationModel(ITextEditor editor) { IDocumentProvider provider = editor.getDocumentProvider(); IAnnotationModel model = provider.getAnnotationModel(editor.getEditorInput()); if (model instanceof AbstractMarkerAnnotationModel) return (AbstractMarkerAnnotationModel) model; return null; } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget# * toggleMethodBreakpoints (org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { // don't support } /* * (non-Javadoc) * * @see * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { // don't support } private PHPStructuredEditor getEditor(IWorkbenchPart part) { if (part instanceof PHPStructuredEditor) { return (PHPStructuredEditor) part; } return null; } public final IResource getResource(IEditorInput input) { IResource resource = null; if (input instanceof IFileEditorInput) resource = ((IFileEditorInput) input).getFile(); if (resource == null) resource = (IResource) input.getAdapter(IFile.class); if (resource == null) resource = (IResource) input.getAdapter(IResource.class); IEditorPart editorPart = null; if (resource == null) { IWorkbench workbench = SSEUIPlugin.getDefault().getWorkbench(); if (workbench != null) { IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); if (window != null) { IPartService service = window.getPartService(); if (service != null) { Object part = service.getActivePart(); if (part != null && part instanceof IEditorPart) { editorPart = (IEditorPart) part; IStructuredModel model = null; ITextEditor textEditor = null; try { if (editorPart instanceof ITextEditor) { textEditor = (ITextEditor) editorPart; } if (textEditor == null) { textEditor = (ITextEditor) editorPart.getAdapter(ITextEditor.class); } if (textEditor != null) { IDocument textDocument = textEditor.getDocumentProvider().getDocument(input); model = StructuredModelManager.getModelManager() .getExistingModelForRead(textDocument); if (model != null) { resource = BreakpointProviderBuilder.getInstance().getResource(input, model.getContentTypeIdentifier(), getFileExtension(input)); } } if (resource == null) { IBreakpointProvider[] providers = BreakpointProviderBuilder.getInstance() .getBreakpointProviders(editorPart, null, getFileExtension(input)); for (int i = 0; i < providers.length && resource == null; i++) { resource = providers[i].getResource(input); } } } catch (Exception e) { Logger.logException(e); } finally { if (model != null) { model.releaseFromRead(); } } } } } } } return resource; } }