org.neuro4j.studio.debug.core.model.FlowLineBreakpoint.java Source code

Java tutorial

Introduction

Here is the source code for org.neuro4j.studio.debug.core.model.FlowLineBreakpoint.java

Source

/*
 * Copyright (c) 2013-2014, Neuro4j.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.neuro4j.studio.debug.core.model;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaLineBreakpoint;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.neuro4j.studio.core.ActionNode;
import org.neuro4j.studio.core.diagram.edit.parts.NodeBaseEditPart;
import org.neuro4j.studio.core.diagram.markers.MarkerMng;
import org.neuro4j.studio.core.util.ClassloaderHelper;
import org.neuro4j.studio.debug.core.BreakpoinMng;
import org.neuro4j.studio.debug.core.DebugExamplesPlugin;
import org.neuro4j.studio.debug.core.launching.IPDAConstants;

import com.sun.jdi.ThreadReference;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.event.ThreadStartEvent;

/**
 * PDA line breakpoint
 */
public abstract class FlowLineBreakpoint extends JavaLineBreakpoint {
    public static final String BEEHIVE_BREAKPOINT_MARKER = DebugExamplesPlugin.getDefault().getID()
            + ".beehiveBreakpointMarker";

    protected static final String EXPIRED = DebugExamplesPlugin.getDefault().getID() + ".expired";

    protected static final String HIT_COUNT = DebugExamplesPlugin.getDefault().getID() + ".hitCount";

    public static final String INSTALL_COUNT = DebugExamplesPlugin.getDefault().getID() + ".installCount";
    private PDADebugElement beehiveElement;
    protected HashMap fRequestsByTarget;
    protected Set installedTargets = null;

    public FlowLineBreakpoint() {
        super();
    }

    @Override
    public boolean hasCondition() {
        // TODO Auto-generated method stub
        return super.hasCondition();

    }

    @Override
    public boolean isConditionEnabled() throws CoreException {
        if (!getMarker().exists()) {
            return false;
        }
        return super.isConditionEnabled();

    }

    @Override
    public boolean isConditionSuspendOnTrue() throws DebugException {
        // TODO Auto-generated method stub
        return super.isConditionSuspendOnTrue();

    }

    //    private String getLocationByNode(ActionNode action)
    //    {
    //        return action.getId() + "=" + ClassloaderHelper.getCurrentResource().getProjectRelativePath().toPortableString();
    //    }

    public FlowLineBreakpoint(String clazz) throws DebugException {
        this(MarkerManager.getBeehiveElementMarkerResource(clazz), new Integer(0), true,
                new HashMap<String, Object>());
    }

