KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > resources > AbstractEditableObject


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.resources;
20
21 import java.sql.*;
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.cache.*;
26 import org.openharmonise.commons.dsi.*;
27 import org.openharmonise.commons.dsi.dml.*;
28 import org.openharmonise.commons.xml.XMLUtils;
29 import org.openharmonise.rm.*;
30 import org.openharmonise.rm.dsi.*;
31 import org.openharmonise.rm.factory.*;
32 import org.openharmonise.rm.publishing.*;
33 import org.openharmonise.rm.resources.lifecycle.*;
34 import org.openharmonise.rm.resources.publishing.Template;
35 import org.openharmonise.rm.resources.users.User;
36 import org.openharmonise.rm.search.*;
37 import org.openharmonise.rm.security.authorization.*;
38 import org.w3c.dom.*;
39
40 import EDU.oswego.cs.dl.util.concurrent.*;
41
42
43 /**
44  * AbstractEditableObject is the abstract implementation of the <code>Editable</code>
45  * interface for objects within Harmonise.
46  *
47  * @author Michael Bell
48  * @version $Revision: 1.9 $
49  *
50  */

51 public abstract class AbstractEditableObject
52     extends AbstractObject
53     implements Editable, Publishable, DataStoreObject, Cloneable JavaDoc, EditEventListener {
54
55     //XML constants
56
/**
57      * Status tag name
58      */

59     public static final String JavaDoc TAG_STATUS = "Status";
60     
61     /**
62      * Display name tag name
63      */

64     public static final String JavaDoc TAG_DISPLAY_NAME = "DisplayName";
65     
66     /**
67      * Version tag name
68      */

69     public static final String JavaDoc TAG_VERSION = "Version";
70     
71     /**
72      * Version comment tag name
73      */

74     public static final String JavaDoc TAG_VERSION_COMMENT = "VersionComment";
75
76     /**
77      * Version date tag name
78      */

79     public static final String JavaDoc TAG_VERSION_DATE = "VersionDate";
80     
81     /**
82      * History date tag name
83      */

84     public static final String JavaDoc TAG_HISTORY_DATE = "HistoryDate";
85     
86     /**
87      * Live version tag name
88      */

89     public static final String JavaDoc TAG_LIVE_VERSION = "Live";
90     
91     /**
92      * Pending version tag name
93      */

94     public static final String JavaDoc TAG_PENDING_VERSION = "Pending";
95     
96     /**
97      * Historical version tag name
98      */

99     public static final String JavaDoc TAG_HISTORICAL_VERSION = "Historical";
100     
101     /**
102      * Locked tag name
103      */

104     public static final String JavaDoc TAG_LOCKED = "Locked";
105     
106     /**
107      * Is locked attribute name
108      */

109     public static final String JavaDoc ATTRIB_IS_LOCKED = "isLocked";
110
111     //DB Constants
112
/**
113      * Version number column name
114      */

115     private static final String JavaDoc CLMN_VERSION_NUMBER = "version_number";
116     
117     /**
118      * Version date column name
119      */

120     private static final String JavaDoc CLMN_VERSION_DATE = "version_date";
121     
122     /**
123      * Version comment column name
124      */

125     private static final String JavaDoc CLMN_VERSION_COMMENT = "version_comment";
126         
127     /**
128      * Status column name
129      */

130     private static final String JavaDoc CLMN_STATUS = "status";
131     
132     /**
133      * Lock user column name
134      */

135     private static final String JavaDoc CLMN_LOCK_USER = "lock_user";
136     
137     /**
138      * Archive date column name
139      */

140     private static final String JavaDoc CLMN_HISTORY_DATE = "history_date";
141     
142     /**
143      * Live object id column name
144      */

145     private static final String JavaDoc CLMN_LIVE_ID = "live_id";
146     
147     /**
148      * Display name column name
149      */

150     protected static final String JavaDoc CLMN_DISPLAY_NAME = "display_name";
151
152     /**
153      * Prefix for all id sequence names
154      *
155      * Note: Id sequence names will follow pattern - 'PRE_SEQ + getTableName()'
156      */

157     private static final String JavaDoc PRE_SEQ = "seq_";
158     
159     /**
160      * Suffix for all key sequence names
161      *
162      * Note: Key sequence names will follow pattern - 'PRE_SEQ + getTableName() + EXT_KEY'
163      */

164     private static final String JavaDoc EXT_KEY = "_key";
165
166     /**
167      * The version number
168      */

169     protected int m_nVersionNumber = 0;
170     
171     /**
172      * The version comment
173      */

174     protected String JavaDoc m_sVersionComment = "";
175     
176     /**
177      * The display name
178      */

179     protected String JavaDoc m_sDisplayName = "";
180     
181     /**
182      * The version date
183      */

184     protected java.util.Date JavaDoc m_dtVersionDate = null;
185     
186     /**
187      * The current status
188      */

189     protected Status m_status = Status.UNKNOWN;
190     
191     /**
192      * The id of the live version
193      */

194     protected int m_nLiveId = -1;
195     
196     /**
197      * The id of the user that locked this resource
198      */

199     protected int m_nLockUserId = NOTDBSAVED_ID;
200     
201     /**
202      * The archive date
203      */

204     protected java.util.Date JavaDoc m_dtHistDate = null;
205     
206     /**
207      * The list of <code>EditListener</code>s registered with this object
208      */

209     private List m_editlisteners = new ArrayList();
210     
211     /**
212      * A cache pointer to the pending version
213      */

214     protected CachePointer m_pending = null;
215     
216     /**
217      * Read-write lock to enable locking of cache access.
218      */

219     private ReadWriteLock m_edit_lock = new WriterPreferenceReadWriteLock();
220
221     
222     /**
223      * Logger for this class
224      */

225     static private Logger m_logger = Logger.getLogger(AbstractEditableObject.class.getName());
226
227     /**
228      * Thread which has acquired the write lock on this object
229      */

230     private Thread JavaDoc m_lockThread = null;
231     
232
233     /**
234      * Constructs a new or anonymous instance without an interface
235      * to the database.
236      */

237     public AbstractEditableObject() {
238         super();
239     }
240
241     /**
242      * Standard constructor for a new or anonymous resource,
243      * registering an <code>AbstractDataStoreInterface</code> to use
244      * with all database communications.
245      *
246      * @param con the interface to the database
247      */

248     public AbstractEditableObject(AbstractDataStoreInterface con) {
249         super(con);
250
251     }
252
253     /**
254       * Standard constructor for an existing resource,
255       * registering an <code>AbstractDataStoreInterface</code> to use
256       * with all database communications.
257       *
258       * @param con the interface to the database
259       * @param nId the id of the resource
260      */

261     public AbstractEditableObject(AbstractDataStoreInterface con, int nId) {
262         super(con, nId);
263
264     }
265
266     /**
267      * Standard constructor for an existing resource which may be historical.
268      *
269      * @param con the interface to the database
270      * @param nId the id of the resource
271      * @param nKey the unique key of the resource
272      * @param bIsHist <code>true</code> if the object is historical
273      */

274     public AbstractEditableObject(
275         AbstractDataStoreInterface con,
276         int nId,
277         int nKey,
278         boolean bIsHist) {
279         super(con, nId,nKey, bIsHist);
280     }
281     
282     /**
283      * Returns the display name of this resource.
284      *
285      * @return the display name of this resource
286      * @throws DataAccessException if an error occurs populating this object
287      */

288     public String JavaDoc getDisplayName() throws DataAccessException {
289         if ((m_sDisplayName == null || m_sDisplayName.length() == 0)
290             && (m_bIsPopulated == false)) {
291             try {
292                 populateFromDatabase();
293             } catch (PopulateException e) {
294                 throw new DataAccessException("populate error",e);
295             }
296         }
297
298         return m_sDisplayName;
299     }
300
301     /**
302      * Sets the display name
303      *
304      * @param sName the display name of this resource
305      */

306     public void setDisplayName(String JavaDoc sDisplayName) {
307         if (m_bIsPopulated) {
308             if (m_sDisplayName.equals(sDisplayName) == false) {
309                 m_bIsChanged = true;
310             }
311         }
312
313         m_sDisplayName = sDisplayName;
314     }
315
316     /**
317      * Returns the version comment.
318      *
319      * @return the version comment
320      * @throws DataAccessException if an error occurs while populating this object
321      */

322     public String JavaDoc getVersionComment() throws DataAccessException {
323         if ((m_sVersionComment == null)
324             || (m_sVersionComment.equals(""))
325             && (m_bIsPopulated == false)) {
326             try {
327                 populateFromDatabase();
328             } catch (PopulateException e) {
329                 throw new DataAccessException(e.getLocalizedMessage());
330             }
331         }
332
333         return m_sVersionComment;
334     }
335
336     /**
337      * Sets the version comment attached to this object.
338      *
339      * @param sVersionComment the version comment
340      */

341     public void setVersionComment(String JavaDoc sVersionComment) {
342         if (sVersionComment == null) {
343             sVersionComment = "";
344         }
345
346         if (m_bIsPopulated) {
347             if ((m_sVersionComment == null && sVersionComment != null)
348                 || (m_sVersionComment.equals(sVersionComment) == false)) {
349                 m_bIsChanged = true;
350             }
351         }
352
353         m_sVersionComment = sVersionComment;
354     }
355
356     /**
357      * Returns the version number of this object.
358      *
359      * @return the version number of the object
360      * @throws DataAccessException if an error occurs while populating this object
361      */

362     public int getVersionNumber() throws DataAccessException {
363         if ((m_nVersionNumber == 0) && (m_bIsPopulated == false)) {
364             try {
365                 populateFromDatabase();
366             } catch (PopulateException e) {
367                 throw new DataAccessException(e.getLocalizedMessage());
368             }
369         }
370
371         return m_nVersionNumber;
372     }
373
374     /**
375      * Returns the version date of this object.
376      *
377      * @return the version date of this object
378      * @throws DataAccessException if an error occurs while populating this object
379      */

380     public java.util.Date JavaDoc getVersionDate() throws DataAccessException {
381         if ((m_dtVersionDate == null) && (m_bIsPopulated == false)) {
382             try {
383                 populateFromDatabase();
384             } catch (PopulateException e) {
385                 throw new DataAccessException(e.getLocalizedMessage());
386             }
387         }
388
389         return m_dtVersionDate;
390     }
391
392     /**
393      * Returns the date this object was archived if this object is an
394      * archived object, otherwise it will return a null.
395      *
396      * @return the date this object was archived
397      * @throws DataAccessException if an error occurs while populating this object
398      */

399     public java.util.Date JavaDoc getHistoryDate() throws DataAccessException {
400         if ((m_dtHistDate == null)
401             && (m_bIsPopulated == false)
402             && isHistorical() == true) {
403             try {
404                 populateFromDatabase();
405             } catch (PopulateException e) {
406                 throw new DataAccessException(e.getLocalizedMessage());
407             }
408         }
409
410         return m_dtHistDate;
411     }
412
413     /* (non-Javadoc)
414      * @see org.openharmonise.rm.resources.lifecycle.Editable#getStatus()
415      */

416     public Status getStatus() throws DataAccessException {
417         if ((m_status == Status.UNKNOWN) && (m_bIsPopulated == false)) {
418             try {
419                 populateFromDatabase();
420             } catch (PopulateException e) {
421                 throw new DataAccessException(e.getLocalizedMessage());
422             }
423         }
424
425         return m_status;
426     }
427
428     /* (non-Javadoc)
429      * @see org.openharmonise.rm.resources.lifecycle.Editable#getLiveVersion()
430      */

431     public Editable getLiveVersion() throws DataAccessException {
432         if (m_bIsPopulated == false) {
433             try {
434                 populateFromDatabase();
435             } catch (PopulateException e) {
436                 throw new DataAccessException(e.getLocalizedMessage(),e);
437             }
438         }
439
440         Editable liveVersion = null;
441
442         if (this.getStatus() == Status.APPROVED && isHistorical() == false) {
443             liveVersion = this;
444         } else if (m_nLiveId > NOTDBSAVED_ID) {
445             if (isHistorical() == true) {
446                 m_nLiveId = m_nId;
447             }
448             try {
449                 liveVersion =
450                     (Editable) HarmoniseObjectFactory.instantiatePublishableObject(
451                         m_dsi,
452                         this.getClass().getName(),
453                         m_nLiveId);
454             } catch (HarmoniseFactoryException e) {
455                 throw new DataAccessException(e.getLocalizedMessage());
456             }
457
458             //if this is historical there might not be a live version - lets check
459
if (((AbstractEditableObject) liveVersion).exists() == false) {
460                 liveVersion = null;
461             }
462         }
463
464         return (Editable) liveVersion;
465     }
466
467     /* (non-Javadoc)
468      * @see org.openharmonise.rm.resources.lifecycle.Editable#isLiveVersion()
469      */

470     public boolean isLiveVersion() throws DataAccessException {
471         if (m_bIsPopulated == false) {
472             try {
473                 populateFromDatabase();
474             } catch (PopulateException e) {
475                 throw new DataAccessException(e);
476             }
477         }
478
479         return (m_status == Status.APPROVED && isHistorical() == false);
480     }
481
482     /**
483      * Returns <code>true</code> if this object is a pending version.
484      *
485      * @return <code>true</code> if this object is a pending version
486      * @throws DataAccessException if an error occurs while populating this object
487      */

488     public boolean isPendingVersion() throws DataAccessException {
489         return (isLiveVersion() == false && isHistorical() == false);
490     }
491
492     /* (non-Javadoc)
493      * @see org.openharmonise.rm.resources.lifecycle.Editable#isLocked()
494      */

495     public boolean isLocked() throws DataAccessException {
496         if ((m_nLockUserId == NOTDBSAVED_ID) && (m_bIsPopulated == false)) {
497             try {
498                 populateFromDatabase();
499             } catch (PopulateException e) {
500                 throw new DataAccessException(e.getLocalizedMessage(), e);
501             }
502         }
503
504         boolean bIsLocked = false;
505
506         //as lock status is taken from the live version, if there is one
507
//we check the status of the live version
508
if (isLiveVersion() == true || getLiveVersion() == null) {
509             bIsLocked = (this.m_nLockUserId != NOTDBSAVED_ID);
510             
511             try {
512                 //if there is a lock on this resource
513
//verify that user still exists
514
//otherwise reset lock info
515
if(bIsLocked == true) {
516                     User lockUser = (User) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, User.class.getName(), m_nLockUserId);
517                     
518                     if(lockUser == null || lockUser.exists() == false) {
519                         
520                         UpdateStatement update = new UpdateStatement();
521                         update.addColumnValue(
522                             getInstanceColumnRef(CLMN_LOCK_USER, false),
523                             null);
524                         update.addWhereCondition(
525                             getInstanceColumnRef(ATTRIB_ID, false),
526                             "=",
527                             m_nId);
528
529                         m_dsi.executeUpdate(update);
530                         
531                         bIsLocked = false;
532                         m_nLockUserId = NOTDBSAVED_ID;
533                     }
534                 }
535             } catch (HarmoniseFactoryException e) {
536                 throw new DataAccessException(e);
537             } catch (DataStoreException e) {
538                 throw new DataAccessException(e);
539             }
540         } else {
541             bIsLocked = getLiveVersion().isLocked();
542         }
543
544         return bIsLocked;
545     }
546
547     /* (non-Javadoc)
548      * @see org.openharmonise.rm.resources.lifecycle.Editable#getLockOwner()
549      */

