/******************************************************************************* * Copyright (c) 2008, 2015 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 *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui.variables; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.model.elements.VariableLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.jdt.debug.core.IJavaInterfaceType; 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.debug.core.IJavaValue; import org.eclipse.jdt.debug.core.IJavaVariable; import org.eclipse.jdt.debug.core.JDIDebugModel; import org.eclipse.jdt.internal.debug.core.model.JDIObjectValue; import org.eclipse.jdt.internal.debug.core.model.JDIThread; import org.eclipse.jdt.internal.debug.ui.DebugUIMessages; import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.jdt.internal.debug.ui.JDIModelPresentation; import org.eclipse.jface.viewers.TreePath; /** * Base implementation of a label provider for Java variables * @since 3.2 */ public class JavaVariableLabelProvider extends VariableLabelProvider implements IPreferenceChangeListener { public static JDIModelPresentation fLabelProvider = new JDIModelPresentation(); /** * Map of view id to qualified name setting */ private Map<String, Boolean> fQualifiedNameSettings = new HashMap<>(); private boolean fQualifiedNames = false; /** * Whether to use a thread rule for a label update job (serialize on thread) */ private int fSerializeMode = SERIALIZE_NONE; private static final int SERIALIZE_ALL = 0; // no toString()'s in line, so serialize labels private static final int SERIALIZE_NONE = 1; // all toString()'s in line, so don't serialize labels (evaluations will be serialized) private static final int SERIALIZE_SOME = 2; // some - only serialize those that don't have formatters (ones with formatters will be serialized by evaluation) public JavaVariableLabelProvider() { IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugUIPlugin.getUniqueIdentifier()); if(prefs != null) { prefs.addPreferenceChangeListener(this); determineSerializationMode(prefs.get(IJDIPreferencesConstants.PREF_SHOW_DETAILS, IJDIPreferencesConstants.DETAIL_PANE)); } } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter#getValueText(org.eclipse.debug.core.model.IVariable, org.eclipse.debug.core.model.IValue) */ @Override protected String getValueText(IVariable variable, IValue value, IPresentationContext context) throws CoreException { if (value instanceof IJavaValue) { return fLabelProvider.getFormattedValueText((IJavaValue) value); } return super.getValueText(variable, value, context); } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter#getValueTypeName(org.eclipse.debug.core.model.IVariable, org.eclipse.debug.core.model.IValue) */ @Override protected String getValueTypeName(IVariable variable, IValue value, IPresentationContext context) throws CoreException { String typeName= DebugUIMessages.JDIModelPresentation_unknown_type__2; try { typeName = value.getReferenceTypeName(); if (!fQualifiedNames) { return fLabelProvider.removeQualifierFromGenericName(typeName); } } catch (DebugException e) {} return typeName; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter#getVariableTypeName(org.eclipse.debug.core.model.IVariable) */ @Override protected String getVariableTypeName(IVariable variable, IPresentationContext context) throws CoreException { String typeName= DebugUIMessages.JDIModelPresentation_unknown_type__2; try { typeName = variable.getReferenceTypeName(); if (!fQualifiedNames) { return fLabelProvider.removeQualifierFromGenericName(typeName); } } catch (DebugException e) {} return typeName; } /** * Returns if the the specified presentation context is showing qualified names or not * @param context * @return true if the presentation context is showing qualified names, false otherwise */ private Boolean isShowQualfiiedNames(IPresentationContext context) { Boolean qualified = fQualifiedNameSettings.get(context.getId()); if (qualified == null) { qualified = Boolean.valueOf(Platform.getPreferencesService().getBoolean( JDIDebugUIPlugin.getUniqueIdentifier(), context.getId() + '.' + IJDIPreferencesConstants.PREF_SHOW_QUALIFIED_NAMES, false, null)); fQualifiedNameSettings.put(context.getId(), qualified); } return qualified; } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter#getColumnText(org.eclipse.debug.core.model.IVariable, org.eclipse.debug.core.model.IValue, java.lang.String, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) */ @Override protected String getColumnText(IVariable variable, IValue value, IPresentationContext context, String columnId) throws CoreException { if (JavaVariableColumnPresentation.COLUMN_INSTANCE_ID.equals(columnId)) { if (value instanceof JDIObjectValue) { long uniqueId = ((JDIObjectValue)value).getUniqueId(); if (uniqueId >= 0) { StringBuffer buffer = new StringBuffer(); buffer.append(uniqueId); return buffer.toString(); } } return ""; //$NON-NLS-1$ } if (JavaVariableColumnPresentation.COLUMN_INSTANCE_COUNT.equals(columnId)) { if (value instanceof IJavaObject) { IJavaType jType = ((IJavaObject)value).getJavaType(); if (jType == null && variable instanceof IJavaVariable) { jType = ((IJavaVariable)variable).getJavaType(); } if (jType instanceof IJavaReferenceType) { if (!(jType instanceof IJavaInterfaceType)) { long count = ((IJavaReferenceType)jType).getInstanceCount(); if (count == -1) { return DebugUIMessages.JavaVariableLabelProvider_0; } StringBuffer buffer = new StringBuffer(); buffer.append(count); return buffer.toString(); } } } return ""; //$NON-NLS-1$ } return super.getColumnText(variable, value, context, columnId); } /** * Sets qualified name setting before building label */ @Override protected void retrieveLabel(ILabelUpdate update) throws CoreException { Boolean showQ = isShowQualfiiedNames(update.getPresentationContext()); fQualifiedNames = showQ.booleanValue(); fLabelProvider.setAttribute(JDIModelPresentation.DISPLAY_QUALIFIED_NAMES, showQ); super.retrieveLabel(update); } /** * Sets the serialization mode for label jobs based on the current preference setting. * * @param value preference value for PREF_SHOW_DETAILS */ private void determineSerializationMode(String value) { if (value.equals(IJDIPreferencesConstants.INLINE_ALL)) { fSerializeMode = SERIALIZE_NONE; } else if (value.equals(IJDIPreferencesConstants.INLINE_FORMATTERS)) { fSerializeMode = SERIALIZE_SOME; } else { fSerializeMode = SERIALIZE_ALL; } } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.model.elements.VariableLabelProvider#getLabel(org.eclipse.jface.viewers.TreePath, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.String) */ @Override protected String getLabel(TreePath elementPath, IPresentationContext context, String columnId) throws CoreException { if (columnId == null) { // when no columns, handle special escaping ourselves IDebugModelPresentation presentation = getModelPresentation(context, JDIDebugModel.getPluginIdentifier()); if (presentation != null) { return presentation.getText(elementPath.getLastSegment()); } } return super.getLabel(elementPath, context, columnId); } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.model.elements.ElementLabelProvider#getRule(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate) */ @Override protected ISchedulingRule getRule(ILabelUpdate update) { IJavaStackFrame frame = null; switch (fSerializeMode) { case SERIALIZE_NONE: return null; case SERIALIZE_ALL: Object input = update.getViewerInput(); frame = (IJavaStackFrame) DebugPlugin.getAdapter(input, IJavaStackFrame.class); break; case SERIALIZE_SOME: Object element = update.getElement(); if (element instanceof IJavaVariable) { try { IValue value = ((IJavaVariable)element).getValue(); if (value instanceof IJavaValue) { if (!fLabelProvider.isShowLabelDetails((IJavaValue)value)) { input = update.getViewerInput(); frame = (IJavaStackFrame) DebugPlugin.getAdapter(input, IJavaStackFrame.class); } } } catch (DebugException e) { } } } if (frame != null) { return ((JDIThread)frame.getThread()).getThreadRule(); } return null; } /* (non-Javadoc) * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) */ @Override public void preferenceChange(PreferenceChangeEvent event) { if (event.getKey().endsWith(IJDIPreferencesConstants.PREF_SHOW_QUALIFIED_NAMES)) { fQualifiedNameSettings.clear(); } else if (event.getKey().equals(IJDIPreferencesConstants.PREF_SHOW_DETAILS)) { determineSerializationMode((String) event.getNewValue()); } } }