/******************************************************************************* * Copyright (c) 2012 Pivotal Software, Inc. * 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: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.groovy.debug.core.evaluation; import groovy.lang.Binding; import groovy.util.Proxy; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IVariable; import org.eclipse.jdt.debug.core.IJavaObject; import org.eclipse.jdt.debug.core.IJavaPrimitiveValue; import org.eclipse.jdt.debug.core.IJavaStackFrame; import org.eclipse.jdt.debug.core.IJavaValue; /** * A binding that will properly update, set * fields and variables in the currently debugged application * @author Andrew Eisenberg * @since 2.5.1 */ public class JDIBinding extends Binding { private final JDITargetDelegate delegate; private final IJavaStackFrame frame; // the metaclass for the 'this'object private JDIMetaClass thisMetaClass; private boolean initialized; public JDIBinding(JDITargetDelegate delegate, IJavaStackFrame frame) { this.delegate = delegate; this.frame = frame; this.initialized = false; } public void markAsInitialized() { this.initialized = true; } public void setThisMetaClass(JDIMetaClass thisMetaClass) { this.thisMetaClass = thisMetaClass; } @Override public void setVariable(String property, Object newValue) { if (!initialized) { // if not yet initialized, only add to binding // don't try to make any changes to running application super.setVariable(property, newValue); return; } try { IJavaValue newJDIObject = delegate.toJDIObject(newValue); if (getVariables().containsKey(property)) { // this is a local variable Proxy variable = (Proxy) getVariable(property); variable.setAdaptee(newJDIObject); variable.setMetaClass(new JDIMetaClass((IJavaObject) newJDIObject, delegate)); IVariable[] vars = frame.getVariables(); for (IVariable var : vars) { if (var.getName().equals(property)) { if (var.getValue() instanceof IJavaPrimitiveValue) { newJDIObject = delegate.convertToUnboxedType(newJDIObject); } var.setValue(newJDIObject); break; } } } else { // assume that this is a property on 'this' // need to call set property on 'this' getMetaClass().setProperty(delegate.getThis(), property, newJDIObject); } } catch (DebugException e) { throw new RuntimeException(e); } } }