550     public User getLockOwner() throws DataAccessException {
551         User usr = null;
552
553         if (isLocked() == true) {
554
555             if (isLiveVersion() == true || getLiveVersion() == null) {
556
557                 try {
558
559                     usr =
560                         (User) HarmoniseObjectFactory.instantiateHarmoniseObject(
561                             m_dsi,
562                             User.class.getName(),
563                             m_nLockUserId);
564                 } catch (HarmoniseFactoryException e) {
565                     throw new DataAccessException(e.getLocalizedMessage());
566                 }
567             } else {
568                 usr = getLiveVersion().getLockOwner();
569             }
570         }
571
572         return usr;
573     }
574
575     /**
576      * Returns the user id for the lock on this object.
577      * @return the user id for the lock on this object
578      * @throws DataAccessException if an error occurs while populating this object
579      */

580     public int getLockUserId() throws DataAccessException {
581         if ((m_nLockUserId == NOTDBSAVED_ID) && (m_bIsPopulated == false)) {
582             try {
583                 populateFromDatabase();
584             } catch (PopulateException e) {
585                 throw new DataAccessException(e.getLocalizedMessage());
586             }
587         }
588
589         return m_nLockUserId;
590     }
591     
592     /* (non-Javadoc)
593      * @see org.openharmonise.rm.resources.lifecycle.Editable#getAllVersions()
594      */

595     public List getAllVersions() throws DataAccessException {
596         List versions = new Vector();
597         
598         SelectStatement select = new SelectStatement();
599         ResultSet rs = null;
600         ColumnRef id_col = null;
601         
602         AbstractEditableObject liveObj = (AbstractEditableObject) getLiveVersion();
603         
604         if(liveObj != null) {
605             versions.add(liveObj);
606         }
607
608         try {
609
610             id_col = getInstanceColumnRef(ATTRIB_ID, true);
611
612             // add the id column because we are going to need
613
// it for historical versions of the object
614
select.addSelectColumn(id_col);
615
616             this.addColumnsToPopulateQuery(select, true);
617
618             select.addWhereCondition(id_col, "=", m_nId);
619
620             select.addOrderBy(getInstanceColumnRef(CLMN_VERSION_DATE, true),SelectStatement.ORDER_DESCENDING);
621         } catch (DataStoreException ds_e) {
622             throw new DataAccessException(
623                 "There was a problem constructing the query",ds_e);
624         }
625
626         try {
627     
628             rs = m_dsi.execute(select);
629
630             AbstractEditableObject nextObj = null;
631             int col_id = -1;
632             while (rs.next()) {
633
634                 int nIdCol = select.getResultSetIndex(id_col);
635
636                 col_id = rs.getInt(nIdCol);
637
638                     nextObj =
639                         (AbstractEditableObject) this.getClass().newInstance();
640
641                     nextObj.setDataStoreInterface(m_dsi);
642                     nextObj.setId(col_id);
643                     nextObj.setHistorical(true);
644                     // this is an historical object
645

646                     nextObj.populateFromResultSetRow(rs, select);
647
648                     versions.add(nextObj);
649
650             }
651         } catch (SQLException sql_e) {
652             throw new DataAccessException(
653                 "There was a problem processing the query",
654                 sql_e);
655         } catch (DataStoreException ds_e) {
656             throw new DataAccessException(
657                 "There was a problem processing the query",
658                 ds_e);
659         } catch (PopulateException pop_e) {
660             throw new DataAccessException(
661                 "There was a problem populating the historical objects",
662                 pop_e);
663         } catch (IllegalAccessException JavaDoc ia_e) {
664             throw new DataAccessException(
665                 "There was a problem constructing the new object",
666                 ia_e);
667         } catch (InstantiationException JavaDoc ins_e) {
668             throw new DataAccessException(
669                 "There was a problem constructing the new object",
670                 ins_e);
671         } finally {
672             if (rs != null) {
673                 try {
674
675                     rs.close();
676                 } catch (SQLException sql_e) {
677                     throw new DataAccessException(
678                         "There was a problem closing the resultset",sql_e);
679                 }
680             }
681
682             select.clear();
683         }
684         
685         return versions;
686     }
687
688     /* (non-Javadoc)
689      * @see org.openharmonise.rm.resources.lifecycle.Editable#getHistoricalVersions()
690      */

