001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.rm.resources.workflow.values;
020:
021: import java.sql.*;
022: import java.util.*;
023: import java.util.logging.*;
024:
025: import org.openharmonise.commons.dsi.*;
026: import org.openharmonise.commons.dsi.dml.SelectStatement;
027: import org.openharmonise.rm.*;
028: import org.openharmonise.rm.factory.*;
029: import org.openharmonise.rm.metadata.*;
030: import org.openharmonise.rm.resources.lifecycle.*;
031: import org.openharmonise.rm.resources.metadata.properties.*;
032: import org.openharmonise.rm.resources.metadata.values.Value;
033:
034: /**
035: * A definition of the workflow stage.
036: *
037: * This class extends <code>Property</code> with utility methods for workflow
038: * specific operations.
039: *
040: * @author Michael Bell
041: * @version $Revision: 1.2 $
042: *
043: */
044: public class WorkflowStageValue extends Value {
045:
046: public static final String TAG_WORKFLOW_STAGE = "WorkflowStage";
047:
048: public static final String PROPNAME_ALLOWED_ROLES = "WORKFLOW_ROLES";
049: public static final String PROPNAME_IS_MANDATORY = "WORKFLOW_MAND";
050: public static final String PROPNAME_IS_INHERITABLE = "WORKFLOW_INHERIT";
051: public static final String PROPNAME_DEPENDENCY = "WORKFLOW_DEPEND";
052: public static final String PROPNAME_DEFINITION = "WORKFLOW_RELN";
053:
054: /**
055: * Logger for this class.
056: */
057: private static final Logger m_logger = Logger
058: .getLogger(WorkflowStageValue.class.getName());
059:
060: /**
061: * Basic constructor.
062: */
063: public WorkflowStageValue() {
064: super ();
065: }
066:
067: /**
068: * Constructs object with an interface to the datastore.
069: *
070: * @param dbintrf
071: */
072: public WorkflowStageValue(AbstractDataStoreInterface dbintrf) {
073: super (dbintrf);
074: }
075:
076: /**
077: * Constructs particular object with interface to datastore.
078: *
079: * @param dbintrf
080: * @param nId
081: */
082: public WorkflowStageValue(AbstractDataStoreInterface dbintrf,
083: int nId) {
084: super (dbintrf, nId);
085: }
086:
087: /**
088: * Constructs object with an interface to the datastore and a flag to specify
089: * whether object is to be historical.
090: *
091: * @param dbintrf
092: * @param bIsHist
093: * @throws Exception
094: */
095: public WorkflowStageValue(AbstractDataStoreInterface dbintrf,
096: boolean bIsHist) throws Exception {
097: super (dbintrf, bIsHist);
098: }
099:
100: /**
101: * Constructs a particular object which may be historical.
102: *
103: * @param dbintrf
104: * @param nId
105: * @param bIsHist
106: */
107: public WorkflowStageValue(AbstractDataStoreInterface dbintrf,
108: int nId, int nKey, boolean bIsHist) {
109: super (dbintrf, nId, nKey, bIsHist);
110: }
111:
112: /**
113: * Returns <code>true</code> if instances of this workflow stage are to be
114: * inherited by successive versions.
115: *
116: * @return
117: * @throws DataAccessException
118: */
119: public boolean isInheritable() throws DataAccessException {
120: boolean bIsInherit = false;
121:
122: try {
123: GeneralPropertyInstance propInst = (GeneralPropertyInstance) getProfile()
124: .getPropertyInstance(PROPNAME_IS_INHERITABLE);
125:
126: if (propInst != null) {
127: bIsInherit = propInst.getBooleanValue();
128: }
129:
130: } catch (InvalidPropertyInstanceException e) {
131: //property was not valid on profile - it really should be
132: //must be a seeding problem - log and ignore it
133: m_logger
134: .log(
135: Level.INFO,
136: "Inheritable property not valid on workflow stage!",
137: e);
138: }
139:
140: return bIsInherit;
141: }
142:
143: /**
144: * Returns the list of workflow stages this stage is dependent on.
145: *
146: * @return
147: * @throws DataAccessException
148: */
149: public List getDependencies() throws DataAccessException {
150: List depends = new ArrayList();
151:
152: try {
153: ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) getProfile()
154: .getPropertyInstance(PROPNAME_DEPENDENCY);
155: if (propInst != null) {
156: depends = propInst.getValues();
157: }
158: } catch (InvalidPropertyInstanceException e) {
159: //property was not valid on profile - it really should be
160: //must be a seeding problem - log and ignore it
161: m_logger
162: .log(
163: Level.INFO,
164: "Inheritable property not valid on workflow stage!",
165: e);
166: }
167:
168: return depends;
169: }
170:
171: /**
172: * Sets the list of workflow stages this work flow stage is dependent on
173: * being complete before this stage can be complete .
174: *
175: * @param depends
176: * @throws PopulateException
177: */
178: public void setDependencies(List depends) throws PopulateException {
179: try {
180: ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) getProfile()
181: .getPropertyInstance(PROPNAME_DEPENDENCY);
182:
183: if (propInst == null) {
184: Property prop = PropertyFactory.getPropertyFromName(
185: m_dsi, PROPNAME_DEPENDENCY);
186: propInst = (ChildObjectPropertyInstance) PropertyInstanceFactory
187: .getPropertyInstance(m_dsi, prop);
188: getProfile().addPropertyInstance(propInst);
189: }
190:
191: propInst.setValues(depends);
192: } catch (InvalidPropertyInstanceException e) {
193: //property was not valid on profile - it really should be
194: //must be a seeding problem - log and ignore it
195: m_logger
196: .log(
197: Level.INFO,
198: "Inheritable property not valid on workflow stage!",
199: e);
200: } catch (DataAccessException e) {
201: throw new PopulateException(e.getLocalizedMessage(), e);
202: } catch (HarmoniseFactoryException e) {
203: throw new PopulateException(e.getLocalizedMessage(), e);
204: } catch (InvalidPropertyValueException e) {
205: throw new PopulateException(e.getLocalizedMessage(), e);
206: } catch (ProfileException e) {
207: throw new PopulateException(e.getLocalizedMessage(), e);
208: }
209: }
210:
211: /**
212: * Returns the list of role <code>Value</code>s that can assign this work flow
213: * stage as complete.
214: *
215: * @return
216: * @throws DataAccessException
217: */
218: public List getRoles() throws DataAccessException {
219: List roles = new ArrayList();
220:
221: try {
222: ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) getProfile()
223: .getPropertyInstance(PROPNAME_ALLOWED_ROLES);
224: if (propInst != null) {
225: roles = propInst.getValues();
226: }
227: } catch (InvalidPropertyInstanceException e) {
228: //property was not valid on profile - it really should be
229: //must be a seeding problem - log and ignore it
230: m_logger
231: .log(
232: Level.INFO,
233: "Inheritable property not valid on workflow stage!",
234: e);
235: }
236:
237: return roles;
238: }
239:
240: /**
241: * Sets the list of role <code>Value</code>s that can assign this work flow
242: * stage as complete.
243: *
244: * @param roles
245: * @throws PopulateException
246: */
247: public void setRoles(List roles) throws PopulateException {
248: try {
249: ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) getProfile()
250: .getPropertyInstance(PROPNAME_ALLOWED_ROLES);
251:
252: if (propInst == null) {
253: Property prop = PropertyFactory.getPropertyFromName(
254: m_dsi, PROPNAME_ALLOWED_ROLES);
255: propInst = (ChildObjectPropertyInstance) PropertyInstanceFactory
256: .getPropertyInstance(m_dsi, prop);
257: getProfile().addPropertyInstance(propInst);
258: }
259:
260: propInst.setValues(roles);
261: } catch (InvalidPropertyInstanceException e) {
262: //property was not valid on profile - it really should be
263: //must be a seeding problem - log and ignore it
264: m_logger
265: .log(
266: Level.INFO,
267: "Inheritable property not valid on workflow stage!",
268: e);
269: } catch (DataAccessException e) {
270: throw new PopulateException(e.getLocalizedMessage(), e);
271: } catch (HarmoniseFactoryException e) {
272: throw new PopulateException(e.getLocalizedMessage(), e);
273: } catch (InvalidPropertyValueException e) {
274: throw new PopulateException(e.getLocalizedMessage(), e);
275: } catch (ProfileException e) {
276: throw new PopulateException(e.getLocalizedMessage(), e);
277: }
278: }
279:
280: /* (non-Javadoc)
281: * @see org.openharmonise.rm.resources.AbstractChildObject#getParentObjectClassName()
282: */
283: public String getParentObjectClassName() {
284: return WorkflowStageValueGroup.class.getName();
285: }
286:
287: /**
288: * Returns <code>true</code> if this stage is mandatory.
289: *
290: * @return
291: */
292: public boolean isMandatory() throws DataAccessException {
293: boolean bIsMandatory = false;
294:
295: try {
296: GeneralPropertyInstance propInst = (GeneralPropertyInstance) getProfile()
297: .getPropertyInstance(PROPNAME_IS_MANDATORY);
298:
299: if (propInst != null) {
300: bIsMandatory = propInst.getBooleanValue();
301: }
302:
303: } catch (InvalidPropertyInstanceException e) {
304: //property was not valid on profile - it really should be
305: //must be a seeding problem - log and ignore it
306: m_logger
307: .log(
308: Level.INFO,
309: "Inheritable property not valid on workflow stage!",
310: e);
311: }
312:
313: return bIsMandatory;
314: }
315:
316: public Editable changeStatus(Status status) throws EditException {
317:
318: //ensure that if this is to be an inheritable stage it's mandatory
319: //dependancies are inheritable too
320: try {
321: Profile prof = this .getProfile();
322: Property inheritProp = PropertyFactory.getPropertyFromName(
323: m_dsi, PROPNAME_IS_INHERITABLE);
324:
325: if (prof != null && prof.isValidProperty(inheritProp)) {
326: GeneralPropertyInstance isInherit = (GeneralPropertyInstance) prof
327: .getPropertyInstance(inheritProp);
328:
329: if (isInherit != null
330: && isInherit.getBooleanValue() == true) {
331: List depends = this .getDependencies();
332:
333: Iterator iter = depends.iterator();
334:
335: while (iter.hasNext()) {
336: WorkflowStageValue stage = (WorkflowStageValue) iter
337: .next();
338: if (stage.isMandatory() == true
339: && stage.isInheritable() == false) {
340: throw new StatusChangeNotAllowedException(
341: "Mandatory dependancies must be inheritable");
342: }
343: }
344:
345: }
346: }
347: } catch (InvalidPropertyInstanceException e) {
348: throw new EditException(e.getLocalizedMessage(), e);
349: } catch (DataAccessException e) {
350: throw new EditException(e.getLocalizedMessage(), e);
351: } catch (HarmoniseFactoryException e) {
352: throw new EditException(e.getLocalizedMessage(), e);
353: }
354:
355: return super .changeStatus(status);
356: }
357:
358: /**
359: * Remove all instances of <code>WorkflowStage</code> which refer to
360: * this stage as their definition.
361: */
362: public void removeAllInstances() throws EditException {
363: ResultSet rs = null;
364:
365: try {
366: SelectStatement select = new SelectStatement();
367:
368: Property prop = PropertyFactory.getPropertyFromName(m_dsi,
369: PROPNAME_DEFINITION);
370:
371: AbstractPropertyInstance propInst = PropertyInstanceFactory
372: .getPropertyInstance(m_dsi, prop);
373: Profile prof = getProfile();
374: propInst.setProfile(prof);
375: select.addSelectColumn(this .getInstanceColumnRef(ATTRIB_ID,
376: false));
377:
378: select.addJoinCondition(prof.getInstanceColumnRef(
379: Profile.ATTRIB_OBJECT_KEY, false), this
380: .getInstanceColumnRef(ATTRIB_KEY, false));
381: select.addJoinCondition(propInst.getInstanceColumnRef(
382: Profile.TAG_PROFILE, false), prof
383: .getInstanceColumnRef(ATTRIB_ID, false));
384:
385: select.addWhereCondition(propInst.getInstanceColumnRef(
386: Property.TAG_PROPERTY, false), "=", prop.getId());
387: select.addWhereCondition(propInst.getInstanceColumnRef(
388: AbstractPropertyInstance.TAG_VALUE, false), "=",
389: getId());
390:
391: rs = m_dsi.execute(select);
392:
393: while (rs.next()) {
394: int nId = rs.getInt(1);
395:
396: WorkflowStageValue stage = (WorkflowStageValue) HarmoniseObjectFactory
397: .instantiateHarmoniseObject(m_dsi,
398: WorkflowStageValue.class.getName(), nId);
399:
400: if (stage != null) {
401: stage.archive();
402: }
403: }
404: } catch (HarmoniseFactoryException e) {
405: throw new EditException(e);
406: } catch (DataAccessException e) {
407: throw new EditException(e);
408: } catch (DataStoreException e) {
409: throw new EditException(e);
410: } catch (SQLException e) {
411: throw new EditException(e);
412: } finally {
413: if (rs != null) {
414: try {
415: rs.close();
416: } catch (SQLException e) {
417: throw new EditException(e);
418: }
419: }
420: }
421: }
422:
423: /* (non-Javadoc)
424: * @see org.openharmonise.rm.publishing.Publishable#getTagName()
425: */
426: public String getTagName() {
427: return TAG_WORKFLOW_STAGE;
428: }
429: }
|