~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to scripting/php/dbginterface/src/org/netbeans/modules/scripting/php/dbginterface/models/Variable.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.scripting.php.dbginterface.models;
 
43
 
 
44
import java.beans.Customizer;
 
45
import java.beans.PropertyChangeEvent;
 
46
import java.beans.PropertyChangeListener;
 
47
import java.util.ArrayList;
 
48
import java.util.Collection;
 
49
import java.util.HashMap;
 
50
import java.util.HashSet;
 
51
import java.util.Iterator;
 
52
import java.util.List;
 
53
import java.util.Map;
 
54
import java.util.Set;
 
55
import org.netbeans.modules.scripting.php.dbginterface.api.VariableNode;
 
56
import org.netbeans.spi.viewmodel.ModelEvent;
 
57
import org.openide.util.NbBundle;
 
58
 
 
59
/**
 
60
 *
 
61
 * @author marcow
 
62
 */
 
63
public class Variable implements VariableNode, PropertyChangeListener, Customizer, Cloneable {
 
64
    public static final String PROP_VALUE = "value"; // NOI18N
 
65
    public static enum Type {
 
66
        UNDEFINED,
 
67
        LONG,
 
68
        DOUBLE,
 
69
        STRING,
 
70
        ARRAY,
 
71
        OBJECT,
 
72
        BOOLEAN,
 
73
        RESOURCE,
 
74
        REFERENCE,
 
75
        SOFT_REFERENCE };
 
76
        
 
77
    private static final Map<Type, String> typeStringMap;
 
78
    static {
 
79
        typeStringMap = new HashMap<Type, String>();
 
80
        typeStringMap.put(Type.UNDEFINED, NbBundle.getBundle(Variable.class).getString("TYPE_undefined")); // NOI18N
 
81
        typeStringMap.put(Type.LONG, NbBundle.getBundle(Variable.class).getString("TYPE_long")); // NOI18N
 
82
        typeStringMap.put(Type.DOUBLE, NbBundle.getBundle(Variable.class).getString("TYPE_double")); // NOI18N
 
83
        typeStringMap.put(Type.STRING, NbBundle.getBundle(Variable.class).getString("TYPE_string")); // NOI18N
 
84
        typeStringMap.put(Type.ARRAY, NbBundle.getBundle(Variable.class).getString("TYPE_array")); // NOI18N
 
85
        typeStringMap.put(Type.OBJECT, NbBundle.getBundle(Variable.class).getString("TYPE_object")); // NOI18N
 
86
        typeStringMap.put(Type.BOOLEAN, NbBundle.getBundle(Variable.class).getString("TYPE_boolean")); // NOI18N
 
87
        typeStringMap.put(Type.RESOURCE, NbBundle.getBundle(Variable.class).getString("TYPE_resource")); // NOI18N
 
88
        typeStringMap.put(Type.REFERENCE, NbBundle.getBundle(Variable.class).getString("TYPE_reference")); // NOI18N
 
89
        typeStringMap.put(Type.SOFT_REFERENCE, NbBundle.getBundle(Variable.class).getString("TYPE_soft_reference")); // NOI18N
 
90
    }
 
91
    
 
92
    // private DbgDebugger debugger; // Something like that, need to listen on state changes and needed to set values!
 
93
    private String name;
 
94
    private String longName;        // including possible parents
 
95
    private Variable parent;
 
96
    private Type type;
 
97
    private String typeString;
 
98
    private String value;           // String value
 
99
    private Variable ref;           // XXX Reference for now?
 
100
    private List<Variable> children;
 
101
    private Set<PropertyChangeListener> listeners = new HashSet<PropertyChangeListener>();
 
102
    
 
103
    /** Creates a new instance of Variable */
 
104
    public Variable(Variable parent, String name, Type type, String typeString) {
 
105
        this.parent = parent;
 
106
        this.type = type;
 
107
        this.typeString = typeString;
 
108
        setName(name);
 
109
        
 
110
        if (typeString == null || typeString.length() == 0) {
 
111
            this.typeString = typeStringMap.get(type);
 
112
        }
 
113
        
 
114
        if (parent != null) {
 
115
            addPropertyChangeListener(parent);
 
116
        }
 
117
    }
 
118
 
 
119
    public Variable(Variable parent, String name, Type type, String typeString, String value) {
 
120
        this(parent, name, type, typeString);
 
121
        
 
122
        this.value = value;
 
123
    }
 
124
    
 
125
    public String getValue() {
 
126
        return value;
 
127
    }
 
128
    
 
129
    public void setValue(String str) {
 
130
        String v;
 
131
        
 
132
        if (type == Type.STRING) {
 
133
            v = longName + "=\"" + str + "\"";
 
134
        }
 
135
        else {
 
136
            v = longName + "=" + str;
 
137
        }
 
138
 
 
139
        List<Variable> ret = new ArrayList<Variable>();
 
140
        // ret = debugger.eval(evalString);
 
141
        
 
142
        for (Variable va : ret) {
 
143
            if (va.longName.equals(longName)) {
 
144
                value = va.value;
 
145
                type = va.type;
 
146
                fireValueChanged(this);
 
147
                
 
148
                break;
 
149
            }
 
150
        }
 
151
    }
 
152
    
 
153
    public void setChildren(List<Variable> cList) {
 
154
        this.children = cList;
 
155
   }
 
156
 
 
157
    public VariableNode[] getChildren(int from, int to) {
 
158
        Variable[] ret = new Variable[to - from];
 
159
        
 
160
        for (int i = from; i < to; i++) {
 
161
            ret[i - from] = children.get(i);
 
162
        }
 
163
        
 
164
        return ret;
 
165
    }
 
166
 
 
167
    public boolean isLeaf() {
 
168
        return children == null || children.size() == 0;
 
169
    }
 
170
 
 
171
    public int getChildrenCount() {
 
172
        if (children == null) {
 
173
            return 0;
 
174
        }
 
175
        
 
176
        return children.size();
 
177
    }
 
178
 
 
179
    public String getTypeName() {
 
180
        return typeString;
 
181
    }
 
182
 
 
183
    public void setRef(Variable ref) {
 
184
        this.ref = ref;
 
185
    }
 
186
    
 
187
    public void setName(String name) {
 
188
        if (parent == null || parent.name == null || parent.name.length() == 0) {
 
189
            this.name = name;
 
190
            this.longName = name;
 
191
        }
 
192
        else {
 
193
            switch (parent.type) {
 
194
            case ARRAY:
 
195
                this.name = "[" + name + "]";
 
196
                this.longName = parent.longName + this.name;
 
197
                break;
 
198
            case OBJECT:
 
199
                this.name = name;
 
200
                this.longName = parent.longName + "->" + this.name;
 
201
                break;
 
202
            default:
 
203
                this.name = name;
 
204
                this.longName = name;
 
205
            }
 
206
        }
 
207
    }
 
208
    
 
209
    public void setObject(Object bean) {
 
210
        if (bean instanceof String) {
 
211
            setValue((String)bean);
 
212
        }
 
213
        else {
 
214
            throw new IllegalArgumentException("" + bean);
 
215
        }
 
216
    }
 
217
 
 
218
    public String toString() {
 
219
        return longName + " = " + getTooltipValue();
 
220
    }
 
221
    
 
222
    
 
223
    public void addPropertyChangeListener(PropertyChangeListener l) {
 
224
        synchronized (listeners) {
 
225
            listeners.add(l);
 
226
        }
 
227
    }
 
228
 
 
229
    public void removePropertyChangeListener(PropertyChangeListener l) {
 
230
        synchronized (listeners) {
 
231
            listeners.remove(l);
 
232
        }
 
233
    }
 
234
 
 
235
    public void propertyChange(PropertyChangeEvent e) {
 
236
        if (children.contains(e.getSource())) {
 
237
            fireValueChanged(e.getSource());
 
238
            
 
239
            return;
 
240
        }
 
241
        throw new UnsupportedOperationException("Not supported yet.");
 
242
    }
 
243
 
 
244
    private void fireValueChanged(Object value) {
 
245
        PropertyChangeEvent evt = new PropertyChangeEvent(this, PROP_VALUE, null, value);
 
246
        PropertyChangeListener[] ls;
 
247
        
 
248
        synchronized (listeners) {
 
249
            ls = listeners.toArray(new PropertyChangeListener[listeners.size()]);
 
250
        }
 
251
        
 
252
        for (int i = 0; i < ls.length; i++) {
 
253
            ls[i].propertyChange(evt);
 
254
        }
 
255
    }
 
256
 
 
257
    public String getName() {
 
258
        return name;
 
259
    }
 
260
 
 
261
    public String getDisplayName() {
 
262
        return longName;
 
263
    }
 
264
 
 
265
    public String getShortDescription() {
 
266
        return null;
 
267
    }
 
268
 
 
269
    public String getIconBase() {
 
270
        // XXX for now
 
271
        return LOCAL_VARIABLE_ICON;
 
272
    }
 
273
    
 
274
 
 
275
    public boolean isReadOnly() {
 
276
       return type != Type.BOOLEAN && type != Type.DOUBLE && type != Type.LONG && type != Type.STRING ;
 
277
    }
 
278
 
 
279
    public String getTooltipValue() {
 
280
        String ret = "";
 
281
        
 
282
        if (children != null) {
 
283
            boolean first = true;
 
284
            
 
285
            ret += "[ ";
 
286
            
 
287
            for (Variable child : children) {
 
288
                if (!first) {
 
289
                    ret += ", ";
 
290
                }
 
291
                ret += child.toString();
 
292
                first = false;
 
293
            }
 
294
            
 
295
            ret += " ]";
 
296
        }
 
297
        else if (ref != null) {
 
298
            ret += " -> " + ref.longName;
 
299
        }
 
300
        else {
 
301
            ret += value;
 
302
        }
 
303
        
 
304
        return ret;
 
305
    }
 
306
 
 
307
    public void collectUpdates(Object source,
 
308
                               Collection<ModelEvent> events,
 
309
                               VariableNode n) {
 
310
        Variable newVar = (Variable)n;
 
311
        boolean hasChanged = false;
 
312
        
 
313
        assert name.equals(newVar.getName());
 
314
 
 
315
        if (type != newVar.type) {
 
316
            type = newVar.type;
 
317
            hasChanged = true;
 
318
        }
 
319
        
 
320
        if (!typeString.equals(newVar.typeString)) {
 
321
            typeString = newVar.typeString;
 
322
            hasChanged = true;
 
323
        }
 
324
        
 
325
        if (value == null && newVar.value != null ||
 
326
                newVar.value != null && !newVar.value.equals(value)) {
 
327
            value = newVar.value;
 
328
            hasChanged = true;
 
329
        }
 
330
        
 
331
        if (ref == null && newVar.ref != null ||
 
332
                newVar.ref != null && !newVar.ref.longName.equals(ref.longName)) {
 
333
            ref = newVar.ref;
 
334
            hasChanged = true;
 
335
        }
 
336
        
 
337
        if (children == null && newVar.children != null) {
 
338
            children = newVar.children;
 
339
            hasChanged = true;
 
340
        }
 
341
        else if (children != null) {
 
342
            Iterator<Variable> it = children.iterator();
 
343
            
 
344
            while (it.hasNext()) {
 
345
                Variable child = it.next();
 
346
                Variable newChild = newVar.findChild(child.name);
 
347
                
 
348
                if (newChild != null) {
 
349
                    newVar.removeChild(newChild);
 
350
                    child.collectUpdates(source, events, newChild);
 
351
                }
 
352
                else {
 
353
                    it.remove();
 
354
                    hasChanged = true;
 
355
                }
 
356
            }
 
357
            
 
358
            if (newVar.children != null && newVar.children.size() > 0) {
 
359
                it = newVar.children.iterator();
 
360
                
 
361
                while (it.hasNext()) {
 
362
                    Variable newChild = it.next();
 
363
                    
 
364
                    it.remove();
 
365
                    addChild(newChild);
 
366
                    hasChanged = true;
 
367
                }
 
368
            }
 
369
        }
 
370
 
 
371
        if (hasChanged) {
 
372
            events.add(new ModelEvent.NodeChanged(source, this));
 
373
        }
 
374
    }
 
375
    
 
376
    private Variable findChild(String n) {
 
377
        if (children == null || n == null || n.length() == 0) {
 
378
            return null;
 
379
        }
 
380
        
 
381
        for (Variable child : children) {
 
382
            if (child.name.equals(n)) {
 
383
                return child;
 
384
            }
 
385
        }
 
386
        
 
387
        return null;
 
388
    }
 
389
    
 
390
    private void removeChild(Variable child) {
 
391
        if (child == null || children == null) {
 
392
            return;
 
393
        }
 
394
        
 
395
        children.remove(child);
 
396
        child.parent = null;
 
397
        // XXX Change events?
 
398
    }
 
399
    
 
400
    private void addChild(Variable child) {
 
401
        if (child == null) {
 
402
            return;
 
403
        }
 
404
        
 
405
        if (children == null) {
 
406
            children = new ArrayList<Variable>();
 
407
        }
 
408
        
 
409
        children.add(child);
 
410
        child.parent = this;
 
411
        // XXX Change events?
 
412
    }
 
413
    
 
414
    public int getType() {
 
415
        return TYPE_LOCAL_FIELD;
 
416
    }
 
417
}