691     public List getHistoricalVersions() throws DataAccessException {
692         List histories = new Vector();
693
694         SelectStatement select = new SelectStatement();
695         ResultSet rs = null;
696         ColumnRef id_col = null;
697         ColumnRef key_col = null;
698
699         try {
700
701             id_col = getInstanceColumnRef(ATTRIB_ID, true);
702             key_col = getInstanceColumnRef(ATTRIB_KEY, true);
703
704             // add the id column because we are going to need
705
// it for historical versions of the object
706
select.addSelectColumn(id_col);
707             select.addSelectColumn(key_col);
708
709             this.addColumnsToPopulateQuery(select, true);
710
711             select.addWhereCondition(id_col, "=", m_nId);
712
713             if (isHistorical() == true) {
714                 select.addWhereCondition(
715                     getInstanceColumnRef(CLMN_VERSION_DATE, true),
716                     "<",
717                     getVersionDate());
718             }
719
720             select.addOrderBy(getInstanceColumnRef(CLMN_VERSION_DATE, true),SelectStatement.ORDER_DESCENDING);
721         } catch (DataStoreException ds_e) {
722             throw new DataAccessException(
723                 "There was a problem constructing the query",ds_e);
724         }
725
726         try {
727             
728             rs = m_dsi.execute(select);
729
730             AbstractEditableObject nextObj = null;
731             boolean bAdd = false;
732             int col_id = -1;
733             while (rs.next()) {
734
735                 int nIdCol = select.getResultSetIndex(id_col);
736                 
737                 col_id = rs.getInt(nIdCol);
738                 int nKey = rs.getInt(select.getResultSetIndex(key_col));
739
740                 if(nextObj == null || nextObj.getKey() != nKey ) {
741                     nextObj =
742                         (AbstractEditableObject) this.getClass().newInstance();
743                     nextObj.setDataStoreInterface(m_dsi);
744                     nextObj.setId(col_id);
745                     nextObj.setKey(nKey);
746                     nextObj.setHistorical(true);
747                     bAdd = true;
748                 }
749
750                 
751                 // this is an historical object
752

753                 nextObj.populateFromResultSetRow(rs, select);
754
755                 if(bAdd == true) {
756                     histories.add(nextObj);
757                     bAdd = false;
758                 }
759                 
760
761             }
762         } catch (SQLException sql_e) {
763             throw new DataAccessException(
764                 "There was a problem processing the query",
765                 sql_e);
766         } catch (DataStoreException ds_e) {
767             throw new DataAccessException(
768                 "There was a problem processing the query",
769                 ds_e);
770         } catch (PopulateException pop_e) {
771             throw new DataAccessException(
772                 "There was a problem populating the historical objects",
773                 pop_e);
774         } catch (IllegalAccessException JavaDoc ia_e) {
775             throw new DataAccessException(
776                 "There was a problem constructing the new object",
777                 ia_e);
778         } catch (InstantiationException JavaDoc ins_e) {
779             throw new DataAccessException(
780                 "There was a problem constructing the new object",
781                 ins_e);
782         } finally {
783             if (rs != null) {
784                 try {
785
786                     rs.close();
787                 } catch (SQLException sql_e) {
788                     throw new DataAccessException(
789                         "There was a problem closing the resultset:"
790                             + sql_e.getLocalizedMessage());
791                 }
792             }
793
794             select.clear();
795         }
796
797         return histories;
798     }
799
800     /* (non-Javadoc)
801      * @see org.openharmonise.rm.resources.lifecycle.Editable#getPendingVersions()
802      */

803     public List getPendingVersions() throws DataAccessException {
804         List pends = new ArrayList();
805
806         if(m_pending == null) {
807         
808             ResultSet rs = null;
809             SelectStatement select = new SelectStatement();
810     
811             try {
812     
813                 select.addSelectColumn(getInstanceColumnRef(ATTRIB_ID, false));
814     
815                 select.addWhereCondition(
816                     getInstanceColumnRef(TAG_LIVE_VERSION, false),
817                     "=",
818                     m_nId);
819     
820                 select.addOrderBy(getInstanceColumnRef(CLMN_VERSION_DATE, false),SelectStatement.ORDER_DESCENDING);
821             } catch (DataStoreException ds_e) {
822                 throw new DataAccessException(
823                     "A problem occured building the query",ds_e);
824             }
825     
826             try {
827     
828                 rs = m_dsi.execute(select);
829     
830                 AbstractEditableObject nextObj = null;
831     
832                 while (rs.next()) {
833                     nextObj =
834                         (
835                             AbstractEditableObject) HarmoniseObjectFactory
836                                 .instantiateHarmoniseObject(
837                             m_dsi,
838                             getClass().getName(),
839                             rs.getInt(1));
840                     
841                     m_pending = CacheHandler.getInstance(m_dsi).getCachePointer(nextObj);
842                     
843                     pends.add(nextObj);
844                     
845                     nextObj.addEditEventListener(this);
846                 }
847             } catch (SQLException sql_e) {
848                 throw new DataAccessException(
849                     "A problem occured processing the query",sql_e);
850             } catch (DataStoreException ds_e) {
851                 throw new DataAccessException(
852                     "A problem occured processing the query",ds_e);
853             } catch (HarmoniseFactoryException fact_e) {
854                 throw new DataAccessException(
855                     "A problem occured processing the query",fact_e);
856             } catch (CacheException e) {
857                 throw new DataAccessException(e.getLocalizedMessage(),e);
858             } finally {
859                 if (rs != null) {
860                     try {
861                         rs.close();
862                     } catch (SQLException sql_e) {
863                         throw new DataAccessException(
864                             "A problem closing the resultset",sql_e);
865                     }
866     
867                 }
868             }
869
870         } else {
871             try {
872                 pends.add(m_pending.getObject());
873             } catch (CacheException e) {
874                 throw new DataAccessException(e.getLocalizedMessage(),e);
875             }
876         }
877
878         return pends;
879     }
880     
881     /* (non-Javadoc)
882      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectArchived(org.openharmonise.rm.resources.lifecycle.EditEvent)
883      */

884     public void workflowObjectArchived(EditEvent event) {
885         Object JavaDoc obj = event.getSource();
886         
887         try {
888             if(m_pending != null && obj.equals(m_pending.getObject())) {
889                 m_pending = null;
890             }
891         } catch (CacheException e) {
892             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
893         }
894     }
895
896     /* (non-Javadoc)
897      * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
898      */

899     public Editable changeStatus(Status status) throws EditException {
900         AbstractEditableObject result = this;
901         
902         if(m_logger.getLevel() == Level.INFO) {
903             m_logger.logp(Level.INFO,this.getClass().getName(),"changeStatus","Changing status of object (id - " + m_nId + ", key - " + m_nObjectKey + ") to " + status);
904
905         }
906
907         if (m_status == status) {
908             //doing nothing if not a change in status
909
return this;
910         }
911
912         if ((m_status != Status.APPROVED) && (status != Status.APPROVED)) {
913             // just a move through a multi stage approval process
914
m_status = status;
915
916             try {
917                 updateDBStatus();
918             } catch (PopulateException e) {
919                 throw new EditException(
920                     "A problem occured updating DB:" + e.getLocalizedMessage());
921             }
922
923         } else if (m_status != Status.APPROVED && status == Status.APPROVED) {
924
925             // archive the parent
926

927             Editable live = null;
928
929             try {
930                 live = getLiveVersion();
931             } catch (DataAccessException e) {
932                 throw new EditException("Had touble getting live version to archive");
933             }
934
935             if (live != null) {
936                 live.archive();
937             }
938
939             if (m_nLiveId > 0) {
940                 //take id from parent
941
m_nId = m_nLiveId;
942                 m_nLiveId = -1;
943             }
944
945             try {
946                 // approving the object
947
m_status = status;
948
949                 // save status change
950
updateDBStatus();
951
952                 HarmoniseIndexer.getInstance().indexObject(result);
953
954             } catch (PopulateException pop_e) {
955                 throw new EditException(pop_e.getLocalizedMessage(),pop_e);
956             } catch (HarmoniseIndexerException idx_e) {
957                 throw new EditException(idx_e.getLocalizedMessage(),idx_e);
958             }
959         }
960
961         //notify listeners
962
EditEvent event = new EditEvent(this, result);
963
964         Iterator iter = m_editlisteners.iterator();
965
966         while (iter.hasNext()) {
967             EditEventListener listener = (EditEventListener) iter.next();
968
969             listener.workflowObjectStatusChanged(event);
970         }
971
972         return result;
973     }
974
975
976     /* (non-Javadoc)
977      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
978      */

