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 package org.imixs.workflow.jee.ejb;
29
30 import java.util.Collection;
31 import java.util.List;
32 import java.util.StringTokenizer;
33 import java.util.logging.Logger;
34
35 import javax.annotation.PostConstruct;
36 import javax.annotation.Resource;
37 import javax.annotation.security.DeclareRoles;
38 import javax.annotation.security.RolesAllowed;
39 import javax.ejb.EJB;
40 import javax.ejb.LocalBean;
41 import javax.ejb.SessionContext;
42 import javax.ejb.Stateless;
43
44 import org.imixs.workflow.ExtendedModel;
45 import org.imixs.workflow.ExtendedWorkflowContext;
46 import org.imixs.workflow.ItemCollection;
47 import org.imixs.workflow.Model;
48 import org.imixs.workflow.WorkflowKernel;
49 import org.imixs.workflow.exceptions.AccessDeniedException;
50 import org.imixs.workflow.exceptions.ProcessingErrorException;
51 import org.imixs.workflow.jee.jpa.EntityIndex;
52
53
54
55
56
57
58
59
60
61
62
63
64 @DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS",
65 "org.imixs.ACCESSLEVEL.READERACCESS",
66 "org.imixs.ACCESSLEVEL.AUTHORACCESS",
67 "org.imixs.ACCESSLEVEL.EDITORACCESS",
68 "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
69 @RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS",
70 "org.imixs.ACCESSLEVEL.READERACCESS",
71 "org.imixs.ACCESSLEVEL.AUTHORACCESS",
72 "org.imixs.ACCESSLEVEL.EDITORACCESS",
73 "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
74 @Stateless
75 @LocalBean
76 public class WorkflowService implements ExtendedWorkflowContext {
77
78 public static final int SORT_ORDER_CREATED_DESC = 0;
79 public static final int SORT_ORDER_CREATED_ASC = 1;
80 public static final int SORT_ORDER_MODIFIED_DESC = 2;
81 public static final int SORT_ORDER_MODIFIED_ASC = 3;
82
83 private int logLevel = WorkflowKernel.LOG_LEVEL_SEVERE;
84
85 @EJB
86 EntityService entityService;
87
88 @EJB
89 ModelService modelService;
90
91 @Resource
92 SessionContext ctx;
93
94 private static Logger logger = Logger.getLogger("org.imixs.workflow");
95
96
97
98
99
100
101 @SuppressWarnings("unused")
102 @PostConstruct
103 private void initIndexProperties() throws AccessDeniedException {
104 entityService.addIndex("namCreator", EntityIndex.TYP_TEXT);
105 entityService.addIndex("txtWorkflowGroup", EntityIndex.TYP_TEXT);
106 entityService.addIndex("$ProcessID", EntityIndex.TYP_INT);
107 entityService.addIndex("$workitemid", EntityIndex.TYP_TEXT);
108 entityService.addIndex("$uniqueidref", EntityIndex.TYP_TEXT);
109 entityService.addIndex("txtname", EntityIndex.TYP_TEXT);
110 entityService.addIndex("namowner", EntityIndex.TYP_TEXT);
111 }
112
113
114
115
116 public ItemCollection getWorkItem(String uniqueid) {
117 return entityService.load(uniqueid);
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public Collection<ItemCollection> getWorkList(String name) {
147 return getWorkList(name, 0, -1, null, 0);
148 }
149
150 public Collection<ItemCollection> getWorkList(String name, int startpos,
151 int count, String type, int sortorder) {
152
153 if (name == null || "".equals(name))
154 name = ctx.getCallerPrincipal().getName();
155
156 String sQuery = null;
157 sQuery = "SELECT";
158 sQuery += " wi FROM Entity as wi " + " JOIN wi.writeAccessList as wa"
159 + " JOIN wi.textItems as s " + "WHERE ";
160
161 if (type != null && !"".equals(type))
162 sQuery += " wi.type='" + type + "' AND ";
163
164 sQuery += " wa.value = '" + name + "'"
165 + " AND s.itemName = '$workitemid' ORDER BY wi.created desc";
166 return entityService.findAllEntities(sQuery, startpos, count);
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public Collection<ItemCollection> getWorkListByCreator(String name,
192 int startpos, int count, String type, int sortorder) {
193
194 if (name == null || "".equals(name))
195 name = ctx.getCallerPrincipal().getName();
196
197 String sQuery = null;
198 sQuery = "SELECT";
199 sQuery += " wi FROM Entity as wi"
200 + " JOIN wi.textItems as t JOIN wi.textItems as s " + "WHERE ";
201 if (type != null && !"".equals(type))
202 sQuery += " wi.type='" + type + "' AND ";
203
204 sQuery += " t.itemName = 'namcreator' and t.itemValue = '" + name + "'"
205 + " AND s.itemName = '$workitemid' "
206 + createSortOrderClause(sortorder);
207
208 return entityService.findAllEntities(sQuery, startpos, count);
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233 public Collection<ItemCollection> getWorkListByOwner(String name,
234 int startpos, int count, String type, int sortorder) {
235
236 if (name == null || "".equals(name))
237 name = ctx.getCallerPrincipal().getName();
238
239 String sQuery = null;
240 sQuery = "SELECT";
241 sQuery += " wi FROM Entity as wi"
242 + " JOIN wi.textItems as t JOIN wi.textItems as s " + "WHERE ";
243 if (type != null && !"".equals(type))
244 sQuery += " wi.type='" + type + "' AND ";
245
246 sQuery += " t.itemName = 'namowner' and t.itemValue = '" + name + "'"
247 + " AND s.itemName = '$workitemid' "
248 + createSortOrderClause(sortorder);
249
250 return entityService.findAllEntities(sQuery, startpos, count);
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 public Collection<ItemCollection> getWorkListByWriteAccess(int startpos,
274 int count, String type, int sortorder) {
275 StringBuffer nameListBuffer = new StringBuffer();
276
277 String name = ctx.getCallerPrincipal().getName();
278
279
280 nameListBuffer.append("'" + name + "'");
281
282
283 String accessRoles = entityService.getAccessRoles();
284
285 String roleList = "org.imixs.ACCESSLEVEL.READERACCESS,org.imixs.ACCESSLEVEL.AUTHORACCESS,org.imixs.ACCESSLEVEL.EDITORACCESS,"
286 + accessRoles;
287
288 StringTokenizer roleListTokens = new StringTokenizer(roleList, ",");
289 while (roleListTokens.hasMoreTokens()) {
290 String testRole = roleListTokens.nextToken().trim();
291 if (!"".equals(testRole) && ctx.isCallerInRole(testRole))
292 nameListBuffer.append(",'" + testRole + "'");
293 }
294
295 String sQuery = "SELECT wi FROM Entity as wi "
296 + " JOIN wi.writeAccessList wa " + " WHERE ";
297 if (type != null && !"".equals(type))
298 sQuery += " wi.type='" + type + "' ";
299
300 sQuery += " AND wa.value IN (" + nameListBuffer.toString() + ")"
301 + createSortOrderClause(sortorder);
302
303 return entityService.findAllEntities(sQuery, startpos, count);
304 }
305
306 public Collection<ItemCollection> getWorkListByGroup(String name,
307 int startpos, int count, String type, int sortorder) {
308
309 String sQuery = null;
310 sQuery = "SELECT";
311 sQuery += " wi FROM Entity as wi " + " JOIN wi.textItems as t "
312 + " JOIN wi.textItems as s " + "WHERE ";
313
314 if (type != null && !"".equals(type))
315 sQuery += " wi.type='" + type + "' AND ";
316
317 sQuery += " t.itemName = 'txtworkflowgroup' and t.itemValue = '" + name
318 + "'" + " AND s.itemName = '$workitemid' "
319 + createSortOrderClause(sortorder);
320 return entityService.findAllEntities(sQuery, startpos, count);
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344 public Collection<ItemCollection> getWorkListByProcessID(int aid,
345 int startpos, int count, String type, int sortorder) {
346
347 String sQuery = null;
348 sQuery = "SELECT";
349 sQuery += " wi FROM Entity as wi "
350 + " JOIN wi.integerItems as t JOIN wi.textItems as s "
351 + "WHERE ";
352
353 if (type != null && !"".equals(type))
354 sQuery += " wi.type='" + type + "' AND ";
355
356 sQuery += " t.itemName = '$processid' and t.itemValue = '" + aid + "'"
357 + " AND s.itemName = '$workitemid' "
358 + createSortOrderClause(sortorder);
359
360 return entityService.findAllEntities(sQuery, startpos, count);
361 }
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 public Collection<ItemCollection> getWorkListByRef(String aref) {
385 return getWorkListByRef(aref, 0, -1, null, 0);
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 public Collection<ItemCollection> getWorkListByRef(String aref,
410 int startpos, int count, String type, int sortorder) {
411
412 String sQuery = null;
413 sQuery = "SELECT";
414 sQuery += " wi FROM Entity as wi "
415 + " JOIN wi.textItems as t JOIN wi.textItems as s " + "WHERE ";
416 if (type != null && !"".equals(type))
417 sQuery += " wi.type='" + type + "' AND ";
418
419 sQuery += " t.itemName = '$uniqueidref' and t.itemValue = '" + aref
420 + "'" + " and s.itemName = '$workitemid' "
421 + createSortOrderClause(sortorder);
422
423 return entityService.findAllEntities(sQuery, startpos, count);
424 }
425
426
427
428
429
430
431
432 private String createSortOrderClause(int asortorder) {
433 switch (asortorder) {
434
435 case WorkflowService.SORT_ORDER_CREATED_ASC: {
436 return " ORDER BY wi.created asc";
437 }
438 case WorkflowService.SORT_ORDER_MODIFIED_ASC: {
439 return " ORDER BY wi.modified asc";
440 }
441 case WorkflowService.SORT_ORDER_MODIFIED_DESC: {
442 return " ORDER BY wi.modified desc";
443 }
444 default:
445 return " ORDER BY wi.created desc";
446 }
447
448 }
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 public ItemCollection processWorkItem(ItemCollection workitem)
470 throws AccessDeniedException, ProcessingErrorException {
471
472 if (workitem == null)
473 throw new ProcessingErrorException(
474 "WorkflowService: error - workitem is null");
475
476
477 ItemCollection currentInstance = this.getWorkItem(workitem
478 .getItemValueString(EntityService.UNIQUEID));
479
480 if (currentInstance != null
481 && currentInstance.getItemValueInteger("$ProcessID") != workitem
482 .getItemValueInteger("$ProcessID"))
483 throw new ProcessingErrorException(
484 "WorkflowService: error - $ProcesssID ("
485 + workitem.getItemValueInteger("$ProcessID")
486 + ") did not match expected $ProcesssID ("
487 + currentInstance.getItemValueInteger("$ProcessID")
488 + ")");
489
490
491
492
493
494
495 String modelversion = workitem.getItemValueString("$modelversion");
496 ItemCollection profile = findModelProfile(modelversion);
497
498 WorkflowKernel workflowkernel = new WorkflowKernel(this);
499
500
501 List<String> vPlugins = profile.getItemValue("txtPlugins");
502 for (int i = 0; i < vPlugins.size(); i++) {
503 String sPlugin = vPlugins.get(i);
504 workflowkernel.registerPlugin(sPlugin);
505 }
506
507
508 String sDebug = profile.getItemValueString("keyDebugLevel");
509 try {
510 int idebug = Integer.parseInt(sDebug);
511 logLevel = idebug;
512 } catch (NumberFormatException e) {
513 logLevel = WorkflowKernel.LOG_LEVEL_FINE;
514 }
515
516
517 if (!modelversion.equals(profile.getItemValueString("$ModelVersion"))) {
518 logger.info("WorkflowService: modelversion '"
519 + modelversion
520 + "' no longer provided. Continue processing with modelversion '"
521 + profile.getItemValueString("$ModelVersion") + "'");
522
523
524
525 modelversion = profile.getItemValueString("$ModelVersion");
526 workitem.replaceItemValue("$modelversion", modelversion);
527 }
528
529
530 String name;
531 name = ctx.getCallerPrincipal().getName();
532
533
534 if ("".equals(workitem.getItemValueString("namCreator")))
535 workitem.replaceItemValue("namCreator", name);
536
537
538 workitem.replaceItemValue("namlasteditor",
539 workitem.getItemValueString("namcurrenteditor"));
540 workitem.replaceItemValue("namcurrenteditor", name);
541
542
543 workflowkernel.process(workitem);
544
545 if (this.getLogLevel() == WorkflowKernel.LOG_LEVEL_FINE)
546 logger.info("[WorkflowManager] workitem processed sucessfull");
547
548 return entityService.save(workitem);
549
550 }
551
552 public void removeWorkItem(ItemCollection aworkitem)
553 throws AccessDeniedException {
554 entityService.remove(aworkitem);
555 }
556
557
558
559
560 public int getLogLevel() {
561 return logLevel;
562 }
563
564
565
566
567
568
569
570 public Model getModel() {
571 return modelService;
572 }
573
574 public ExtendedModel getExtendedModel() {
575 return modelService;
576 }
577
578 public Object getSessionContext() {
579 return ctx;
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600 private ItemCollection findModelProfile(String modelversion)
601 throws ProcessingErrorException {
602 ItemCollection profile = null;
603
604
605 if (modelversion == null || "".equals(modelversion)) {
606 modelversion = modelService.getLatestVersion();
607 }
608
609
610
611
612 Collection<ItemCollection> col;
613 String sQuery = null;
614 sQuery = "SELECT";
615 sQuery += " environment FROM Entity AS environment"
616 + " JOIN environment.textItems as n "
617 + " JOIN environment.textItems as v "
618 + " WHERE environment.type = 'WorkflowEnvironmentEntity'"
619 + " AND n.itemName = 'txtname' AND n.itemValue = 'environment.profile'"
620 + " AND v.itemName = '$modelversion' AND v.itemValue >= '"
621 + modelversion + "' ORDER BY v.itemValue";
622 col = entityService.findAllEntities(sQuery, 0, 1);
623
624
625 if (col.size() == 0) {
626 logger.severe("WorkflowService: fatal error - no valid model version '"
627 + modelversion + "' found! Verify WorkflowModels.");
628 throw new ProcessingErrorException(
629 "WorkflowService: fatal error - no valid model version '"
630 + modelversion + "' found! Verify WorkflowModels.");
631 }
632
633 profile = col.iterator().next();
634
635 return profile;
636 }
637
638
639
640
641
642
643
644
645
646 public EntityService getEntityService() {
647 return entityService;
648 }
649
650
651
652
653
654
655
656
657
658 public ModelService getModelService() {
659 return modelService;
660 }
661
662
663
664
665
666
667
668 public String getUserName() {
669 return ctx.getCallerPrincipal().getName();
670
671 }
672
673
674
675
676
677
678
679 public boolean isUserInRole(String rolename) {
680 try {
681 return ctx.isCallerInRole(rolename);
682 } catch (Exception e) {
683
684 return false;
685 }
686 }
687
688
689
690
691
692
693
694 public List<String> getUserNameList() {
695 return entityService.getUserNameList();
696 }
697 }