/*
* #%~
* org.overture.ide.debug
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ide.debug.core.model.internal;
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.overture.ide.debug.core.dbgp.IDbgpProperty;
import org.overture.ide.debug.core.dbgp.commands.IDbgpCoreCommands;
import org.overture.ide.debug.core.dbgp.exceptions.DbgpException;
import org.overture.ide.debug.core.model.DebugEventHelper;
import org.overture.ide.debug.core.model.IRefreshableVdmVariable;
import org.overture.ide.debug.core.model.IVdmStackFrame;
import org.overture.ide.debug.core.model.IVdmThread;
import org.overture.ide.debug.core.model.IVdmVariable;
public class VdmVariable extends VdmDebugElement implements IVdmVariable,
IRefreshableVdmVariable
{
private final IVdmStackFrame frame;
private final String name;
private IDbgpProperty property;
private IValue value;
private boolean isValueChanged = false;
public VdmVariable(IVdmStackFrame frame, String name, IDbgpProperty property)
{
this.frame = frame;
this.name = name;
this.property = property;
}
public IDebugTarget getDebugTarget()
{
return frame.getDebugTarget();
}
public synchronized IValue getValue() throws DebugException
{
if (value == null)
{
value = VdmValue.createValue(frame, property);
}
return value;
}
public String getName()
{
return name;
}
public String getReferenceTypeName() throws DebugException
{
return property.getType();
}
public boolean hasValueChanged() throws DebugException
{
return isValueChanged;
}
public synchronized void setValue(String expression) throws DebugException
{
try
{
if ("String".equals(property.getType()) && //$NON-NLS-1$
(!expression.startsWith("'") || !expression.endsWith("'")) && //$NON-NLS-1$ //$NON-NLS-2$
(!expression.startsWith("\"") || !expression.endsWith("\"")))
{
expression = "\"" + expression.replaceAll("\\\"", "\\\\\"") + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
// if (getCoreCommands().setProperty(property.getEvalName(),
// frame.getLevel(), expression)) {
// clearEvaluationManagerCache();
// update();
}
if (getCoreCommands().setProperty(property.getEvalName(), property.getKey(), expression))
{
clearEvaluationManagerCache();
update();
}
} catch (DbgpException e)
{
// TODO: localize
throw wrapDbgpException("VdmVariable_cantAssignVariable", e);
}
}
private IDbgpCoreCommands getCoreCommands()
{
return ((IVdmThread) frame.getThread()).getDbgpSession().getCoreCommands();
}
private void clearEvaluationManagerCache()
{
VdmThread thread = (VdmThread) frame.getThread();
thread.notifyModified();
}
private void update() throws DbgpException
{
this.value = null;
// String key = property.getKey();
String name = property.getEvalName();
// TODO: Use key if provided
// this.property = getCoreCommands().getProperty(name, frame.getLevel());
this.property = getCoreCommands().getPropertyByKey(property.getPage(), name, frame.getLevel(), property.getKey());
DebugEventHelper.fireChangeEvent(this);
}
public void setValue(IValue value) throws DebugException
{
setValue(value.getValueString());
}
public boolean supportsValueModification()
{
return !property.isConstant();
}
public boolean verifyValue(String expression) throws DebugException
{
// TODO: perform more smart verification
return expression != null;
}
public boolean verifyValue(IValue value) throws DebugException
{
return verifyValue(value.getValueString());
}
public boolean isConstant()
{
return property.isConstant();
}
public String toString()
{
return getName();
}
public String getId()
{
return property.getKey();
}
/**
* @param newVariable
* @return
* @throws DebugException
*/
public IVariable refreshVariable(IVariable newVariable)
throws DebugException
{
if (newVariable instanceof VdmVariable)
{
final VdmVariable v = (VdmVariable) newVariable;
if (property.hasChildren() && v.property.hasChildren())
{
isValueChanged = false;
if (value != null
&& ((VdmValue) value).hasChildrenValuesLoaded())
{
/*
* Refresh children if some of them are loaded. Since it could be a hash - it is safer to get all of
* the new children.
*/
VdmStackFrame.refreshVariables(v.getValue().getVariables(), ((VdmValue) value).variables);
}
}
isValueChanged = !equals(property, v.property);
value = v.value;
property = v.property;
return this;
} else
{
return newVariable;
}
}
private static boolean equals(IDbgpProperty p1, IDbgpProperty p2)
{
if (p1.hasChildren() != p2.hasChildren())
{
return false;
}
if (!StrUtils.equals(p1.getType(), p2.getType()))
{
return false;
}
if (!StrUtils.equals(p1.getValue(), p2.getValue()))
{
return false;
}
if (StrUtils.isNotEmpty(p1.getKey())
&& StrUtils.isNotEmpty(p2.getKey()))
{
return p1.getKey().equals(p2.getKey());
}
return true;
}
}