979     public void populate(Element xmlElement, State state)
980         throws PopulateException {
981         String JavaDoc sTagName = xmlElement.getTagName();
982         Text txt = null;
983
984         if (sTagName.equals(TAG_VERSION_COMMENT) == true) {
985             txt = (Text) xmlElement.getFirstChild();
986             setVersionComment(txt.getNodeValue());
987         } else if (sTagName.equals(TAG_DISPLAY_NAME)) {
988             txt = (Text) xmlElement.getFirstChild();
989             if(txt != null) {
990                 setDisplayName(txt.getNodeValue());
991             }
992         } else {
993             super.populate(xmlElement, state);
994         }
995     }
996
997     /* (non-Javadoc)
998      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
999      */

1000    public Element publish(Element topEl, HarmoniseOutput xmlDoc, State state)
1001        throws PublishException {
1002        String JavaDoc sTagName = topEl.getTagName();
1003        Element docEl = null;
1004        Text txt = null;
1005
1006        try {
1007
1008            if (sTagName.equals(TAG_VERSION_COMMENT)) {
1009                docEl = xmlDoc.createElement(TAG_VERSION_COMMENT);
1010                txt = xmlDoc.createTextNode(getVersionComment());
1011                docEl.appendChild(txt);
1012            } else if (sTagName.equals(TAG_DISPLAY_NAME)) {
1013                docEl = xmlDoc.createElement(sTagName);
1014                txt = xmlDoc.createTextNode(getDisplayName());
1015                docEl.appendChild(txt);
1016                xmlDoc.copyChildren(docEl, topEl, new Vector());
1017            } else if (sTagName.equals(TAG_VERSION)) {
1018                docEl = xmlDoc.createElement(TAG_VERSION);
1019                txt =
1020                    xmlDoc.createTextNode(Integer.toString(getVersionNumber()));
1021
1022                docEl.appendChild(txt);
1023
1024            } else if (sTagName.equals(TAG_VERSION_DATE)) {
1025                docEl = xmlDoc.createElement(TAG_VERSION_DATE);
1026                txt = xmlDoc.createTextNode(getVersionDate().toString());
1027
1028                docEl.appendChild(txt);
1029
1030            } else if (sTagName.equals(TAG_HISTORY_DATE)) {
1031                docEl = xmlDoc.createElement(TAG_HISTORY_DATE);
1032                txt = xmlDoc.createTextNode(getHistoryDate().toString());
1033
1034                docEl.appendChild(txt);
1035
1036            } else if (sTagName.equals(TAG_LOCKED)) {
1037                docEl = xmlDoc.createElement(TAG_LOCKED);
1038
1039                if (isLocked()) {
1040                    docEl.setAttribute(ATTRIB_IS_LOCKED, "true");
1041
1042                    NodeList childnodes = topEl.getChildNodes();
1043
1044                    for (int i = 0; i < childnodes.getLength(); i++) {
1045                        Node child = childnodes.item(i);
1046
1047                        if ((child.getNodeType() == Node.ELEMENT_NODE)
1048                            && child.getNodeName().equals(
1049                                Template.TAG_TEMPLATE)) {
1050                            Template templ = null;
1051                            try {
1052                                templ = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, Template.class.getName(), Integer.parseInt(
1053                                        ((Element) child).getAttribute(
1054                                                ATTRIB_ID)));
1055                            } catch (NumberFormatException JavaDoc e) {
1056                                throw new PublishException(e);
1057                            } catch (HarmoniseFactoryException e) {
1058                                throw new PublishException(e);
1059                            }
1060                            
1061                            Element templRoot = templ.getTemplateRootElement();
1062
1063                            if (templRoot.getNodeName().equals(User.TAG_USER)
1064                                == false) {
1065                                throw new InvalidXMLElementException("User tag needed");
1066                            }
1067
1068                            int lockId = this.getLockUserId();
1069                            User lockUser = (User) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, User.class.getName(), lockId);
1070                            Element tempEl =
1071                                lockUser.publish(templRoot, xmlDoc, state);
1072
1073                            if (tempEl != null) {
1074                                docEl.appendChild(tempEl);
1075                            }
1076                        }
1077                    }
1078                } else {
1079                    docEl.setAttribute(ATTRIB_IS_LOCKED, "false");
1080                }
1081            } else if (sTagName.equals(TAG_STATUS)) {
1082                docEl = xmlDoc.createElement(TAG_STATUS);
1083
1084                txt = xmlDoc.createTextNode(m_status.getStringValue());
1085
1086                docEl.appendChild(txt);
1087            } else if (sTagName.equals(TAG_LIVE_VERSION)) {
1088                docEl = xmlDoc.createElement(TAG_LIVE_VERSION);
1089                
1090                AbstractEditableObject eObj = (AbstractEditableObject) getLiveVersion();
1091                
1092                if(eObj != null) {
1093                    List nodes = XMLUtils.getChildrenByName(topEl, Template.TAG_TEMPLATE);
1094                
1095                    if(nodes.size() > 0) {
1096                        Element templateEl = (Element) nodes.get(0);
1097                        
1098                        Template template = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, templateEl, state);
1099                        
1100                        docEl = eObj.publish(template, xmlDoc, state);
1101                        
1102                    } else {
1103                        Element objEl = xmlDoc.createElement(getTagName());
1104                        objEl.setAttribute(ATTRIB_ID, String.valueOf(eObj.getId()));
1105                        docEl.appendChild(objEl);
1106                    }
1107                }
1108                
1109                
1110            } else {
1111                docEl = super.publish(topEl, xmlDoc, state);
1112            }
1113
1114        } catch (PublishException pub_e) {
1115            throw pub_e;
1116        } catch (DataAccessException da_e) {
1117            throw new PublishException(da_e.getLocalizedMessage());
1118        } catch (Exception JavaDoc ex) {
1119            throw new PublishException(ex.getLocalizedMessage());
1120        }
1121
1122        return docEl;
1123    }
1124
1125    /* (non-Javadoc)
1126     * @see org.openharmonise.rm.resources.lifecycle.Editable#reactivate()
1127     */

1128    public Editable reactivate() throws EditException {
1129        Editable result = null;
1130        
1131        if(m_logger.isLoggable(Level.INFO)) {
1132            m_logger.logp(Level.INFO,this.getClass().getName(),"reactivate", "Reactivating object, id - " + m_nId + ", key - " + m_nObjectKey);
1133        }
1134
1135        if (!this.isHistorical()) {
1136            if(m_logger.isLoggable(Level.INFO)) {
1137                m_logger.log(Level.INFO,"Can't reactivate - non-historical version");
1138            }
1139            throw new EditException("can't reactivate non-historical version");
1140        }
1141
1142        if (isPopulated() == false) {
1143            try {
1144
1145                fullPopulate();
1146            } catch (PopulateException pop_e) {
1147                throw new EditException(
1148                    "Problem populating object",pop_e);
1149            }
1150        }
1151
1152        setHistorical(false);
1153
1154        //try to find it's live version
1155
m_nLiveId = m_nId;
1156        AbstractEditableObject live = null;
1157
1158        try {
1159
1160            live =
1161                (AbstractEditableObject) CacheHandler.getInstance(
1162                    m_dsi).getObject(
1163                    this.getClass().getName(),
1164                    m_nLiveId);
1165        } catch (CacheException cache_ex) {
1166            throw new EditException(
1167                "Problem getting current version from cache",cache_ex);
1168        }
1169
1170        //set to be a new object
1171
try {
1172            markAsNew();
1173        } catch (PopulateException e) {
1174            throw new EditException("PopulateException", e);
1175        }
1176
1177        //ensure other stuff is set appropriately
1178
if (live != null && live.exists() == true) {
1179            try {
1180
1181                m_nVersionNumber = live.getVersionNumber();
1182            } catch (DataAccessException da_e) {
1183                throw new EditException(
1184                    "Problem occurred accessing data from current version",da_e);
1185            }
1186        }
1187
1188        // save this version
1189
result = ((Editable) this).save();
1190
1191        // notify listeners
1192
EditEvent event = new EditEvent(this, result);
1193
1194        Iterator iter = m_editlisteners.iterator();
1195
1196        while (iter.hasNext()) {
1197            EditEventListener listener = (EditEventListener) iter.next();
1198
1199            listener.workflowObjectReactivated(event);
1200        }
1201
1202        return result;
1203    }
1204
1205    /* (non-Javadoc)
1206     * @see org.openharmonise.rm.resources.lifecycle.Editable#lock(org.openharmonise.rm.resources.users.User)
1207     */

