View Javadoc

1   /*
2    * Copyright (c) 2005, The K-Wf Grid Consortium
3    * Fraunhofer Institute for Computer Architecture and Software Technology
4    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
5    */
6   package net.kwfgrid.gworkflowdl.protocol.xupdate;
7   
8   import net.kwfgrid.gworkflowdl.protocol.calls.IMethodCallMarshaller;
9   import net.kwfgrid.gworkflowdl.protocol.structure.*;
10  import net.kwfgrid.gworkflowdl.protocol.util.StructureUtils;
11  import net.kwfgrid.gworkflowdl.protocol.xml.GWDLMarshaller;
12  import net.kwfgrid.gworkflowdl.structure.*;
13  import net.kwfgrid.jxupdate.xupdate.XUpdateSerializer;
14  import org.xmlpull.v1.XmlSerializer;
15  
16  import java.io.IOException;
17  
18  /***
19   * Implementation of <code>IMethodCallMarshaller</code> which marshals method calls in XUpdate syntax.
20   */
21  public class XUMethodCallMarshaller implements IMethodCallMarshaller {
22      public XUMethodCallMarshaller() {
23          //
24      }
25  
26      ///
27      /// Generic Methods
28      /// ----------------------------------------------------------------------------------------------------
29  
30      protected void marshalSetDescription(XUpdateSerializer serializer, String select, String child, String olddescription, String newdescription) throws IOException {
31          if (GWDLMarshaller.isDefaultDescription(olddescription) && GWDLMarshaller.isDefaultDescription(newdescription)) {
32              //
33          } else if (GWDLMarshaller.isDefaultDescription(olddescription)) {
34              serializer.startAppend(select, child);
35              GWDLMarshaller.description(serializer, newdescription);
36              serializer.endAppend();
37          } else if (GWDLMarshaller.isDefaultDescription(newdescription)) {
38              serializer.remove(select + "/description");
39          } else {
40              serializer.update(select + "/description", newdescription);
41          }
42  
43      }
44  
45      protected void marshalSetProperty(XUpdateSerializer serializer, String select, String child, String key, String oldvalue, String newvalue) throws IOException {
46          if (oldvalue != null && newvalue != null) {
47              serializer.update(select + "/property[@name='" + key + "']", newvalue);
48          } else if (oldvalue == null && newvalue != null) {
49              serializer.startAppend(select, child);
50              GWDLMarshaller.property(serializer, key, newvalue);
51              serializer.endAppend();
52          } else if (oldvalue != null && newvalue == null) {
53              serializer.remove(select + "/property[@name='" + key + "']");
54          }
55      }
56  
57      protected void marshalRemoveProperty(XUpdateSerializer serializer, String select, String key, String oldvalue) throws IOException {
58          if (oldvalue != null) {
59              serializer.remove(select + "/property[@name='" + key + "']");
60          }
61      }
62  
63      protected void marshalAppendOwlsGwdlList(XUpdateSerializer serializer, String select, int offset, String[] owl) throws IOException {
64          for (int i = 0; i < owl.length; i++) {
65              serializer.startAppend(select, "" + (offset + i));
66              GWDLMarshaller.owlgwdl(serializer, owl[i]);
67              serializer.endAppend();
68          }
69      }
70  
71      ///
72      /// Methods for GenericProperties
73      /// ----------------------------------------------------------------------------------------------------
74  
75      public void marshalGenericPropertiesSetProperty(XmlSerializer x, ProtocolProperties properties, int index, ProtocolProperty property)
76              throws IOException, IndexOutOfBoundsException {
77          XUpdateSerializer serializer = (XUpdateSerializer) x;
78          if (index >= properties.size())
79              throw new IndexOutOfBoundsException("Property index out of range of GenericProperties size.");
80          Property old = properties.getProperty(index);
81          Object owner = properties.getParent();
82          String select = null;
83          if (owner instanceof Workflow) {
84              select = "/workflow";
85          } else if (owner instanceof Place) {
86              select = selectPlace((Place) owner);
87          } else if (owner instanceof Transition) {
88              select = selectTransition((Transition) owner);
89          } else {
90              throw new IOException("Owner of GenericProperties must be Workflow, Place or Transition, not " + owner.getClass().getName());
91          }
92          String selectkey = select + "/property[@name='" + old.getKey() + "']/@name";
93          String selectvalue = select + "/property[@name='" + property.getKey() + "']";
94          serializer.update(selectkey, property.getKey());
95          serializer.update(selectvalue, property.getValue());
96      }
97  
98      public void marshalGenericPropertiesPut(XmlSerializer x, ProtocolProperties properties, String key, String value) throws IOException {
99          XUpdateSerializer serializer = (XUpdateSerializer) x;
100         String old = properties.get(key);
101         Object owner = properties.getParent();
102         String select;
103         int child;
104         if (owner instanceof Workflow) {
105             select = "/workflow";
106             child = afterLastPropertyIndex((Workflow) owner);
107         } else if (owner instanceof Place) {
108             select = selectPlace((Place) owner);
109             child = afterLastPropertyIndex((Place) owner);
110         } else if (owner instanceof Transition) {
111             select = selectTransition((Transition) owner);
112             child = afterLastPropertyIndex((Transition) owner);
113         } else {
114             throw new IOException("Owner of GenericProperties must be Workflow, Place or Transition, not " + owner.getClass().getName());
115         }
116         marshalSetProperty(serializer, select, "" + child, key, old, value);
117     }
118 
119     public void marshalGenericPropertiesSetProperties(XmlSerializer x, ProtocolProperties properties, ProtocolProperty[] newproperties) throws IOException {
120         XUpdateSerializer serializer = (XUpdateSerializer) x;
121         Object owner = properties.getParent();
122         String select;
123         int child;
124         if (owner instanceof Workflow) {
125             select = "/workflow";
126             child = firstPropertyIndex((Workflow) owner);
127         } else if (owner instanceof Place) {
128             select = selectPlace((Place) owner);
129             child = firstPropertyIndex((Place) owner);
130         } else if (owner instanceof Transition) {
131             select = selectTransition((Transition) owner);
132             child = firstPropertyIndex((Transition) owner);
133         } else {
134             throw new IOException("Owner of GenericProperties must be Workflow, Place, Transition, or Token not " + owner.getClass().getName());
135         }
136         serializer.remove(select + "/property");
137         for (int i = 0; i < newproperties.length; i++) {
138             Property p = newproperties[i];
139             marshalSetProperty(serializer, select, "" + child, p.getKey(), null, p.getValue());
140             child++;
141         }
142     }
143 
144     public void marshalGenericPropertiesRemove(XmlSerializer x, ProtocolProperties properties, String key) throws IOException {
145         XUpdateSerializer serializer = (XUpdateSerializer) x;
146         String old = properties.get(key);
147         if (old != null) {
148             Object owner = properties.getParent();
149             String select;
150             if (owner instanceof Workflow) {
151                 select = "/workflow";
152             } else if (owner instanceof Place) {
153                 select = selectPlace((Place) owner);
154             } else if (owner instanceof Transition) {
155                 select = selectTransition((Transition) owner);
156             } else {
157                 throw new IOException("Owner of GenericProperties must be Workflow, Place or Transition, not " + owner.getClass().getName());
158             }
159             serializer.remove(select + "/property[@name='" + key + "']");
160         }
161     }
162 
163     ///
164     /// Methods for Property
165     /// ----------------------------------------------------------------------------------------------------
166 
167     public void marshalPropertySetKey(XmlSerializer x, ProtocolProperty prop, String key) throws IOException {
168         XUpdateSerializer serializer = (XUpdateSerializer) x;
169         String old = prop.getKey();
170         Object owner = ((IChildObject) prop.getParent()).getParent();
171         String select;
172         if (owner instanceof Workflow) {
173             select = "/workflow";
174         } else if (owner instanceof Place) {
175             select = selectPlace((Place) owner);
176         } else if (owner instanceof Transition) {
177             select = selectTransition((Transition) owner);
178         } else {
179             throw new IOException("Owner of GenericProperties must be Workflow, Place or Transition, not " + owner.getClass().getName());
180         }
181         serializer.update(select + "/property[@name='" + old + "']/@name", key);
182     }
183 
184     public void marshalPropertySetValue(XmlSerializer x, ProtocolProperty prop, String value) throws IOException {
185         XUpdateSerializer serializer = (XUpdateSerializer) x;
186         Object owner = ((IChildObject) prop.getParent()).getParent();
187         String select;
188         if (owner instanceof Workflow) {
189             select = "/workflow";
190         } else if (owner instanceof Place) {
191             select = selectPlace((Place) owner);
192         } else if (owner instanceof Transition) {
193             select = selectTransition((Transition) owner);
194         } else {
195             throw new IOException("Owner of GenericProperties must be Workflow, Place or Transition, not " + owner.getClass().getName());
196         }
197         serializer.update(select + "/property[@name='" + prop.getKey() + "']", value);
198     }
199 
200     ///
201     /// Methods for Owls
202     /// ----------------------------------------------------------------------------------------------------
203 
204     public void marshalOwlsAddOwl(XmlSerializer x, ProtocolOwls o, String owl) throws IOException {
205         XUpdateSerializer serializer = (XUpdateSerializer) x;
206         if (o instanceof Workflow) {
207             marshalWorkflowAddOwl(serializer, (ProtocolWorkflow) o, owl);
208         } else if (o instanceof Place) {
209             marshalPlaceAddOwl(serializer, (ProtocolPlace) o, owl);
210         } else if (o instanceof OperationClass) {
211             marshalOperationClassAddOwl(serializer, (ProtocolOperationClass) o, owl);
212         } else if (o instanceof OperationCandidate) {
213             marshalOperationCandidateAddOwl(serializer, (ProtocolOperationCandidate) o, owl);
214         } else {
215             throw new IOException("Unknown implementation of Owls: " + o.getClass().getName());
216         }
217     }
218 
219     public void marshalOwlsRemoveOwl(XmlSerializer x, ProtocolOwls o, int i) throws IOException {
220         XUpdateSerializer serializer = (XUpdateSerializer) x;
221         if (o instanceof Workflow) {
222             marshalWorkflowRemoveOwl(serializer, (ProtocolWorkflow) o, i);
223         } else if (o instanceof Place) {
224             marshalPlaceRemoveOwl(serializer, (ProtocolPlace) o, i);
225         } else if (o instanceof OperationClass) {
226             marshalOperationClassRemoveOwl(serializer, (ProtocolOperationClass) o, i);
227         } else if (o instanceof OperationCandidate) {
228             marshalOperationCandidateRemoveOwl(serializer, (ProtocolOperationCandidate) o, i);
229         } else {
230             throw new IOException("Unknown implementation of Owls: " + o.getClass().getName());
231         }
232     }
233 
234     public void marshalOwlsSetOwls(XmlSerializer x, ProtocolOwls o, String[] owls) throws IOException {
235         XUpdateSerializer serializer = (XUpdateSerializer) x;
236         if (o instanceof Workflow) {
237             marshalWorkflowSetOwls(serializer, (ProtocolWorkflow) o, owls);
238         } else if (o instanceof Place) {
239             marshalPlaceSetOwls(serializer, (ProtocolPlace) o, owls);
240         } else if (o instanceof OperationClass) {
241             marshalOperationClassSetOwls(serializer, (ProtocolOperationClass) o, owls);
242         } else if (o instanceof OperationCandidate) {
243             marshalOperationCandidateSetOwls(serializer, (ProtocolOperationCandidate) o, owls);
244         } else {
245             throw new IOException("Unknown implementation of Owls: " + o.getClass().getName());
246         }
247     }
248 
249     ///
250     /// Methods for Workflow
251     /// ----------------------------------------------------------------------------------------------------
252 
253     protected int firstOwlIndex(Workflow wf) {
254         return 1;
255     }
256 
257     protected int afterLastOwlIndex(Workflow wf) {
258         return firstOwlIndex(wf) + wf.owlsCount();
259     }
260 
261     protected int descriptionIndex(Workflow wf) {
262         return afterLastOwlIndex(wf);
263     }
264 
265     protected int firstPropertyIndex(Workflow wf) {
266         return descriptionIndex(wf) + (GWDLMarshaller.isDefaultDescription(wf.getDescription()) ? 0 : 1);
267     }
268 
269     protected int afterLastPropertyIndex(Workflow wf) {
270         return firstPropertyIndex(wf) + wf.getProperties().size();
271     }
272 
273     protected int firstPlaceIndex(Workflow wf) {
274         return afterLastPropertyIndex(wf);
275     }
276 
277     protected int afterLastPlaceIndex(Workflow wf) {
278         return firstPlaceIndex(wf) + wf.placeCount();
279     }
280 
281     protected int firstTransitionIndex(Workflow wf) {
282         return afterLastPlaceIndex(wf);
283     }
284 
285     protected int afterLastTransitionIndex(Workflow wf) {
286         return firstTransitionIndex(wf) + wf.transitionCount();
287     }
288 
289     /// ----------------------------------------------------------------------------------------------------
290 
291     protected void marshalAppendPlacesList(XUpdateSerializer serializer, int offset, Place[] places) throws IOException {
292         for (int i = 0; i < places.length; i++) {
293             serializer.startAppend("/workflow", "" + (offset + i));
294             GWDLMarshaller.place(serializer, places[i]);
295             serializer.endAppend();
296         }
297     }
298 
299     protected void marshalAppendTransitionsList(XUpdateSerializer serializer, int offset, Transition[] transitions) throws IOException {
300         for (int i = 0; i < transitions.length; i++) {
301             serializer.startAppend("/workflow", "" + (offset + i));
302             GWDLMarshaller.transition(serializer, transitions[i]);
303             serializer.endAppend();
304         }
305     }
306 
307     protected void marshalWorkflowAddOwl(XUpdateSerializer serializer, ProtocolWorkflow wf, String owl) throws IOException {
308         String select = "/workflow";
309         int child = afterLastOwlIndex(wf);
310         serializer.startAppend(select, "" + child);
311         GWDLMarshaller.owlgwdl(serializer, owl);
312         serializer.endAppend();
313     }
314 
315     protected void marshalWorkflowRemoveOwl(XUpdateSerializer serializer, ProtocolWorkflow wf, int i) throws IOException {
316         String select = "/workflow/owl[" + (i + 1) + "]";
317         serializer.remove(select);
318     }
319 
320     protected void marshalWorkflowSetOwls(XUpdateSerializer serializer, ProtocolWorkflow wf, String[] owl) throws IOException {
321         serializer.remove("/workflow/owl");
322         marshalAppendOwlsGwdlList(serializer, "/workflow", firstOwlIndex(wf), owl);
323     }
324 
325     /// ----------------------------------------------------------------------------------------------------
326 
327     public void marshalWorkflowFromXML(XmlSerializer x, ProtocolWorkflow workflow, String xml) throws IOException {
328         XUpdateSerializer serializer = (XUpdateSerializer) x;
329         Workflow wf = null;
330 
331         try {
332             wf = JdomString.string2workflow(xml);
333         } catch (Exception y) {
334             IOException ix = new IOException("Could not parse workflow description.");
335             ix.initCause(y);
336             throw ix;
337         }
338 
339         serializer.remove("/workflow/*");
340         // serializer.update("/workflow/@ID", wf.getID());
341 
342         int offset = 1;
343         String[] owl = wf.getOwls();
344         marshalAppendOwlsGwdlList(serializer, "/workflow", offset, owl);
345 
346         offset += owl.length;
347         if (!GWDLMarshaller.isDefaultDescription(wf.getDescription())) {
348             serializer.startAppend("/workflow", "" + offset);
349             GWDLMarshaller.description(serializer, wf.getDescription());
350             serializer.endAppend();
351             offset++;
352         }
353 
354         Property[] props = wf.getProperties().getProperties();
355         for (int i = 0; i < props.length; i++) {
356             serializer.startAppend("/workflow", "" + (offset + i));
357             GWDLMarshaller.property(serializer, props[i].getKey(), props[i].getValue());
358             serializer.endAppend();
359         }
360 
361         offset += props.length;
362         Place[] places = wf.getPlaces();
363         marshalAppendPlacesList(serializer, offset, places);
364 
365         offset += places.length;
366         Transition[] transitions = wf.getTransitions();
367         marshalAppendTransitionsList(serializer, offset, transitions);
368 
369         /*
370         serializer.startAppend("/workflow", "first()");
371 
372         GWDLMarshaller.owls(serializer, wf);
373         GWDLMarshaller.description(serializer, wf.getDescription());
374         GWDLMarshaller.properties(serializer, wf.getProperties());
375 
376         Place[] places = wf.getPlaces();
377         if (places!=null) {
378         for (int i=0; i<places.length; i++) {
379         GWDLMarshaller.place(serializer, places[i]);
380         }
381         }
382 
383         Transition[] transitions = wf.getTransitions();
384         if (transitions!=null) {
385         for (int i=0; i<transitions.length; i++) {
386         GWDLMarshaller.transition(serializer, transitions[i]);
387         }
388         }
389 
390         serializer.endAppend();
391       */
392     }
393 
394     /*
395     public void marshalWorkflowSetID(XmlSerializer x, ProtocolWorkflow wf, String id) throws IOException {
396 	XUpdateSerializer serializer = (XUpdateSerializer)x;
397 	serializer.update("/workflow/@ID", id);
398     }
399     */
400 
401     public void marshalWorkflowSetDescription(XmlSerializer x, ProtocolWorkflow wf, String description) throws IOException {
402         XUpdateSerializer serializer = (XUpdateSerializer) x;
403         String select = "/workflow";
404         String oldvalue = wf.getDescription();
405         int i = descriptionIndex(wf);
406         marshalSetDescription(serializer, select, "" + i, oldvalue, description);
407     }
408 
409     public void marshalWorkflowAddPlace(XmlSerializer x, ProtocolWorkflow wf, ProtocolPlace place) throws IOException {
410         XUpdateSerializer serializer = (XUpdateSerializer) x;
411         String select = "/workflow";
412         int i = afterLastPlaceIndex(wf);
413         serializer.startAppend(select, "" + i);
414         GWDLMarshaller.place(serializer, place);
415         serializer.endAppend();
416     }
417 
418     public void marshalWorkflowRemovePlace(XmlSerializer x, ProtocolWorkflow wf, int i) throws IOException {
419         XUpdateSerializer serializer = (XUpdateSerializer) x;
420         String select = "/workflow/place[" + (i + 1) + "]";
421         serializer.remove(select);
422     }
423 
424     public void marshalWorkflowSetPlaces(XmlSerializer x, ProtocolWorkflow wf, ProtocolPlace[] places) throws IOException {
425         XUpdateSerializer serializer = (XUpdateSerializer) x;
426         String select = "/workflow/place";
427         serializer.remove(select);
428         marshalAppendPlacesList(serializer, firstPlaceIndex(wf), places);
429     }
430 
431     public void marshalWorkflowAddTransition(XmlSerializer x, ProtocolWorkflow wf, ProtocolTransition transition) throws IOException {
432         XUpdateSerializer serializer = (XUpdateSerializer) x;
433         String select = "/workflow";
434         int i = afterLastTransitionIndex(wf);
435         serializer.startAppend(select, "" + i);
436         GWDLMarshaller.transition(serializer, transition);
437         serializer.endAppend();
438     }
439 
440     public void marshalWorkflowRemoveTransition(XmlSerializer x, ProtocolWorkflow wf, int i) throws IOException {
441         XUpdateSerializer serializer = (XUpdateSerializer) x;
442         String select = "/workflow/transition[" + (i + 1) + "]";
443         serializer.remove(select);
444     }
445 
446     public void marshalWorkflowSetTransitions(XmlSerializer x, ProtocolWorkflow wf, ProtocolTransition[] transitions) throws IOException {
447         XUpdateSerializer serializer = (XUpdateSerializer) x;
448         String select = "/workflow/transition";
449         serializer.remove(select);
450         marshalAppendTransitionsList(serializer, firstTransitionIndex(wf), transitions);
451     }
452 
453     public void marshalWorkflowSetProperties(XmlSerializer x, ProtocolWorkflow wf, ProtocolProperties properties) throws IOException {
454         marshalGenericPropertiesSetProperties(x,
455                 (ProtocolProperties) wf.getProperties(),
456                 (ProtocolProperty[]) StructureUtils.castArray(ProtocolProperty.class, properties.getProperties()));
457     }
458 
459     ///
460     /// Methods for Place
461     /// ----------------------------------------------------------------------------------------------------
462 
463     protected String selectPlace(Place p) {
464         return "/workflow/place[@ID='" + p.getID() + "']";
465     }
466 
467     protected int descriptionIndex(Place p) {
468         return 1;
469     }
470 
471     protected int firstPropertyIndex(Place p) {
472         return descriptionIndex(p) + (GWDLMarshaller.isDefaultDescription(p.getDescription()) ? 0 : 1);
473     }
474 
475     protected int afterLastPropertyIndex(Place p) {
476         return firstPropertyIndex(p) + p.getProperties().size();
477     }
478 
479     protected int tokenClassIndex(Place p) {
480         return afterLastPropertyIndex(p);
481     }
482 
483     protected int firstOwlIndex(Place p) {
484         return 1; // owl is first element inside tokenClass
485     }
486 
487     protected int afterLastOwlIndex(Place p) {
488         return firstOwlIndex(p) + p.owlsCount();
489     }
490 
491     protected int firstTokenIndex(Place p) {
492         return tokenClassIndex(p) + (GWDLMarshaller.isDefaultTokenClass(p, p.getTokenType()) ? 0 : 1);
493     }
494 
495     protected int afterLastTokenIndex(Place p) {
496         return firstTokenIndex(p) + p.getTokens().length;
497     }
498 
499     /***
500      * Returns the index of the token in the list of tokens of the place in XPath numbering.
501      */
502     protected int tokenIndex(Place p, Token t) throws IOException {
503         Token[] tokens = p.getTokens();
504         for (int i = 0; i < tokens.length; i++) {
505             // if (tokens[i].equals(t)) return i+firstTokenIndex(p);  // token.equals() seems to be broken
506             if (tokens[i] == t) return i + 1;
507         }
508         throw new IOException("Specified Token is not a child of specified Place.");
509     }
510 
511     /// ----------------------------------------------------------------------------------------------------
512 
513     protected void marshalPlaceAddOwl(XUpdateSerializer serializer, ProtocolPlace p, String owl) throws IOException {
514         String select = selectPlace(p);
515         if (GWDLMarshaller.isDefaultTokenClass(p, p.getTokenType())) {
516             serializer.startAppend(select, "" + tokenClassIndex(p));
517             GWDLMarshaller.tokenClass(serializer, new String[]{owl}, p.getTokenType());
518             serializer.endAppend();
519         } else {
520             serializer.startAppend(select + "/tokenClass", "" + afterLastOwlIndex(p));
521             GWDLMarshaller.owlgwdl(serializer, owl);
522             serializer.endAppend();
523         }
524     }
525 
526     protected void marshalPlaceRemoveOwl(XUpdateSerializer serializer, ProtocolPlace p, int i) throws IOException {
527         String select = selectPlace(p);
528         if (p.owlsCount() == 1 && i == 0 && GWDLMarshaller.isDefaultType(p.getTokenType())) {
529             serializer.remove(select + "/tokenClass");
530         } else {
531             serializer.remove(select + "/tokenClass/owl[" + (i + 1) + "]");
532         }
533     }
534 
535     protected void marshalPlaceSetOwls(XUpdateSerializer serializer, ProtocolPlace p, String[] owls) throws IOException {
536         String select = selectPlace(p);
537         if (GWDLMarshaller.isDefaultTokenClass(p, p.getTokenType())) {
538             serializer.startAppend(select, "" + tokenClassIndex(p));
539             GWDLMarshaller.tokenClass(serializer, owls, p.getTokenType());
540             serializer.endAppend();
541         } else if (owls.length == 0 && GWDLMarshaller.isDefaultType(p.getTokenType())) {
542             serializer.remove(select + "/tokenClass");
543         } else {
544             serializer.remove(select + "/tokenClass/owl");
545             marshalAppendOwlsGwdlList(serializer, select + "/tokenClass", firstOwlIndex(p), owls);
546         }
547     }
548 
549     /// ----------------------------------------------------------------------------------------------------
550 
551     public void marshalPlaceSetID(XmlSerializer x, ProtocolPlace p, String newid) throws IOException {
552         XUpdateSerializer serializer = (XUpdateSerializer) x;
553         String select = selectPlace(p);
554         serializer.update(select + "/@ID", newid);
555     }
556 
557     public void marshalPlaceSetDescription(XmlSerializer x, ProtocolPlace p, String newdescription) throws IOException {
558         XUpdateSerializer serializer = (XUpdateSerializer) x;
559         String select = selectPlace(p);
560         String olddescription = p.getDescription();
561         int i = descriptionIndex(p);
562         marshalSetDescription(serializer, select, "" + i, olddescription, newdescription);
563     }
564 
565     public void marshalPlaceSetTokenType(XmlSerializer x, ProtocolPlace p, String newtype) throws IOException {
566         XUpdateSerializer serializer = (XUpdateSerializer) x;
567         String oldtype = p.getTokenType();
568         if (GWDLMarshaller.isDefaultType(oldtype) && GWDLMarshaller.isDefaultType(newtype)) return;
569         String select = selectPlace(p);
570         if (GWDLMarshaller.isDefaultTokenClass(p, oldtype)) {
571             int index = tokenClassIndex(p);
572             serializer.startAppend(select, "" + index);
573             GWDLMarshaller.tokenClass(serializer, p, newtype);
574             serializer.endAppend();
575         } else if (GWDLMarshaller.isDefaultTokenClass(p, newtype)) {
576             serializer.remove(select + "/tokenClass");
577         } else {
578             select = select + "/tokenClass";
579             if (GWDLMarshaller.isDefaultType(oldtype)) {
580                 serializer.startAppend(select, "first()");
581                 GWDLMarshaller.type(serializer, newtype);
582                 serializer.endAppend();
583             } else if (GWDLMarshaller.isDefaultType(newtype)) {
584                 serializer.remove(select + "/@type");
585             } else {
586                 serializer.update(select + "/@type", newtype);
587             }
588         }
589     }
590 
591     public void marshalPlaceAddToken(XmlSerializer x, ProtocolPlace p, ProtocolToken token) throws IOException {
592         XUpdateSerializer serializer = (XUpdateSerializer) x;
593         int index = afterLastTokenIndex(p);
594         serializer.startAppend(selectPlace(p), "" + index);
595         GWDLMarshaller.token(serializer, token);
596         serializer.endAppend();
597     }
598 
599     public void marshalPlaceSetTokens(XmlSerializer x, ProtocolPlace p, ProtocolToken[] ts) throws IOException, UnsupportedOperationException {
600         XUpdateSerializer serializer = (XUpdateSerializer) x;
601         String select = selectPlace(p);
602         int offset = firstTokenIndex(p);
603         serializer.remove(select + "/token");
604         for (int i = 0; i < ts.length; i++) {
605             serializer.startAppend(select, "" + (offset + i));
606             GWDLMarshaller.token(serializer, ts[i]);
607             serializer.endAppend();
608         }
609     }
610 
611     public void marshalPlaceRemoveToken(XmlSerializer x, ProtocolPlace p, ProtocolToken token) throws IOException {
612         XUpdateSerializer serializer = (XUpdateSerializer) x;
613         int index = tokenIndex(p, token);
614         marshalPlaceRemoveToken(serializer, p, index - 1);  // because "index" here is XPath index and method expects java index.
615     }
616 
617     public void marshalPlaceRemoveToken(XmlSerializer x, ProtocolPlace p, int index) throws IOException {
618         XUpdateSerializer serializer = (XUpdateSerializer) x;
619         String select = selectPlace(p);
620         serializer.remove(select + "/token[" + (index + 1) + "]");
621     }
622 
623     public void marshalPlaceSetCapacity(XmlSerializer x, ProtocolPlace p, int newcapacity) throws IOException {
624         XUpdateSerializer serializer = (XUpdateSerializer) x;
625         String select = selectPlace(p);
626         int oldcapacity = p.getCapacity();
627         if (!(GWDLMarshaller.isDefaultCapacity(oldcapacity) && GWDLMarshaller.isDefaultCapacity(newcapacity))) {
628             if (GWDLMarshaller.isDefaultCapacity(oldcapacity)) {
629                 serializer.startAppend(select, "last()");
630                 GWDLMarshaller.capacity(serializer, newcapacity);
631                 serializer.endAppend();
632             } else if (GWDLMarshaller.isDefaultCapacity(newcapacity)) {
633                 serializer.remove(select + "/@capacity");
634             } else {
635                 serializer.update(select + "/@capacity", "" + newcapacity);
636             }
637         }
638     }
639 
640     public void marshalPlaceRemoveAllTokens(XmlSerializer x, ProtocolPlace p) throws IOException {
641         XUpdateSerializer serializer = (XUpdateSerializer) x;
642         String select = selectPlace(p);
643         serializer.remove(select + "/token");
644     }
645 
646     public void marshalPlaceSetProperties(XmlSerializer x, ProtocolPlace place, ProtocolProperties properties) throws IOException {
647         marshalGenericPropertiesSetProperties(x,
648                 (ProtocolProperties) place.getProperties(),
649                 (ProtocolProperty[]) StructureUtils.castArray(ProtocolProperty.class, properties.getProperties()));
650     }
651 
652     /// 
653     /// Methods for Token
654     /// ----------------------------------------------------------------------------------------------------
655 
656     public void marshalTokenSetID(XmlSerializer x, ProtocolToken p, String newid) throws IOException {
657          throw new UnsupportedOperationException();
658 //        XUpdateSerializer serializer = (XUpdateSerializer) x;
659 //        String select = selectToken(t);
660 //        serializer.update(select + "/@ID", newid);
661     }
662 
663     public void marshalTokenSetProperties(XmlSerializer x, ProtocolToken token, ProtocolProperties properties) throws IOException {
664         marshalGenericPropertiesSetProperties(x,
665                 (ProtocolProperties) token.getProperties(),
666                 (ProtocolProperty[]) StructureUtils.castArray(ProtocolProperty.class, properties.getProperties()));
667     }
668 
669     public void marshalTokenSetControl(XmlSerializer x, ProtocolToken token, Boolean control) throws IOException, UnsupportedOperationException {
670         throw new UnsupportedOperationException();
671 //        XUpdateSerializer serializer = (XUpdateSerializer)x;
672 //        String select = selectToken(token);
673 //        String oldcontrol = token.getControl();
674 //        int i = descriptionIndex(p);
675 //        marshalTSetDescription(serializer, select, ""+i, olddescription, newdescription);
676 //        ...
677     }
678 
679 
680     public void marshalTokenSetData(XmlSerializer x, ProtocolToken token, ProtocolData data) throws IOException, UnsupportedOperationException {
681         throw new UnsupportedOperationException();
682 //        throw new UnsupportedOperationException();
683 //        XUpdateSerializer serializer = (XUpdateSerializer)x;
684 //        int index = afterLastTokenIndex(p);
685 //        serializer.startAppend(selectPlace(p), ""+index);
686 //        GWDLMarshaller.token(serializer, token);
687 //        serializer.endAppend();
688 //        ...
689     }
690 
691     ///
692     /// Methods for Data
693     /// ----------------------------------------------------------------------------------------------------
694 
695     public void marshalDataFromXML(XmlSerializer x, ProtocolData d, String xml) throws UnsupportedOperationException {
696         throw new UnsupportedOperationException();
697         /*
698         try {
699         Element e = JdomString.string2element(xml);
700         marshalTokenSet(x, t, e);
701         } catch (WorkflowFormatException wfx) {
702         IOException iox = new IOException("Could not read operationObject specification.");
703         iox.initCause(wfx);
704         throw iox;
705         }
706       */
707     }
708 
709     public void marshalDataSet(XmlSerializer x, ProtocolData d, Object o) throws UnsupportedOperationException {
710         throw new UnsupportedOperationException();
711     }
712 
713     ///
714     /// Methods for Transition
715     /// ----------------------------------------------------------------------------------------------------
716 
717     protected String selectTransition(Transition t) {
718         return "/workflow/transition[@ID='" + t.getID() + "']";
719     }
720 
721     protected int descriptionIndex(Transition t) {
722         return 1;
723     }
724 
725     protected int firstPropertyIndex(Transition t) {
726         return descriptionIndex(t) + (GWDLMarshaller.isDefaultDescription(t.getDescription()) ? 0 : 1);
727     }
728 
729     protected int afterLastPropertyIndex(Transition t) {
730         return firstPropertyIndex(t) + t.getProperties().size();
731     }
732 
733     protected int firstReadPlaceIndex(Transition t) {
734         return afterLastPropertyIndex(t);
735     }
736 
737     protected int firstInputPlaceIndex(Transition t) {
738         return afterLastReadPlaceIndex(t);
739     }
740 
741     protected int afterLastReadPlaceIndex(Transition t) {
742         return firstReadPlaceIndex(t) + t.getReadEdges().length;
743     }
744 
745     protected int afterLastInputPlaceIndex(Transition t) {
746         return firstInputPlaceIndex(t) + t.getInEdges().length;
747     }
748 
749     protected int firstWritePlaceIndex(Transition t) {
750         return afterLastInputPlaceIndex(t);
751     }
752 
753     protected int afterLastWritePlaceIndex(Transition t) {
754         return firstWritePlaceIndex(t) + t.getWriteEdges().length;
755     }
756 
757     protected int firstOutputPlaceIndex(Transition t) {
758         return afterLastReadPlaceIndex(t);
759     }
760 
761     protected int afterLastOutputPlaceIndex(Transition t) {
762         return firstOutputPlaceIndex(t) + t.getOutEdges().length;
763     }
764 
765     protected int firstConditionIndex(Transition t) {
766         return afterLastOutputPlaceIndex(t);
767     }
768 
769     protected int afterLastConditionIndex(Transition t) {
770         return firstConditionIndex(t) + t.getConditions().length;
771     }
772 
773     protected int operationIndex(Transition t) {
774         return afterLastConditionIndex(t);
775     }
776 
777     /// ----------------------------------------------------------------------------------------------------
778 
779     public void marshalTransitionSetID(XmlSerializer x, ProtocolTransition t, String newid) throws IOException {
780         XUpdateSerializer serializer = (XUpdateSerializer) x;
781         String select = selectTransition(t);
782         serializer.update(select + "/@ID", newid);
783     }
784 
785     public void marshalTransitionSetDescription(XmlSerializer x, ProtocolTransition t, String newdescription) throws IOException {
786         XUpdateSerializer serializer = (XUpdateSerializer) x;
787         String select = selectTransition(t);
788         String olddescription = t.getDescription();
789         int i = descriptionIndex(t);
790         marshalSetDescription(serializer, select, "" + i, olddescription, newdescription);
791     }
792 
793     public void marshalTransitionAddReadEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
794         XUpdateSerializer serializer = (XUpdateSerializer) x;
795         String select = selectTransition(t);
796         int offset = afterLastReadPlaceIndex(t);
797         serializer.startAppend(select, "" + offset);
798         GWDLMarshaller.readPlace(serializer, edge);
799         serializer.endAppend();
800     }
801 
802     public void marshalTransitionRemoveReadEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
803         XUpdateSerializer serializer = (XUpdateSerializer) x;
804         String select = selectReadPlace(edge);
805         serializer.remove(select);
806     }
807 
808     public void marshalTransitionSetReadEdges(XmlSerializer x, ProtocolTransition t, ProtocolEdge[] edges) throws IOException {
809         XUpdateSerializer serializer = (XUpdateSerializer) x;
810         String select = selectTransition(t);
811         int offset = firstReadPlaceIndex(t);
812         serializer.remove(select + "/readPlace");
813         for (int i = 0; i < edges.length; i++) {
814             serializer.startAppend(select, "" + (offset + i));
815             GWDLMarshaller.readPlace(serializer, edges[i]);
816             serializer.endAppend();
817         }
818     }
819 
820     public void marshalTransitionAddInEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
821         XUpdateSerializer serializer = (XUpdateSerializer) x;
822         String select = selectTransition(t);
823         int offset = afterLastInputPlaceIndex(t);
824         serializer.startAppend(select, "" + offset);
825         GWDLMarshaller.inputPlace(serializer, edge);
826         serializer.endAppend();
827     }
828 
829     public void marshalTransitionRemoveInEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
830         XUpdateSerializer serializer = (XUpdateSerializer) x;
831         String select = selectInputPlace(edge);
832         serializer.remove(select);
833     }
834 
835     public void marshalTransitionSetInEdges(XmlSerializer x, ProtocolTransition t, ProtocolEdge[] edges) throws IOException {
836         XUpdateSerializer serializer = (XUpdateSerializer) x;
837         String select = selectTransition(t);
838         int offset = firstInputPlaceIndex(t);
839         serializer.remove(select + "/inputPlace");
840         for (int i = 0; i < edges.length; i++) {
841             serializer.startAppend(select, "" + (offset + i));
842             GWDLMarshaller.inputPlace(serializer, edges[i]);
843             serializer.endAppend();
844         }
845     }
846 
847     public void marshalTransitionAddWriteEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
848         XUpdateSerializer serializer = (XUpdateSerializer) x;
849         String select = selectTransition(t);
850         int offset = afterLastWritePlaceIndex(t);
851         serializer.startAppend(select, "" + offset);
852         GWDLMarshaller.writePlace(serializer, edge);
853         serializer.endAppend();
854     }
855 
856     public void marshalTransitionRemoveWriteEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
857         XUpdateSerializer serializer = (XUpdateSerializer) x;
858         String select = selectWritePlace(edge);
859         serializer.remove(select);
860     }
861 
862     public void marshalTransitionSetWriteEdges(XmlSerializer x, ProtocolTransition t, ProtocolEdge[] edges) throws IOException {
863         XUpdateSerializer serializer = (XUpdateSerializer) x;
864         String select = selectTransition(t);
865         int offset = firstWritePlaceIndex(t);
866         serializer.remove(select + "/writePlace");
867         for (int i = 0; i < edges.length; i++) {
868             serializer.startAppend(select, "" + (offset + i));
869             GWDLMarshaller.writePlace(serializer, edges[i]);
870             serializer.endAppend();
871         }
872     }
873 
874     public void marshalTransitionAddOutEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
875         XUpdateSerializer serializer = (XUpdateSerializer) x;
876         String select = selectTransition(t);
877         int offset = afterLastOutputPlaceIndex(t);
878         serializer.startAppend(select, "" + offset);
879         GWDLMarshaller.outputPlace(serializer, edge);
880         serializer.endAppend();
881     }
882 
883     public void marshalTransitionRemoveOutEdge(XmlSerializer x, ProtocolTransition t, ProtocolEdge edge) throws IOException {
884         XUpdateSerializer serializer = (XUpdateSerializer) x;
885         String select = selectOutputPlace(edge);
886         serializer.remove(select);
887     }
888 
889     public void marshalTransitionSetOutEdges(XmlSerializer x, ProtocolTransition t, ProtocolEdge[] edges) throws IOException {
890         XUpdateSerializer serializer = (XUpdateSerializer) x;
891         String select = selectTransition(t);
892         int offset = firstOutputPlaceIndex(t);
893         serializer.remove(select + "/outputPlace");
894         for (int i = 0; i < edges.length; i++) {
895             serializer.startAppend(select, "" + (offset + i));
896             GWDLMarshaller.outputPlace(serializer, edges[i]);
897             serializer.endAppend();
898         }
899     }
900 
901     public void marshalTransitionAddCondition(XmlSerializer x, ProtocolTransition t, String condition) throws IOException {
902         XUpdateSerializer serializer = (XUpdateSerializer) x;
903         int index = operationIndex(t);
904         serializer.startAppend(selectTransition(t), "" + index);
905         GWDLMarshaller.condition(serializer, condition);
906         serializer.endAppend();
907     }
908 
909     public void marshalTransitionRemoveCondition(XmlSerializer x, ProtocolTransition t, int index) throws IOException {
910         XUpdateSerializer serializer = (XUpdateSerializer) x;
911         serializer.remove(selectTransition(t) + "/condition[" + (index + 1) + "]");
912     }
913 
914     public void marshalTransitionSetConditions(XmlSerializer x, ProtocolTransition t, String[] conditions) throws IOException {
915         XUpdateSerializer serializer = (XUpdateSerializer) x;
916         String select = selectTransition(t);
917         int offset = firstConditionIndex(t);
918         serializer.remove(select + "/condition");
919         for (int i = 0; i < conditions.length; i++) {
920             serializer.startAppend(select, "" + (offset + i));
921             GWDLMarshaller.condition(serializer, conditions[i]);
922             serializer.endAppend();
923         }
924     }
925 
926     public void marshalTransitionSetOperation(XmlSerializer x, ProtocolTransition t, ProtocolOperation op) throws IOException {
927         XUpdateSerializer serializer = (XUpdateSerializer) x;
928         String select = selectTransition(t);
929         int child = operationIndex(t);
930         Operation oldoperation = t.getOperation();
931         if (!GWDLMarshaller.isDefaultOperation(oldoperation)) {
932             serializer.remove(select + "/operation");
933         }
934         if (!GWDLMarshaller.isDefaultOperation(op)) {
935             serializer.startAppend(select, "" + child);
936             GWDLMarshaller.operation(serializer, op);
937             serializer.endAppend();
938         }
939     }
940 
941     public void marshalTransitionSetProperties(XmlSerializer x, ProtocolTransition transition, ProtocolProperties properties) throws IOException {
942         marshalGenericPropertiesSetProperties(x,
943                 (ProtocolProperties) transition.getProperties(),
944                 (ProtocolProperty[]) StructureUtils.castArray(ProtocolProperty.class, properties.getProperties()));
945     }
946 
947     ///
948     /// Methods for Edge
949     /// ----------------------------------------------------------------------------------------------------
950 
951     protected boolean isReadEdge(Transition t, Edge e) {
952         Edge[] edges = t.getReadEdges();
953         for (int i = 0; i < edges.length; i++) {
954             if (edges[i] == e) return true;
955         }
956         return false;
957     }
958 
959     protected boolean isInEdge(Transition t, Edge e) {
960         Edge[] edges = t.getInEdges();
961         for (int i = 0; i < edges.length; i++) {
962             if (edges[i] == e) return true;
963         }
964         return false;
965     }
966 
967     protected boolean isWriteEdge(Transition t, Edge e) {
968         Edge[] edges = t.getWriteEdges();
969         for (int i = 0; i < edges.length; i++) {
970             if (edges[i] == e) return true;
971         }
972         return false;
973     }
974 
975     protected boolean isOutEdge(Transition t, Edge e) {
976         Edge[] edges = t.getOutEdges();
977         for (int i = 0; i < edges.length; i++) {
978             if (edges[i] == e) return true;
979         }
980         return false;
981     }
982 
983     protected String selectReadPlace(ProtocolEdge e) {
984         ProtocolTransition t = (ProtocolTransition) e.getParent();
985         return selectTransition(t) + "/readPlace[@placeID='" + e.getPlaceID() + "']";
986     }
987 
988     protected String selectInputPlace(ProtocolEdge e) {
989         ProtocolTransition t = (ProtocolTransition) e.getParent();
990         return selectTransition(t) + "/inputPlace[@placeID='" + e.getPlaceID() + "']";
991     }
992 
993     protected String selectWritePlace(ProtocolEdge e) {
994         ProtocolTransition t = (ProtocolTransition) e.getParent();
995         return selectTransition(t) + "/writePlace[@placeID='" + e.getPlaceID() + "']";
996     }
997 
998     protected String selectOutputPlace(ProtocolEdge e) {
999         ProtocolTransition t = (ProtocolTransition) e.getParent();
1000         return selectTransition(t) + "/outputPlace[@placeID='" + e.getPlaceID() + "']";
1001     }
1002 
1003     /// ----------------------------------------------------------------------------------------------------
1004 
1005     public void marshalEdgeSetExpression(XmlSerializer x, ProtocolEdge e, String newexpression) throws IOException, IllegalArgumentException {
1006         XUpdateSerializer serializer = (XUpdateSerializer) x;
1007         String select = null;
1008         String oldexpression = e.getExpression();
1009         Transition t = (Transition) e.getParent();
1010         if (isReadEdge(t, e)) {
1011             select = selectReadPlace(e);
1012         } else if (isInEdge(t, e)) {
1013             select = selectInputPlace(e);
1014         } else if (isWriteEdge(t, e)) {
1015             select = selectWritePlace(e);
1016         } else if (isOutEdge(t, e)) {
1017             select = selectOutputPlace(e);
1018         } else {
1019             throw new IllegalArgumentException("Edge is neither read, in, write, nor out-edge of it's Transition.");
1020         }
1021         if (GWDLMarshaller.isDefaultExpression(oldexpression) && GWDLMarshaller.isDefaultExpression(newexpression)) {
1022             //
1023         } else if (GWDLMarshaller.isDefaultExpression(oldexpression)) {
1024             serializer.startAppend(select, "last()");
1025             GWDLMarshaller.edgeExpression(serializer, newexpression);
1026             serializer.endAppend();
1027         } else if (GWDLMarshaller.isDefaultExpression(newexpression)) {
1028             serializer.remove(select + "/@edgeExpression");
1029         } else {
1030             serializer.update(select + "/@edgeExpression", newexpression);
1031         }
1032     }
1033 
1034     /***
1035      * Currently not supported.
1036      *
1037      * @throws UnsupportedOperationException Always.
1038      */
1039     public void marshalEdgeSetPlace(XmlSerializer x, ProtocolEdge e, ProtocolPlace place) throws UnsupportedOperationException {
1040         XUpdateSerializer serializer = (XUpdateSerializer) x;
1041         throw new UnsupportedOperationException();
1042     }
1043 
1044     ///
1045     /// Methods for Operation
1046     /// ----------------------------------------------------------------------------------------------------
1047 
1048     protected String selectOperation(ProtocolOperation o) {
1049         ProtocolTransition t = (ProtocolTransition) o.getParent();
1050         return selectTransition(t) + "/operation";
1051     }
1052 
1053     protected void marshalOperationSetOperationClass(XUpdateSerializer serializer, ProtocolOperation o, ProtocolOperationClass oc) throws IOException {
1054         String select = selectOperation(o);
1055         serializer.startAppend(select, "first()");
1056         GWDLMarshaller.operationClass(serializer, oc);
1057         serializer.endAppend();
1058     }
1059 
1060     public void marshalOperationSetOperationClass(XmlSerializer x, ProtocolOperation o, ProtocolOperationClass oc) throws IOException {
1061         XUpdateSerializer serializer = (XUpdateSerializer) x;
1062         if (o.get() instanceof OperationClass) {
1063             OperationClass old = (OperationClass) o.get();
1064             if (!GWDLMarshaller.isDefaultOperationClass(old)) {
1065                 serializer.remove(selectOperation(o) + "/*");
1066             }
1067             if (GWDLMarshaller.isDefaultOperationClass(oc)) {
1068                 return;
1069             }
1070         }
1071         marshalOperationSetOperationClass(serializer, o, oc);
1072     }
1073 
1074     ///
1075     /// Methods for operationClass
1076     /// ----------------------------------------------------------------------------------------------------
1077 
1078     protected int firstOwlIndex(OperationClass o) {
1079         return 1;
1080     }
1081 
1082     protected int afterLastOwlIndex(OperationClass o) {
1083         return firstOwlIndex(o) + o.owlsCount();
1084     }
1085 
1086     protected int firstOperationCandidateIndex(OperationClass oc) {
1087         return 1;
1088     }
1089 
1090     protected int afterLastOperationCandidateIndex(OperationClass oc) {
1091         return firstOperationCandidateIndex(oc) + oc.getOperationCount();
1092     }
1093 
1094     protected String selectOperationClass(ProtocolOperationClass wsco) {
1095         ProtocolOperation o = (ProtocolOperation) wsco.getParent();
1096         return selectOperation(o) + "/operationClass";
1097     }
1098 
1099     public void marshalOperationClassSetName(XmlSerializer x, ProtocolOperationClass o, String name) throws IOException {
1100         XUpdateSerializer serializer = (XUpdateSerializer) x;
1101         String old = o.getName();
1102         String select = selectOperationClass(o);
1103         // index not required for attributes (?)
1104         //int child = nameIndex(o);
1105         if (GWDLMarshaller.isDefaultName(old) &&
1106                 GWDLMarshaller.isDefaultName(name)) {
1107             return;
1108         } else if (GWDLMarshaller.isDefaultName(old)) {
1109             // serializer.startAppend(select, child);
1110             serializer.startAppend(select, null);
1111             GWDLMarshaller.name(serializer, name);
1112             serializer.endAppend();
1113         } else if (GWDLMarshaller.isDefaultName(name)) {
1114             serializer.remove(select + "/@name");
1115         } else {
1116             serializer.update(select + "/@name", name);
1117         }
1118     }
1119 
1120     protected void marshalAppendOwlsocList(XUpdateSerializer serializer, String select, int offset, String[] owl) throws IOException {
1121         for (int i = 0; i < owl.length; i++) {
1122             serializer.startAppend(select, "" + (offset + i));
1123             GWDLMarshaller.owloc(serializer, owl[i]);
1124             serializer.endAppend();
1125         }
1126     }
1127 
1128     protected void marshalOperationClassAddOwl(XUpdateSerializer serializer, ProtocolOperationClass poc, String owl) throws IOException {
1129         String select = selectOperationClass(poc);
1130         int child = afterLastOwlIndex(poc);
1131         serializer.startAppend(select, "" + child);
1132         GWDLMarshaller.owloc(serializer, owl);
1133         serializer.endAppend();
1134     }
1135 
1136     protected void marshalOperationClassRemoveOwl(XUpdateSerializer serializer, ProtocolOperationClass poc, int i) throws IOException {
1137         String select = selectOperationClass(poc) + "/owl[" + (i + 1) + "]";
1138         serializer.remove(select);
1139     }
1140 
1141     protected void marshalOperationClassSetOwls(XUpdateSerializer serializer, ProtocolOperationClass poc, String[] owls) throws IOException {
1142         String select = selectOperationClass(poc);
1143         serializer.remove(select + "/owl");
1144         marshalAppendOwlsocList(serializer, select, firstOwlIndex(poc), owls);
1145     }
1146 
1147     public void marshalOperationClassSetOperationCandidates(XmlSerializer x, ProtocolOperationClass poc, OperationCandidate[] pocs) throws IOException, UnsupportedOperationException {
1148         XUpdateSerializer serializer = (XUpdateSerializer) x;
1149         String select = selectOperationClass(poc);
1150         // ToDo: check occurrence of owl element
1151         int offset = 1;
1152         serializer.remove(select + "/operationCandidate");
1153         for (int i = 0; i < pocs.length; i++) {
1154             serializer.startAppend(select, "" + (offset + i));
1155             GWDLMarshaller.operationCandidate(serializer, pocs[i]);
1156             serializer.endAppend();
1157         }
1158     }
1159 
1160     public void marshalOperationClassRemoveOperationCandidate(XmlSerializer x, ProtocolOperationClass poc, int i) throws IOException, UnsupportedOperationException {
1161         XUpdateSerializer serializer = (XUpdateSerializer) x;
1162         String select = selectOperationClass(poc) + "/operationCandidate[" + (i + 1) + "]";
1163         serializer.remove(select);
1164     }
1165 
1166     public void marshalOperationClassAddOperationCandidate(XmlSerializer x, ProtocolOperationClass poc, OperationCandidate o) throws IOException, UnsupportedOperationException {
1167         XUpdateSerializer serializer = (XUpdateSerializer) x;
1168         String select = selectOperationCandidate((ProtocolOperationCandidate) o);
1169         int child = afterLastOperationCandidateIndex(poc);
1170         serializer.startAppend(select, "" + child);
1171         GWDLMarshaller.operationCandidate(serializer, o);
1172         serializer.endAppend();
1173     }
1174 
1175     ///
1176     /// Methods for operationCandidate
1177     /// ----------------------------------------------------------------------------------------------------
1178 
1179     protected int firstOwlIndex(OperationCandidate o) {
1180         return 1;
1181     }
1182 
1183     protected int afterLastOwlIndex(OperationCandidate o) {
1184         return firstOwlIndex(o) + o.owlsCount();
1185     }
1186 
1187     protected int operationCandidateIndex(OperationClass oc, OperationCandidate oca) throws IOException {
1188         OperationCandidate[] ocs = oc.getOperationCandidates();
1189         for (int i = 0; i < ocs.length; i++) {
1190             if (ocs[i] == oca) {
1191                 return i + 1;
1192             }
1193         }
1194         throw new IOException("Specified OperationCandidate not a child of specified OperationClass.");
1195     }
1196 
1197     protected String selectOperationCandidate(ProtocolOperationCandidate o) throws IOException {
1198         ProtocolOperationClass poc = (ProtocolOperationClass) o.getParent();
1199         int oi = operationCandidateIndex(poc, o);
1200         String select = selectOperationClass(poc) + "/" + o.getNAME() + "[" + oi + "]";
1201         return select;
1202     }
1203 
1204     protected void marshalOperationCandidateAddOwl(XUpdateSerializer serializer, ProtocolOperationCandidate poc, String owl) throws IOException {
1205         String select = selectOperationCandidate(poc);
1206         int child = afterLastOwlIndex(poc);
1207         serializer.startAppend(select, "" + child);
1208         GWDLMarshaller.owloc(serializer, owl);
1209         serializer.endAppend();
1210     }
1211 
1212     protected void marshalOperationCandidateSetOwls(XUpdateSerializer serializer, ProtocolOperationCandidate poc, String[] owls) throws IOException {
1213         String select = selectOperationCandidate(poc);
1214         serializer.remove(select + "/owl");
1215         marshalAppendOwlsocList(serializer, select, firstOwlIndex(poc), owls);
1216     }
1217 
1218     protected void marshalOperationCandidateRemoveOwl(XUpdateSerializer serializer, ProtocolOperationCandidate poc, int i) throws IOException {
1219         String select = selectOperationCandidate(poc) + "/owl[" + (i + 1) + "]";
1220         serializer.remove(select);
1221     }
1222 
1223     public void marshalOperationCandidateSetType(XmlSerializer x, ProtocolOperationCandidate poc, String type) throws IOException, UnsupportedOperationException {
1224         XUpdateSerializer serializer = (XUpdateSerializer) x;
1225         String old = poc.getType();
1226         String select = selectOperationCandidate(poc);
1227         if (GWDLMarshaller.isDefaultOperationType(old) &&
1228                 GWDLMarshaller.isDefaultOperationType(type)) {
1229             return;
1230         } else if (GWDLMarshaller.isDefaultOperationType(old)) {
1231             serializer.startAppend(select, null);
1232             GWDLMarshaller.operationType(serializer, type);
1233             serializer.endAppend();
1234         } else if (GWDLMarshaller.isDefaultOperationType(type)) {
1235             serializer.remove(select + "/@type");
1236         } else {
1237             serializer.update(select + "/@type", type);
1238         }
1239     }
1240 
1241     public void marshalOperationCandidateSetOperationName(XmlSerializer x, ProtocolOperationCandidate poc, String name) throws IOException, UnsupportedOperationException {
1242         XUpdateSerializer serializer = (XUpdateSerializer) x;
1243         String old = poc.getOperationName();
1244         String select = selectOperationCandidate(poc);
1245         if (GWDLMarshaller.isDefaultOperationName(old) &&
1246                 GWDLMarshaller.isDefaultOperationName(name)) {
1247             return;
1248         } else if (GWDLMarshaller.isDefaultOperationName(old)) {
1249             serializer.startAppend(select, null);
1250             GWDLMarshaller.operationName(serializer, name);
1251             serializer.endAppend();
1252         } else if (GWDLMarshaller.isDefaultOperationName(name)) {
1253             serializer.remove(select + "/@operationName");
1254         } else {
1255             serializer.update(select + "/@operationName", name);
1256         }
1257     }
1258 
1259     public void marshalOperationCandidateSetResourceName(XmlSerializer x, ProtocolOperationCandidate poc, String name) throws IOException, UnsupportedOperationException {
1260         XUpdateSerializer serializer = (XUpdateSerializer) x;
1261         String old = poc.getResourceName();
1262         String select = selectOperationCandidate(poc);
1263         if (GWDLMarshaller.isDefaultResourceName(old) &&
1264                 GWDLMarshaller.isDefaultResourceName(name)) {
1265             return;
1266         } else if (GWDLMarshaller.isDefaultResourceName(old)) {
1267             serializer.startAppend(select, null);
1268             GWDLMarshaller.resourceName(serializer, name);
1269             serializer.endAppend();
1270         } else if (GWDLMarshaller.isDefaultResourceName(name)) {
1271             serializer.remove(select + "/@resourceName");
1272         } else {
1273             serializer.update(select + "/@resourceName", name);
1274         }
1275     }
1276 
1277     public void marshalOperationCandidateSetQuality(XmlSerializer x, ProtocolOperationCandidate poc, float quality) throws IOException, UnsupportedOperationException {
1278         XUpdateSerializer serializer = (XUpdateSerializer) x;
1279         float old = poc.getQuality();
1280         String select = selectOperationCandidate(poc);
1281         if (GWDLMarshaller.isDefaultQuality(old) &&
1282                 GWDLMarshaller.isDefaultQuality(quality)) {
1283             return;
1284         } else if (GWDLMarshaller.isDefaultQuality(old)) {
1285             serializer.startAppend(select, null);
1286             GWDLMarshaller.quality(serializer, quality);
1287             serializer.endAppend();
1288         } else if (GWDLMarshaller.isDefaultQuality(quality)) {
1289             serializer.remove(select + "/@quality");
1290         } else {
1291             serializer.update(select + "/@quality", ""+quality);
1292         }
1293     }
1294 
1295     public void marshalOperationCandidateSetSelected(XmlSerializer x, ProtocolOperationCandidate poc, boolean selected) throws IOException, UnsupportedOperationException {
1296         XUpdateSerializer serializer = (XUpdateSerializer) x;
1297         boolean old = poc.isSelected();
1298         String select = selectOperationCandidate(poc);
1299         if (GWDLMarshaller.isDefaultSelected(old) &&
1300                 GWDLMarshaller.isDefaultSelected(selected)) {
1301             return;
1302         } else if (GWDLMarshaller.isDefaultSelected(old)) {
1303             serializer.startAppend(select, null);
1304             GWDLMarshaller.selected(serializer, selected);
1305             serializer.endAppend();
1306         } else if (GWDLMarshaller.isDefaultSelected(selected)) {
1307             serializer.remove(select + "/@selected");
1308         } else {
1309             serializer.update(select + "/@selected", ""+selected);
1310         }
1311     }
1312 
1313 }