KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > workflow > WorkflowPropertyInstance


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.rm.workflow;
20
21 import java.util.*;
22 import java.util.logging.*;
23
24 import org.openharmonise.commons.dsi.*;
25 import org.openharmonise.rm.*;
26 import org.openharmonise.rm.logging.*;
27 import org.openharmonise.rm.metadata.*;
28 import org.openharmonise.rm.resources.*;
29 import org.openharmonise.rm.resources.lifecycle.EditException;
30 import org.openharmonise.rm.resources.metadata.properties.Property;
31 import org.openharmonise.rm.resources.metadata.values.Value;
32 import org.openharmonise.rm.resources.users.User;
33 import org.openharmonise.rm.resources.workflow.properties.ranges.WorkflowRange;
34 import org.openharmonise.rm.resources.workflow.values.WorkflowStageValue;
35 import org.openharmonise.rm.security.authorization.*;
36
37
38 /**
39  * Class to represent an instance of a workflow.
40  *
41  * This class extends <code>ChildObjectPropertyInstance</code>, offering
42  * utility methods specific to handling workflows and will only accept
43  * <code>WorkflowStageInstance</code> values.
44  *
45  * @author Michael Bell
46  * @version $Revision: 1.2 $
47  *
48  */

49 public class WorkflowPropertyInstance extends ChildObjectPropertyInstance {
50
51     //TODO review the need for this flag which allows <code>Search</code> to work
52
//allows the addition of values to prop inst for search
53
private boolean m_bAllowSave = true;
54
55     /**
56      * Logger for this class
57      */

58     static private Logger m_logger = Logger
59             .getLogger(WorkflowPropertyInstance.class.getName());
60
61     /**
62      * Basic constructor
63      */

64     public WorkflowPropertyInstance() {
65         super();
66     }
67
68     /**
69      * Constructs object with a interface to the datastore
70      *
71      * @param dbintrf
72      */

73     public WorkflowPropertyInstance(AbstractDataStoreInterface dbintrf) {
74         super(dbintrf);
75     }
76
77     /**
78      * Returns a list of the completed workflow stage instances for this
79      * workflow instance
80      *
81      * @return @throws
82      * DataAccessException
83      */

84     public List getCompletedStages() throws DataAccessException {
85         return super.getValues();
86     }
87
88     /**
89      * Returns <code>true</code> if work flow is complete
90      *
91      * @return @throws
92      * DataAccessException
93      */

94     public boolean isComplete() throws DataAccessException {
95         boolean bIsComplete = true;
96
97         Property prop = getProperty();
98
99         WorkflowRange range = (WorkflowRange) prop.getRange();
100
101         List vals = range.getAvailableValues();
102
103         Iterator iter = vals.iterator();
104
105         List currVals = getValues();
106
107         while (iter.hasNext() && bIsComplete == true) {
108             WorkflowStageValue stage = (WorkflowStageValue) iter.next();
109
110             if (stage.isMandatory() && currVals.contains(stage) == false) {
111                 bIsComplete = false;
112                 if(m_logger.isLoggable(Level.FINER)) {
113                     try {
114                         AbstractProfiledObject profObj = getProfiledObject();
115                         m_logger.logp(Level.FINER, this.getClass().getName(), "isComplete", "stage " + stage.getName() + " not complete for " + profObj.getClass().getName() + "(" + profObj.getKey() + ")");
116                     } catch (DataAccessException e) {
117                         m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
118                     }
119                 }
120             }
121         }
122
123         if (m_logger.isLoggable(Level.FINE)) {
124             try {
125                 AbstractProfiledObject profObj = getProfiledObject();
126                 m_logger.logp(Level.FINE, this.getClass().getName(),
127                         "isComplete", "workflow (" + getName() + ") for "
128                                 + profObj.getClass().getName() + "("
129                                 + profObj.getKey() + ") complete - "
130                                 + bIsComplete);
131             } catch (DataAccessException e) {
132                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
133             }
134         }
135
136         return bIsComplete;
137     }
138
139     /**
140      * Returns <code>true</code> if the given workflow stage instance is valid
141      * for this workflow instance
142      *
143      * @param instance
144      * @return
145      */

146     private boolean isValidStage(WorkflowStageValue stage)
147             throws DataAccessException {
148         boolean bIsValid = false;
149
150         List depends = stage.getDependencies();
151
152         if (depends.size() > 0) {
153             List completes = getCompletedStages();
154             bIsValid = completes.containsAll(depends);
155
156         } else {
157             bIsValid = true;
158         }
159
160         return bIsValid;
161     }
162
163     /* (non-Javadoc)
164      * @see org.openharmonise.rm.metadata.ChildObjectPropertyInstance#addValue(org.openharmonise.rm.resources.AbstractChildObject)
165      */

166     public void addValue(AbstractChildObject child)
167             throws PopulateException {
168         m_bAllowSave = false;
169         super.addValue(child);
170     }
171
172     /**
173      * Adds stage to this workflow instance
174      *
175      * @param stage
176      * @param usr
177      * @throws InvalidPropertyValueException
178      */

179     public void addWorkflowStage(WorkflowStageValue stage, User usr)
180             throws PopulateException {
181         try {
182
183             boolean bRoleValid = false;
184
185             //super users can do ANYTHING
186
if (AuthorizationValidator.isSuperUser(usr) == true) {
187                 bRoleValid = true;
188             } else {
189
190                 List roles = AuthorizationValidator.getUserRoles(usr);
191
192                 List stageRoles = stage.getRoles();
193                 if (stageRoles != null && stageRoles.size() > 0) {
194                     Iterator iter = stageRoles.iterator();
195
196                     while (iter.hasNext() && bRoleValid == false) {
197                         Value roleVal = (Value) iter.next();
198                         if (roles.contains(roleVal)) {
199                             bRoleValid = true;
200                         }
201                     }
202                 } else {
203                     ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) stage
204                             .getPropertyInstance(WorkflowStageValue.PROPNAME_DEFINITION);
205
206                     WorkflowStageValue defn = (WorkflowStageValue) propInst.getValue();
207
208                     stageRoles = defn.getRoles();
209
210                     Iterator iter = stageRoles.iterator();
211
212                     while (iter.hasNext() && bRoleValid == false) {
213                         Value roleVal = (Value) iter.next();
214                         if (roles.contains(roleVal)) {
215                             bRoleValid = true;
216                         }
217                     }
218                 }
219             }
220
221             if (bRoleValid == true) {
222                 if (isValidStage(stage) == true) {
223
224                     super.addValue(stage);
225
226                     // should probably log during save but this is the
227
//only time we've got the user as well as the stage
228
LogEvent event = new LogEvent();
229                     AbstractProfiledObject profObj = getProfiledObject();
230                     if (profObj != null
231                             && profObj.getId() == AbstractObject.NOTDBSAVED_ID) {
232                         AbstractProfiledObject liveObj = (AbstractProfiledObject) profObj
233                                 .getLiveVersion();
234                         if (liveObj != null) {
235                             profObj = liveObj;
236                         }
237                     }
238                     event.setEventObject(profObj);
239                     event.setLabel("Workflow");
240                     event.addAdditionalInfo(stage.getName() + " completed");
241                     event.setUser(usr);
242                     EventLogController logger = EventLogController
243                             .getInstance();
244                     logger.logEvent(event);
245
246                 } else {
247                     throw new InvalidWorkflowStageException(
248                             "Dependency restrictions have not been met");
249                 }
250
251             } else {
252                 throw new InvalidWorkflowStageException(
253                         "User not allowed to add stage");
254             }
255         } catch (InvalidPropertyInstanceException e) {
256             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
257         } catch (DataAccessException e) {
258             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
259         } catch (AuthorizationException e) {
260             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
261         } catch (LogException e) {
262             throw new InvalidPropertyValueException(e);
263         }
264
265     }
266
267     /**
268      * Adds stage to this workflow instance
269      *
270      * @param stage
271      * @param usr
272      * @throws InvalidPropertyValueException
273      */