1208    public synchronized void lock(User usr) throws EditException {
1209        int nUserId = usr.getId();
1210
1211        if (m_bIsPopulated == false) {
1212            try {
1213                populateFromDatabase();
1214            } catch (PopulateException e) {
1215                throw new EditException(e.getLocalizedMessage());
1216            }
1217        }
1218        
1219        if(m_logger.isLoggable(Level.INFO)) {
1220            m_logger.logp(Level.INFO, this.getClass().getName(), "lock", "User " + nUserId + " locking object, id - " + m_nId + ", key - " + m_nObjectKey);
1221        }
1222        
1223        if ((m_nLockUserId > 0) && (m_nLockUserId != nUserId)) {
1224            if(m_logger.isLoggable(Level.INFO)) {
1225                m_logger.log(Level.INFO, "unable to lock object - invalid user");
1226
1227            }
1228            throw new InvalidLockOwnerException("This object is locked by another user");
1229        } else {
1230            try {
1231
1232                m_nLockUserId = nUserId;
1233
1234                // as lock status is taken from the live version, if there is one
1235
//we lock the live version
1236
if (isLiveVersion() == true || this.getLiveVersion() == null) {
1237
1238                    UpdateStatement update = new UpdateStatement();
1239                    update.addColumnValue(
1240                        getInstanceColumnRef(CLMN_LOCK_USER, false),
1241                        m_nLockUserId);
1242                    update.addWhereCondition(
1243                        getInstanceColumnRef(ATTRIB_ID, false),
1244                        "=",
1245                        m_nId);
1246
1247                    m_dsi.executeUpdate(update);
1248
1249                } else {
1250                    Editable live = getLiveVersion();
1251
1252                    live.lock(usr);
1253                }
1254
1255            } catch (DataStoreException ds_e) {
1256                throw new EditException(ds_e.getLocalizedMessage());
1257            } catch (DataAccessException da_e) {
1258                throw new EditException(da_e.getLocalizedMessage());
1259            }
1260
1261            // notify listeners
1262
EditEvent event = new EditEvent(this);
1263
1264            Iterator iter = m_editlisteners.iterator();
1265
1266            while (iter.hasNext()) {
1267                EditEventListener listener = (EditEventListener) iter.next();
1268
1269                listener.workflowObjectLocked(event);
1270            }
1271        }
1272    }
1273
1274    /* (non-Javadoc)
1275     * @see org.openharmonise.rm.resources.lifecycle.Editable#unlock(org.openharmonise.rm.resources.users.User)
1276     */

1277    public void unlock(User usr) throws EditException {
1278        
1279        boolean bCanUnlock = true;
1280        try {
1281            bCanUnlock =
1282                (getLockOwner().equals(usr) == true
1283                    || AuthorizationValidator.isSuperUser(usr) == true);
1284        } catch (DataAccessException e) {
1285            throw new EditException(
1286                "Error occured accessing lock owner",e);
1287        } catch (AuthorizationException e) {
1288            throw new EditException(
1289                "Error occured testing super user status",e);
1290        }
1291
1292        if (bCanUnlock == true) {
1293            boolean bIsLocked = false;
1294            
1295            if(m_logger.isLoggable(Level.INFO)) {
1296                m_logger.logp(Level.INFO, this.getClass().getName(), "unlock", "User " + usr.getId() + "unlocking object, id - " + m_nId + ", key - " + m_nObjectKey);
1297            }
1298
1299            try {
1300                bIsLocked = isLocked();
1301            } catch (DataAccessException da_e) {
1302                throw new EditException(
1303                    "Problem occurred accessing lock info",da_e);
1304            }
1305
1306            if (bIsLocked == true) {
1307
1308                try {
1309                    // as lock status is taken from the live version, if there is one
1310
//we unlock the live version
1311
if (isLiveVersion() == true || getLiveVersion() == null) {
1312
1313                        try {
1314
1315                            UpdateStatement update = new UpdateStatement();
1316                            update.addColumnValue(
1317                                getInstanceColumnRef(CLMN_LOCK_USER, false),
1318                                null);
1319                            update.addWhereCondition(
1320                                getInstanceColumnRef(ATTRIB_ID, false),
1321                                "=",
1322                                m_nId);
1323
1324                            m_dsi.executeUpdate(update);
1325                        } catch (DataStoreException ds_e) {
1326                            throw new EditException(
1327                                "Problem occurred updating lock info",ds_e);
1328                        }
1329                    } else {
1330                        getLiveVersion().unlock(usr);
1331                    }
1332
1333                    m_nLockUserId = 0;
1334                } catch (DataAccessException e) {
1335                    throw new EditException("DA problem unlocking", e);
1336                }
1337
1338                // notify listeners
1339
EditEvent event = new EditEvent(this);
1340
1341                Iterator iter = m_editlisteners.iterator();
1342
1343                while (iter.hasNext()) {
1344                    EditEventListener listener =
1345                        (EditEventListener) iter.next();
1346
1347                    listener.workflowObjectUnlocked(event);
1348                }
1349            }
1350
1351        } else {
1352            if(m_logger.isLoggable(Level.INFO)) {
1353                m_logger.log(Level.INFO, "Unable to unlock object - invalid user");
1354
1355            }
1356            throw new InvalidLockOwnerException("User not authorised to unlock");
1357        }
1358    }
1359
1360    /* (non-Javadoc)
1361     * @see org.openharmonise.rm.resources.AbstractObject#getColumnRef(java.lang.String, java.lang.String, boolean)
1362     */

1363    public static ColumnRef getColumnRef(
1364        String JavaDoc sClassname,
1365        String JavaDoc sColumn,
1366        boolean bHist)
1367        throws DataStoreException {
1368        ColumnRef returnColRef = null;
1369        String JavaDoc sTable = getTableName(sClassname, bHist);
1370
1371        return AbstractEditableObject.getObjectColumnRef(sTable, sColumn);
1372    }
1373
1374    /* (non-Javadoc)
1375     * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
1376     */

1377    public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
1378        throws DataStoreException {
1379        String JavaDoc sDBTable = getTableName(bIsHist);
1380
1381        return getObjectColumnRef(sDBTable, sColumn);
1382    }
1383
1384    /* (non-Javadoc)
1385     * @see org.openharmonise.rm.resources.AbstractObject#getObjectColumnRef(java.lang.String, java.lang.String)
1386     */

1387    public static ColumnRef getObjectColumnRef(String JavaDoc sTable, String JavaDoc sColumn)
1388        throws DataStoreException {
1389        ColumnRef returnColRef = null;
1390
1391        if (sColumn.equals(TAG_VERSION) == true
1392            || sColumn.equals(CLMN_VERSION_NUMBER) == true) {
1393            returnColRef =
1394                new ColumnRef(sTable, CLMN_VERSION_NUMBER, ColumnRef.NUMBER);
1395        } else if (sColumn.equals(TAG_DISPLAY_NAME) == true
1396            || sColumn.equals(CLMN_DISPLAY_NAME) == true) {
1397            returnColRef = new ColumnRef(sTable, CLMN_DISPLAY_NAME, ColumnRef.TEXT);
1398        } else if (
1399            sColumn.equals(TAG_VERSION_COMMENT) == true
1400                || sColumn.equals(CLMN_VERSION_COMMENT) == true) {
1401            returnColRef =
1402                new ColumnRef(sTable, CLMN_VERSION_COMMENT, ColumnRef.TEXT);
1403        } else if (
1404            sColumn.equals(TAG_LIVE_VERSION) == true
1405                || sColumn.equals(CLMN_LIVE_ID) == true) {
1406            returnColRef =
1407                new ColumnRef(sTable, CLMN_LIVE_ID, ColumnRef.NUMBER);
1408        } else if (
1409            sColumn.equals(TAG_STATUS) == true
1410                || sColumn.equals(CLMN_STATUS) == true) {
1411            returnColRef = new ColumnRef(sTable, CLMN_STATUS, ColumnRef.NUMBER);
1412        } else if (
1413            sColumn.equals(TAG_VERSION_DATE) == true
1414                || sColumn.equals(CLMN_VERSION_DATE) == true) {
1415            returnColRef =
1416                new ColumnRef(sTable, CLMN_VERSION_DATE, ColumnRef.DATE);
1417        } else if (sColumn.equals(CLMN_HISTORY_DATE)) {
1418            returnColRef =
1419                new ColumnRef(sTable, CLMN_HISTORY_DATE, ColumnRef.DATE);
1420        } else if (sColumn.equals(CLMN_LOCK_USER)) {
1421            returnColRef =
1422                new ColumnRef(sTable, CLMN_LOCK_USER, ColumnRef.NUMBER);
1423        }
1424
1425        if (returnColRef != null) {
1426            return returnColRef;
1427        } else {
1428            return AbstractObject.getObjectColumnRef(sTable, sColumn);
1429        }
1430    }
1431
1432    /* (non-Javadoc)
1433     * @see java.lang.Object#clone()
1434     */

1435    public Object JavaDoc clone() {
1436        AbstractEditableObject other = null;
1437        try {
1438
1439            if (!m_bIsPopulated) {
1440                populateFromDatabase();
1441            }
1442
1443            other = (AbstractEditableObject) super.clone();
1444
1445            if (this.getVersionDate() != null) {
1446                other.setVersionDate((java.util.Date JavaDoc) getVersionDate().clone());
1447            }
1448
1449            
1450        } catch (DataAccessException e) {
1451            m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1452        } catch (PopulateException e) {
1453            m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1454        }
1455
1456        return other;
1457
1458    }
1459
1460
1461    /* (non-Javadoc)
1462     * @see org.openharmonise.rm.resources.AbstractObject#clear()
1463     */

