001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.debug.core.logicalstructures;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.HashMap;
015: import java.util.HashSet;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019: import java.util.Set;
020: import java.util.StringTokenizer;
021:
022: import org.eclipse.core.runtime.CoreException;
023: import org.eclipse.core.runtime.IConfigurationElement;
024: import org.eclipse.core.runtime.IExtensionPoint;
025: import org.eclipse.core.runtime.Platform;
026: import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
027: import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
028: import org.eclipse.debug.core.DebugException;
029: import org.eclipse.debug.core.ILogicalStructureProvider;
030: import org.eclipse.debug.core.ILogicalStructureType;
031: import org.eclipse.debug.core.model.IValue;
032: import org.eclipse.jdt.debug.core.IJavaClassType;
033: import org.eclipse.jdt.debug.core.IJavaInterfaceType;
034: import org.eclipse.jdt.debug.core.IJavaObject;
035: import org.eclipse.jdt.debug.core.IJavaType;
036: import org.eclipse.jdt.debug.core.JDIDebugModel;
037: import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
038:
039: public class JavaLogicalStructures implements ILogicalStructureProvider {
040:
041: // preference values
042: static final char IS_SUBTYPE_TRUE = 'T';
043: static final char IS_SUBTYPE_FALSE = 'F';
044:
045: /**
046: * The list of java logical structures.
047: */
048: private static Map fJavaLogicalStructureMap;
049:
050: /**
051: * The list of java logical structures in this Eclipse install.
052: */
053: private static List fPluginContributedJavaLogicalStructures;
054:
055: /**
056: * The list of java logical structures defined by the user.
057: */
058: private static List fUserDefinedJavaLogicalStructures;
059:
060: /**
061: * The list of java logical structures listeners.
062: */
063: private static Set fListeners = new HashSet();
064:
065: /**
066: * Preference key for the list of user defined Java logical structures
067: *
068: * @since 3.1
069: */
070: private static final String PREF_JAVA_LOGICAL_STRUCTURES = JDIDebugModel
071: .getPluginIdentifier()
072: + ".PREF_JAVA_LOGICAL_STRUCTURES"; //$NON-NLS-1$
073:
074: /**
075: * Updates user defined logical structures if the preference changes
076: */
077: static class PreferenceListener implements IPropertyChangeListener {
078:
079: /* (non-Javadoc)
080: * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
081: */
082: public void propertyChange(PropertyChangeEvent event) {
083: if (PREF_JAVA_LOGICAL_STRUCTURES
084: .equals(event.getProperty())) {
085: initUserDefinedJavaLogicalStructures();
086: initJavaLogicalStructureMap();
087: Iterator iter = fListeners.iterator();
088: while (iter.hasNext()) {
089: ((IJavaStructuresListener) iter.next())
090: .logicalStructuresChanged();
091: }
092: }
093: }
094:
095: }
096:
097: /**
098: * Get the logical structure from the extension point and the preference store,
099: * and initialize the map.
100: */
101: static {
102: initPluginContributedJavaLogicalStructure();
103: initUserDefinedJavaLogicalStructures();
104: initJavaLogicalStructureMap();
105: JDIDebugPlugin.getDefault().getPluginPreferences()
106: .addPropertyChangeListener(new PreferenceListener());
107: }
108:
109: private static void initJavaLogicalStructureMap() {
110: fJavaLogicalStructureMap = new HashMap();
111: addAllLogicalStructures(fPluginContributedJavaLogicalStructures);
112: addAllLogicalStructures(fUserDefinedJavaLogicalStructures);
113: }
114:
115: /**
116: * @param pluginContributedJavaLogicalStructures
117: */
118: private static void addAllLogicalStructures(
119: List pluginContributedJavaLogicalStructures) {
120: for (Iterator iter = pluginContributedJavaLogicalStructures
121: .iterator(); iter.hasNext();) {
122: addLogicalStructure((JavaLogicalStructure) iter.next());
123: }
124: }
125:
126: /**
127: * @param structure
128: */
129: private static void addLogicalStructure(
130: JavaLogicalStructure structure) {
131: String typeName = structure.getQualifiedTypeName();
132: List logicalStructure = (List) fJavaLogicalStructureMap
133: .get(typeName);
134: if (logicalStructure == null) {
135: logicalStructure = new ArrayList();
136: fJavaLogicalStructureMap.put(typeName, logicalStructure);
137: }
138: logicalStructure.add(structure);
139: }
140:
141: /**
142: * Get the configuration elements for the extension point.
143: */
144: private static void initPluginContributedJavaLogicalStructure() {
145: fPluginContributedJavaLogicalStructures = new ArrayList();
146: IExtensionPoint extensionPoint = Platform
147: .getExtensionRegistry()
148: .getExtensionPoint(
149: JDIDebugPlugin.getUniqueIdentifier(),
150: JDIDebugPlugin.EXTENSION_POINT_JAVA_LOGICAL_STRUCTURES);
151: IConfigurationElement[] javaLogicalStructureElements = extensionPoint
152: .getConfigurationElements();
153: for (int i = 0; i < javaLogicalStructureElements.length; i++) {
154: try {
155: fPluginContributedJavaLogicalStructures
156: .add(new JavaLogicalStructure(
157: javaLogicalStructureElements[i]));
158: } catch (CoreException e) {
159: JDIDebugPlugin.log(e);
160: }
161: }
162: }
163:
164: /**
165: * Get the user defined logical structures (from the preference store).
166: */
167: private static void initUserDefinedJavaLogicalStructures() {
168: fUserDefinedJavaLogicalStructures = new ArrayList();
169: String logicalStructuresString = JDIDebugModel.getPreferences()
170: .getString(PREF_JAVA_LOGICAL_STRUCTURES);
171: StringTokenizer tokenizer = new StringTokenizer(
172: logicalStructuresString, "\0", true); //$NON-NLS-1$
173: while (tokenizer.hasMoreTokens()) {
174: String type = tokenizer.nextToken();
175: tokenizer.nextToken();
176: String description = tokenizer.nextToken();
177: tokenizer.nextToken();
178: String isSubtypeValue = tokenizer.nextToken();
179: boolean isSubtype = isSubtypeValue.charAt(0) == IS_SUBTYPE_TRUE;
180: tokenizer.nextToken();
181: String value = tokenizer.nextToken();
182: if (value.charAt(0) == '\0') {
183: value = null;
184: } else {
185: tokenizer.nextToken();
186: }
187: String variablesCounterValue = tokenizer.nextToken();
188: int variablesCounter = Integer
189: .parseInt(variablesCounterValue);
190: tokenizer.nextToken();
191: String[][] variables = new String[variablesCounter][2];
192: for (int i = 0; i < variablesCounter; i++) {
193: variables[i][0] = tokenizer.nextToken();
194: tokenizer.nextToken();
195: variables[i][1] = tokenizer.nextToken();
196: tokenizer.nextToken();
197: }
198: fUserDefinedJavaLogicalStructures
199: .add(new JavaLogicalStructure(type, isSubtype,
200: value, description, variables));
201: }
202: }
203:
204: /**
205: * Save the user defined logical structures in the preference store.
206: */
207: public static void saveUserDefinedJavaLogicalStructures() {
208: StringBuffer logicalStructuresString = new StringBuffer();
209: for (Iterator iter = fUserDefinedJavaLogicalStructures
210: .iterator(); iter.hasNext();) {
211: JavaLogicalStructure logicalStructure = (JavaLogicalStructure) iter
212: .next();
213: logicalStructuresString.append(
214: logicalStructure.getQualifiedTypeName()).append(
215: '\0');
216: logicalStructuresString.append(
217: logicalStructure.getDescription()).append('\0');
218: logicalStructuresString.append(
219: logicalStructure.isSubtypes() ? IS_SUBTYPE_TRUE
220: : IS_SUBTYPE_FALSE).append('\0');
221: String value = logicalStructure.getValue();
222: if (value != null) {
223: logicalStructuresString.append(value);
224: }
225: logicalStructuresString.append('\0');
226: String[][] variables = logicalStructure.getVariables();
227: logicalStructuresString.append(variables.length).append(
228: '\0');
229: for (int i = 0; i < variables.length; i++) {
230: String[] strings = variables[i];
231: logicalStructuresString.append(strings[0]).append('\0');
232: logicalStructuresString.append(strings[1]).append('\0');
233: }
234: }
235: JDIDebugModel.getPreferences().setValue(
236: PREF_JAVA_LOGICAL_STRUCTURES,
237: logicalStructuresString.toString());
238: }
239:
240: /**
241: * Return all the defined logical structures.
242: */
243: public static JavaLogicalStructure[] getJavaLogicalStructures() {
244: JavaLogicalStructure[] logicalStructures = new JavaLogicalStructure[fPluginContributedJavaLogicalStructures
245: .size()
246: + fUserDefinedJavaLogicalStructures.size()];
247: int i = 0;
248: for (Iterator iter = fPluginContributedJavaLogicalStructures
249: .iterator(); iter.hasNext();) {
250: logicalStructures[i++] = (JavaLogicalStructure) iter.next();
251: }
252: for (Iterator iter = fUserDefinedJavaLogicalStructures
253: .iterator(); iter.hasNext();) {
254: logicalStructures[i++] = (JavaLogicalStructure) iter.next();
255: }
256: return logicalStructures;
257: }
258:
259: /**
260: * Set the user defined logical structures.
261: */
262: public static void setUserDefinedJavaLogicalStructures(
263: JavaLogicalStructure[] logicalStructures) {
264: fUserDefinedJavaLogicalStructures = Arrays
265: .asList(logicalStructures);
266: saveUserDefinedJavaLogicalStructures();
267: }
268:
269: public static void addStructuresListener(
270: IJavaStructuresListener listener) {
271: fListeners.add(listener);
272: }
273:
274: public static void removeStructuresListener(
275: IJavaStructuresListener listener) {
276: fListeners.remove(listener);
277: }
278:
279: public ILogicalStructureType[] getLogicalStructureTypes(IValue value) {
280: if (!(value instanceof IJavaObject)) {
281: return new ILogicalStructureType[0];
282: }
283: IJavaObject javaValue = (IJavaObject) value;
284: List logicalStructures = new ArrayList();
285: try {
286: IJavaType type = javaValue.getJavaType();
287: if (!(type instanceof IJavaClassType)) {
288: return new ILogicalStructureType[0];
289: }
290: IJavaClassType classType = (IJavaClassType) type;
291: List list = (List) fJavaLogicalStructureMap.get(classType
292: .getName());
293: if (list != null) {
294: logicalStructures.addAll(list);
295: }
296: IJavaClassType super Class = classType.getSuperclass();
297: while (super Class != null) {
298: addIfIsSubtype(logicalStructures,
299: (List) fJavaLogicalStructureMap.get(super Class
300: .getName()));
301: super Class = super Class.getSuperclass();
302: }
303: IJavaInterfaceType[] super Interfaces = classType
304: .getAllInterfaces();
305: for (int i = 0; i < super Interfaces.length; i++) {
306: addIfIsSubtype(logicalStructures,
307: (List) fJavaLogicalStructureMap
308: .get(super Interfaces[i].getName()));
309: }
310: } catch (DebugException e) {
311: JDIDebugPlugin.log(e);
312: return new ILogicalStructureType[0];
313: }
314: return (ILogicalStructureType[]) logicalStructures
315: .toArray(new ILogicalStructureType[logicalStructures
316: .size()]);
317: }
318:
319: private void addIfIsSubtype(List logicalStructures, List list) {
320: if (list == null) {
321: return;
322: }
323: for (Iterator iter = list.iterator(); iter.hasNext();) {
324: JavaLogicalStructure logicalStructure = (JavaLogicalStructure) iter
325: .next();
326: if (logicalStructure.isSubtypes()) {
327: logicalStructures.add(logicalStructure);
328: }
329: }
330: }
331:
332: }
|