274     public void removeWorkflowStage(WorkflowStageValue stage, User usr)
275             throws InvalidPropertyValueException {
276         try {
277
278             boolean bRoleValid = false;
279
280             //super users can do ANYTHING
281
if (AuthorizationValidator.isSuperUser(usr) == true) {
282                 bRoleValid = true;
283             } else {
284
285                 List roles = AuthorizationValidator.getUserRoles(usr);
286
287                 List stageRoles = stage.getRoles();
288                 if (stageRoles != null && stageRoles.size() > 0) {
289                     Iterator iter = stageRoles.iterator();
290
291                     while (iter.hasNext() && bRoleValid == false) {
292                         Value roleVal = (Value) iter.next();
293                         if (roles.contains(roleVal)) {
294                             bRoleValid = true;
295                         }
296                     }
297                 } else {
298                     ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) stage
299                             .getPropertyInstance(WorkflowStageValue.PROPNAME_DEFINITION);
300
301                     WorkflowStageValue defn = (WorkflowStageValue) propInst.getValue();
302
303                     stageRoles = defn.getRoles();
304
305                     Iterator iter = stageRoles.iterator();
306
307                     while (iter.hasNext() && bRoleValid == false) {
308                         Value roleVal = (Value) iter.next();
309                         if (roles.contains(roleVal)) {
310                             bRoleValid = true;
311                         }
312                     }
313                 }
314             }
315
316             if (bRoleValid == true) {
317
318                 List vals = this.getValues();
319                 EventLogController logger = EventLogController.getInstance();
320
321                 for (Iterator iter = vals.iterator(); iter.hasNext();) {
322                     WorkflowStageValue tmpStage = (WorkflowStageValue) iter.next();
323                     if (isStageDependant(stage, tmpStage)) {
324                         super.removeValue(tmpStage);
325                         // should probably log during save but this is the
326
//only time we've got the user as well as the stage
327

328                         LogEvent event = new LogEvent();
329                         event.setEventObject(this.getProfiledObject());
330                         event.setLabel("Workflow");
331                         event.addAdditionalInfo(tmpStage.getName()
332                                 + " rescinded");
333                         event.setUser(usr);
334                         logger.logEvent(event);
335                     }
336                 }
337
338                 super.removeValue(stage);
339
340                 LogEvent event = new LogEvent();
341                 event.setEventObject(this.getProfiledObject());
342                 event.setLabel("Workflow");
343                 event.addAdditionalInfo(stage.getName() + " rescinded");
344                 event.setUser(usr);
345                 logger.logEvent(event);
346             } else {
347                 throw new InvalidWorkflowStageException(
348                         "User not allowed to remove stage");
349             }
350         } catch (InvalidPropertyInstanceException e) {
351             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
352         } catch (DataAccessException e) {
353             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
354         } catch (AuthorizationException e) {
355             throw new InvalidPropertyValueException(e.getLocalizedMessage(), e);
356         } catch (LogException e) {
357             throw new InvalidPropertyValueException(e);
358         }
359
360     }
361
362     /**
363      * @param stage
364      * @param tmpStage
365      * @return @throws
366      * DataAccessException
367      */

