|
1 |
| |
|
2 |
| |
|
3 |
| |
|
4 |
| |
|
5 |
| |
|
6 |
| |
|
7 |
| |
|
8 |
| |
|
9 |
| |
|
10 |
| |
|
11 |
| |
|
12 |
| |
|
13 |
| |
|
14 |
| |
|
15 |
| |
|
16 |
| |
|
17 |
| |
|
18 |
| |
|
19 |
| |
|
20 |
| |
|
21 |
| |
|
22 |
| |
|
23 |
| |
|
24 |
| |
|
25 |
| |
|
26 |
| |
|
27 |
| |
|
28 |
| |
|
29 |
| |
|
30 |
| |
|
31 |
| |
|
32 |
| |
|
33 |
| |
|
34 |
| |
|
35 |
| |
|
36 |
| |
|
37 |
| package edu.rice.cs.drjava.config; |
|
38 |
| |
|
39 |
| import java.util.Set; |
|
40 |
| import java.util.Map; |
|
41 |
| import java.util.HashSet; |
|
42 |
| import java.util.HashMap; |
|
43 |
| import java.util.Iterator; |
|
44 |
| import edu.rice.cs.plt.lambda.Lambda; |
|
45 |
| |
|
46 |
| |
|
47 |
| |
|
48 |
| |
|
49 |
| public abstract class DrJavaProperty implements Cloneable { |
|
50 |
| |
|
51 |
| public volatile boolean DEACTIVATED_DUE_TO_ERROR = false; |
|
52 |
| |
|
53 |
| |
|
54 |
| protected String _name; |
|
55 |
| |
|
56 |
| protected String _value = "--uninitialized--"; |
|
57 |
| |
|
58 |
| protected boolean _isCurrent = false; |
|
59 |
| |
|
60 |
| protected String _help = "Help unavailable."; |
|
61 |
| |
|
62 |
| protected HashMap<String,String> _attributes = new HashMap<String,String>(); |
|
63 |
| |
|
64 |
| |
|
65 |
| protected Set<DrJavaProperty> _listening = new HashSet<DrJavaProperty>(); |
|
66 |
| |
|
67 |
| |
|
68 |
6106
| public DrJavaProperty(String name, String help) {
|
|
69 |
0
| if (name == null) { throw new IllegalArgumentException("DrJavaProperty name is null"); }
|
|
70 |
6106
| _name = name;
|
|
71 |
6106
| if (help != null) { _help = help; }
|
|
72 |
6106
| resetAttributes();
|
|
73 |
| } |
|
74 |
| |
|
75 |
| |
|
76 |
320
| public DrJavaProperty(String name, String value, String help) {
|
|
77 |
320
| this(name, help);
|
|
78 |
0
| if (value == null) { throw new IllegalArgumentException("DrJavaProperty value is null"); }
|
|
79 |
320
| if (help != null) { _help = help; }
|
|
80 |
320
| _value = value;
|
|
81 |
320
| _isCurrent = true;
|
|
82 |
| } |
|
83 |
| |
|
84 |
| |
|
85 |
43442
| public String getName() { return _name; }
|
|
86 |
| |
|
87 |
| |
|
88 |
| |
|
89 |
456
| public String getCurrent(PropertyMaps pm) {
|
|
90 |
456
| if (!isCurrent()) {
|
|
91 |
456
| update(pm);
|
|
92 |
0
| if (_value == null) { throw new IllegalArgumentException("DrJavaProperty value is null"); }
|
|
93 |
456
| _isCurrent = true;
|
|
94 |
| } |
|
95 |
456
| return _value;
|
|
96 |
| } |
|
97 |
| |
|
98 |
| |
|
99 |
| |
|
100 |
64
| public String getLazy(PropertyMaps pm) {
|
|
101 |
0
| if (_value == null) { throw new IllegalArgumentException("DrJavaProperty value is null"); }
|
|
102 |
64
| return _value;
|
|
103 |
| } |
|
104 |
| |
|
105 |
| |
|
106 |
| |
|
107 |
| public abstract void update(PropertyMaps pm); |
|
108 |
| |
|
109 |
| |
|
110 |
1238
| public void resetAttributes() { _attributes.clear(); }
|
|
111 |
| |
|
112 |
| |
|
113 |
| |
|
114 |
| |
|
115 |
| |
|
116 |
| |
|
117 |
346
| public void setAttribute(String key, String value) {
|
|
118 |
346
| if (!_attributes.containsKey(key)) {
|
|
119 |
1
| throw new IllegalArgumentException("Attribute " + key + " not known to property " + _name);
|
|
120 |
| } |
|
121 |
345
| _attributes.put(key, value);
|
|
122 |
| } |
|
123 |
| |
|
124 |
| |
|
125 |
| |
|
126 |
| |
|
127 |
| |
|
128 |
| |
|
129 |
7
| public void setAttributes(HashMap<String,String> attrs, Lambda<String,String> replaceLambda) {
|
|
130 |
7
| for(Map.Entry<String,String> e: attrs.entrySet()) {
|
|
131 |
10
| setAttribute(e.getKey(), replaceLambda.value(e.getValue()));
|
|
132 |
| } |
|
133 |
| } |
|
134 |
| |
|
135 |
| |
|
136 |
| |
|
137 |
| |
|
138 |
| |
|
139 |
0
| public String getAttribute(String key) {
|
|
140 |
0
| if (!_attributes.containsKey(key)) {
|
|
141 |
0
| throw new IllegalArgumentException("Attribute " + key + " not known to property " + _name);
|
|
142 |
| } |
|
143 |
0
| return _attributes.get(key);
|
|
144 |
| } |
|
145 |
| |
|
146 |
| |
|
147 |
32
| public String toString() { return _value; }
|
|
148 |
| |
|
149 |
| |
|
150 |
274
| public String getHelp() { return _help; }
|
|
151 |
| |
|
152 |
| |
|
153 |
6
| public boolean isCurrent() { return _isCurrent; }
|
|
154 |
| |
|
155 |
| |
|
156 |
6
| public void invalidate() {
|
|
157 |
6
| _invalidate();
|
|
158 |
6
| invalidateOthers(new HashSet<DrJavaProperty>());
|
|
159 |
| } |
|
160 |
| |
|
161 |
| |
|
162 |
357
| protected void _invalidate() { _isCurrent = false; }
|
|
163 |
| |
|
164 |
298
| public DrJavaProperty listenToInvalidatesOf(DrJavaProperty other) {
|
|
165 |
298
| if (other == this) {
|
|
166 |
0
| DEACTIVATED_DUE_TO_ERROR = true;
|
|
167 |
0
| RuntimeException e =
|
|
168 |
| new IllegalArgumentException("Property cannot listen for invalidation of itself. " + |
|
169 |
| "Variables for external processes will not function correctly anymore. " + |
|
170 |
| "This is a SERIOUS programming error. Please notify the DrJava team."); |
|
171 |
0
| edu.rice.cs.drjava.ui.DrJavaErrorHandler.record(e);
|
|
172 |
0
| throw e;
|
|
173 |
| } |
|
174 |
298
| other._listening.add(this);
|
|
175 |
298
| return this;
|
|
176 |
| } |
|
177 |
| |
|
178 |
| |
|
179 |
156
| public boolean equals(Object other) {
|
|
180 |
0
| if (other == null || other.getClass() != this.getClass()) return false;
|
|
181 |
| |
|
182 |
156
| DrJavaProperty o = (DrJavaProperty) other;
|
|
183 |
156
| return _name.equals(o._name);
|
|
184 |
| |
|
185 |
| } |
|
186 |
| |
|
187 |
| |
|
188 |
1366
| public int hashCode() { return _name.hashCode(); }
|
|
189 |
| |
|
190 |
| |
|
191 |
| |
|
192 |
534
| protected void invalidateOthers(Set<DrJavaProperty> alreadyVisited) {
|
|
193 |
0
| if (DEACTIVATED_DUE_TO_ERROR) { return; }
|
|
194 |
534
| if (alreadyVisited.contains(this)) {
|
|
195 |
0
| Iterator<DrJavaProperty> it = alreadyVisited.iterator();
|
|
196 |
0
| StringBuilder sb = new StringBuilder("Invalidating ");
|
|
197 |
0
| sb.append(getName());
|
|
198 |
0
| sb.append(" after already having invalidated ");
|
|
199 |
0
| boolean first = true;
|
|
200 |
0
| while (it.hasNext()) {
|
|
201 |
0
| if (first) { first = false; }
|
|
202 |
0
| else { sb.append(", "); }
|
|
203 |
0
| sb.append(it.next().getName());
|
|
204 |
| } |
|
205 |
0
| sb.append(". Variables for external processes will not function correctly anymore. " +
|
|
206 |
| "This is a SERIOUS programming error. Please notify the DrJava team."); |
|
207 |
0
| DEACTIVATED_DUE_TO_ERROR = true;
|
|
208 |
0
| RuntimeException e = new InfiniteLoopException(sb.toString());
|
|
209 |
0
| edu.rice.cs.drjava.ui.DrJavaErrorHandler.record(e);
|
|
210 |
0
| throw e;
|
|
211 |
| } |
|
212 |
534
| alreadyVisited.add(this);
|
|
213 |
534
| Iterator<DrJavaProperty> it = _listening.iterator();
|
|
214 |
534
| while(it.hasNext()) {
|
|
215 |
351
| DrJavaProperty prop = it.next();
|
|
216 |
351
| prop._invalidate();
|
|
217 |
351
| prop.invalidateOthers(alreadyVisited);
|
|
218 |
| } |
|
219 |
| } |
|
220 |
| |
|
221 |
| |
|
222 |
| public static class InfiniteLoopException extends RuntimeException { |
|
223 |
0
| public InfiniteLoopException(String s) { super(s); }
|
|
224 |
| } |
|
225 |
| } |