--- a/api.debugger.jpda/apichanges.xml
+++ a/api.debugger.jpda/apichanges.xml
@@ -835,6 +835,28 @@
+
+
+ A possibility to get/set mirror objects from debugger variables.
+
+
+
+
+
+ MutableVariable
interface is introduced. It's to be implemented by
+ variables that can change their values. Field
,
+ LocalVariable
and JPDAWatch
now extend
+ MutableVariable
.
+
+ Object createMirrorObject()
method is added to Variable
+ class and void setFromMirrorObject(Object obj)
method
+ is declared by MutableVariable
.
+
+
+
+
+
+
--- a/api.debugger.jpda/manifest.mf
+++ a/api.debugger.jpda/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.api.debugger.jpda/2
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties
-OpenIDE-Module-Specification-Version: 2.43
+OpenIDE-Module-Specification-Version: 2.44
OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]
--- a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/Field.java
+++ a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/Field.java
@@ -58,7 +58,7 @@
* @see ObjectVariable
* @author Jan Jancura
*/
-public interface Field extends Variable {
+public interface Field extends MutableVariable {
/**
* Declared name of field.
@@ -100,6 +100,7 @@
* @return sets value of this field represented as text
* @throws InvalidExpressionException if the expression is not correct
*/
+ @Override
public abstract void setValue (String value)
throws InvalidExpressionException;
}
--- a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/JPDAWatch.java
+++ a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/JPDAWatch.java
@@ -57,7 +57,7 @@
* @author Jan Jancura
*/
-public interface JPDAWatch extends Variable {
+public interface JPDAWatch extends MutableVariable {
/**
* Watched expression.
@@ -105,6 +105,7 @@
*
* @param value a new value of this variable represented as text
*/
+ @Override
public abstract void setValue (String value) throws InvalidExpressionException;
/**
--- a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LocalVariable.java
+++ a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/LocalVariable.java
@@ -58,7 +58,7 @@
* @see ObjectVariable
* @author Jan Jancura
*/
-public interface LocalVariable extends Variable {
+public interface LocalVariable extends MutableVariable {
/**
* Declared name of local.
@@ -87,6 +87,7 @@
* @param value a new value of this local represented as text
* @throws InvalidExpressionException if the expression is not correct
*/
+ @Override
public abstract void setValue (String value)
throws InvalidExpressionException;
}
--- a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/MutableVariable.java
+++ a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/MutableVariable.java
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.api.debugger.jpda;
+
+import java.io.InvalidObjectException;
+
+/**
+ * Represents a variable that can be modified.
+ *
+ *
+ * Since JDI interfaces evolve from one version to another, it's strongly recommended
+ * not to implement this interface in client code. New methods can be added to
+ * this interface at any time to keep up with the JDI functionality.
+ *
+ * @see LocalVariable
+ * @see Field
+ * @see JPDAWatch
+ *
+ * @author Martin Entlicher
+ * @since 2.44
+ */
+public interface MutableVariable extends Variable {
+
+ /**
+ * Sets a value represented as text, to this variable.
+ *
+ * @param value The string value to be set to this variable
+ * @throws InvalidExpressionException if the expression is not correct
+ */
+ void setValue (String value) throws InvalidExpressionException;
+
+ /**
+ * Set the value of this variable to match the given mirror object.
+ *
+ * @param obj The mirror object
+ * @throws InvalidObjectException when it was not possible to set value of
+ * this variable from the provided object.
+ * @see Variable#createMirrorObject()
+ */
+ void setFromMirrorObject(Object obj) throws InvalidObjectException;
+
+}
--- a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/Variable.java
+++ a/api.debugger.jpda/src/org/netbeans/api/debugger/jpda/Variable.java
@@ -77,4 +77,14 @@
* @return text representation of current value of "this" variable
*/
public abstract String getValue ();
+
+ /**
+ * Create an object in this JVM, which mirrors the value of this variable in
+ * the target JVM.
+ *
+ * @return The mirror object, or null
when a mirror object can not be created.
+ * @since 2.44
+ */
+ Object createMirrorObject();
+
}
--- a/debugger.jpda/test/unit/src/org/netbeans/api/debugger/jpda/MirrorValuesTest.java
+++ a/debugger.jpda/test/unit/src/org/netbeans/api/debugger/jpda/MirrorValuesTest.java
@@ -0,0 +1,183 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.api.debugger.jpda;
+
+import java.awt.Color;
+import java.awt.Point;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import junit.framework.Test;
+import org.netbeans.api.debugger.DebuggerManager;
+import org.netbeans.junit.NbTestCase;
+
+/**
+ * Tests {@link Variable#createMirrorObject()} and {@link MutableVariable#setFromMirrorObject(java.lang.Object)}.
+ *
+ * @author Martin Entlicher
+ */
+public class MirrorValuesTest extends NbTestCase {
+
+ private static final String CLASS_NAME =
+ "org.netbeans.api.debugger.jpda.testapps.MirrorValuesApp";
+
+ private JPDASupport support;
+ private DebuggerManager dm = DebuggerManager.getDebuggerManager ();
+
+ public MirrorValuesTest(String s) {
+ super(s);
+ }
+
+ public static Test suite() {
+ return JPDASupport.createTestSuite(MirrorValuesTest.class);
+ }
+
+ public void testMirrors() throws Exception {
+ try {
+ Utils.BreakPositions bp = Utils.getBreakPositions(System.getProperty ("test.dir.src") +
+ "org/netbeans/api/debugger/jpda/testapps/MirrorValuesApp.java");
+ LineBreakpoint lb = bp.getLineBreakpoints().get(0);
+ dm.addBreakpoint (lb);
+
+ support = JPDASupport.attach (CLASS_NAME);
+
+ support.waitState (JPDADebugger.STATE_STOPPED); // breakpoint hit
+
+ CallStackFrame sf = support.getDebugger ().getCurrentCallStackFrame ();
+ LocalVariable [] vars = sf.getLocalVariables ();
+ Map variablesByName = getVariablesByName(vars);
+ Map mirrorsByName = getMirrorsByName();
+
+ Variable v;
+ Object m;
+
+ // Test of createMirrorObject():
+ for (String name : mirrorsByName.keySet()) {
+ v = variablesByName.get(name);
+ m = v.createMirrorObject();
+ assertNotNull(name, m);
+ Object mm = mirrorsByName.get(name);
+ if (mm.getClass().isArray()) {
+ assertTrue(name+" is array", m.getClass().isArray());
+ assertTrue(name+" array "+arrayToString(mm)+
+ " does not equal to "+arrayToString(m),
+ compareArrays(mm, m));
+ } else {
+ assertEquals(name, mm, m);
+ }
+ }
+
+ // Test of setFromMirrorObject():
+ v = variablesByName.get("boo");
+ assertEquals("boo", "true", v.getValue());
+ ((MutableVariable) v).setFromMirrorObject(Boolean.FALSE);
+ assertEquals("boo", "false", v.getValue());
+
+ v = variablesByName.get("i");
+ assertEquals("i", "10000", v.getValue());
+ ((MutableVariable) v).setFromMirrorObject(12345);
+ assertEquals("i", "12345", v.getValue());
+
+ v = variablesByName.get("color");
+ assertEquals("color", "java.awt.Color[r=255,g=0,b=0]", ((ObjectVariable) v).getToStringValue());
+ ((MutableVariable) v).setFromMirrorObject(Color.GREEN);
+ assertEquals("color", "java.awt.Color[r=0,g=255,b=0]", ((ObjectVariable) v).getToStringValue());
+
+ } finally {
+ support.doFinish ();
+ }
+
+ }
+
+ private static boolean compareArrays(Object arr1, Object arr2) {
+ if (arr1 instanceof Object[]) {
+ return Arrays.deepEquals((Object[]) arr1, (Object[]) arr2);
+ } else if (arr1 instanceof int[]) {
+ return Arrays.equals((int[]) arr1, (int[]) arr2);
+ } else {
+ throw new IllegalStateException(arr1+", "+arr2);
+ }
+ }
+
+ private static String arrayToString(Object a) {
+ if (a instanceof Object[]) {
+ return Arrays.deepToString((Object[]) a);
+ } else if (a instanceof int[]) {
+ return Arrays.toString((int[]) a);
+ } else {
+ throw new IllegalStateException(a.toString());
+ }
+ }
+
+ private static Map getVariablesByName(LocalVariable[] vars) {
+ Map map = new HashMap();
+ for (LocalVariable lv : vars) {
+ assertTrue("Not mutable", lv instanceof MutableVariable);
+ map.put(lv.getName(), lv);
+ }
+ return map;
+ }
+
+ private static Map getMirrorsByName() {
+ String[] names = { "boo", "b", "s", "i", "l",
+ "f", "d",
+ "iarr",
+ "darr",
+ "str", "date", "color",
+ "point", "file" };
+ Object[] mirrors = { true, (byte) 5, (short) 512, 10000, Long.MAX_VALUE,
+ 12.12f, 1e150,
+ new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+ new double[][] { { 0.1, 0.2, 0.3 }, { 1.1, 1.2, 1.3 }, { 2.1, 2.2, 2.3 } },
+ "A String", new Date(1000000000l), Color.RED,
+ new Point(10, 10), new File("/tmp/Foo.txt") };
+
+ Map map = new HashMap();
+ assertEquals(names.length, mirrors.length);
+ for (int i = 0; i < names.length; i++) {
+ map.put(names[i], mirrors[i]);
+ }
+ return map;
+ }
+}
--- a/debugger.jpda/test/unit/src/org/netbeans/api/debugger/jpda/testapps/MirrorValuesApp.java
+++ a/debugger.jpda/test/unit/src/org/netbeans/api/debugger/jpda/testapps/MirrorValuesApp.java
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.api.debugger.jpda.testapps;
+
+import java.awt.Color;
+import java.awt.Point;
+import java.io.File;
+import java.util.Date;
+
+/**
+ * A test application for mirror values.
+ *
+ * @author Martin Entlicher
+ */
+public class MirrorValuesApp {
+
+ public static void main(String[] args) {
+ MirrorValuesApp mva = new MirrorValuesApp();
+ mva.mirrors();
+ }
+
+ private void mirrors() {
+ boolean boo = true;
+ byte b = 5;
+ short s = 512;
+ int i = 10000;
+ long l = Long.MAX_VALUE;
+ float f = 12.12f;
+ double d = 1e150;
+
+ int[] iarr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ double[][] darr = new double[][] { { 0.1, 0.2, 0.3 }, { 1.1, 1.2, 1.3 }, { 2.1, 2.2, 2.3 } };
+
+ String str = "A String";
+
+ Date date = new Date(1000000000l);
+ Color color = Color.RED;
+ Point point = new Point(10, 10);
+ File file = new File("/tmp/Foo.txt");
+
+ Color[][] colors = new Color[][] { { Color.WHITE, Color.BLACK }, { Color.YELLOW, Color.GRAY } };
+
+ System.currentTimeMillis(); // LBREAKPOINT
+ }
+}