1464    public void clear() {
1465        m_nVersionNumber = 0;
1466        m_sVersionComment = "";
1467        m_sDisplayName = "";
1468        m_dtVersionDate = null;
1469        m_status = Status.UNKNOWN;
1470        m_nLockUserId = NOTDBSAVED_ID;
1471        m_nLiveId = NOTDBSAVED_ID;
1472
1473        super.clear();
1474    }
1475
1476    /* (non-Javadoc)
1477     * @see org.openharmonise.rm.resources.lifecycle.Editable#archive()
1478     */

1479    public Editable archive() throws EditException {
1480        AbstractEditableObject newObj = null;
1481        
1482        if(m_logger.isLoggable(Level.INFO)) {
1483            m_logger.logp(Level.INFO,this.getClass().getName(),"archive","Archiving object (id - " + m_nId + ", key - " + m_nObjectKey + ")");
1484
1485        }
1486        
1487        //clear the cached pending
1488
m_pending = null;
1489        
1490        try {
1491            fullPopulate();
1492        
1493            //if it's a live version we'll archive it
1494
//otherwise it'll just be a delete
1495
if(isLiveVersion() == true) {
1496            
1497                // create a historical version of this Document, then save it
1498
newObj = (AbstractEditableObject) clone();
1499                try {
1500                    newObj.markAsNew();
1501                } catch (PopulateException e) {
1502                    throw new EditException(
1503                        "Problem occurring marking object as new: ",
1504                        e);
1505                }
1506                newObj.setLiveVersion(this);
1507                newObj.setHistorical(true);
1508                newObj.save();
1509            }
1510        } catch (PopulateException e) {
1511            throw new EditException(e.getLocalizedMessage(),e);
1512        } catch (DataAccessException e) {
1513            throw new EditException(e.getLocalizedMessage(),e);
1514        }
1515
1516        // notify listeners before complete deletion so that listeners
1517
// that maybe removed during deletion know about the archive event
1518
EditEvent event = new EditEvent(this);
1519         event.setResult(newObj);
1520
1521         Iterator iter = new ArrayList(m_editlisteners).iterator();
1522
1523         while (iter.hasNext()) {
1524             EditEventListener listener = (EditEventListener) iter.next();
1525
1526             listener.workflowObjectArchived(event);
1527         }
1528
1529        try {
1530
1531            // now delete the original Document (without deleting history!!)
1532
delete(false);
1533        } catch (DataStoreException ds_e) {
1534            throw new EditException(
1535                "Problem ocurred deleting object from datastore",
1536                ds_e);
1537        } catch (PopulateException pop_e) {
1538            throw new EditException(pop_e.getLocalizedMessage(), pop_e);
1539        } catch (DataAccessException da_e) {
1540            throw new EditException(da_e.getLocalizedMessage(), da_e);
1541        }
1542
1543        return (Editable) newObj;
1544    }
1545    
1546    
1547    /**
1548     * Acquire a lock on child addition and removal
1549     *
1550     * Note: this method provides a mechanism for external
1551     * classes to implement locking on the management of
1552     * children but does NOT guarantee that other threads
1553     * cannot manipulate the children of the collection
1554     *
1555     * @throws EditException
1556     */

1557    public void acquireEditWriteLock() throws EditException {
1558        try {
1559            m_edit_lock.writeLock().acquire();
1560            
1561            m_lockThread = Thread.currentThread();
1562            
1563        } catch (InterruptedException JavaDoc e) {
1564            throw new EditException(e);
1565        }
1566    }
1567    
1568    /**
1569     * Release lock on child additions and removals
1570     *
1571     */

1572    public void releaseEditWriteLock() {
1573        m_edit_lock.writeLock().release();
1574        m_lockThread = null;
1575    }
1576
1577    /* (non-Javadoc)
1578     * @see org.openharmonise.rm.resources.lifecycle.Editable#save()
1579     */

1580    public Editable save() throws EditException {
1581        
1582        if(isLockThread() == false) {
1583            throw new EditException("This object is locked by another thread");
1584        }
1585        
1586        Editable result = this;
1587        boolean bNotifyListeners = true;
1588
1589        // ensure we have a full copy
1590
if (isPopulated() == false) {
1591            try {
1592
1593                this.populateFromDatabase();
1594            } catch (PopulateException pop_e) {
1595                throw new EditException(
1596                    "Problem occured populating object for save",pop_e);
1597            }
1598        }
1599
1600        if (m_nId == NOTDBSAVED_ID) {
1601            
1602            if(m_logger.isLoggable(Level.INFO)) {
1603                try {
1604                    m_logger.logp(Level.INFO, this.getClass().getName(), "save", "saving new version of " + getName());
1605                } catch (DataAccessException e) {
1606                    m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1607                }
1608            }
1609            
1610            String JavaDoc sTable = getDBTableName();
1611            boolean bIsHist = isHistorical();
1612
1613            try {
1614
1615                InsertStatement insert = new InsertStatement();
1616
1617                // For historical documents, the id is the history_id (as it is unique)
1618
// and the parent is stored in the id column, as it is the persistant id
1619
if (bIsHist == false) {
1620                    m_nId = m_dsi.getSequenceNextValue(PRE_SEQ + sTable);
1621                    m_nObjectKey =
1622                        m_dsi.getSequenceNextValue(PRE_SEQ + sTable + EXT_KEY);
1623                    // increment version number
1624
m_nVersionNumber++;
1625                } else {
1626                    sTable = getHistoricalDBTableName();
1627                    m_nId = m_nLiveId;
1628                    m_nLiveId = NOTDBSAVED_ID;
1629                }
1630
1631                m_status = Status.UNAPPROVED;
1632
1633                insert.setTable(sTable);
1634
1635                addDataToSave(insert);
1636
1637                m_dsi.execute(insert);
1638
1639                saveCoreData();
1640
1641            } catch (DataStoreException ds_e) {
1642                throw new EditException(
1643                    "A problem occurred saving data to DB",
1644                    ds_e);
1645            } catch (SQLException sql_e) {
1646                throw new EditException(
1647                    "A problem occurred saving data to DB",sql_e);
1648            }
1649
1650            m_bIsChanged = false;
1651            m_bIsPopulated = true;
1652            result = (Editable) this;
1653            // cache new object
1654
try {
1655                CacheHandler.getInstance(m_dsi).addToCache(this);
1656            } catch (CacheException e) {
1657                // assume the object hasn't been cached but we don't want
1658
// to break execution just cause there's been a problem
1659
// caching the object. do we?
1660
m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1661            }
1662
1663        } else {
1664            try {
1665
1666                if (isChanged() == true && isLiveVersion() == true) {
1667                    // create a new object and save it
1668
AbstractEditableObject objNew =
1669                        (AbstractEditableObject) this.clone();
1670                    try {
1671                        objNew.markAsNew();
1672                    } catch (PopulateException e) {
1673                        throw new EditException(
1674                            "Problem occurring marking object as new: ",
1675                            e);
1676                    }
1677
1678                    objNew.setLiveVersion(this);
1679                    objNew.save();
1680
1681                    // delete any changes made to this object that are for the new object
1682
clear();
1683
1684                    result = (Editable) objNew;
1685                } else if (isChanged() == true && isLiveVersion() == false) {
1686                    update();
1687
1688                } else {
1689                    // nothing's changed so nothing to do
1690
bNotifyListeners = false;
1691                }
1692            } catch (EditException ed_e) {
1693                throw ed_e;
1694            } catch (DataAccessException da_e) {
1695                throw new EditException(
1696                    "Problem accessing data on object",
1697                    da_e);
1698            } catch (DataStoreException ds_e) {
1699                throw new EditException("Problem updating object", ds_e);
1700            }
1701        }
1702
1703        saveNonCoreData();
1704
1705        if (bNotifyListeners == true) {
1706            // notify listeners
1707
EditEvent event = new EditEvent(this, result);
1708
1709            Iterator iter = m_editlisteners.iterator();
1710
1711            while (iter.hasNext()) {
1712                EditEventListener listener = (EditEventListener) iter.next();
1713
1714                listener.workflowObjectSaved(event);
1715            }
1716        }
1717
1718        return result;
1719    }
1720
1721    /**
1722     * Returns <code>true</code> if a write lock has been acquired on
1723     * this object and the current thread acquired that lock, or there
1724     * is no write lock currently acquired.
1725     *
1726     * @return <code>true</code> if a write lock has been acquired on
1727     * this object and the current thread acquired that lock, or there
1728     * is no write lock currently acquired.
1729     */

1730    protected boolean isLockThread() {
1731        return m_lockThread == null || m_lockThread == Thread.currentThread();
1732    }
1733
1734    /* (non-Javadoc)
1735     * @see org.openharmonise.rm.resources.lifecycle.Editable#createNewVersion()
1736     */