    public FlowLineBreakpoint(final IResource resource, final int hitCount, final boolean add,
            final Map<String, Object> attributes) throws DebugException {

        final BreakPointParamContainer container = BreakPointContainerFactory.getBreakPointContainer();

        IWorkspaceRunnable wr = new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {

                setMarker(resource.createMarker("org.eclipse.jdt.debug.javaLineBreakpointMarker"));
                // setMarker(resource.createMarker("org.neuro4j.studio.debug.core.flowLineBreakpointMarker"));

                addLineBreakpointAttributes(attributes, getModelIdentifier(), true, container.getLineNumber(),
                        container.getStartChar(), container.getEndChar());
                addTypeNameAndHitCount(attributes, container.getBaseClassName(), hitCount);
                // attributes.put("locations", getLocationByNode(action));
                attributes.put("flowType", BreakpoinMng.DEBUGSERV_STRING);
                // attributes.put("uuids", action.getId());
                attributes.put("org.eclipse.jdt.debug.core.suspendPolicy", new Integer(getDefaultSuspendPolicy()));
                setAttribute(IBreakpoint.ID, getModelIdentifier());
                ensureMarker().setAttributes(attributes);
                DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(FlowLineBreakpoint.this);
                register(add);
            }
        };
        run(getMarkerRule(resource), wr);
    }

    public FlowLineBreakpoint(final JavaLineBreakpoint javaBp) throws DebugException {

        IWorkspaceRunnable wr = new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {
                setMarker(javaBp.getMarker());
                setCondition(javaBp.getCondition());
                setConditionEnabled(javaBp.isConditionEnabled());
                setSuspendPolicy(javaBp.getSuspendPolicy());
                setHitCount(javaBp.getHitCount());
                setConditionSuspendOnTrue(javaBp.isConditionSuspendOnTrue());

                setAttribute(IBreakpoint.ID, getModelIdentifier());
                ensureMarker().setAttributes(javaBp.getMarker().getAttributes());
            }
        };
        run(getMarkerRule(javaBp.getMarker().getResource()), wr);
    }

    public boolean handleBreakpointEvent(Event event, JDIThread thread, boolean suspendVote) {
        expireHitCount(event);
        return !suspend(thread, suspendVote);
    }

    private boolean processCheckIfSuspend(JDIThread thread) {
        try {
            if (thread.getStackFrames() == null || thread.getStackFrames().length == 0) {
                return true;
            }
            JDIStackFrame sframe = (JDIStackFrame) thread.getStackFrames()[0];

            String uuid = BreakpoinMng.getInstance().getCurrentUuid(sframe);

            if (BreakpoinMng.getInstance().isUUIDInBreakpoint(uuid)) {
                return true;
            }

        } catch (DebugException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return false;
    }

    protected boolean suspend(JDIThread thread, boolean suspendVote) {
        if (!getMarker().exists()) {
            return false;
        }

        boolean suspend = thread.handleSuspendForBreakpoint(this, suspendVote);

        boolean needSusspend = processCheckIfSuspend(thread);
        if (needSusspend) {
            try {
                String uuid = BreakpoinMng.getInstance().getCurrentUuid((JDIStackFrame) thread.getTopStackFrame());
                NodeBaseEditPart editPart = (NodeBaseEditPart) MarkerMng.getInstance().getEditPartAndMark(uuid);
                if (editPart != null) {
                    BreakpoinMng.getInstance().suspend(editPart);
                }
                // else {
                // BreakpoinMng.getInstance().resume();
                // }
                System.out.println(uuid);
            } catch (DebugException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (CoreException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return true;
        } else {
            // thread.resume();
            return false;
        }

    }

    public String getCondition() throws CoreException {
        return super.getCondition();

    }

    public String getModelIdentifier() {
        return IPDAConstants.ID_PDA_DEBUG_MODEL;
    }

    public boolean isInstalled() throws CoreException {
        return ensureMarker().getAttribute(INSTALL_COUNT, 0) > 0;
    }

    public void addToTarget(FlowDebugTarget target) throws CoreException {
        if (!isInstalledIn(target)) {
            setInstalledIn(target, true);

            incrementInstallCount();
        }
    }

    @Override
    protected IJavaProject getJavaProject(IJavaStackFrame stackFrame) {
        return computeJavaProject(stackFrame);
        //return super.getJavaProject(stackFrame);
    }

    private IJavaProject computeJavaProject(IJavaStackFrame stackFrame) {
        ILaunch launch = stackFrame.getLaunch();
        if (launch == null) {
            return null;
        }
        try {
            String projectName = launch.getLaunchConfiguration()
                    .getAttribute("org.eclipse.jdt.launching.PROJECT_ATTR", "");
            if (projectName != null) {
                IJavaProject jProject = ClassloaderHelper.getJavaProject(projectName);
                if (jProject != null) {
                    return jProject;
                }
            }

        } catch (CoreException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        ISourceLocator locator = launch.getSourceLocator();
        if (locator == null)
            return null;

        Object sourceElement = null;
        try {
            if (locator instanceof ISourceLookupDirector && !stackFrame.isStatic()) {
                IJavaType thisType = stackFrame.getThis().getJavaType();
                if (thisType instanceof IJavaReferenceType) {
                    String[] sourcePaths = ((IJavaReferenceType) thisType).getSourcePaths(null);
                    if (sourcePaths != null && sourcePaths.length > 0) {
                        sourceElement = ((ISourceLookupDirector) locator).getSourceElement(sourcePaths[0]);
                    }
                }
            }
        } catch (DebugException e) {
            DebugPlugin.log(e);
        }
        if (sourceElement == null) {
            sourceElement = locator.getSourceElement(stackFrame);
        }
        if (!(sourceElement instanceof IJavaElement) && sourceElement instanceof IAdaptable) {
            Object element = ((IAdaptable) sourceElement).getAdapter(IJavaElement.class);
            if (element != null) {
                sourceElement = element;
            }
        }
        if (sourceElement instanceof IJavaElement) {
            return ((IJavaElement) sourceElement).getJavaProject();
        } else if (sourceElement instanceof IResource) {
            IJavaProject project = JavaCore.create(((IResource) sourceElement).getProject());
            if (project.exists()) {
                return project;
            }
        }

        return null;
    }

    protected void decrementInstallCount() throws CoreException {
        int count = getInstallCount();
        if (count > 0) {
            setAttribute(INSTALL_COUNT, count - 1);
        }
    }

    protected void incrementInstallCount() throws CoreException {
        int count = getInstallCount();
        setAttribute(INSTALL_COUNT, count + 1);
    }

    public int getInstallCount() throws CoreException {
        int markerInstallCount = ensureMarker().getAttribute(INSTALL_COUNT, 0);
        int registeredTargetsCount = this.installedTargets != null ? this.installedTargets.size() : 0;

        if (markerInstallCount != registeredTargetsCount) {
            ensureMarker().setAttribute(INSTALL_COUNT, registeredTargetsCount);
            return registeredTargetsCount;
        }
        return markerInstallCount;
    }

    public boolean handleEvent(Event event, JDIDebugTarget target, boolean suspendVote, EventSet eventSet) {
        if ((event instanceof ClassPrepareEvent)) {
            return handleClassPrepareEvent((ClassPrepareEvent) event, target, suspendVote);
        }
        ThreadReference threadRef = ((LocatableEvent) event).thread();
        JDIThread thread = target.findThread(threadRef);

        if (thread == null) {
            try {
                Job.getJobManager().join(ThreadStartEvent.class, null);
            } catch (OperationCanceledException localOperationCanceledException) {
            } catch (InterruptedException localInterruptedException) {
            }
            thread = target.findThread(threadRef);
        }
        if ((thread == null) || (thread.isIgnoringBreakpoints())) {
            return true;
        }

        return handleBreakpointEvent(event, thread, suspendVote);
    }

    protected boolean isInstalledIn(FlowDebugTarget target) {
        return (this.installedTargets != null) && (this.installedTargets.contains(target));
    }

    @Override
    public void removeFromTarget(JDIDebugTarget target) throws CoreException {
        // TODO Auto-generated method stub
        super.removeFromTarget(target);
        // MarkerMng.getInstance().removeMarker(this.getMarker());
    }

    protected void setInstalledIn(FlowDebugTarget target, boolean installed) {
        if (installed) {
            if (this.installedTargets == null) {
                this.installedTargets = new HashSet();
            }
            this.installedTargets.add(target);
        } else if (this.installedTargets != null) {
            this.installedTargets.remove(target);
        }
    }

    @Override
    public int getLineNumber() throws CoreException {
        // TODO Auto-generated method stub
        return super.getLineNumber();
    }

    @Override
    public int getCharStart() throws CoreException {
        // TODO Auto-generated method stub
        return super.getCharStart();
    }

    @Override
    public int getCharEnd() throws CoreException {
        // TODO Auto-generated method stub
        return super.getCharEnd();
    }

    @Override
    protected boolean suspendForEvent(Event event, JDIThread thread, boolean suspendVote) {
        // TODO Auto-generated method stub
        return super.suspendForEvent(event, thread, suspendVote);
    }

    @Override
    public void eventSetComplete(Event event, JDIDebugTarget target, boolean suspend, EventSet eventSet) {
        // TODO Auto-generated method stub
        super.eventSetComplete(event, target, suspend, eventSet);
    }

    @Override
    public boolean handleClassPrepareEvent(ClassPrepareEvent event, JDIDebugTarget target, boolean suspendVote) {
        System.out.println("handleClassPrepareEvent");
        return super.handleClassPrepareEvent(event, target, suspendVote);
    }

    @Override
    public void addInstanceFilter(IJavaObject object) throws CoreException {
        System.out.println("addInstanceFilter");
        super.addInstanceFilter(object);
    }

    @Override
    public synchronized void addBreakpointListener(String identifier) throws CoreException {
        System.out.println("addBreakpointListener");
        super.addBreakpointListener(identifier);
    }

    @Override
    public IMarker getMarker() {
        return super.getMarker();
    }

    public void connectBreakpoint() {
        IMarker marker = getMarker();
        String uuids;

        uuids = (String) marker.getAttribute("uuids", "");
        String[] u = uuids.split(" ");
        for (String uuid : u) {
            if (uuid.length() > 20) {
                BreakpoinMng.getInstance().registerUUIDForSuspend(uuid);

                NodeBaseEditPart part = (NodeBaseEditPart) MarkerMng.getInstance().getEditPartAndMark(uuid);
                if (part != null) {
                    part.setConnected();
                }
            }
        }

    }

}