1
2
3
4
5
6 package net.kwfgrid.gworkflowdl.protocol.client;
7
8 import net.kwfgrid.gworkflowdl.protocol.IncompatibleVersionsException;
9 import net.kwfgrid.gworkflowdl.protocol.IllegalModificationException;
10 import net.kwfgrid.gworkflowdl.protocol.IMethodCallEncoder;
11 import net.kwfgrid.gworkflowdl.protocol.AbstractMethodCallStrategyExt;
12 import net.kwfgrid.gworkflowdl.protocol.Protocol;
13 import net.kwfgrid.gworkflowdl.protocol.service.IStructureService;
14 import net.kwfgrid.gworkflowdl.protocol.calls.MethodCallException;
15 import net.kwfgrid.gworkflowdl.protocol.calls.IMethodCall;
16 import net.kwfgrid.gworkflowdl.protocol.structure.IStructureTask;
17 import net.kwfgrid.gworkflowdl.protocol.structure.ProtocolWorkflow;
18 import net.kwfgrid.gworkflowdl.structure.WorkflowFormatException;
19 import net.kwfgrid.gworkflowdl.structure.CapacityException;
20
21 import java.rmi.RemoteException;
22 import java.io.IOException;
23 import java.util.List;
24
25 import org.apache.log4j.Logger;
26
27 /***
28 Extended default implementation of <code>IClientDelegate</code>.
29 This implementation calls the methods of <code>IStructureListenerExt</code> and
30 executes additional tasks added to the queue <code>IRootObject.getTaskQueue()</code>
31 during structure event dispatching.
32 */
33 public class DefaultClientDelegateExt extends AbstractMethodCallStrategyExt implements IClientDelegate {
34 private IStructureService _servicestub;
35 private String _userID;
36
37 private static final Logger logger = Logger.getLogger(DefaultClientDelegate.class);
38
39 /***
40 Constructor.
41 @param servicestub The service stub to contact the server.
42 * @param userID
43 */
44 public DefaultClientDelegateExt(IStructureService servicestub, String userID) {
45 _servicestub = servicestub;
46 _userID = userID;
47 }
48
49 public Object execute(IMethodCall call) throws MethodCallException, IllegalModificationException, IncompatibleVersionsException {
50 IClientRootObject structure = (IClientRootObject)call.getTarget();
51 IMethodCallEncoder encoder = Protocol.getMethodCallEncoder();
52 String enc = null;
53 Object ret = null;
54 IStructureTask tasks[] = null;
55
56 synchronized(structure.getStructureLock()) {
57 try {
58 enc = encoder.encode(call);
59 } catch (IOException x) {
60 IllegalModificationException ix = new IllegalModificationException("Could not encode method call.");
61 ix.initCause(x);
62 throw ix;
63 }
64 try {
65 commit(structure, enc);
66 } catch (RemoteException x) {
67 IllegalModificationException ix = new IllegalModificationException("Could not commit changes. Exception on server-side.");
68 ix.initCause(x);
69 throw ix;
70 }
71
72 fireBeginModifications(structure);
73
74 try {
75 ret = call.execute();
76 } catch (Exception x) {
77 fireException(structure, x);
78 throw new MethodCallException("Could not invoke method call. Structure invalid and needs to be checked out again.", x);
79 }
80
81 fireEndModifications(structure);
82
83 List queue = structure.getTaskQueue();
84 tasks = (IStructureTask[])queue.toArray(new IStructureTask[queue.size()]);
85 queue.clear();
86 }
87
88 try {
89 for (int i=0; i<tasks.length; i++) {
90 tasks[i].run();
91 }
92 } catch (IncompatibleVersionsException x) {
93 IncompatibleVersionsException ix = new IncompatibleVersionsException("Nested IncompatibleVersionsException.", x);
94 throw ix;
95 } catch (IllegalModificationException x) {
96 IllegalModificationException ix = new IllegalModificationException("Nested IllegalModificationException.", x);
97 throw ix;
98 } catch (Exception x) {
99 throw new MethodCallException("Could not execute inner method call.", x);
100 }
101
102 return ret;
103 }
104
105 public void commit(IClientRootObject structure, String modification) throws IllegalModificationException, IncompatibleVersionsException, RemoteException {
106 synchronized (structure.getStructureLock()) {
107 int newversion = _servicestub.commitModification(structure.getID(), structure.getVersionNumber(), modification, _userID);
108 structure.setVersionNumber(newversion);
109 }
110 }
111
112 public void update(IClientRootObject structure) throws IllegalModificationException, RemoteException {
113 boolean exception = true;
114 IStructureTask tasks[] = null;
115
116 try {
117 synchronized (structure.getStructureLock()) {
118
119 String[][] updates = _servicestub.getModificationsForUpdate(structure.getID(), structure.getVersionNumber(), _userID);
120
121 if (updates.length > 0) {
122
123 fireBeginModifications(structure);
124
125 for (int i=0; i<updates.length; i++) {
126 String version = updates[i][0];
127 String command = updates[i][1];
128 String content = updates[i][2];
129 handleUpdate(structure, updates[i][1], updates[i][2]);
130 structure.setVersionNumber(Integer.parseInt(updates[i][0]));
131 }
132
133 fireEndModifications(structure);
134
135 List queue = structure.getTaskQueue();
136 tasks = (IStructureTask[])queue.toArray(new IStructureTask[queue.size()]);
137 queue.clear();
138 }
139
140 exception = false;
141 }
142 } catch (NumberFormatException x) {
143 throw new IllegalModificationException("Could not parse version number as int.", x);
144 } finally {
145 if (exception) fireException(structure, new Exception("Unknown exception during client update. See log output for details"));
146 }
147
148 try {
149 for (int i=0; tasks!=null && i<tasks.length; i++) {
150 tasks[i].run();
151 }
152 } catch (IncompatibleVersionsException x) {
153 IllegalModificationException ix = new IllegalModificationException("Nested IncompatibleVersionsException.", x);
154 throw ix;
155 } catch (IllegalModificationException x) {
156 IllegalModificationException ix = new IllegalModificationException("Nested IllegalModificationException.", x);
157 throw ix;
158 } catch (Exception x) {
159 IllegalModificationException ix = new IllegalModificationException("Nested Exception during inner method call.", x);
160 throw ix;
161 }
162 }
163
164 private void handleUpdate(IClientRootObject structure, String command, String content) throws IllegalModificationException {
165 if (Protocol.IDENTIFIER_FULLUPDATE.equals(command)) {
166 try {
167 ((ProtocolWorkflow)structure).__fromXML(content);
168 } catch (WorkflowFormatException x) {
169 throw new IllegalModificationException("Could not parse workflow description.", x);
170 } catch (CapacityException x) {
171 throw new IllegalModificationException("Could not parse workflow description.", x);
172 }
173 } else if (Protocol.IDENTIFIER_MODIFICATION.equals(command)) {
174 Protocol.getModificationHandler().handleModification(structure, content);
175 } else {
176 throw new IllegalModificationException("Unknown update command: "+command);
177 }
178 }
179 }