1 package net.kwfgrid.gworkflowdl.analysis;
2
3 import net.kwfgrid.gworkflowdl.structure.Place;
4 import net.kwfgrid.gworkflowdl.structure.Transition;
5 import net.kwfgrid.gworkflowdl.structure.Workflow;
6
7 /***
8 * Created by IntelliJ IDEA.
9 * User: hans
10 * Date: 24.10.2005
11 * Time: 16:38:39
12 * To change this template use File | Settings | File Templates.
13 */
14 public class WorkflowAnalyzer {
15 public static final int SHOW_LIGHT = 0;
16 public static final int SHOW_FULL = 1;
17
18 public KarpMillerAnalyzer kma;
19 public Workflow workflow;
20 Workflow wfSmart;
21 ComplexityReducer cr;
22
23 public WorkflowAnalyzer(Workflow wf) {
24 workflow = wf;
25 wfSmart = SmartCopy.copy(wf);
26
27 cr = new ComplexityReducer(wfSmart);
28 cr.reduce();
29
30 kma = new KarpMillerAnalyzer(wfSmart);
31 }
32
33
34 public String searchForPlace(String id) {
35 String pID = id;
36
37 while (true) {
38 Place sp = wfSmart.getPlace(pID);
39
40 if (sp != null) {
41 return sp.getID();
42 } else {
43 pID = (String) cr.rememberPlaces.get(pID);
44
45 if (pID == null) {
46 return null;
47 }
48 }
49 }
50 }
51
52
53 public String searchForPlaceBack(String id) {
54 String pIDold = id;
55 String pIDnew;
56 while (true) {
57 pIDnew = (String) cr.rememberPlacesBack.get(pIDold);
58 if (pIDnew == null) {
59 return pIDold;
60 } else {
61 pIDold = pIDnew;
62 }
63 }
64 }
65
66 public String searchForTransition(String id) {
67 String pID = (String) cr.rememberTransitions.get(id);
68
69 return searchForPlace(pID);
70 }
71
72 /***
73 * checks whether a transition can fire
74 *
75 * @param t transition
76 * @return answer
77 */
78 public boolean isQuasiLive(Transition t) {
79 Transition tt = wfSmart.getTransition(t.getID());
80 if (tt != null) {
81 return kma.isQuasiLive(tt);
82 } else {
83 Place pp = wfSmart.getPlace(searchForTransition(t.getID()));
84 return kma.isQuasiLive(pp);
85 }
86 }
87
88
89 /***
90 * checks whether a place can get a token
91 *
92 * @param p
93 * @return answer
94 */
95 public boolean isQuasiLive(Place p) {
96 Place pp = wfSmart.getPlace(searchForPlace(p.getID()));
97 return kma.isQuasiLive(pp);
98 }
99
100 public boolean isUnbounded(Place p) {
101 Place pp = wfSmart.getPlace(searchForPlace(p.getID()));
102 return kma.isUnbounded(pp);
103 }
104
105 public boolean isUnbounded() {
106 return kma.isUnbounded();
107 }
108
109
110 /***
111 * @param p Place
112 * @return true if Place p must have a token finally
113 */
114 public boolean isFinallyMarked(Place p) {
115
116 Place pp = wfSmart.getPlace(p.getID());
117 if (pp == null) {
118 return false;
119 }
120 return kma.isFinallyMarked(pp);
121 }
122
123 public int initialMarked(Place p) {
124 return p.getTokenNumber();
125 }
126
127 public Decision[] getDecisions() {
128 Decision[] ds = kma.getDecisions();
129
130 Decision[] ret = new Decision[ds.length];
131 for (int i = 0; i < ds.length; i++) {
132 ret[i] = new Decision();
133 ret[i].type = ds[i].type;
134 String id = ds[i].place.getID();
135
136 ret[i].place = workflow.getPlace(searchForPlaceBack(id));
137 ret[i].transitions = new Transition[ds[i].transitions.length];
138 for (int j = 0; j < ds[i].transitions.length; j++) {
139 ret[i].transitions[j] = workflow.getTransition(ds[i].transitions[j].getID());
140 }
141 }
142
143 return ret;
144
145 }
146
147 public boolean isPersistent() {
148 return kma.isPersistent();
149 }
150
151 public boolean hasInfiniteRun() {
152 return kma.hasInfiniteRun();
153 }
154
155 public boolean isComplete() {
156 return kma.isComplete();
157 }
158
159 public int getComplexity() {
160 return kma.getComplexity();
161 }
162
163
164 public void showAnalysis() {
165 System.out.println(analysis2string());
166 }
167
168 public void showAnalysis(int showType) {
169 System.out.println(analysis2string(showType));
170 }
171
172 public String place2string(Place p, int showType) {
173 String s = "";
174 if (!isQuasiLive(p)) {
175 s += " dead";
176 }
177 if (isFinallyMarked(p)) {
178 s += " finally_marked";
179 }
180 if (isUnbounded(p)) {
181 s += " unbounded";
182 }
183 if (initialMarked(p) > 0) {
184 s += " marking=" + initialMarked(p);
185 }
186 String ret = " " + p.getID() + s + "\n";
187 if (showType == SHOW_LIGHT && s.equals("")) {
188 ret = "";
189 }
190 return ret;
191 }
192
193 public String transition2string(Transition t, int showType) {
194
195 String s = "";
196 if (!isQuasiLive(t)) {
197 s += " dead";
198 }
199 if (t.isEnabled()) {
200 s += " enabled";
201 }
202 String ret = " " + t.getID() + s + "\n";
203 if (showType == SHOW_LIGHT && s.equals("")) {
204 ret = "";
205 }
206 return ret;
207 }
208
209
210 public String general2string() {
211 String s = "";
212 if (isComplete()) {
213 s += " Karp-Miller-Tree complete\n";
214 } else {
215 s += " Karp-Miller-Tree uncomplete\n";
216 }
217 s += " complexity=" + getComplexity() + "\n";
218
219 if (isUnbounded()) {
220 s += " unbounded\n";
221 } else {
222 s += " bounded\n";
223 }
224 if (hasInfiniteRun()) {
225 s += " infinite_run\n";
226 } else {
227 s += " stopping\n";
228 }
229 if (isPersistent()) {
230 s += " persistent\n";
231 } else {
232 s += " not_persistent\n";
233 }
234
235 return s;
236 }
237
238 public String analysis2string(int showType) {
239 String s = "== general information ==\n";
240 s += general2string();
241 s += "\n";
242 s += "== places ==\n";
243 Place[] ps = workflow.getPlaces();
244 for (int i = 0; i < ps.length; i++) {
245 s += place2string(ps[i], showType);
246 }
247 s += "\n";
248 s += "== transitions ==\n";
249 Transition[] ts = workflow.getTransitions();
250 for (int i = 0; i < ts.length; i++) {
251 s += transition2string(ts[i], showType);
252 }
253 s += "\n";
254 s += "== decisions / conflicts ==\n";
255 Decision[] ds = getDecisions();
256 for (int i = 0; i < ds.length; i++) {
257 s += ds[i].toString();
258 }
259 s += "\n";
260 return s;
261 }
262
263 public String analysis2string() {
264 return analysis2string(SHOW_LIGHT);
265 }
266
267 }