PageRenderTime 2ms CodeModel.GetById 29ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/webs/kaleo-web/docroot/WEB-INF/src/com/liferay/portal/workflow/kaleo/parser/XMLWorkflowModelParser.java

https://github.com/l15k4/liferay-plugins
Java | 669 lines | 452 code | 199 blank | 18 comment | 59 complexity | 0d001d1f331aada1e31f49340617da77 MD5 | raw file
  1/**
  2 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
  3 *
  4 * This library is free software; you can redistribute it and/or modify it under
  5 * the terms of the GNU Lesser General Public License as published by the Free
  6 * Software Foundation; either version 2.1 of the License, or (at your option)
  7 * any later version.
  8 *
  9 * This library is distributed in the hope that it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 12 * details.
 13 */
 14
 15package com.liferay.portal.workflow.kaleo.parser;
 16
 17import com.liferay.portal.kernel.util.GetterUtil;
 18import com.liferay.portal.kernel.util.Validator;
 19import com.liferay.portal.kernel.workflow.WorkflowException;
 20import com.liferay.portal.kernel.xml.Document;
 21import com.liferay.portal.kernel.xml.Element;
 22import com.liferay.portal.kernel.xml.SAXReaderUtil;
 23import com.liferay.portal.workflow.kaleo.definition.Action;
 24import com.liferay.portal.workflow.kaleo.definition.ActionAware;
 25import com.liferay.portal.workflow.kaleo.definition.AddressRecipient;
 26import com.liferay.portal.workflow.kaleo.definition.Assignment;
 27import com.liferay.portal.workflow.kaleo.definition.Condition;
 28import com.liferay.portal.workflow.kaleo.definition.Definition;
 29import com.liferay.portal.workflow.kaleo.definition.DelayDuration;
 30import com.liferay.portal.workflow.kaleo.definition.DurationScale;
 31import com.liferay.portal.workflow.kaleo.definition.Fork;
 32import com.liferay.portal.workflow.kaleo.definition.Join;
 33import com.liferay.portal.workflow.kaleo.definition.Node;
 34import com.liferay.portal.workflow.kaleo.definition.Notification;
 35import com.liferay.portal.workflow.kaleo.definition.NotificationAware;
 36import com.liferay.portal.workflow.kaleo.definition.ResourceActionAssignment;
 37import com.liferay.portal.workflow.kaleo.definition.RoleAssignment;
 38import com.liferay.portal.workflow.kaleo.definition.RoleRecipient;
 39import com.liferay.portal.workflow.kaleo.definition.ScriptAssignment;
 40import com.liferay.portal.workflow.kaleo.definition.State;
 41import com.liferay.portal.workflow.kaleo.definition.Task;
 42import com.liferay.portal.workflow.kaleo.definition.Timer;
 43import com.liferay.portal.workflow.kaleo.definition.Transition;
 44import com.liferay.portal.workflow.kaleo.definition.UserAssignment;
 45import com.liferay.portal.workflow.kaleo.definition.UserRecipient;
 46
 47import java.io.InputStream;
 48
 49import java.util.Collections;
 50import java.util.HashSet;
 51import java.util.List;
 52import java.util.Set;
 53
 54/**
 55 * @author Michael C. Han
 56 * @author Marcellus Tavares
 57 * @author Eduardo Lundgren
 58 */
 59public class XMLWorkflowModelParser implements WorkflowModelParser {
 60
 61	public Definition parse(InputStream inputStream) throws WorkflowException {
 62		try {
 63			return doParse(inputStream);
 64		}
 65		catch (Exception e) {
 66			throw new WorkflowException("Unable to parse definition", e);
 67		}
 68	}
 69
 70	public void setValidate(boolean validate) {
 71		_validate = validate;
 72	}
 73
 74	protected Definition doParse(InputStream inputStream) throws Exception {
 75		Document document = SAXReaderUtil.read(inputStream, _validate);
 76
 77		Element rootElement = document.getRootElement();
 78
 79		String name = rootElement.elementText("name");
 80		String description = rootElement.elementText("description");
 81		int version = GetterUtil.getInteger(rootElement.elementText("version"));
 82
 83		Definition definition = new Definition(
 84			name, description, document.formattedString(), version);
 85
 86		List<Element> conditionElements = rootElement.elements("condition");
 87
 88		for (Element conditionElement : conditionElements) {
 89			Condition condition = parseCondition(conditionElement);
 90
 91			definition.addNode(condition);
 92		}
 93
 94		List<Element> forkElements = rootElement.elements("fork");
 95
 96		for (Element forkElement : forkElements) {
 97			Fork fork = parseFork(forkElement);
 98
 99			definition.addNode(fork);
100		}
101
102		List<Element> joinElements = rootElement.elements("join");
103
104		for (Element joinElement : joinElements) {
105			Join join = parseJoin(joinElement);
106
107			definition.addNode(join);
108		}
109
110		List<Element> stateElements = rootElement.elements("state");
111
112		for (Element stateElement : stateElements) {
113			State state = parseState(stateElement);
114
115			definition.addNode(state);
116		}
117
118		List<Element> taskElements = rootElement.elements("task");
119
120		for (Element taskElement : taskElements) {
121			Task task = parseTask(taskElement);
122
123			definition.addNode(task);
124		}
125
126		parseTransitions(
127			definition, conditionElements, forkElements,
128			joinElements, stateElements, taskElements);
129
130		return definition;
131	}
132
133	protected void parseActionElements(
134		List<Element> actionElements, ActionAware actionAware) {
135
136		if (actionElements.isEmpty()) {
137			return;
138		}
139
140		Set<Action> actions = new HashSet<Action>(actionElements.size());
141
142		for (Element actionElement : actionElements) {
143			String name = actionElement.elementText("name");
144			String description = actionElement.elementText("description");
145			String executionType = actionElement.elementText("execution-type");
146			String script = actionElement.elementText("script");
147			String language = actionElement.elementText("script-language");
148			int priority = GetterUtil.getInteger(
149				actionElement.elementText("priority"));
150
151			Action action = new Action(
152				name, description, executionType, script, language, priority);
153
154			actions.add(action);
155		}
156
157		actionAware.setActions(actions);
158	}
159
160	protected void parseActionsElement(Element actionsElement, Node node) {
161		if (actionsElement == null) {
162			return;
163		}
164
165		List<Element> actionElements = actionsElement.elements("action");
166
167		parseActionElements(actionElements, node);
168
169		List<Element> notificationElements = actionsElement.elements(
170			"notification");
171
172		parseNotificationElements(notificationElements, node);
173	}
174
175	protected Set<Assignment> parseAssignments(Element assignmentsElement) {
176		if (assignmentsElement == null) {
177			return Collections.emptySet();
178		}
179
180		Set<Assignment> assignments = new HashSet<Assignment>();
181
182		Element resourceActionsElement = assignmentsElement.element(
183			"resource-actions");
184
185		if (resourceActionsElement != null) {
186			List<Element> resourceActionElements =
187				resourceActionsElement.elements("resource-action");
188
189			for (Element resourceActionElement : resourceActionElements) {
190				String actionId = resourceActionElement.getText();
191
192				if (Validator.isNotNull(actionId)) {
193					ResourceActionAssignment resourceActionAssignment =
194						new ResourceActionAssignment(actionId);
195
196					assignments.add(resourceActionAssignment);
197				}
198			}
199		}
200
201		Element rolesElement = assignmentsElement.element("roles");
202
203		if (rolesElement != null) {
204			List<Element> roleAssignmentElements = rolesElement.elements(
205				"role");
206
207			for (Element roleAssignmentElement : roleAssignmentElements) {
208				long roleId = GetterUtil.getLong(
209					roleAssignmentElement.elementText("role-id"));
210				String roleType = roleAssignmentElement.elementText(
211					"role-type");
212				String name = roleAssignmentElement.elementText("name");
213
214				RoleAssignment roleAssignment = null;
215
216				if (Validator.isNotNull(name)) {
217					roleAssignment = new RoleAssignment(name, roleType);
218
219					boolean autoCreate = GetterUtil.getBoolean(
220						roleAssignmentElement.elementText("auto-create"), true);
221
222					roleAssignment.setAutoCreate(autoCreate);
223				}
224				else {
225					roleAssignment = new RoleAssignment(roleId, roleType);
226				}
227
228				assignments.add(roleAssignment);
229			}
230		}
231
232		List<Element> scriptedAssignmentElements = assignmentsElement.elements(
233			"scripted-assignment");
234
235		for (Element scriptedAssignmentElement : scriptedAssignmentElements) {
236			String script = scriptedAssignmentElement.elementText("script");
237			String scriptLanguage = scriptedAssignmentElement.elementText(
238				"script-language");
239
240			ScriptAssignment scriptAssignment = new ScriptAssignment(
241				script, scriptLanguage);
242
243			assignments.add(scriptAssignment);
244		}
245
246		List<Element> userAssignmentElements = assignmentsElement.elements(
247			"user");
248
249		for (Element userAssignmentElement : userAssignmentElements) {
250			long userId = GetterUtil.getLong(
251				userAssignmentElement.elementText("user-id"));
252			String screenName = userAssignmentElement.elementText(
253				"screen-name");
254			String emailAddress = userAssignmentElement.elementText(
255				"email-address");
256
257			UserAssignment userAssignment = new UserAssignment(
258				userId, screenName, emailAddress);
259
260			assignments.add(userAssignment);
261		}
262
263		return assignments;
264	}
265
266	protected Condition parseCondition(Element conditionElement) {
267		String name = conditionElement.elementText("name");
268		String description = conditionElement.elementText("description");
269		String script = conditionElement.elementText("script");
270		String scriptLanguage = conditionElement.elementText("script-language");
271
272		Condition condition = new Condition(
273			name, description, script, scriptLanguage);
274
275		String metadata = conditionElement.elementText("metadata");
276
277		condition.setMetadata(metadata);
278
279		Element actionsElement = conditionElement.element("actions");
280
281		parseActionsElement(actionsElement, condition);
282
283		Element timersElement = conditionElement.element("timers");
284
285		parseTimerElements(timersElement, condition);
286
287		return condition;
288	}
289
290	protected DelayDuration parseDelay(Element delayElement) {
291		if (delayElement == null) {
292			return null;
293		}
294
295		double duration = GetterUtil.getDouble(
296			delayElement.elementText("duration"));
297		DurationScale durationScale = DurationScale.parse(
298			delayElement.elementText("scale"));
299
300		return new DelayDuration(duration, durationScale);
301	}
302
303	protected Fork parseFork(Element forkElement) {
304		String name = forkElement.elementText("name");
305		String description = forkElement.elementText("description");
306
307		Fork fork = new Fork(name, description);
308
309		String metadata = forkElement.elementText("metadata");
310
311		fork.setMetadata(metadata);
312
313		Element actionsElement = forkElement.element("actions");
314
315		parseActionsElement(actionsElement, fork);
316
317		Element timersElement = forkElement.element("timers");
318
319		parseTimerElements(timersElement, fork);
320
321		return fork;
322	}
323
324	protected Join parseJoin(Element joinElement) {
325		String name = joinElement.elementText("name");
326		String description = joinElement.elementText("description");
327
328		Join join = new Join(name, description);
329
330		String metadata = joinElement.elementText("metadata");
331
332		join.setMetadata(metadata);
333
334		Element actionsElement = joinElement.element("actions");
335
336		parseActionsElement(actionsElement, join);
337
338		Element timersElement = joinElement.element("timers");
339
340		parseTimerElements(timersElement, join);
341
342		return join;
343	}
344
345	protected void parseNotificationElements(
346		List<Element> notificationElements,
347		NotificationAware notificationAware) {
348
349		if (notificationElements.isEmpty()) {
350			return;
351		}
352
353		Set<Notification> notifications = new HashSet<Notification>(
354			notificationElements.size());
355
356		for (Element notificationElement : notificationElements) {
357			String name = notificationElement.elementText("name");
358			String description = notificationElement.elementText("description");
359			String executionType = notificationElement.elementText(
360				"execution-type");
361			String template = notificationElement.elementText("template");
362			String templateLanguage = notificationElement.elementText(
363				"template-language");
364
365			Notification notification = new Notification(
366				name, description, executionType, template, templateLanguage);
367
368			List<Element> notificationTypeElements =
369				notificationElement.elements("notification-type");
370
371			for (Element notificationTypeElement : notificationTypeElements) {
372				notification.addNotificationType(
373					notificationTypeElement.getText());
374			}
375
376			Element recipientsElement = notificationElement.element(
377				"recipients");
378
379			parseRecipients(recipientsElement, notification);
380
381			notifications.add(notification);
382		}
383
384		notificationAware.setNotifications(notifications);
385	}
386
387	protected void parseRecipients(
388		Element recipientsElement, Notification notification) {
389
390		if (recipientsElement == null) {
391			return;
392		}
393
394		List<Element> addressRecipientElements = recipientsElement.elements(
395			"address");
396
397		for (Element addressRecipientElement : addressRecipientElements) {
398			AddressRecipient addressRecipient = new AddressRecipient(
399				addressRecipientElement.getText());
400
401			notification.addRecipients(addressRecipient);
402		}
403
404		List<Element> roleReceipientElements = recipientsElement.elements(
405			"role");
406
407		for (Element roleAssignmentElement : roleReceipientElements) {
408			long roleId = GetterUtil.getLong(
409				roleAssignmentElement.elementText("role-id"));
410			String roleType = roleAssignmentElement.elementText("role-type");
411			String name = roleAssignmentElement.elementText("name");
412
413			RoleRecipient roleRecipient = null;
414
415			if (roleId > 0) {
416				roleRecipient = new RoleRecipient(roleId, roleType);
417			}
418			else {
419				roleRecipient = new RoleRecipient(name, roleType);
420
421				boolean autoCreate = GetterUtil.getBoolean(
422					roleAssignmentElement.elementText("auto-create"), true);
423
424				roleRecipient.setAutoCreate(autoCreate);
425			}
426
427			notification.addRecipients(roleRecipient);
428		}
429
430		List<Element> userRecipientElements = recipientsElement.elements(
431			"user");
432
433		for (Element userRecipientElement : userRecipientElements) {
434			long userId = GetterUtil.getLong(
435				userRecipientElement.elementText("user-id"));
436			String screenName = userRecipientElement.elementText("screen-name");
437			String emailAddress = userRecipientElement.elementText(
438				"email-address");
439
440			UserRecipient userRecipient = new UserRecipient(
441				userId, screenName, emailAddress);
442
443			notification.addRecipients(userRecipient);
444		}
445	}
446
447	protected State parseState(Element stateElement) {
448		String name = stateElement.elementText("name");
449		String description = stateElement.elementText("description");
450		boolean initial = GetterUtil.getBoolean(
451			stateElement.elementText("initial"), false);
452
453		State state = new State(name, description, initial);
454
455		String metadata = stateElement.elementText("metadata");
456
457		state.setMetadata(metadata);
458
459		Element actionsElement = stateElement.element("actions");
460
461		parseActionsElement(actionsElement, state);
462
463		Element timersElement = stateElement.element("timers");
464
465		parseTimerElements(timersElement, state);
466
467		return state;
468	}
469
470	protected Task parseTask(Element taskElement) {
471		String name = taskElement.elementText("name");
472		String description = taskElement.elementText("description");
473
474		Task task = new Task(name, description);
475
476		String metadata = taskElement.elementText("metadata");
477
478		task.setMetadata(metadata);
479
480		Element actionsElement = taskElement.element("actions");
481
482		parseActionsElement(actionsElement, task);
483
484		Element assignmentsElement = taskElement.element("assignments");
485
486		if (assignmentsElement != null) {
487			Set<Assignment> assignments = parseAssignments(assignmentsElement);
488
489			task.setAssignments(assignments);
490		}
491
492		Element timersElement = taskElement.element("task-timers");
493
494		parseTaskTimerElements(timersElement, task);
495
496		return task;
497	}
498
499	protected void parseTaskTimerElements(
500		Element taskTimersElement, Node node) {
501
502		if (taskTimersElement == null) {
503			return;
504		}
505
506		List<Element> taskTimerElements = taskTimersElement.elements(
507			"task-timer");
508
509		if (taskTimerElements.isEmpty()) {
510			return;
511		}
512
513		Set<Timer> timers = new HashSet<Timer>(taskTimerElements.size());
514
515		for (Element timerElement : taskTimerElements) {
516			Timer timer = parseTimerElement(timerElement, true);
517
518			timers.add(timer);
519		}
520
521		node.setTimers(timers);
522	}
523
524	protected void parseTimerActions(Element timersElement, Timer timer) {
525		if (timersElement == null) {
526			return;
527		}
528
529		List<Element> timerActionElements = timersElement.elements(
530			"timer-action");
531
532		parseActionElements(timerActionElements, timer);
533
534		List<Element> timerNotificationElements = timersElement.elements(
535			"timer-notification");
536
537		parseNotificationElements(timerNotificationElements, timer);
538
539		Element reassignmentsElement = timersElement.element("reassignments");
540
541		if (reassignmentsElement != null) {
542			Set<Assignment> assignments = parseAssignments(
543				reassignmentsElement);
544
545			timer.setReassignments(assignments);
546		}
547	}
548
549	protected Timer parseTimerElement(
550		Element timerElement, boolean isTaskTimer) {
551
552		String name = timerElement.elementText("name");
553		String description = timerElement.elementText("description");
554		boolean blocking = GetterUtil.getBoolean(
555			timerElement.elementText("blocking"), !isTaskTimer);
556
557		Timer timer = new Timer(name, description, blocking);
558
559		Element delayElement = timerElement.element("delay");
560
561		DelayDuration delayDuration = parseDelay(delayElement);
562
563		timer.setDelayDuration(delayDuration);
564
565		if (!blocking) {
566			Element recurrenceElement = timerElement.element("recurrence");
567
568			DelayDuration recurrence = parseDelay(recurrenceElement);
569
570			timer.setRecurrence(recurrence);
571		}
572
573		Element timerActions = timerElement.element("timer-actions");
574
575		parseTimerActions(timerActions, timer);
576
577		return timer;
578	}
579
580	protected void parseTimerElements(Element timersElement, Node node) {
581		if (timersElement == null) {
582			return;
583		}
584
585		List<Element> timerElements = timersElement.elements("timer");
586
587		if (timerElements.isEmpty()) {
588			return;
589		}
590
591		Set<Timer> timers = new HashSet<Timer>(timerElements.size());
592
593		for (Element timerElement : timerElements) {
594			Timer timer = parseTimerElement(timerElement, false);
595
596			timers.add(timer);
597		}
598
599		node.setTimers(timers);
600	}
601
602	protected void parseTransition(Definition definition, Element nodeElement) {
603		String sourceName = nodeElement.elementText("name");
604
605		Node sourceNode = definition.getNode(sourceName);
606
607		Element transitionsElement = nodeElement.element("transitions");
608
609		if (transitionsElement == null) {
610			return;
611		}
612
613		List<Element> transitionElements = transitionsElement.elements(
614			"transition");
615
616		for (Element transitionElement : transitionElements) {
617			String transitionName = transitionElement.elementText("name");
618
619			String targetName = transitionElement.elementText("target");
620
621			Node targetNode = definition.getNode(targetName);
622
623			boolean defaultValue = GetterUtil.getBoolean(
624				transitionElement.elementText("default"), true);
625
626			Transition transition = new Transition(
627				transitionName, sourceNode, targetNode, defaultValue);
628
629			Element timerElement = transitionElement.element("timer");
630
631			if (timerElement != null) {
632				Timer timer = parseTimerElement(timerElement, false);
633
634				transition.setTimers(timer);
635			}
636
637			sourceNode.addTransition(transition);
638		}
639	}
640
641	protected void parseTransitions(
642		Definition definition, List<Element> conditionElements,
643		List<Element> forkElements, List<Element> joinElements,
644		List<Element> stateElements, List<Element> taskElements) {
645
646		for (Element conditionElement : conditionElements) {
647			parseTransition(definition, conditionElement);
648		}
649
650		for (Element forkElement : forkElements) {
651			parseTransition(definition, forkElement);
652		}
653
654		for (Element joinElement : joinElements) {
655			parseTransition(definition, joinElement);
656		}
657
658		for (Element stateElement : stateElements) {
659			parseTransition(definition, stateElement);
660		}
661
662		for (Element taskElement : taskElements) {
663			parseTransition(definition, taskElement);
664		}
665	}
666
667	private boolean _validate;
668
669}