/*******************************************************************************
* Copyright (c) 2008, 2012 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* QNX Software Systems - catchpoints - bug 226689
*******************************************************************************/
package org.eclipse.cdt.debug.ui.breakpoints;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.debug.core.CDIDebugModel;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
public class CBreakpointUIContributionFactory {
private static final String EXTENSION_POINT_NAME = "breakpointContribution"; //$NON-NLS-1$
private static CBreakpointUIContributionFactory instance;
protected ArrayList<ICBreakpointsUIContribution> contributions;
private CBreakpointUIContributionFactory() {
contributions = new ArrayList<ICBreakpointsUIContribution>();
loadSubtypeContributions();
}
/**
* Calculates the breakpoint contributions for the given breakpoint.
*
* @param breakpoint Breakpoint to find UI contributions for.
* @return non-null array of ICBreakpointsUIContribution
* @throws CoreException if cannot get marker attributes from bearkpoint
*/
public ICBreakpointsUIContribution[] getBreakpointUIContributions(IBreakpoint breakpoint) throws CoreException {
String debugModelId = null;
IMarker bmarker = breakpoint.getMarker();
Map<String, Object> attributes = Collections.emptyMap();
String markerType = CDIDebugModel.calculateMarkerType(breakpoint);
if (bmarker != null) {
Map<String, Object> _attributes = bmarker.getAttributes();
attributes = _attributes;
markerType = bmarker.getType();
}
return getBreakpointUIContributions(debugModelId, markerType, attributes);
}
/**
* Calculates the breakpoint contributions for the given breakpoint.
*
* @param breakpoint Breakpoint to find UI contributions for.
* @param attributes Attributes of the breakpoint
* @return non-null array of ICBreakpointsUIContribution
* @throws CoreException if cannot get marker attributes from bearkpoint
* @since 7.2
*/
public ICBreakpointsUIContribution[] getBreakpointUIContributions(String[] debugModelIDs, IBreakpoint breakpoint,
Map<String, Object> attributes) throws CoreException
{
IMarker bmarker = breakpoint.getMarker();
String markerType = CDIDebugModel.calculateMarkerType(breakpoint);
if (bmarker != null) {
markerType = bmarker.getType();
}
return getBreakpointUIContributions(debugModelIDs, markerType, attributes);
}
/**
* Default debug model ID list which will cause only the general UI contributions to be returned.
* @since 7.2
*/
public final static String[] DEBUG_MODEL_IDS_DEFAULT = new String[] {};
/**
* Calculates the breakpoint UI contributions for the given breakpoint.
*
* @param debugModelId The debug model ID of the active debug context for
* which to calculate contributions.
* @param breakpoint Breakpoint to find UI contributions for.
* @param markerType Marker type of the breakpoint.
* @param attributes Attributes of the breakpoint
* @return non-null array of ICBreakpointsUIContribution
* @throws CoreException
* @throws CoreException if cannot get marker attributes from berakpoint
*/
public ICBreakpointsUIContribution[] getBreakpointUIContributions(String debugModelId, String markerType,
Map<String, Object> attributes)
{
return getBreakpointUIContributions(
debugModelId != null ? new String[] { debugModelId } : null,
markerType,
attributes);
}
/**
* Calculates the breakpoint UI contributions for the given breakpoint.
*
* @param debugModelId The debug model IDs of the active debug context for
* which to calculate contributions.
* @param breakpoint Breakpoint to find UI contributions for.
* @param markerType Marker type of the breakpoint.
* @param attributes Attributes of the breakpoint
* @return non-null array of ICBreakpointsUIContribution
* @throws CoreException
* @throws CoreException if cannot get marker attributes from berakpoint
*
* @since 7.2
*/
public ICBreakpointsUIContribution[] getBreakpointUIContributions(String[] debugModelIds, String markerType,
Map<String, Object> attributes)
{
List<String> debugModelIdsList = null;
if (debugModelIds != null ) {
debugModelIdsList = Arrays.asList(debugModelIds);
}
ArrayList<ICBreakpointsUIContribution> list = new ArrayList<ICBreakpointsUIContribution>();
for (ICBreakpointsUIContribution con : contributions) {
try {
if (con.getDebugModelId() == null ||
((debugModelIdsList == null || debugModelIdsList.contains(con.getDebugModelId()))))
{
String contributedMarkerType = con.getMarkerType();
if (isMarkerSubtypeOf(markerType, contributedMarkerType)) {
if (attributes == null || con.isApplicable(attributes)) {
list.add(con);
}
}
}
} catch (Exception e) {
CDebugUIPlugin.log(e);
}
}
return list.toArray(new ICBreakpointsUIContribution[list.size()]);
}
public boolean isMarkerSubtypeOf(String currentType, String type) throws CoreException {
return getWorkspace().getMarkerManager().isSubtype(currentType, type);
}
private Workspace getWorkspace() {
return (Workspace) CDebugUIPlugin.getWorkspace();
}
private void loadSubtypeContributions() {
IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(CDebugUIPlugin.getUniqueIdentifier(),
EXTENSION_POINT_NAME);
if (ep == null)
return;
IConfigurationElement[] elements = ep.getConfigurationElements();
for (int i = 0; i < elements.length; i++) {
IConfigurationElement configurationElement = elements[i];
if (configurationElement.getName().equals(ICBreakpointsUIContribution.BREAKPOINT_LABELS) ||
configurationElement.getName().equals(ICBreakpointsUIContribution.BREAKPOINT_EDITORS))
{
String mainElement = configurationElement.getName();
String modelId = configurationElement.getAttribute("debugModelId"); //$NON-NLS-1$
String markerType = getRequired(configurationElement, "markerType"); //$NON-NLS-1$
if (markerType == null)
continue;
IConfigurationElement[] children = configurationElement.getChildren("attribute"); //$NON-NLS-1$
for (IConfigurationElement att : children) {
DefaultCBreakpointUIContribution adapter = new DefaultCBreakpointUIContribution(att);
adapter.setMainElement(mainElement);
adapter.setMarkerType(markerType);
adapter.setDebugModelId(modelId);
if (processAttribute(att, adapter) == false)
continue;
}
}
}
}
private boolean processAttribute(IConfigurationElement attrElement,
DefaultCBreakpointUIContribution adapter)
{
String attrId = getRequired(attrElement, "name"); //$NON-NLS-1$
String attrLabel = getRequired(attrElement, "label"); //$NON-NLS-1$
String fieldEditorClass = attrElement.getAttribute("fieldEditor"); //$NON-NLS-1$
String fieldEditorFactoryClass = attrElement.getAttribute("fieldEditorFactory"); //$NON-NLS-1$
String type = attrElement.getAttribute("type"); //$NON-NLS-1$
String svisible = attrElement.getAttribute("visible"); //$NON-NLS-1$
if (attrId == null) {
return false;
}
if (attrLabel == null) {
return false;
}
if (type == null) {
type = "string"; //$NON-NLS-1$
}
boolean visible = true;
if (svisible != null && svisible.equalsIgnoreCase("false")) { //$NON-NLS-1$
visible = false;
}
adapter.setId(attrId);
adapter.setLabel(attrLabel);
adapter.setControlClass(fieldEditorClass);
adapter.setFieldEditorFactory(fieldEditorFactoryClass);
adapter.setType(type);
adapter.setVisible(visible);
addContribution(adapter);
IConfigurationElement[] children = attrElement.getChildren("value"); //$NON-NLS-1$
for (IConfigurationElement value : children) {
processValue(value, adapter);
}
return true;
}
private void processValue(IConfigurationElement valueElement, DefaultCBreakpointUIContribution adapter) {
String valueId = getRequired(valueElement, "value"); //$NON-NLS-1$
String valueLabel = getRequired(valueElement, "label"); //$NON-NLS-1$
if (valueId == null)
return;
if (valueLabel == null)
return;
adapter.addValue(valueId, valueLabel);
IConfigurationElement[] children = valueElement.getChildren("attribute"); //$NON-NLS-1$
for (IConfigurationElement att : children) {
DefaultCBreakpointUIContribution adapter2 = new DefaultCBreakpointUIContribution(att);
// inherit values
adapter2.setMainElement(adapter.getMainElement());
adapter2.setMarkerType(adapter.getMarkerType());
adapter2.setDebugModelId(adapter.getDebugModelId());
adapter2.addContionsAll(adapter.getConditions());
// add value condition
adapter2.addContionEquals(adapter.getId(), valueId);
if (processAttribute(att, adapter2) == false)
continue;
}
}
public void addContribution(ICBreakpointsUIContribution contribution) {
contributions.add(contribution);
}
public static CBreakpointUIContributionFactory getInstance() {
if (instance == null) {
instance = new CBreakpointUIContributionFactory();
}
return instance;
}
private static String getRequired(IConfigurationElement configurationElement, String name) {
String elementValue = configurationElement.getAttribute(name);
if (elementValue == null)
CDebugUIPlugin.log(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(),
DebugPlugin.INTERNAL_ERROR, "Extension " //$NON-NLS-1$
+ configurationElement.getDeclaringExtension().getUniqueIdentifier()
+ " missing required attribute: " + name, null)); //$NON-NLS-1$
return elementValue;
}
}