1737    public Editable createNewVersion() throws EditException {
1738        AbstractEditableObject newVersion = this;
1739            
1740        try {
1741            if (isLiveVersion() == true) {
1742                //check there is no pending versions already
1743
if(getPendingVersions().size() > 0) {
1744                    if(m_logger.isLoggable(Level.WARNING)) {
1745                        m_logger.logp(Level.WARNING, this.getClass().getName(), "createNewVersion", "Can't create new version as pending exists, id - " + m_nId + ", key - " + m_nObjectKey);
1746
1747                    }
1748                    throw new EditException("Can't create new version, there is already an existing pending version");
1749                }
1750                
1751                if(m_logger.isLoggable(Level.INFO)) {
1752                    m_logger.logp(Level.INFO, this.getClass().getName(), "createNewVersion", "Creating new version, id - " + m_nId + ", key - " + m_nObjectKey);
1753
1754                }
1755                
1756                newVersion = (AbstractEditableObject) this.clone();
1757
1758                newVersion.markAsNew();
1759
1760                newVersion.setLiveVersion(this);
1761                newVersion.save();
1762            } else {
1763                if(m_logger.isLoggable(Level.INFO)) {
1764                    m_logger.logp(Level.INFO, this.getClass().getName(), "createNewVersion", "Can't create new version as object is not live, id - " + m_nId + ", key - " + m_nObjectKey);
1765
1766                }
1767            }
1768        } catch (DataAccessException e) {
1769            throw new EditException("Data access error", e);
1770        } catch (PopulateException e) {
1771            throw new EditException("Population error", e);
1772        }
1773
1774        return newVersion;
1775    }
1776
1777    /* (non-Javadoc)
1778     * @see org.openharmonise.rm.resources.lifecycle.Editable#addEditEventListener(org.openharmonise.rm.resources.lifecycle.EditEventListener)
1779     */

1780    public void addEditEventListener(EditEventListener listener) {
1781        if (m_editlisteners.contains(listener) == false && listener != this) {
1782            m_editlisteners.add(listener);
1783        }
1784    }
1785
1786    /* (non-Javadoc)
1787     * @see org.openharmonise.rm.resources.lifecycle.Editable#removeEditEventListener(org.openharmonise.rm.resources.lifecycle.EditEventListener)
1788     */

1789    public void removeEditEventListener(EditEventListener listener) {
1790        m_editlisteners.remove(listener);
1791    }
1792
1793    /*----------------------------------------------------------------------------
1794    Protected Methods
1795    -----------------------------------------------------------------------------*/

1796
1797    /**
1798     * Save data external to the main object DB table yet part of
1799     * it's core data to the database.
1800     *
1801     * @throws EditException if an error occurs
1802     */

1803    protected abstract void saveCoreData() throws EditException;
1804
1805    /**
1806     * Saves data external to the main object DB table and not part of
1807     * it's core data gets saved to the database.
1808     *
1809     * @throws EditException if an error occurs
1810     */

1811    protected abstract void saveNonCoreData() throws EditException;
1812
1813    /* (non-Javadoc)
1814     * @see org.openharmonise.rm.resources.AbstractObject#addColumnsToPopulateQuery(org.openharmonise.commons.dsi.dml.SelectStatement, boolean)
1815     */

1816    protected void addColumnsToPopulateQuery(
1817        SelectStatement select,
1818        boolean bIsHist)
1819        throws DataStoreException {
1820
1821        try {
1822            ColumnRefCache cache = ColumnRefCache.getInstance();
1823
1824            select.addSelectColumn(cache.getColumnRef(this,TAG_DISPLAY_NAME, bIsHist));
1825            
1826            select.addSelectColumn(
1827                cache.getColumnRef(this, TAG_STATUS, bIsHist));
1828            select.addSelectColumn(
1829                cache.getColumnRef(this, TAG_VERSION, bIsHist));
1830            select.addSelectColumn(
1831                cache.getColumnRef(this, TAG_VERSION_COMMENT, bIsHist));
1832            select.addSelectColumn(
1833                cache.getColumnRef(this, TAG_VERSION_DATE, bIsHist));
1834            select.addSelectColumn(
1835                cache.getColumnRef(this, TAG_LIVE_VERSION, bIsHist));
1836
1837            if (bIsHist == true) {
1838                select.addSelectColumn(
1839                    cache.getColumnRef(this, CLMN_HISTORY_DATE, bIsHist));
1840            } else {
1841                select.addSelectColumn(
1842                    cache.getColumnRef(this, CLMN_LOCK_USER, bIsHist));
1843            }
1844        } catch (CacheException e) {
1845            throw new DataStoreException("cache error", e);
1846        }
1847
1848        super.addColumnsToPopulateQuery(select, bIsHist);
1849
1850    }
1851
1852    /**
1853     * Deletes object data from data store. If <code>bDeleteHist</code> is
1854     * <code>true</code> then the archived data will also be deleted.
1855     *
1856     * @param bDeleteHist <code>true</code> if the the archived data should be deleted
1857     * @throws DataStoreException if an error occurs
1858     */

1859    protected void delete(boolean bDeleteHist)
1860        throws
1861            DataStoreException,
1862            DataAccessException,
1863            EditException,
1864            PopulateException {
1865
1866        if (m_nObjectKey <= 0 && isPopulated() == false) {
1867            populateFromDatabase();
1868        }
1869
1870        String JavaDoc sTable = getDBTableName();
1871        boolean bIsHist = isHistorical();
1872
1873        if (bIsHist == true) {
1874            sTable = getHistoricalDBTableName();
1875        }
1876
1877        DeleteStatement deleteStmt = new DeleteStatement();
1878
1879        deleteStmt.setTable(sTable);
1880        deleteStmt.addWhereCondition(
1881            getInstanceColumnRef(ATTRIB_KEY, bIsHist),
1882            "=",
1883            m_nObjectKey);
1884
1885        m_dsi.execute(deleteStmt);
1886        deleteStmt.clear();
1887
1888        int i = 0;
1889
1890        if (bDeleteHist == true) {
1891            AbstractEditableObject nextObj = null;
1892            Iterator iter = null;
1893
1894            List listHistorical = getHistoricalVersions();
1895
1896            iter = listHistorical.iterator();
1897
1898            while (iter.hasNext()) {
1899                nextObj = (AbstractEditableObject) iter.next();
1900
1901                // set delete history to false so it doesn't cascade
1902
nextObj.delete(false);
1903            }
1904
1905            // if this isn't an historical version get rid of everything else
1906
if (bIsHist == false) {
1907                // unapproved versions
1908
List pends = getPendingVersions();
1909
1910                iter = pends.iterator();
1911
1912                while (iter.hasNext()) {
1913                    nextObj = (AbstractEditableObject) iter.next();
1914                    nextObj.delete(false);
1915                }
1916
1917            }
1918        }
1919        
1920        try {
1921            //ensure that object is not still in the cache
1922
CacheHandler.getInstance(m_dsi).getCache(getClass())
1923                .removeObjectFromCache(String.valueOf(m_nId));
1924        } catch (CacheException e) {
1925            throw new EditException(e);
1926        }
1927
1928        // set everything to its default states
1929
m_nId = NOTDBSAVED_ID;
1930        m_nObjectKey = NOTDBSAVED_KEY;
1931    }
1932
1933    /* (non-Javadoc)
1934     * @see org.openharmonise.rm.resources.AbstractObject#populateFromResultSetRow(java.sql.ResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
1935     */

1936    protected void populateFromResultSetRow(
1937        ResultSet rs,
1938        SelectStatement select)
1939        throws PopulateException {
1940
1941        if (isPopulated() == false) {
1942
1943            String JavaDoc sTemp = null;
1944            int nTemp = -1;
1945            java.util.Date JavaDoc dTemp = null;
1946            ColumnRef colref = null;
1947
1948            try {
1949                ColumnRefCache cache = ColumnRefCache.getInstance();
1950
1951                boolean bIsHist = isHistorical();
1952                
1953                ColumnRef dispNameCol = cache.getColumnRef(this,CLMN_DISPLAY_NAME,bIsHist);
1954                
1955                if (select.containsSelectColumn(dispNameCol) == true) {
1956
1957                    sTemp = rs.getString(select.getResultSetIndex(dispNameCol));
1958
1959                    if ((sTemp != null) && (sTemp.length() > 0)) {
1960                        if ((m_sDisplayName == null) || (m_sDisplayName.length() == 0)) {
1961                            m_sDisplayName = sTemp;
1962                        } else if (m_sDisplayName.equals(sTemp) == false) {
1963                            m_bIsChanged = true;
1964                        }
1965                    }
1966                }
1967
1968                colref = cache.getColumnRef(this, CLMN_STATUS, bIsHist);
1969
1970                if (select.containsSelectColumn(colref) == true) {
1971
1972                    nTemp = rs.getInt(select.getResultSetIndex(colref));
1973
1974                    if (m_status == Status.UNKNOWN) {
1975                        m_status = Status.getStatus(nTemp);
1976                    } else if (m_status.getIntValue() != nTemp) {
1977                        setIsChanged(true);
1978                    }
1979
1980                }
1981
1982                colref = cache.getColumnRef(this, CLMN_VERSION_NUMBER, bIsHist);
1983
1984                if (select.containsSelectColumn(colref) == true) {
1985                    nTemp = rs.getInt(select.getResultSetIndex(colref));
1986
1987                    if (nTemp >= 0) {
1988                        setVersionNumber(nTemp);
1989                    }
1990                }
1991
1992                colref =
1993                    cache.getColumnRef(this, CLMN_VERSION_COMMENT, bIsHist);
1994
1995                if (select.containsSelectColumn(colref) == true) {
1996                    sTemp = rs.getString(select.getResultSetIndex(colref));
1997
1998                    if ((sTemp != null) && (sTemp.length() > 0)) {
1999                        this.setVersionComment(sTemp);
2000                    }
2001                }
2002
2003                colref = cache.getColumnRef(this, CLMN_VERSION_DATE, bIsHist);
2004
2005                if (select.containsSelectColumn(colref) == true) {
2006                    dTemp = rs.getTimestamp(select.getResultSetIndex(colref));
2007
2008                    if (dTemp != null) {
2009                        this.setVersionDate(dTemp);
2010                    }
2011                }
2012
2013                if (bIsHist == false) {
2014
2015                    colref =
2016                        cache.getColumnRef(this, TAG_LIVE_VERSION, bIsHist);
2017
2018                    if (select.containsSelectColumn(colref) == true) {
2019                        nTemp = rs.getInt(select.getResultSetIndex(colref));
2020
2021                        if (nTemp >= 0) {
2022                            m_nLiveId = nTemp;
2023                        }
2024                    }
2025                } else {
2026                    m_nLiveId = m_nId;
2027                }
2028
2029                colref = cache.getColumnRef(this, CLMN_LOCK_USER, bIsHist);
2030
2031                if (select.containsSelectColumn(colref) == true) {
2032                    nTemp = rs.getInt(select.getResultSetIndex(colref));
2033
2034                    if (nTemp > 0) {
2035                        m_nLockUserId = nTemp;
2036                    }
2037                }
2038
2039                if (bIsHist == true) {
2040                    colref =
2041                        cache.getColumnRef(this, CLMN_HISTORY_DATE, bIsHist);
2042
2043                    if (select.containsSelectColumn(colref) == true) {
2044                        dTemp = rs.getTimestamp(select.getResultSetIndex(colref));
2045
2046                        if (dTemp != null) {
2047                            this.m_dtHistDate = dTemp;
2048                        }
2049                    }
2050                }
2051            } catch (SQLException eSQL) {
2052                throw new PopulateException("sql error", eSQL);
2053            } catch (CacheException e) {
2054                throw new PopulateException("cache error", e);
2055            }
2056
2057            super.populateFromResultSetRow(rs, select);
2058
2059        }
2060
2061    }
2062
2063    /**
2064     * Updates data in database.
2065     *
2066     * @throws DataStoreException if any database errors occur
2067     * @throws EditException if any errors occur processing the data
2068     */

