/*******************************************************************************
* Copyright © 2011, 2013 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.edt.debug.internal.core.java.variables;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.edt.debug.core.java.IEGLJavaStackFrame;
import org.eclipse.edt.debug.core.java.IEGLJavaThread;
import org.eclipse.edt.debug.core.java.IEGLJavaValue;
import org.eclipse.edt.debug.core.java.IEGLJavaVariable;
import org.eclipse.edt.debug.core.java.SMAPVariableInfo;
import org.eclipse.edt.debug.core.java.variables.VariableUtil;
import org.eclipse.edt.debug.internal.core.java.EGLJavaValue;
import org.eclipse.edt.debug.internal.core.java.EGLJavaVariable;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIPlaceholderVariable;
/**
* Represents a java.util.Map.
*/
@SuppressWarnings("restriction")
public class MapVariable extends EGLJavaVariable
{
public MapVariable( IDebugTarget target, IJavaVariable javaVariable, SMAPVariableInfo variableInfo, IEGLJavaStackFrame frame, IEGLJavaValue parent )
{
super( target, javaVariable, variableInfo, frame, parent );
}
@Override
protected IEGLJavaValue createEGLValue( IJavaValue javaValue )
{
return new MapValue( getDebugTarget(), (IJavaValue)javaValue, this );
}
private class MapValue extends EGLJavaValue
{
public MapValue( IDebugTarget target, IJavaValue value, EGLJavaVariable parent )
{
super( target, value, parent );
}
@Override
public synchronized IVariable[] getVariables() throws DebugException
{
if ( children != null )
{
return children;
}
if ( javaValue instanceof IJavaObject )
{
IEGLJavaThread eglThread = getEGLStackFrame().getEGLThread();
IJavaValue entrySetValue = VariableUtil.runSendMessage( eglThread, (IJavaObject)javaValue, null,
"entrySet", "()Ljava/util/Set;", false ); //$NON-NLS-1$ //$NON-NLS-2$
if ( entrySetValue instanceof IJavaObject )
{
IJavaValue toArrayValue = VariableUtil.runSendMessage( eglThread, (IJavaObject)entrySetValue, null,
"toArray", "()[Ljava/lang/Object;", false ); //$NON-NLS-1$ //$NON-NLS-2$
if ( toArrayValue != null )
{
IVariable[] vars = toArrayValue.getVariables();
List<IEGLJavaVariable> list = new ArrayList<IEGLJavaVariable>( vars.length );
SMAPVariableInfo parentInfo = parentVariable.getVariableInfo();
for ( IVariable var : vars )
{
IValue value = var.getValue();
if ( value instanceof IJavaObject )
{
IJavaValue nextkey = VariableUtil.runSendMessage( eglThread, (IJavaObject)value, null,
"getKey", "()Ljava/lang/Object;", false ); //$NON-NLS-1$ //$NON-NLS-2$
IJavaValue nextvalue = VariableUtil.runSendMessage( eglThread, (IJavaObject)value, null,
"getValue", "()Ljava/lang/Object;", false ); //$NON-NLS-1$ //$NON-NLS-2$
if ( nextkey != null && nextvalue instanceof IJavaValue )
{
SMAPVariableInfo info = new SMAPVariableInfo( nextkey.getValueString(), nextkey.getValueString(),
getTypeNameForElement( nextvalue ), parentInfo.lineDeclared, parentInfo.smapEntry ); //$NON-NLS-1$
list.add( VariableUtil.createEGLVariable( new JDIPlaceholderVariable( nextkey.getValueString(), nextvalue ),
info, parentVariable.getEGLStackFrame(), this ) );
}
}
}
children = list.toArray( new IEGLJavaVariable[ list.size() ] );
}
}
}
if ( children == null )
{
children = super.getVariables();
}
return children;
}
@Override
public String getValueString()
{
return javaValue.isNull()
? "null" : ""; //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
public String computeDetail()
{
return getValueString();
}
}
/**
* @return the type name to display for the given element of the map. Subclasses may override this method. By default the Java value's type name
* will be used.
* @throws DebugException
*/
protected String getTypeNameForElement( IJavaValue value ) throws DebugException
{
return value.getReferenceTypeName();
}
@Override
protected boolean shouldCheckJavaElementAdapter()
{
return false;
}
}