1 package cz.cuni.amis.pogamut.sposh.elements;
2
3 import cz.cuni.amis.pogamut.sposh.exceptions.CycleException;
4 import cz.cuni.amis.pogamut.sposh.exceptions.DuplicateNameException;
5 import cz.cuni.amis.pogamut.sposh.exceptions.FubarException;
6 import cz.cuni.amis.pogamut.sposh.exceptions.InvalidNameException;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.awt.datatransfer.DataFlavor;
10 import java.util.Collections;
11 import java.util.LinkedList;
12 import java.util.logging.Level;
13 import java.util.logging.Logger;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public final class DriveCollection extends PoshDummyElement<DriveCollection, PoshPlan> implements INamedElement, IConditionElement<DriveCollection> {
46
47
48
49
50 private String name;
51
52
53
54
55
56
57
58 private final Trigger<DriveCollection> goal = new Trigger<DriveCollection>(this);
59
60
61
62
63 private final List<DriveElement> elements = new LinkedList<DriveElement>();
64
65
66
67 private final List<DriveElement> elementsUm = Collections.unmodifiableList(elements);
68
69
70
71 public static final String dcName = "dcName";
72
73
74
75 public static final DataFlavor dataFlavor = new DataFlavor(DriveCollection.class, "drive-collection-node");
76
77
78
79
80
81
82
83 DriveCollection(String name) {
84 assert name != null && !name.isEmpty();
85 this.name = name;
86 }
87
88
89
90
91
92
93
94
95
96 public void addDrive(DriveElement drive) throws DuplicateNameException {
97 int behindLastDriveIndex = elementsUm.size();
98 addDrive(behindLastDriveIndex, drive);
99 }
100
101 public void addDrive(int index, DriveElement drive) throws DuplicateNameException {
102 assert !elementsUm.contains(drive);
103
104 if (drive.getParent() != null) {
105 assert !drive.getParent().getChildDataNodes().contains(drive);
106 }
107
108 if (isUsedName(drive.getName(), elements)) {
109 throw new DuplicateNameException("DC " + name + " already have drive with name " + drive.getName());
110 }
111
112 elements.add(index, drive);
113 drive.setParent(this);
114
115 emitChildNode(drive);
116 }
117
118
119
120
121
122
123 public Trigger<DriveCollection> getGoal() {
124 return goal;
125 }
126
127
128
129
130
131
132
133 @Override
134 public Trigger<DriveCollection> getCondition() {
135 return getGoal();
136 }
137
138
139
140
141
142
143
144 public List<DriveElement> getDrives() {
145 return elementsUm;
146 }
147
148
149
150
151
152
153
154 public DriveElement getDrive(int id) {
155 return elementsUm.get(id);
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 @Override
174 public String toString() {
175 StringBuilder sb = new StringBuilder();
176 sb.append("\t(DC ").append(name);
177
178 if (!goal.isEmpty()) {
179 sb.append(" (goal ").append(goal.toString()).append(')');
180 }
181 sb.append('\n');
182
183 sb.append("\t\t(drives \n");
184 for (DriveElement element : elements) {
185
186 sb.append("\t\t\t (").append(element.toString()).append(")\n");
187 }
188 sb.append("\t\t)\n");
189 sb.append("\t)");
190 return sb.toString();
191 }
192
193
194
195
196
197
198
199 @Override
200 public List<PoshElement> getChildDataNodes() {
201 List<PoshElement> children = new ArrayList<PoshElement>(goal);
202 children.addAll(elementsUm);
203
204 return children;
205 }
206
207
208
209
210
211
212 @Override
213 public String getName() {
214 return name;
215 }
216
217
218
219
220
221
222
223
224 public void setName(String newName) throws InvalidNameException {
225 newName = newName.trim();
226 if (newName.matches(IDENT_PATTERN)) {
227 String oldName = name;
228 name = newName;
229 firePropertyChange(dcName, oldName, name);
230 } else {
231 throw new InvalidNameException("Name " + newName + " is not valid.");
232 }
233 }
234
235
236
237
238
239
240
241 @Override
242 public void rename(String newName) throws InvalidNameException, CycleException, DuplicateNameException {
243 setName(newName);
244 }
245
246 @Override
247 public boolean moveChild(int newIndex, PoshElement child) {
248 assert child instanceof DriveElement;
249 return moveChildInList(elements, (DriveElement) child, newIndex);
250 }
251
252 @Override
253 public DataFlavor getDataFlavor() {
254 return dataFlavor;
255 }
256
257 @Override
258 public LapType getType() {
259 return LapType.DRIVE_COLLECTION;
260 }
261
262
263
264
265
266
267
268
269 public void removeDrive(DriveElement drive) {
270 assert elements.contains(drive);
271
272 if (elements.size() == 1) {
273 String unusedName = getUnusedName("drive-", elementsUm);
274 try {
275 addDrive(LapElementsFactory.createDriveElement(unusedName));
276 } catch (DuplicateNameException ex) {
277 String msg = "Unused name " + unusedName + " is not unused.";
278 Logger.getLogger(DriveCollection.class.getName()).log(Level.SEVERE, msg, ex);
279 throw new FubarException(msg, ex);
280 }
281 }
282
283 int removedDrivePosition = elementsUm.indexOf(drive);
284
285 elements.remove(drive);
286 drive.setParent(null);
287
288 emitChildDeleted(drive, removedDrivePosition);
289 }
290 }