2069    protected void update() throws DataStoreException, EditException {
2070
2071        if(m_logger.isLoggable(Level.INFO)) {
2072            try {
2073                m_logger.logp(Level.INFO, this.getClass().getName(), "update", "updating object " + getKey());
2074            } catch (DataAccessException e) {
2075                m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
2076            }
2077        }
2078        
2079        UpdateStatement update = new UpdateStatement();
2080
2081        addDataToSave(update);
2082
2083        update.addWhereCondition(
2084            getInstanceColumnRef(ATTRIB_KEY, isHistorical()),
2085            "=",
2086            m_nObjectKey);
2087
2088        m_dsi.execute(update);
2089        
2090        m_bIsChanged = false;
2091
2092    }
2093
2094    /**
2095     *
2096     * Adds data to insert statement which will be executed in the
2097     * <code>save()</code> method.
2098     *
2099     * @param insert the insert statement
2100     * @throws DataStoreException if an error occurs
2101     */

2102    protected void addDataToSave(InsertStatement insert)
2103        throws DataStoreException {
2104
2105        boolean bIsHist = isHistorical();
2106
2107        insert.addColumnValue(
2108            this.getInstanceColumnRef(ATTRIB_ID, bIsHist),
2109            m_nId);
2110        insert.addColumnValue(
2111            this.getInstanceColumnRef(ATTRIB_KEY, bIsHist),
2112            m_nObjectKey);
2113        insert.addColumnValue(
2114            this.getInstanceColumnRef(TAG_LIVE_VERSION, bIsHist),
2115            m_nLiveId);
2116
2117        java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
2118
2119        if (bIsHist == false) {
2120            m_dtVersionDate = (java.util.Date JavaDoc) dtNow.clone();
2121            
2122            insert.addColumnValue(
2123                getInstanceColumnRef(CLMN_VERSION_DATE, bIsHist),
2124                m_dtVersionDate);
2125        } else {
2126            insert.addColumnValue(
2127                getInstanceColumnRef(CLMN_VERSION_DATE, bIsHist),
2128                m_dtVersionDate);
2129            insert.addColumnValue(
2130                getInstanceColumnRef(CLMN_HISTORY_DATE, bIsHist),
2131                dtNow);
2132        }
2133
2134        insert.addColumnValue(
2135            getInstanceColumnRef(CLMN_VERSION_NUMBER, bIsHist),
2136            m_nVersionNumber);
2137
2138        if (m_sVersionComment != null) {
2139            insert.addColumnValue(
2140                getInstanceColumnRef(CLMN_VERSION_COMMENT, bIsHist),
2141                m_sVersionComment);
2142        }
2143
2144        insert.addColumnValue(
2145            getInstanceColumnRef(CLMN_STATUS, bIsHist),
2146            m_status.getIntValue());
2147
2148        if (m_sName != null) {
2149            insert.addColumnValue(
2150                this.getInstanceColumnRef(TAG_NAME, bIsHist),
2151                m_sName);
2152        }
2153        
2154        if (m_sDisplayName != null) {
2155            insert.addColumnValue(
2156                this.getInstanceColumnRef(TAG_DISPLAY_NAME, bIsHist),
2157                m_sDisplayName);
2158        }
2159
2160        if (m_sSummary != null) {
2161            insert.addColumnValue(
2162                this.getInstanceColumnRef(TAG_SUMMARY, bIsHist),
2163                m_sSummary);
2164        }
2165
2166        insert.addColumnValue(
2167            this.getInstanceColumnRef(ATTRIB_TYPE, bIsHist),
2168            this.m_sType);
2169    }
2170
2171    /**
2172     * Updates the database with the new status value and any
2173     * other relavent changes, such as id, key and live id.
2174     *
2175     * @throws PopulateException if an error occurs
2176     */

2177    protected void updateDBStatus() throws PopulateException {
2178
2179        try {
2180
2181            UpdateStatement update = new UpdateStatement();
2182
2183            update.addColumnValue(
2184                this.getInstanceColumnRef(TAG_STATUS, false),
2185                m_status.getIntValue());
2186            update.addColumnValue(
2187                this.getInstanceColumnRef(ATTRIB_ID, false),
2188                m_nId);
2189            update.addColumnValue(
2190                this.getInstanceColumnRef(TAG_LIVE_VERSION, false),
2191                m_nLiveId);
2192            update.addWhereCondition(
2193                this.getInstanceColumnRef(ATTRIB_KEY, false),
2194                "=",
2195                m_nObjectKey);
2196
2197            this.m_dsi.execute(update);
2198
2199        } catch (DataStoreException e) {
2200            throw new PopulateException(e.getLocalizedMessage());
2201        }
2202    }
2203
2204    /*----------------------------------------------------------------------------
2205    Private Methods
2206    -----------------------------------------------------------------------------*/

2207
2208    /**
2209     * Sets the status of this object.
2210     *
2211     * @param the status
2212     */

2213    private void setStatus(Status status) {
2214        m_status = status;
2215    }
2216
2217    /**
2218     * Sets the version number.
2219     *
2220     * @param nVersionNumber The version number
2221     */

2222    private void setVersionNumber(int nVersionNumber) {
2223        m_nVersionNumber = nVersionNumber;
2224    }
2225
2226    /**
2227     * Sets the version date.
2228     *
2229     * @param nVersionNumber the version date
2230     */

2231    private void setVersionDate(java.util.Date JavaDoc dtDate) {
2232        m_dtVersionDate = dtDate;
2233    }
2234
2235    /**
2236     * Sets the live version of this resource.
2237     *
2238     * @param liveVersion the live version of this object
2239     */

2240    private void setLiveVersion(AbstractEditableObject liveVersion) {
2241        //ensure live version is indeed the same type
2242
if ((this.getClass().isInstance(liveVersion)) == false) {
2243            throw new IllegalArgumentException JavaDoc();
2244        }
2245
2246        if (m_nId <= NOTDBSAVED_ID) {
2247            m_nLiveId = liveVersion.getId();
2248        }
2249    }
2250
2251    /* (non-Javadoc)
2252     * @see org.openharmonise.rm.resources.AbstractObject#isKeySupported()
2253     */

2254    protected boolean isKeySupported() {
2255        return true;
2256    }
2257    /* (non-Javadoc)
2258     * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectLocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2259     */

2260    public void workflowObjectLocked(EditEvent event) {
2261        // nothing to do
2262

2263    }
2264
2265    /* (non-Javadoc)
2266     * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectReactivated(org.openharmonise.rm.resources.lifecycle.EditEvent)
2267     */

2268    public void workflowObjectReactivated(EditEvent event) {
2269        // nothing to do
2270

2271    }
2272
2273    /* (non-Javadoc)
2274     * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectSaved(org.openharmonise.rm.resources.lifecycle.EditEvent)
2275     */

2276    public void workflowObjectSaved(EditEvent event) {
2277        // nothing to do
2278

2279    }
2280
2281    /* (non-Javadoc)
2282     * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectStatusChanged(org.openharmonise.rm.resources.lifecycle.EditEvent)
2283     */

2284    public void workflowObjectStatusChanged(EditEvent event) {
2285        // nothing to do
2286

2287    }
2288
2289    /* (non-Javadoc)
2290     * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectUnlocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2291     */

2292    public void workflowObjectUnlocked(EditEvent event) {
2293        // nothing to do
2294

2295    }
2296}
2297
Popular Tags