368     private boolean isStageDependant(WorkflowStageValue primaryStage,
369             WorkflowStageValue dependStage) throws DataAccessException {
370         boolean bIsDependant = false;
371
372         List depends = dependStage.getDependencies();
373
374         if (depends.contains(primaryStage)) {
375             bIsDependant = true;
376         } else {
377             for (Iterator iter = depends.iterator(); iter.hasNext();) {
378                 WorkflowStageValue tmpStage = (WorkflowStageValue) iter.next();
379                 bIsDependant = isStageDependant(primaryStage, tmpStage);
380             }
381         }
382
383         return bIsDependant;
384     }
385
386     /* (non-Javadoc)
387      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#save(org.openharmonise.rm.metadata.Profile)
388      */

389     protected void save(Profile prof) throws ProfileException, EditException {
390
391         if (m_bAllowSave == false) {
392             throw new EditException(
393                     "Invalid value contined in PropertyInstance");
394         }
395
396         super.save(prof);
397     }
398
399     /* (non-Javadoc)
400      * @see org.openharmonise.rm.metadata.AbstractPropertyInstance#getValues()
401      */

402     public List getValues() {
403         List result = new ArrayList();
404         List vals = super.getValues();
405
406         try {
407             //check all current values are valid, in case workflow def has
408
//changed
409
for (Iterator iter = vals.iterator(); iter.hasNext();) {
410                 WorkflowStageValue stage = (WorkflowStageValue) iter.next();
411                 if (isValidStage(stage) == false) {
412                     removeChildReferences(stage);
413                 } else {
414                     result.add(stage);
415                 }
416             }
417         } catch (DataAccessException e) {
418             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
419         } catch (DataStoreException e) {
420             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
421         }
422
423         return result;
424     }
425 }
Popular Tags