PageRenderTime 109ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/debugger.jpda.visual/src/org/netbeans/modules/debugger/jpda/visual/JavaComponentInfo.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 946 lines | 789 code | 82 blank | 75 comment | 107 complexity | 1c39021e8be6eb9f906b203522dd7c77 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2011 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.debugger.jpda.visual;
  43. import com.sun.jdi.AbsentInformationException;
  44. import com.sun.jdi.ClassNotLoadedException;
  45. import com.sun.jdi.ClassType;
  46. import com.sun.jdi.Field;
  47. import com.sun.jdi.IncompatibleThreadStateException;
  48. import com.sun.jdi.InvalidTypeException;
  49. import com.sun.jdi.InvocationException;
  50. import com.sun.jdi.Method;
  51. import com.sun.jdi.ObjectReference;
  52. import com.sun.jdi.PrimitiveType;
  53. import com.sun.jdi.PrimitiveValue;
  54. import com.sun.jdi.StringReference;
  55. import com.sun.jdi.ThreadReference;
  56. import com.sun.jdi.Type;
  57. import com.sun.jdi.Value;
  58. import com.sun.jdi.VirtualMachine;
  59. import java.awt.Rectangle;
  60. import java.beans.PropertyChangeListener;
  61. import java.beans.PropertyChangeSupport;
  62. import java.beans.PropertyVetoException;
  63. import java.lang.reflect.InvocationTargetException;
  64. import java.util.ArrayList;
  65. import java.util.Collections;
  66. import java.util.HashMap;
  67. import java.util.List;
  68. import java.util.Map;
  69. import java.util.TreeMap;
  70. import java.util.concurrent.locks.Lock;
  71. import org.netbeans.api.debugger.jpda.CallStackFrame;
  72. import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl;
  73. import org.netbeans.modules.debugger.jpda.expr.InvocationExceptionTranslated;
  74. import org.netbeans.modules.debugger.jpda.jdi.ClassNotPreparedExceptionWrapper;
  75. import org.netbeans.modules.debugger.jpda.jdi.ClassTypeWrapper;
  76. import org.netbeans.modules.debugger.jpda.jdi.InternalExceptionWrapper;
  77. import org.netbeans.modules.debugger.jpda.jdi.MethodWrapper;
  78. import org.netbeans.modules.debugger.jpda.jdi.MirrorWrapper;
  79. import org.netbeans.modules.debugger.jpda.jdi.ObjectCollectedExceptionWrapper;
  80. import org.netbeans.modules.debugger.jpda.jdi.ObjectReferenceWrapper;
  81. import org.netbeans.modules.debugger.jpda.jdi.ReferenceTypeWrapper;
  82. import org.netbeans.modules.debugger.jpda.jdi.StringReferenceWrapper;
  83. import org.netbeans.modules.debugger.jpda.jdi.TypeComponentWrapper;
  84. import org.netbeans.modules.debugger.jpda.jdi.TypeWrapper;
  85. import org.netbeans.modules.debugger.jpda.jdi.UnsupportedOperationExceptionWrapper;
  86. import org.netbeans.modules.debugger.jpda.jdi.VMDisconnectedExceptionWrapper;
  87. import org.netbeans.modules.debugger.jpda.jdi.ValueWrapper;
  88. import org.netbeans.modules.debugger.jpda.jdi.VirtualMachineWrapper;
  89. import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl;
  90. import org.netbeans.modules.debugger.jpda.visual.spi.ComponentInfo;
  91. import org.openide.DialogDisplayer;
  92. import org.openide.NotifyDescriptor;
  93. import org.openide.nodes.Node;
  94. import org.openide.nodes.Node.Property;
  95. import org.openide.nodes.Node.PropertySet;
  96. import org.openide.nodes.PropertySupport.ReadOnly;
  97. import org.openide.util.Exceptions;
  98. import org.openide.util.NbBundle;
  99. import org.openide.util.RequestProcessor;
  100. /**
  101. *
  102. * @author Jaroslav Bachorik
  103. */
  104. abstract public class JavaComponentInfo implements ComponentInfo {
  105. private static final JavaComponentInfo[] NO_SUBCOMPONENTS = new JavaComponentInfo[]{};
  106. private static final int MAX_TEXT_LENGTH = 80;
  107. //private AWTComponentInfo parent;
  108. private Rectangle bounds;
  109. private Rectangle windowBounds;
  110. private String name;
  111. private String type;
  112. private JavaComponentInfo[] subComponents;
  113. private List<PropertySet> propertySets = new ArrayList<PropertySet>();
  114. private PropertyChangeSupport pchs = new PropertyChangeSupport(this);
  115. private JPDAThreadImpl thread;
  116. private ObjectReference component;
  117. private FieldInfo fieldInfo;
  118. private String componentText;
  119. private RemoteServices.ServiceType sType;
  120. long uid;
  121. public JavaComponentInfo(JPDAThreadImpl t, ObjectReference component, RemoteServices.ServiceType sType) throws RetrievalException {
  122. this.thread = t;
  123. this.component = component;
  124. try {
  125. this.type = ReferenceTypeWrapper.name(ObjectReferenceWrapper.referenceType(component));
  126. } catch (InternalExceptionWrapper ex) {
  127. throw new RetrievalException(ex.getLocalizedMessage(), ex);
  128. } catch (VMDisconnectedExceptionWrapper ex) {
  129. throw RetrievalException.disconnected();
  130. } catch (ObjectCollectedExceptionWrapper ex) {
  131. throw new RetrievalException(ex.getLocalizedMessage(), ex);
  132. }
  133. this.sType = sType;
  134. this.uid = component.uniqueID();
  135. }
  136. final protected void init() throws RetrievalException {
  137. retrieve();
  138. addProperties();
  139. if (!RemoteAWTScreenshot.FAST_FIELDS_SEARCH) {
  140. findComponentFields();
  141. }
  142. }
  143. abstract protected void retrieve() throws RetrievalException;
  144. final public JPDAThreadImpl getThread() {
  145. return thread;
  146. }
  147. final public ObjectReference getComponent() {
  148. return component;
  149. }
  150. /** Provide the stack information about where this component was added into the hierarchy */
  151. public Stack getAddCallStack() {
  152. return VisualDebuggerListener.getStackOf(thread.getDebugger(), component);
  153. }
  154. final public String getName() {
  155. return name;
  156. }
  157. final public String getTypeName() {
  158. int d = type.lastIndexOf('.');
  159. String typeName;
  160. if (d > 0) {
  161. typeName = type.substring(d + 1);
  162. } else {
  163. typeName = type;
  164. }
  165. return typeName;
  166. }
  167. final public void setComponentText(String componentText) {
  168. if (componentText.length() > MAX_TEXT_LENGTH) {
  169. this.componentText = componentText.substring(0, MAX_TEXT_LENGTH) + "...";
  170. } else {
  171. this.componentText = componentText;
  172. }
  173. }
  174. @Override
  175. public String getDisplayName() {
  176. String typeName = getTypeName();
  177. String text = (componentText != null) ? " \"" + componentText + "\"" : "";
  178. return getFieldName() + "[" + typeName + "]" + text;
  179. }
  180. @Override
  181. public String getHtmlDisplayName() {
  182. if (isCustomType() || componentText != null) {
  183. String typeName = getTypeName();
  184. if (isCustomType()) {
  185. typeName = "<b>" + typeName + "</b>";
  186. }
  187. String text;
  188. if (componentText != null) {
  189. text = escapeHTML(componentText);
  190. text = " <font color=\"#A0A0A0\">\"" + text + "\"</font>";
  191. } else {
  192. text = "";
  193. }
  194. return getFieldName() + "[" + typeName + "]" + text;
  195. } else {
  196. return null;
  197. }
  198. }
  199. protected String getFieldName() {
  200. return (fieldInfo != null) ? fieldInfo.getName() + " " : "";
  201. }
  202. final public String getType() {
  203. return type;
  204. }
  205. final public FieldInfo getField() {
  206. return fieldInfo;
  207. }
  208. final public boolean isCustomType() {
  209. return isCustomType(type);
  210. }
  211. public static boolean isCustomType(String type) {
  212. return !(type.startsWith("java.awt.") ||
  213. type.startsWith("javax.swing.") ||
  214. type.startsWith("javafx.") ||
  215. type.startsWith("com.sun.")); // NOI18N
  216. }
  217. @Override
  218. final public Rectangle getBounds() {
  219. return bounds;
  220. }
  221. @Override
  222. final public Rectangle getWindowBounds() {
  223. if (windowBounds == null) {
  224. return bounds;
  225. } else {
  226. return windowBounds;
  227. }
  228. }
  229. final public void addPropertySet(PropertySet ps) {
  230. propertySets.add(ps);
  231. }
  232. @Override
  233. final public PropertySet[] getPropertySets() {
  234. return propertySets.toArray(new PropertySet[]{});
  235. }
  236. final protected void setSubComponents(JavaComponentInfo[] subComponents) {
  237. this.subComponents = subComponents;
  238. }
  239. @Override
  240. final public JavaComponentInfo[] getSubComponents() {
  241. if (subComponents == null) {
  242. return NO_SUBCOMPONENTS;
  243. } else {
  244. return subComponents;
  245. }
  246. }
  247. @Override
  248. final public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
  249. pchs.addPropertyChangeListener(propertyChangeListener);
  250. }
  251. @Override
  252. final public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) {
  253. pchs.removePropertyChangeListener(propertyChangeListener);
  254. }
  255. final protected void firePropertyChange(String name, Object o, Object n) {
  256. pchs.firePropertyChange(name, o, n);
  257. }
  258. final public void setFieldInfo(FieldInfo fieldInfo) {
  259. this.fieldInfo = fieldInfo;
  260. }
  261. final public void setBounds(Rectangle r) {
  262. this.bounds = r;
  263. }
  264. final public void setWindowBounds(Rectangle rectangle) {
  265. this.windowBounds = rectangle;
  266. }
  267. final public void setName(String value) {
  268. this.name = value;
  269. }
  270. final public void setComponent(ObjectReference component) {
  271. this.component = component;
  272. }
  273. final public void setType(String name) {
  274. this.type = name;
  275. }
  276. private void addProperties() {
  277. addPropertySet(new PropertySet("main", NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropMain"),
  278. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropMainDescr")) {
  279. @Override
  280. public Property<?>[] getProperties() {
  281. return new Property[] {
  282. new ReadOnly("name", String.class,
  283. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropName"),
  284. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropNameDescr")) {
  285. @Override
  286. public Object getValue() throws IllegalAccessException, InvocationTargetException {
  287. return JavaComponentInfo.this.getName();
  288. }
  289. },
  290. new ReadOnly("type", String.class,
  291. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropType"),
  292. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropTypeDescr")) {
  293. @Override
  294. public Object getValue() throws IllegalAccessException, InvocationTargetException {
  295. return JavaComponentInfo.this.getType();
  296. }
  297. },
  298. new ReadOnly("bounds", String.class,
  299. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropBounds"),
  300. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropBoundsDescr")) {
  301. @Override
  302. public Object getValue() throws IllegalAccessException, InvocationTargetException {
  303. Rectangle r = JavaComponentInfo.this.getWindowBounds();
  304. return "[x=" + r.x + ",y=" + r.y + ",width=" + r.width + ",height=" + r.height + "]";
  305. }
  306. },
  307. };
  308. }
  309. });
  310. // TODO: Try to find out the BeanInfo of the class
  311. List<Method> allMethods;
  312. Map<String, Method> methodsByName;
  313. try {
  314. allMethods = ReferenceTypeWrapper.allMethods(ObjectReferenceWrapper.referenceType(component));
  315. //System.err.println("Have "+allMethods.size()+" methods.");
  316. methodsByName = new HashMap<String, Method>(allMethods.size());
  317. for (Method m : allMethods) {
  318. String mName = TypeComponentWrapper.name(m);
  319. if ((mName.startsWith("get") || mName.startsWith("set")) && mName.length() > 3 ||
  320. mName.startsWith("is") && mName.length() > 2) {
  321. if ((mName.startsWith("get") || mName.startsWith("is")) && m.argumentTypeNames().size() == 0 ||
  322. mName.startsWith("set") && MethodWrapper.argumentTypeNames(m).size() == 1 && "void".equals(MethodWrapper.returnTypeName(m))) {
  323. methodsByName.put(mName, m);
  324. }
  325. }
  326. }
  327. } catch (ClassNotPreparedExceptionWrapper cnpex) {
  328. // no class - no properties
  329. return ;
  330. } catch (InternalExceptionWrapper iex) {
  331. // no go
  332. return ;
  333. } catch (ObjectCollectedExceptionWrapper ocex) {
  334. // gone
  335. return ;
  336. } catch (VMDisconnectedExceptionWrapper vmdex) {
  337. // gone
  338. return ;
  339. }
  340. Map<String, Property> sortedProperties = new TreeMap<String, Property>();
  341. //final List<Property> properties = new ArrayList<Property>();
  342. for (String mName : methodsByName.keySet()) {
  343. //System.err.println(" Have method '"+name+"'...");
  344. if (mName.startsWith("set")) {
  345. continue;
  346. }
  347. String property;
  348. String setName;
  349. if (mName.startsWith("is")) {
  350. property = Character.toLowerCase(mName.charAt(2)) + mName.substring(3);
  351. setName = "set" + mName.substring(2);
  352. } else { // startsWith("get"):
  353. property = Character.toLowerCase(mName.charAt(3)) + mName.substring(4);
  354. setName = "set" + mName.substring(3);
  355. }
  356. Property p = new ComponentProperty(property, methodsByName.get(mName), methodsByName.get(setName),
  357. this, component, getThread(), getThread().getDebugger(), sType);
  358. sortedProperties.put(property, p);
  359. //System.err.println(" => property '"+property+"', p = "+p);
  360. }
  361. final Property[] properties = sortedProperties.values().toArray(new Property[] {});
  362. addPropertySet(
  363. new PropertySet("Properties",
  364. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentProps"),
  365. NbBundle.getMessage(JavaComponentInfo.class, "MSG_ComponentPropsDescr")) {
  366. @Override
  367. public Property<?>[] getProperties() {
  368. return properties;//.toArray(new Property[] {});
  369. }
  370. });
  371. Method getTextMethod = methodsByName.get("getText"); // NOI18N
  372. if (getTextMethod != null) {
  373. try {
  374. Value theText = ObjectReferenceWrapper.invokeMethod(component, getThread().getThreadReference(), getTextMethod, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED);
  375. if (theText instanceof StringReference) {
  376. setComponentText(StringReferenceWrapper.value((StringReference) theText));
  377. }
  378. } catch (VMDisconnectedExceptionWrapper vmdex) {
  379. return;
  380. } catch (Exception ex) {
  381. Exceptions.printStackTrace(ex);
  382. }
  383. }
  384. }
  385. protected static boolean isInstanceOfClass(ClassType c1, ClassType c2) {
  386. if (c1.equals(c2)) {
  387. return true;
  388. }
  389. c1 = c1.superclass();
  390. if (c1 == null) {
  391. return false;
  392. }
  393. return isInstanceOfClass(c1, c2);
  394. }
  395. private void findComponentFields() {
  396. List<JavaComponentInfo> customParents = new ArrayList<JavaComponentInfo>();
  397. fillCustomParents(customParents, this);
  398. findFieldsInParents(customParents, this);
  399. }
  400. private static void fillCustomParents(List<JavaComponentInfo> customParents, JavaComponentInfo ci) {
  401. ComponentInfo[] subs = ci.getSubComponents();
  402. if (subs.length > 0 && ci.isCustomType()) {
  403. customParents.add(ci);
  404. }
  405. for (ComponentInfo sci : subs) {
  406. fillCustomParents(customParents, (JavaComponentInfo)sci);
  407. }
  408. }
  409. private static void findFieldsInParents(List<JavaComponentInfo> customParents, JavaComponentInfo ci) {
  410. ComponentInfo[] subComponents = ci.getSubComponents();
  411. ObjectReference component = ci.getComponent();
  412. for (JavaComponentInfo cp : customParents) {
  413. try {
  414. ObjectReference c = cp.getComponent();
  415. Map<Field, Value> fieldValues = ObjectReferenceWrapper.getValues(c, ReferenceTypeWrapper.fields(ObjectReferenceWrapper.referenceType(c)));
  416. for (Map.Entry<Field, Value> e : fieldValues.entrySet()) {
  417. if (component.equals(e.getValue())) {
  418. ci.setFieldInfo(new JavaComponentInfo.FieldInfo(e.getKey(), cp));
  419. }
  420. }
  421. } catch (InternalExceptionWrapper ex) {
  422. } catch (VMDisconnectedExceptionWrapper ex) {
  423. return ;
  424. } catch (ObjectCollectedExceptionWrapper ex) {
  425. } catch (ClassNotPreparedExceptionWrapper ex) {
  426. }
  427. }
  428. for (ComponentInfo sci : subComponents) {
  429. findFieldsInParents(customParents, (JavaComponentInfo)sci);
  430. }
  431. }
  432. private static class ComponentProperty extends Node.Property {
  433. private String propertyName;
  434. private Method getter;
  435. private Method setter;
  436. private JavaComponentInfo ci;
  437. private ObjectReference component;
  438. private JPDAThreadImpl t;
  439. private ThreadReference tawt;
  440. private JPDADebuggerImpl debugger;
  441. private String value;
  442. private final Object valueLock = new Object();
  443. private final String valueCalculating = "calculating";
  444. private final RemoteServices.ServiceType sType;
  445. private boolean valueIsEditable;
  446. private Type valueType;
  447. ComponentProperty(String propertyName, Method getter, Method setter,
  448. JavaComponentInfo ci, ObjectReference component,
  449. JPDAThreadImpl t, JPDADebuggerImpl debugger, RemoteServices.ServiceType sType) {
  450. super(String.class);
  451. this.propertyName = propertyName;
  452. this.getter = getter;
  453. this.setter = setter;
  454. this.ci = ci;
  455. this.component = component;
  456. this.t = t;
  457. this.tawt = t.getThreadReference();
  458. this.debugger = debugger;
  459. this.sType = sType;
  460. }
  461. @Override
  462. public String getName() {
  463. return propertyName;
  464. }
  465. @Override
  466. public String getDisplayName() {
  467. return propertyName;
  468. }
  469. @Override
  470. public boolean canRead() {
  471. return getter != null;
  472. }
  473. @Override
  474. public Object getValue() throws IllegalAccessException, InvocationTargetException {
  475. synchronized (valueLock) {
  476. if (value == null) {
  477. value = valueCalculating;
  478. debugger.getRequestProcessor().post(new Runnable() {
  479. @Override
  480. public void run() {
  481. try {
  482. RemoteServices.runOnStoppedThread(t, new Runnable() {
  483. @Override
  484. public void run() {
  485. boolean[] isEditablePtr = new boolean[] { false };
  486. Type[] typePtr = new Type[] { null };
  487. String v = getValueLazy(isEditablePtr, typePtr);
  488. synchronized (valueLock) {
  489. value = v;
  490. valueIsEditable = isEditablePtr[0];
  491. valueType = typePtr[0];
  492. }
  493. ci.firePropertyChange(propertyName, null, v);
  494. }
  495. }, sType);
  496. } catch (PropertyVetoException ex) {
  497. value = ex.getLocalizedMessage();
  498. }
  499. }
  500. });
  501. }
  502. return value;
  503. }
  504. }
  505. private String getValueLazy(boolean[] isEditablePtr, Type[] typePtr) {
  506. Lock l = t.accessLock.writeLock();
  507. l.lock();
  508. try {
  509. Value v = ObjectReferenceWrapper.invokeMethod(component, tawt, getter, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED);
  510. if (v != null) {
  511. typePtr[0] = ValueWrapper.type(v);
  512. }
  513. if (v instanceof StringReference) {
  514. isEditablePtr[0] = true;
  515. return StringReferenceWrapper.value((StringReference) v);
  516. }
  517. if (v instanceof ObjectReference) {
  518. isEditablePtr[0] = false;
  519. Type t = ValueWrapper.type(v);
  520. if (t instanceof ClassType) {
  521. Method toStringMethod = ClassTypeWrapper.concreteMethodByName((ClassType) t, "toString", "()Ljava/lang/String;");
  522. v = ObjectReferenceWrapper.invokeMethod((ObjectReference) v, tawt, toStringMethod, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED);
  523. if (v instanceof StringReference) {
  524. return StringReferenceWrapper.value((StringReference) v);
  525. }
  526. }
  527. } else if (v instanceof PrimitiveValue) {
  528. isEditablePtr[0] = true;
  529. }
  530. return (v == null) ? "null" : MirrorWrapper.toString(v);
  531. } catch (InvalidTypeException ex) {
  532. Exceptions.printStackTrace(ex);
  533. return ex.getMessage();
  534. } catch (ClassNotPreparedExceptionWrapper ex) {
  535. Exceptions.printStackTrace(ex);
  536. return ex.getMessage();
  537. } catch (ClassNotLoadedException ex) {
  538. return ex.getMessage();
  539. } catch (IncompatibleThreadStateException ex) {
  540. Exceptions.printStackTrace(ex);
  541. return ex.getMessage();
  542. } catch (InternalExceptionWrapper ex) {
  543. return ex.getMessage();
  544. } catch (ObjectCollectedExceptionWrapper ocex) {
  545. return ocex.getLocalizedMessage();
  546. } catch (VMDisconnectedExceptionWrapper vmdex) {
  547. return vmdex.getLocalizedMessage();
  548. } catch (final InvocationException ex) {
  549. final InvocationExceptionTranslated iextr = new InvocationExceptionTranslated(ex, debugger);
  550. iextr.setPreferredThread(t);
  551. /*
  552. RequestProcessor.getDefault().post(new Runnable() {
  553. @Override
  554. public void run() {
  555. iextr.getMessage();
  556. iextr.getLocalizedMessage();
  557. iextr.getCause();
  558. iextr.getStackTrace();
  559. Exceptions.printStackTrace(iextr);
  560. Exceptions.printStackTrace(ex);
  561. }
  562. }, 100);
  563. */
  564. //Exceptions.printStackTrace(iextr);
  565. //Exceptions.printStackTrace(ex);
  566. return iextr.getMessage();
  567. } finally {
  568. l.unlock();
  569. }
  570. }
  571. private String setValueLazy(String val, String oldValue, Type type) {
  572. Value v;
  573. VirtualMachine vm = type.virtualMachine();
  574. try {
  575. if (type instanceof PrimitiveType) {
  576. String ts = TypeWrapper.name(type);
  577. try {
  578. if (Boolean.TYPE.getName().equals(ts)) {
  579. v = VirtualMachineWrapper.mirrorOf(vm, Boolean.parseBoolean(val));
  580. } else if (Byte.TYPE.getName().equals(ts)) {
  581. v = VirtualMachineWrapper.mirrorOf(vm, Byte.parseByte(val));
  582. } else if (Character.TYPE.getName().equals(ts)) {
  583. if (val.length() == 0) {
  584. throw new NumberFormatException("Zero length input.");
  585. }
  586. v = VirtualMachineWrapper.mirrorOf(vm, val.charAt(0));
  587. } else if (Short.TYPE.getName().equals(ts)) {
  588. v = VirtualMachineWrapper.mirrorOf(vm, Short.parseShort(val));
  589. } else if (Integer.TYPE.getName().equals(ts)) {
  590. v = VirtualMachineWrapper.mirrorOf(vm, Integer.parseInt(val));
  591. } else if (Long.TYPE.getName().equals(ts)) {
  592. v = VirtualMachineWrapper.mirrorOf(vm, Long.parseLong(val));
  593. } else if (Float.TYPE.getName().equals(ts)) {
  594. v = VirtualMachineWrapper.mirrorOf(vm, Float.parseFloat(val));
  595. } else if (Double.TYPE.getName().equals(ts)) {
  596. v = VirtualMachineWrapper.mirrorOf(vm, Double.parseDouble(val));
  597. } else {
  598. throw new IllegalArgumentException("Unknown type '"+ts+"'");
  599. }
  600. val = MirrorWrapper.toString(v);
  601. } catch (NumberFormatException nfex) {
  602. NotifyDescriptor msg = new NotifyDescriptor.Message(nfex.getLocalizedMessage(), NotifyDescriptor.WARNING_MESSAGE);
  603. DialogDisplayer.getDefault().notify(msg);
  604. return oldValue;
  605. }
  606. } else {
  607. if ("java.lang.String".equals(TypeWrapper.name(type))) {
  608. v = VirtualMachineWrapper.mirrorOf(vm, val);
  609. } else {
  610. throw new IllegalArgumentException("Unknown type '"+type.name()+"'");
  611. }
  612. }
  613. } catch (InternalExceptionWrapper iex) {
  614. return oldValue;
  615. } catch (UnsupportedOperationExceptionWrapper uex) {
  616. NotifyDescriptor msg = new NotifyDescriptor.Message(uex.getLocalizedMessage(), NotifyDescriptor.WARNING_MESSAGE);
  617. DialogDisplayer.getDefault().notify(msg);
  618. return oldValue;
  619. } catch (VMDisconnectedExceptionWrapper vmd) {
  620. return oldValue;
  621. }
  622. Lock l = t.accessLock.writeLock();
  623. l.lock();
  624. try {
  625. ObjectReferenceWrapper.invokeMethod(component, tawt, setter, Collections.singletonList(v), ObjectReference.INVOKE_SINGLE_THREADED);
  626. return val;
  627. } catch (InvalidTypeException ex) {
  628. Exceptions.printStackTrace(ex);
  629. return oldValue;
  630. } catch (ClassNotLoadedException ex) {
  631. Exceptions.printStackTrace(ex);
  632. return oldValue;
  633. } catch (IncompatibleThreadStateException ex) {
  634. Exceptions.printStackTrace(ex);
  635. return oldValue;
  636. } catch (InternalExceptionWrapper iex) {
  637. return oldValue;
  638. } catch (ObjectCollectedExceptionWrapper ocex) {
  639. NotifyDescriptor msg = new NotifyDescriptor.Message(ocex.getLocalizedMessage(), NotifyDescriptor.WARNING_MESSAGE);
  640. DialogDisplayer.getDefault().notify(msg);
  641. return oldValue;
  642. } catch (VMDisconnectedExceptionWrapper vmd) {
  643. return oldValue;
  644. } catch (final InvocationException ex) {
  645. final InvocationExceptionTranslated iextr = new InvocationExceptionTranslated(ex, debugger);
  646. iextr.setPreferredThread(t);
  647. RequestProcessor.getDefault().post(new Runnable() {
  648. @Override
  649. public void run() {
  650. iextr.getMessage();
  651. iextr.getLocalizedMessage();
  652. iextr.getCause();
  653. iextr.getStackTrace();
  654. Exceptions.printStackTrace(iextr);
  655. //Exceptions.printStackTrace(ex);
  656. }
  657. }, 100);
  658. //Exceptions.printStackTrace(iextr);
  659. //Exceptions.printStackTrace(ex);
  660. return oldValue;
  661. } finally {
  662. l.unlock();
  663. }
  664. }
  665. @Override
  666. public boolean canWrite() {
  667. synchronized (valueLock) {
  668. return setter != null && valueIsEditable;
  669. }
  670. }
  671. @Override
  672. public void setValue(final Object val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  673. if (!(val instanceof String)) {
  674. throw new IllegalArgumentException("val = "+val);
  675. }
  676. final String oldValue;
  677. final Type type;
  678. synchronized (valueLock) {
  679. oldValue = value;
  680. type = valueType;
  681. value = valueCalculating;
  682. }
  683. debugger.getRequestProcessor().post(new Runnable() {
  684. @Override
  685. public void run() {
  686. try {
  687. RemoteServices.runOnStoppedThread(t, new Runnable() {
  688. @Override
  689. public void run() {
  690. String v;
  691. Throwable t = null;
  692. try {
  693. v = setValueLazy((String) val, oldValue, type);
  694. } catch (Throwable th) {
  695. if (th instanceof ThreadDeath) {
  696. throw (ThreadDeath) th;
  697. }
  698. t = th;
  699. v = oldValue;
  700. }
  701. synchronized (valueLock) {
  702. value = v;
  703. }
  704. ci.firePropertyChange(propertyName, null, v);
  705. if (t != null) {
  706. Exceptions.printStackTrace(t);
  707. }
  708. }
  709. }, sType);
  710. } catch (PropertyVetoException ex) {
  711. NotifyDescriptor msg = new NotifyDescriptor.Message(ex.getLocalizedMessage(), NotifyDescriptor.WARNING_MESSAGE);
  712. DialogDisplayer.getDefault().notify(msg);
  713. }
  714. }
  715. });
  716. }
  717. }
  718. public static class FieldInfo {
  719. private String name;
  720. private Field f;
  721. private JavaComponentInfo parent;
  722. FieldInfo(Field f, JavaComponentInfo parent) {
  723. this.name = f.name();
  724. this.f = f;
  725. this.parent = parent;
  726. }
  727. public String getName() {
  728. return name;
  729. }
  730. public Field getField() {
  731. return f;
  732. }
  733. public JavaComponentInfo getParent() {
  734. return parent;
  735. }
  736. }
  737. public static class Stack {
  738. private Frame[] frames;
  739. public Stack(Frame[] frames) {
  740. this.frames = frames;
  741. }
  742. public Stack(CallStackFrame[] stackFrames) {
  743. int n = stackFrames.length;
  744. frames = new Frame[n];
  745. for (int i = 0; i < n; i++) {
  746. CallStackFrame sf = stackFrames[i];
  747. try {
  748. frames[i] = new Frame(sf.getClassName(), sf.getMethodName(), sf.getSourceName(null), sf.getLineNumber(null));
  749. } catch (AbsentInformationException ex) {
  750. frames[i] = new Frame(sf.getClassName(), sf.getMethodName(), null, sf.getLineNumber(null));
  751. }
  752. }
  753. }
  754. public Frame[] getFrames() {
  755. return frames;
  756. }
  757. @Override
  758. public String toString() {
  759. StringBuilder sb = new StringBuilder("Stack with "+frames.length+" elements.");
  760. for (Frame f : frames) {
  761. sb.append("\n ");
  762. sb.append(f.toString());
  763. }
  764. return sb.toString();
  765. }
  766. public static class Frame {
  767. private String className;
  768. private String methodName;
  769. private String fileName;
  770. private int lineNumber;
  771. public Frame(String className, String methodName, String fileName, int lineNumber) {
  772. this.className = className;
  773. this.methodName = methodName;
  774. this.fileName = fileName;
  775. this.lineNumber = lineNumber;
  776. }
  777. /** Parse a stack trace frame line */
  778. static Frame parseLine(String line) {
  779. if (line.startsWith("at ")) {
  780. line = line.substring(3);
  781. }
  782. int p = line.indexOf('(');
  783. if (p < 0) {
  784. return new Frame(line, "", "", 1);
  785. }
  786. int d = line.lastIndexOf('.', p);
  787. int start = line.lastIndexOf(' ', p);
  788. if (start < 0) start = 0;
  789. String cn;
  790. String mn;
  791. if (d >= 0) {
  792. cn = line.substring(start, d);
  793. mn = line.substring(d + 1, p);
  794. } else {
  795. cn = line.substring(start, p);
  796. mn = "";
  797. }
  798. p++;
  799. int col = line.indexOf(':', p);
  800. String fn;
  801. int ln;
  802. if (col > 0) {
  803. fn = line.substring(p, col);
  804. String lns = line.substring(col + 1);
  805. if (lns.endsWith(")")) lns = lns.substring(0, lns.length() - 1);
  806. try {
  807. ln = Integer.parseInt(lns);
  808. } catch (NumberFormatException nfex) {
  809. ln = 1;
  810. }
  811. } else {
  812. fn = line.substring(p);
  813. if (fn.endsWith(")")) fn = fn.substring(0, fn.length() - 1);
  814. ln = 1;
  815. }
  816. return new Frame(cn, mn, fn, ln);
  817. }
  818. public String getClassName() {
  819. return className;
  820. }
  821. public String getMethodName() {
  822. return methodName;
  823. }
  824. public String getFileName() {
  825. return fileName;
  826. }
  827. public int getLineNumber() {
  828. return lineNumber;
  829. }
  830. @Override
  831. public String toString() {
  832. return "Frame "+className+"."+methodName+"("+fileName+":"+lineNumber+")";
  833. }
  834. }
  835. }
  836. private static String escapeHTML(String message) {
  837. if (message == null) {
  838. return null;
  839. }
  840. int len = message.length();
  841. StringBuilder result = new StringBuilder(len + 20);
  842. char aChar;
  843. for (int i = 0; i < len; i++) {
  844. aChar = message.charAt(i);
  845. switch (aChar) {
  846. case '<':
  847. result.append("&lt;");
  848. break;
  849. case '>':
  850. result.append("&gt;");
  851. break;
  852. case '&':
  853. result.append("&amp;");
  854. break;
  855. case '"':
  856. result.append("&quot;");
  857. break;
  858. default:
  859. result.append(aChar);
  860. }
  861. }
  862. return result.toString();
  863. }
  864. }