0001: /*
0002: * The contents of this file are subject to the
0003: * Mozilla Public License Version 1.1 (the "License");
0004: * you may not use this file except in compliance with the License.
0005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0006: *
0007: * Software distributed under the License is distributed on an "AS IS"
0008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
0009: * See the License for the specific language governing rights and
0010: * limitations under the License.
0011: *
0012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
0013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
0014: *
0015: * All Rights Reserved.
0016: *
0017: * Contributor(s):
0018: */
0019: package org.openharmonise.rm.resources;
0020:
0021: import java.sql.*;
0022: import java.util.*;
0023: import java.util.logging.*;
0024:
0025: import org.openharmonise.commons.cache.*;
0026: import org.openharmonise.commons.dsi.*;
0027: import org.openharmonise.commons.dsi.dml.*;
0028: import org.openharmonise.commons.xml.XMLUtils;
0029: import org.openharmonise.rm.*;
0030: import org.openharmonise.rm.dsi.*;
0031: import org.openharmonise.rm.factory.*;
0032: import org.openharmonise.rm.publishing.*;
0033: import org.openharmonise.rm.resources.lifecycle.*;
0034: import org.openharmonise.rm.resources.publishing.Template;
0035: import org.openharmonise.rm.resources.users.User;
0036: import org.openharmonise.rm.search.*;
0037: import org.openharmonise.rm.security.authorization.*;
0038: import org.w3c.dom.*;
0039:
0040: import EDU.oswego.cs.dl.util.concurrent.*;
0041:
0042: /**
0043: * AbstractEditableObject is the abstract implementation of the <code>Editable</code>
0044: * interface for objects within Harmonise.
0045: *
0046: * @author Michael Bell
0047: * @version $Revision: 1.9.2.3 $
0048: *
0049: */
0050: public abstract class AbstractEditableObject extends AbstractObject
0051: implements Editable, Publishable, DataStoreObject, Cloneable,
0052: EditEventListener {
0053:
0054: //XML constants
0055: /**
0056: * Status tag name
0057: */
0058: public static final String TAG_STATUS = "Status";
0059:
0060: /**
0061: * Display name tag name
0062: */
0063: public static final String TAG_DISPLAY_NAME = "DisplayName";
0064:
0065: /**
0066: * Version tag name
0067: */
0068: public static final String TAG_VERSION = "Version";
0069:
0070: /**
0071: * Version comment tag name
0072: */
0073: public static final String TAG_VERSION_COMMENT = "VersionComment";
0074:
0075: /**
0076: * Version date tag name
0077: */
0078: public static final String TAG_VERSION_DATE = "VersionDate";
0079:
0080: /**
0081: * History date tag name
0082: */
0083: public static final String TAG_HISTORY_DATE = "HistoryDate";
0084:
0085: /**
0086: * Live version tag name
0087: */
0088: public static final String TAG_LIVE_VERSION = "Live";
0089:
0090: /**
0091: * Pending version tag name
0092: */
0093: public static final String TAG_PENDING_VERSION = "Pending";
0094:
0095: /**
0096: * Historical version tag name
0097: */
0098: public static final String TAG_HISTORICAL_VERSION = "Historical";
0099:
0100: /**
0101: * Locked tag name
0102: */
0103: public static final String TAG_LOCKED = "Locked";
0104:
0105: /**
0106: * Is locked attribute name
0107: */
0108: public static final String ATTRIB_IS_LOCKED = "isLocked";
0109:
0110: //DB Constants
0111: /**
0112: * Version number column name
0113: */
0114: private static final String CLMN_VERSION_NUMBER = "version_number";
0115:
0116: /**
0117: * Version date column name
0118: */
0119: private static final String CLMN_VERSION_DATE = "version_date";
0120:
0121: /**
0122: * Version comment column name
0123: */
0124: private static final String CLMN_VERSION_COMMENT = "version_comment";
0125:
0126: /**
0127: * Status column name
0128: */
0129: private static final String CLMN_STATUS = "status";
0130:
0131: /**
0132: * Lock user column name
0133: */
0134: private static final String CLMN_LOCK_USER = "lock_user";
0135:
0136: /**
0137: * Archive date column name
0138: */
0139: private static final String CLMN_HISTORY_DATE = "history_date";
0140:
0141: /**
0142: * Live object id column name
0143: */
0144: private static final String CLMN_LIVE_ID = "live_id";
0145:
0146: /**
0147: * Display name column name
0148: */
0149: protected static final String CLMN_DISPLAY_NAME = "display_name";
0150:
0151: /**
0152: * Prefix for all id sequence names
0153: *
0154: * Note: Id sequence names will follow pattern - 'PRE_SEQ + getTableName()'
0155: */
0156: private static final String PRE_SEQ = "seq_";
0157:
0158: /**
0159: * Suffix for all key sequence names
0160: *
0161: * Note: Key sequence names will follow pattern - 'PRE_SEQ + getTableName() + EXT_KEY'
0162: */
0163: private static final String EXT_KEY = "_key";
0164:
0165: /**
0166: * The version number
0167: */
0168: protected int m_nVersionNumber = 0;
0169:
0170: /**
0171: * The version comment
0172: */
0173: protected String m_sVersionComment = "";
0174:
0175: /**
0176: * The display name
0177: */
0178: protected String m_sDisplayName = "";
0179:
0180: /**
0181: * The version date
0182: */
0183: protected java.util.Date m_dtVersionDate = null;
0184:
0185: /**
0186: * The current status
0187: */
0188: protected Status m_status = Status.UNKNOWN;
0189:
0190: /**
0191: * The id of the live version
0192: */
0193: protected int m_nLiveId = -1;
0194:
0195: /**
0196: * The id of the user that locked this resource
0197: */
0198: protected int m_nLockUserId = NOTDBSAVED_ID;
0199:
0200: /**
0201: * The archive date
0202: */
0203: protected java.util.Date m_dtHistDate = null;
0204:
0205: /**
0206: * The list of <code>EditListener</code>s registered with this object
0207: */
0208: private List m_editlisteners = new ArrayList();
0209:
0210: /**
0211: * A cache pointer to the pending version
0212: */
0213: protected CachePointer m_pending = null;
0214:
0215: /**
0216: * Read-write lock to enable locking of cache access.
0217: */
0218: private ReadWriteLock m_edit_lock = new WriterPreferenceReadWriteLock();
0219:
0220: /**
0221: * Logger for this class
0222: */
0223: static private Logger m_logger = Logger
0224: .getLogger(AbstractEditableObject.class.getName());
0225:
0226: /**
0227: * Thread which has acquired the write lock on this object
0228: */
0229: private Thread m_lockThread = null;
0230:
0231: /**
0232: * Constructs a new or anonymous instance without an interface
0233: * to the database.
0234: */
0235: public AbstractEditableObject() {
0236: super ();
0237: }
0238:
0239: /**
0240: * Standard constructor for a new or anonymous resource,
0241: * registering an <code>AbstractDataStoreInterface</code> to use
0242: * with all database communications.
0243: *
0244: * @param con the interface to the database
0245: */
0246: public AbstractEditableObject(AbstractDataStoreInterface con) {
0247: super (con);
0248:
0249: }
0250:
0251: /**
0252: * Standard constructor for an existing resource,
0253: * registering an <code>AbstractDataStoreInterface</code> to use
0254: * with all database communications.
0255: *
0256: * @param con the interface to the database
0257: * @param nId the id of the resource
0258: */
0259: public AbstractEditableObject(AbstractDataStoreInterface con,
0260: int nId) {
0261: super (con, nId);
0262:
0263: }
0264:
0265: /**
0266: * Standard constructor for an existing resource which may be historical.
0267: *
0268: * @param con the interface to the database
0269: * @param nId the id of the resource
0270: * @param nKey the unique key of the resource
0271: * @param bIsHist <code>true</code> if the object is historical
0272: */
0273: public AbstractEditableObject(AbstractDataStoreInterface con,
0274: int nId, int nKey, boolean bIsHist) {
0275: super (con, nId, nKey, bIsHist);
0276: }
0277:
0278: /**
0279: * Returns the display name of this resource.
0280: *
0281: * @return the display name of this resource
0282: * @throws DataAccessException if an error occurs populating this object
0283: */
0284: public String getDisplayName() throws DataAccessException {
0285: if ((m_sDisplayName == null || m_sDisplayName.length() == 0)
0286: && (m_bIsPopulated == false)) {
0287: try {
0288: populateFromDatabase();
0289: } catch (PopulateException e) {
0290: throw new DataAccessException("populate error", e);
0291: }
0292: }
0293:
0294: return m_sDisplayName;
0295: }
0296:
0297: /**
0298: * Sets the display name
0299: *
0300: * @param sName the display name of this resource
0301: */
0302: public void setDisplayName(String sDisplayName) {
0303: if (m_bIsPopulated) {
0304: if (m_sDisplayName.equals(sDisplayName) == false) {
0305: m_bIsChanged = true;
0306: }
0307: }
0308:
0309: m_sDisplayName = sDisplayName;
0310: }
0311:
0312: /**
0313: * Returns the version comment.
0314: *
0315: * @return the version comment
0316: * @throws DataAccessException if an error occurs while populating this object
0317: */
0318: public String getVersionComment() throws DataAccessException {
0319: if ((m_sVersionComment == null)
0320: || (m_sVersionComment.equals(""))
0321: && (m_bIsPopulated == false)) {
0322: try {
0323: populateFromDatabase();
0324: } catch (PopulateException e) {
0325: throw new DataAccessException(e.getLocalizedMessage());
0326: }
0327: }
0328:
0329: return m_sVersionComment;
0330: }
0331:
0332: /**
0333: * Sets the version comment attached to this object.
0334: *
0335: * @param sVersionComment the version comment
0336: */
0337: public void setVersionComment(String sVersionComment) {
0338: if (sVersionComment == null) {
0339: sVersionComment = "";
0340: }
0341:
0342: if (m_bIsPopulated) {
0343: if ((m_sVersionComment == null && sVersionComment != null)
0344: || (m_sVersionComment.equals(sVersionComment) == false)) {
0345: m_bIsChanged = true;
0346: }
0347: }
0348:
0349: m_sVersionComment = sVersionComment;
0350: }
0351:
0352: /**
0353: * Returns the version number of this object.
0354: *
0355: * @return the version number of the object
0356: * @throws DataAccessException if an error occurs while populating this object
0357: */
0358: public int getVersionNumber() throws DataAccessException {
0359: if ((m_nVersionNumber == 0) && (m_bIsPopulated == false)) {
0360: try {
0361: populateFromDatabase();
0362: } catch (PopulateException e) {
0363: throw new DataAccessException(e.getLocalizedMessage());
0364: }
0365: }
0366:
0367: return m_nVersionNumber;
0368: }
0369:
0370: /**
0371: * Returns the version date of this object.
0372: *
0373: * @return the version date of this object
0374: * @throws DataAccessException if an error occurs while populating this object
0375: */
0376: public java.util.Date getVersionDate() throws DataAccessException {
0377: if ((m_dtVersionDate == null) && (m_bIsPopulated == false)) {
0378: try {
0379: populateFromDatabase();
0380: } catch (PopulateException e) {
0381: throw new DataAccessException(e.getLocalizedMessage());
0382: }
0383: }
0384:
0385: return m_dtVersionDate;
0386: }
0387:
0388: /**
0389: * Returns the date this object was archived if this object is an
0390: * archived object, otherwise it will return a null.
0391: *
0392: * @return the date this object was archived
0393: * @throws DataAccessException if an error occurs while populating this object
0394: */
0395: public java.util.Date getHistoryDate() throws DataAccessException {
0396: if ((m_dtHistDate == null) && (m_bIsPopulated == false)
0397: && isHistorical() == true) {
0398: try {
0399: populateFromDatabase();
0400: } catch (PopulateException e) {
0401: throw new DataAccessException(e.getLocalizedMessage());
0402: }
0403: }
0404:
0405: return m_dtHistDate;
0406: }
0407:
0408: /* (non-Javadoc)
0409: * @see org.openharmonise.rm.resources.lifecycle.Editable#getStatus()
0410: */
0411: public Status getStatus() throws DataAccessException {
0412: if ((m_status == Status.UNKNOWN) && (m_bIsPopulated == false)) {
0413: try {
0414: populateFromDatabase();
0415: } catch (PopulateException e) {
0416: throw new DataAccessException(e.getLocalizedMessage());
0417: }
0418: }
0419:
0420: return m_status;
0421: }
0422:
0423: /* (non-Javadoc)
0424: * @see org.openharmonise.rm.resources.lifecycle.Editable#getLiveVersion()
0425: */
0426: public Editable getLiveVersion() throws DataAccessException {
0427: if (m_bIsPopulated == false) {
0428: try {
0429: populateFromDatabase();
0430: } catch (PopulateException e) {
0431: throw new DataAccessException(e.getLocalizedMessage(),
0432: e);
0433: }
0434: }
0435:
0436: Editable liveVersion = null;
0437:
0438: if (this .getStatus() == Status.APPROVED
0439: && isHistorical() == false) {
0440: liveVersion = this ;
0441: } else if (m_nLiveId > NOTDBSAVED_ID) {
0442: if (isHistorical() == true) {
0443: m_nLiveId = m_nId;
0444: }
0445: try {
0446: liveVersion = (Editable) HarmoniseObjectFactory
0447: .instantiatePublishableObject(m_dsi, this
0448: .getClass().getName(), m_nLiveId);
0449: } catch (HarmoniseFactoryException e) {
0450: throw new DataAccessException(e.getLocalizedMessage());
0451: }
0452:
0453: //if this is historical there might not be a live version - lets check
0454: if (((AbstractEditableObject) liveVersion).exists() == false) {
0455: liveVersion = null;
0456: }
0457: }
0458:
0459: return (Editable) liveVersion;
0460: }
0461:
0462: /* (non-Javadoc)
0463: * @see org.openharmonise.rm.resources.lifecycle.Editable#isLiveVersion()
0464: */
0465: public boolean isLiveVersion() throws DataAccessException {
0466: if (m_bIsPopulated == false) {
0467: try {
0468: populateFromDatabase();
0469: } catch (PopulateException e) {
0470: throw new DataAccessException(e);
0471: }
0472: }
0473:
0474: return (m_status == Status.APPROVED && isHistorical() == false);
0475: }
0476:
0477: /**
0478: * Returns <code>true</code> if this object is a pending version.
0479: *
0480: * @return <code>true</code> if this object is a pending version
0481: * @throws DataAccessException if an error occurs while populating this object
0482: */
0483: public boolean isPendingVersion() throws DataAccessException {
0484: return (isLiveVersion() == false && isHistorical() == false);
0485: }
0486:
0487: /* (non-Javadoc)
0488: * @see org.openharmonise.rm.resources.lifecycle.Editable#isLocked()
0489: */
0490: public boolean isLocked() throws DataAccessException {
0491: if ((m_nLockUserId == NOTDBSAVED_ID)
0492: && (m_bIsPopulated == false)) {
0493: try {
0494: populateFromDatabase();
0495: } catch (PopulateException e) {
0496: throw new DataAccessException(e.getLocalizedMessage(),
0497: e);
0498: }
0499: }
0500:
0501: boolean bIsLocked = false;
0502:
0503: //as lock status is taken from the live version, if there is one
0504: //we check the status of the live version
0505: if (isLiveVersion() == true || getLiveVersion() == null) {
0506: bIsLocked = (this .m_nLockUserId != NOTDBSAVED_ID);
0507:
0508: try {
0509: //if there is a lock on this resource
0510: //verify that user still exists
0511: //otherwise reset lock info
0512: if (bIsLocked == true) {
0513: User lockUser = (User) HarmoniseObjectFactory
0514: .instantiateHarmoniseObject(m_dsi,
0515: User.class.getName(), m_nLockUserId);
0516:
0517: if (lockUser == null || lockUser.exists() == false) {
0518:
0519: UpdateStatement update = new UpdateStatement();
0520: update.addColumnValue(getInstanceColumnRef(
0521: CLMN_LOCK_USER, false), null);
0522: update.addWhereCondition(getInstanceColumnRef(
0523: ATTRIB_ID, false), "=", m_nId);
0524:
0525: m_dsi.executeUpdate(update);
0526:
0527: bIsLocked = false;
0528: m_nLockUserId = NOTDBSAVED_ID;
0529: }
0530: }
0531: } catch (HarmoniseFactoryException e) {
0532: throw new DataAccessException(e);
0533: } catch (DataStoreException e) {
0534: throw new DataAccessException(e);
0535: }
0536: } else {
0537: bIsLocked = getLiveVersion().isLocked();
0538: }
0539:
0540: return bIsLocked;
0541: }
0542:
0543: /* (non-Javadoc)
0544: * @see org.openharmonise.rm.resources.lifecycle.Editable#getLockOwner()
0545: */
0546: public User getLockOwner() throws DataAccessException {
0547: User usr = null;
0548:
0549: if (isLocked() == true) {
0550:
0551: if (isLiveVersion() == true || getLiveVersion() == null) {
0552:
0553: try {
0554:
0555: usr = (User) HarmoniseObjectFactory
0556: .instantiateHarmoniseObject(m_dsi,
0557: User.class.getName(), m_nLockUserId);
0558: } catch (HarmoniseFactoryException e) {
0559: throw new DataAccessException(e
0560: .getLocalizedMessage());
0561: }
0562: } else {
0563: usr = getLiveVersion().getLockOwner();
0564: }
0565: }
0566:
0567: return usr;
0568: }
0569:
0570: /**
0571: * Returns the user id for the lock on this object.
0572: * @return the user id for the lock on this object
0573: * @throws DataAccessException if an error occurs while populating this object
0574: */
0575: public int getLockUserId() throws DataAccessException {
0576: if ((m_nLockUserId == NOTDBSAVED_ID)
0577: && (m_bIsPopulated == false)) {
0578: try {
0579: populateFromDatabase();
0580: } catch (PopulateException e) {
0581: throw new DataAccessException(e.getLocalizedMessage());
0582: }
0583: }
0584:
0585: return m_nLockUserId;
0586: }
0587:
0588: /* (non-Javadoc)
0589: * @see org.openharmonise.rm.resources.lifecycle.Editable#getAllVersions()
0590: */
0591: public List getAllVersions() throws DataAccessException {
0592: List versions = new Vector();
0593:
0594: SelectStatement select = new SelectStatement();
0595: ResultSet rs = null;
0596: ColumnRef id_col = null;
0597:
0598: AbstractEditableObject liveObj = (AbstractEditableObject) getLiveVersion();
0599:
0600: if (liveObj != null) {
0601: versions.add(liveObj);
0602: }
0603:
0604: try {
0605:
0606: id_col = getInstanceColumnRef(ATTRIB_ID, true);
0607:
0608: // add the id column because we are going to need
0609: // it for historical versions of the object
0610: select.addSelectColumn(id_col);
0611:
0612: this .addColumnsToPopulateQuery(select, true);
0613:
0614: select.addWhereCondition(id_col, "=", m_nId);
0615:
0616: select.addOrderBy(getInstanceColumnRef(CLMN_VERSION_DATE,
0617: true), SelectStatement.ORDER_DESCENDING);
0618: } catch (DataStoreException ds_e) {
0619: throw new DataAccessException(
0620: "There was a problem constructing the query", ds_e);
0621: }
0622:
0623: try {
0624:
0625: rs = m_dsi.execute(select);
0626:
0627: AbstractEditableObject nextObj = null;
0628: int col_id = -1;
0629: while (rs.next()) {
0630:
0631: int nIdCol = select.getResultSetIndex(id_col);
0632:
0633: col_id = rs.getInt(nIdCol);
0634:
0635: nextObj = (AbstractEditableObject) this .getClass()
0636: .newInstance();
0637:
0638: nextObj.setDataStoreInterface(m_dsi);
0639: nextObj.setId(col_id);
0640: nextObj.setHistorical(true);
0641: // this is an historical object
0642:
0643: nextObj.populateFromResultSetRow(rs, select);
0644:
0645: versions.add(nextObj);
0646:
0647: }
0648: } catch (SQLException sql_e) {
0649: throw new DataAccessException(
0650: "There was a problem processing the query", sql_e);
0651: } catch (DataStoreException ds_e) {
0652: throw new DataAccessException(
0653: "There was a problem processing the query", ds_e);
0654: } catch (PopulateException pop_e) {
0655: throw new DataAccessException(
0656: "There was a problem populating the historical objects",
0657: pop_e);
0658: } catch (IllegalAccessException ia_e) {
0659: throw new DataAccessException(
0660: "There was a problem constructing the new object",
0661: ia_e);
0662: } catch (InstantiationException ins_e) {
0663: throw new DataAccessException(
0664: "There was a problem constructing the new object",
0665: ins_e);
0666: } finally {
0667: if (rs != null) {
0668: try {
0669:
0670: rs.close();
0671: } catch (SQLException sql_e) {
0672: throw new DataAccessException(
0673: "There was a problem closing the resultset",
0674: sql_e);
0675: }
0676: }
0677:
0678: select.clear();
0679: }
0680:
0681: return versions;
0682: }
0683:
0684: /* (non-Javadoc)
0685: * @see org.openharmonise.rm.resources.lifecycle.Editable#getHistoricalVersions()
0686: */
0687: public List getHistoricalVersions() throws DataAccessException {
0688: List histories = new Vector();
0689:
0690: SelectStatement select = new SelectStatement();
0691: ResultSet rs = null;
0692: ColumnRef id_col = null;
0693: ColumnRef key_col = null;
0694:
0695: try {
0696:
0697: id_col = getInstanceColumnRef(ATTRIB_ID, true);
0698: key_col = getInstanceColumnRef(ATTRIB_KEY, true);
0699:
0700: // add the id column because we are going to need
0701: // it for historical versions of the object
0702: select.addSelectColumn(id_col);
0703: select.addSelectColumn(key_col);
0704:
0705: this .addColumnsToPopulateQuery(select, true);
0706:
0707: select.addWhereCondition(id_col, "=", m_nId);
0708:
0709: if (isHistorical() == true) {
0710: select
0711: .addWhereCondition(getInstanceColumnRef(
0712: CLMN_VERSION_DATE, true), "<",
0713: getVersionDate());
0714: }
0715:
0716: select.addOrderBy(getInstanceColumnRef(CLMN_VERSION_DATE,
0717: true), SelectStatement.ORDER_DESCENDING);
0718: } catch (DataStoreException ds_e) {
0719: throw new DataAccessException(
0720: "There was a problem constructing the query", ds_e);
0721: }
0722:
0723: try {
0724:
0725: rs = m_dsi.execute(select);
0726:
0727: AbstractEditableObject nextObj = null;
0728: boolean bAdd = false;
0729: int col_id = -1;
0730: while (rs.next()) {
0731:
0732: int nIdCol = select.getResultSetIndex(id_col);
0733:
0734: col_id = rs.getInt(nIdCol);
0735: int nKey = rs.getInt(select.getResultSetIndex(key_col));
0736:
0737: if (nextObj == null || nextObj.getKey() != nKey) {
0738: nextObj = (AbstractEditableObject) this .getClass()
0739: .newInstance();
0740: nextObj.setDataStoreInterface(m_dsi);
0741: nextObj.setId(col_id);
0742: nextObj.setKey(nKey);
0743: nextObj.setHistorical(true);
0744: bAdd = true;
0745: }
0746:
0747: // this is an historical object
0748:
0749: nextObj.populateFromResultSetRow(rs, select);
0750:
0751: if (bAdd == true) {
0752: histories.add(nextObj);
0753: bAdd = false;
0754: }
0755:
0756: }
0757: } catch (SQLException sql_e) {
0758: throw new DataAccessException(
0759: "There was a problem processing the query", sql_e);
0760: } catch (DataStoreException ds_e) {
0761: throw new DataAccessException(
0762: "There was a problem processing the query", ds_e);
0763: } catch (PopulateException pop_e) {
0764: throw new DataAccessException(
0765: "There was a problem populating the historical objects",
0766: pop_e);
0767: } catch (IllegalAccessException ia_e) {
0768: throw new DataAccessException(
0769: "There was a problem constructing the new object",
0770: ia_e);
0771: } catch (InstantiationException ins_e) {
0772: throw new DataAccessException(
0773: "There was a problem constructing the new object",
0774: ins_e);
0775: } finally {
0776: if (rs != null) {
0777: try {
0778:
0779: rs.close();
0780: } catch (SQLException sql_e) {
0781: throw new DataAccessException(
0782: "There was a problem closing the resultset:"
0783: + sql_e.getLocalizedMessage());
0784: }
0785: }
0786:
0787: select.clear();
0788: }
0789:
0790: return histories;
0791: }
0792:
0793: /* (non-Javadoc)
0794: * @see org.openharmonise.rm.resources.lifecycle.Editable#getPendingVersions()
0795: */
0796: public List getPendingVersions() throws DataAccessException {
0797: List pends = new ArrayList();
0798:
0799: if (m_pending == null) {
0800:
0801: ResultSet rs = null;
0802: SelectStatement select = new SelectStatement();
0803:
0804: try {
0805:
0806: select.addSelectColumn(getInstanceColumnRef(ATTRIB_ID,
0807: false));
0808:
0809: select.addWhereCondition(getInstanceColumnRef(
0810: TAG_LIVE_VERSION, false), "=", m_nId);
0811:
0812: select.addOrderBy(getInstanceColumnRef(
0813: CLMN_VERSION_DATE, false),
0814: SelectStatement.ORDER_DESCENDING);
0815: } catch (DataStoreException ds_e) {
0816: throw new DataAccessException(
0817: "A problem occured building the query", ds_e);
0818: }
0819:
0820: try {
0821:
0822: rs = m_dsi.execute(select);
0823:
0824: AbstractEditableObject nextObj = null;
0825:
0826: while (rs.next()) {
0827: nextObj = (AbstractEditableObject) HarmoniseObjectFactory
0828: .instantiateHarmoniseObject(m_dsi,
0829: getClass().getName(), rs.getInt(1));
0830:
0831: m_pending = CacheHandler.getInstance(m_dsi)
0832: .getCachePointer(nextObj);
0833:
0834: pends.add(nextObj);
0835:
0836: nextObj.addEditEventListener(this );
0837: }
0838: } catch (SQLException sql_e) {
0839: throw new DataAccessException(
0840: "A problem occured processing the query", sql_e);
0841: } catch (DataStoreException ds_e) {
0842: throw new DataAccessException(
0843: "A problem occured processing the query", ds_e);
0844: } catch (HarmoniseFactoryException fact_e) {
0845: throw new DataAccessException(
0846: "A problem occured processing the query",
0847: fact_e);
0848: } catch (CacheException e) {
0849: throw new DataAccessException(e.getLocalizedMessage(),
0850: e);
0851: } finally {
0852: if (rs != null) {
0853: try {
0854: rs.close();
0855: } catch (SQLException sql_e) {
0856: throw new DataAccessException(
0857: "A problem closing the resultset",
0858: sql_e);
0859: }
0860:
0861: }
0862: }
0863:
0864: } else {
0865: try {
0866: pends.add(m_pending.getObject());
0867: } catch (CacheException e) {
0868: throw new DataAccessException(e.getLocalizedMessage(),
0869: e);
0870: }
0871: }
0872:
0873: return pends;
0874: }
0875:
0876: /* (non-Javadoc)
0877: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectArchived(org.openharmonise.rm.resources.lifecycle.EditEvent)
0878: */
0879: public void workflowObjectArchived(EditEvent event) {
0880: Object obj = event.getSource();
0881:
0882: try {
0883: if (m_pending != null && obj.equals(m_pending.getObject())) {
0884: m_pending = null;
0885: }
0886: } catch (CacheException e) {
0887: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
0888: }
0889: }
0890:
0891: /* (non-Javadoc)
0892: * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
0893: */
0894: public Editable changeStatus(Status status) throws EditException {
0895: AbstractEditableObject result = this ;
0896:
0897: if (m_logger.getLevel() == Level.INFO) {
0898: m_logger.logp(Level.INFO, this .getClass().getName(),
0899: "changeStatus", "Changing status of object (id - "
0900: + m_nId + ", key - " + m_nObjectKey
0901: + ") to " + status);
0902:
0903: }
0904:
0905: if (m_status == status) {
0906: //doing nothing if not a change in status
0907: return this ;
0908: }
0909:
0910: if ((m_status != Status.APPROVED)
0911: && (status != Status.APPROVED)) {
0912: // just a move through a multi stage approval process
0913: m_status = status;
0914:
0915: try {
0916: updateDBStatus();
0917: } catch (PopulateException e) {
0918: throw new EditException(
0919: "A problem occured updating DB:"
0920: + e.getLocalizedMessage());
0921: }
0922:
0923: } else if (m_status != Status.APPROVED
0924: && status == Status.APPROVED) {
0925:
0926: // archive the parent
0927:
0928: Editable live = null;
0929:
0930: try {
0931: live = getLiveVersion();
0932: } catch (DataAccessException e) {
0933: throw new EditException(
0934: "Had touble getting live version to archive");
0935: }
0936:
0937: if (live != null) {
0938: live.archive();
0939: }
0940:
0941: if (m_nLiveId > 0) {
0942: //take id from parent
0943: m_nId = m_nLiveId;
0944: m_nLiveId = -1;
0945: }
0946:
0947: try {
0948: // approving the object
0949: m_status = status;
0950:
0951: // save status change
0952: updateDBStatus();
0953:
0954: HarmoniseIndexer.getInstance().indexObject(result);
0955:
0956: } catch (PopulateException pop_e) {
0957: throw new EditException(pop_e.getLocalizedMessage(),
0958: pop_e);
0959: } catch (HarmoniseIndexerException idx_e) {
0960: throw new EditException(idx_e.getLocalizedMessage(),
0961: idx_e);
0962: }
0963: }
0964:
0965: //notify listeners
0966: EditEvent event = new EditEvent(this , result);
0967:
0968: Iterator iter = m_editlisteners.iterator();
0969:
0970: while (iter.hasNext()) {
0971: EditEventListener listener = (EditEventListener) iter
0972: .next();
0973:
0974: listener.workflowObjectStatusChanged(event);
0975: }
0976:
0977: return result;
0978: }
0979:
0980: /* (non-Javadoc)
0981: * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
0982: */
0983: public void populate(Element xmlElement, State state)
0984: throws PopulateException {
0985: String sTagName = xmlElement.getTagName();
0986: Text txt = null;
0987:
0988: if (sTagName.equals(TAG_VERSION_COMMENT) == true) {
0989: txt = (Text) xmlElement.getFirstChild();
0990: setVersionComment(txt.getNodeValue());
0991: } else if (sTagName.equals(TAG_DISPLAY_NAME)) {
0992: txt = (Text) xmlElement.getFirstChild();
0993: if (txt != null) {
0994: setDisplayName(txt.getNodeValue());
0995: }
0996: } else {
0997: super .populate(xmlElement, state);
0998: }
0999: }
1000:
1001: /* (non-Javadoc)
1002: * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
1003: */
1004: public Element publish(Element topEl, HarmoniseOutput xmlDoc,
1005: State state) throws PublishException {
1006: String sTagName = topEl.getTagName();
1007: Element docEl = null;
1008: Text txt = null;
1009:
1010: try {
1011:
1012: if (sTagName.equals(TAG_VERSION_COMMENT)) {
1013: docEl = xmlDoc.createElement(TAG_VERSION_COMMENT);
1014: txt = xmlDoc.createTextNode(getVersionComment());
1015: docEl.appendChild(txt);
1016: } else if (sTagName.equals(TAG_DISPLAY_NAME)) {
1017: docEl = xmlDoc.createElement(sTagName);
1018: txt = xmlDoc.createTextNode(getDisplayName());
1019: docEl.appendChild(txt);
1020: xmlDoc.copyChildren(docEl, topEl, new Vector());
1021: } else if (sTagName.equals(TAG_VERSION)) {
1022: docEl = xmlDoc.createElement(TAG_VERSION);
1023: txt = xmlDoc.createTextNode(Integer
1024: .toString(getVersionNumber()));
1025:
1026: docEl.appendChild(txt);
1027:
1028: } else if (sTagName.equals(TAG_VERSION_DATE)) {
1029: docEl = xmlDoc.createElement(TAG_VERSION_DATE);
1030: txt = xmlDoc
1031: .createTextNode(getVersionDate().toString());
1032:
1033: docEl.appendChild(txt);
1034:
1035: } else if (sTagName.equals(TAG_HISTORY_DATE)) {
1036: docEl = xmlDoc.createElement(TAG_HISTORY_DATE);
1037: txt = xmlDoc
1038: .createTextNode(getHistoryDate().toString());
1039:
1040: docEl.appendChild(txt);
1041:
1042: } else if (sTagName.equals(TAG_LOCKED)) {
1043: docEl = xmlDoc.createElement(TAG_LOCKED);
1044:
1045: if (isLocked()) {
1046: docEl.setAttribute(ATTRIB_IS_LOCKED, "true");
1047:
1048: NodeList childnodes = topEl.getChildNodes();
1049:
1050: for (int i = 0; i < childnodes.getLength(); i++) {
1051: Node child = childnodes.item(i);
1052:
1053: if ((child.getNodeType() == Node.ELEMENT_NODE)
1054: && child.getNodeName().equals(
1055: Template.TAG_TEMPLATE)) {
1056: Template templ = null;
1057: try {
1058: templ = (Template) HarmoniseObjectFactory
1059: .instantiateHarmoniseObject(
1060: m_dsi,
1061: Template.class
1062: .getName(),
1063: Integer
1064: .parseInt(((Element) child)
1065: .getAttribute(ATTRIB_ID)));
1066: } catch (NumberFormatException e) {
1067: throw new PublishException(e);
1068: } catch (HarmoniseFactoryException e) {
1069: throw new PublishException(e);
1070: }
1071:
1072: Element templRoot = templ
1073: .getTemplateRootElement();
1074:
1075: if (templRoot.getNodeName().equals(
1076: User.TAG_USER) == false) {
1077: throw new InvalidXMLElementException(
1078: "User tag needed");
1079: }
1080:
1081: int lockId = this .getLockUserId();
1082: User lockUser = (User) HarmoniseObjectFactory
1083: .instantiateHarmoniseObject(m_dsi,
1084: User.class.getName(),
1085: lockId);
1086: Element tempEl = lockUser.publish(
1087: templRoot, xmlDoc, state);
1088:
1089: if (tempEl != null) {
1090: docEl.appendChild(tempEl);
1091: }
1092: }
1093: }
1094: } else {
1095: docEl.setAttribute(ATTRIB_IS_LOCKED, "false");
1096: }
1097: } else if (sTagName.equals(TAG_STATUS)) {
1098: docEl = xmlDoc.createElement(TAG_STATUS);
1099:
1100: txt = xmlDoc.createTextNode(m_status.getStringValue());
1101:
1102: docEl.appendChild(txt);
1103: } else if (sTagName.equals(TAG_LIVE_VERSION)) {
1104: docEl = xmlDoc.createElement(TAG_LIVE_VERSION);
1105:
1106: AbstractEditableObject eObj = (AbstractEditableObject) getLiveVersion();
1107:
1108: if (eObj != null) {
1109: List nodes = XMLUtils.getChildrenByName(topEl,
1110: Template.TAG_TEMPLATE);
1111:
1112: if (nodes.size() > 0) {
1113: Element templateEl = (Element) nodes.get(0);
1114:
1115: Template template = (Template) HarmoniseObjectFactory
1116: .instantiateHarmoniseObject(m_dsi,
1117: templateEl, state);
1118:
1119: docEl = eObj.publish(template, xmlDoc, state);
1120:
1121: } else {
1122: Element objEl = xmlDoc
1123: .createElement(getTagName());
1124: objEl.setAttribute(ATTRIB_ID, String
1125: .valueOf(eObj.getId()));
1126: docEl.appendChild(objEl);
1127: }
1128: }
1129:
1130: } else {
1131: docEl = super .publish(topEl, xmlDoc, state);
1132: }
1133:
1134: } catch (PublishException pub_e) {
1135: throw pub_e;
1136: } catch (DataAccessException da_e) {
1137: throw new PublishException(da_e);
1138: } catch (Exception ex) {
1139: throw new PublishException(ex);
1140: }
1141:
1142: return docEl;
1143: }
1144:
1145: /* (non-Javadoc)
1146: * @see org.openharmonise.rm.resources.lifecycle.Editable#reactivate()
1147: */
1148: public Editable reactivate() throws EditException {
1149: Editable result = null;
1150:
1151: if (m_logger.isLoggable(Level.INFO)) {
1152: m_logger.logp(Level.INFO, this .getClass().getName(),
1153: "reactivate", "Reactivating object, id - " + m_nId
1154: + ", key - " + m_nObjectKey);
1155: }
1156:
1157: if (!this .isHistorical()) {
1158: if (m_logger.isLoggable(Level.INFO)) {
1159: m_logger.log(Level.INFO,
1160: "Can't reactivate - non-historical version");
1161: }
1162: throw new EditException(
1163: "can't reactivate non-historical version");
1164: }
1165:
1166: try {
1167: fullPopulate();
1168: } catch (PopulateException e) {
1169: throw new EditException(e);
1170: }
1171:
1172: setHistorical(false);
1173:
1174: //try to find it's live version
1175: m_nLiveId = m_nId;
1176: AbstractEditableObject live = null;
1177:
1178: try {
1179:
1180: live = (AbstractEditableObject) CacheHandler.getInstance(
1181: m_dsi).getObject(this .getClass().getName(),
1182: m_nLiveId);
1183: } catch (CacheException cache_ex) {
1184: throw new EditException(
1185: "Problem getting current version from cache",
1186: cache_ex);
1187: }
1188:
1189: //set to be a new object
1190: try {
1191: markAsNew();
1192: } catch (PopulateException e) {
1193: throw new EditException("PopulateException", e);
1194: }
1195:
1196: //ensure other stuff is set appropriately
1197: if (live != null && live.exists() == true) {
1198: try {
1199:
1200: m_nVersionNumber = live.getVersionNumber();
1201: } catch (DataAccessException da_e) {
1202: throw new EditException(
1203: "Problem occurred accessing data from current version",
1204: da_e);
1205: }
1206: }
1207:
1208: // save this version
1209: result = ((Editable) this ).save();
1210:
1211: // notify listeners
1212: EditEvent event = new EditEvent(this , result);
1213:
1214: Iterator iter = m_editlisteners.iterator();
1215:
1216: while (iter.hasNext()) {
1217: EditEventListener listener = (EditEventListener) iter
1218: .next();
1219:
1220: listener.workflowObjectReactivated(event);
1221: }
1222:
1223: return result;
1224: }
1225:
1226: /* (non-Javadoc)
1227: * @see org.openharmonise.rm.resources.lifecycle.Editable#lock(org.openharmonise.rm.resources.users.User)
1228: */
1229: public synchronized void lock(User usr) throws EditException {
1230: int nUserId = usr.getId();
1231:
1232: if (m_bIsPopulated == false) {
1233: try {
1234: populateFromDatabase();
1235: } catch (PopulateException e) {
1236: throw new EditException(e.getLocalizedMessage());
1237: }
1238: }
1239:
1240: if (m_logger.isLoggable(Level.INFO)) {
1241: m_logger.logp(Level.INFO, this .getClass().getName(),
1242: "lock", "User " + nUserId
1243: + " locking object, id - " + m_nId
1244: + ", key - " + m_nObjectKey);
1245: }
1246:
1247: if ((m_nLockUserId > 0) && (m_nLockUserId != nUserId)) {
1248: if (m_logger.isLoggable(Level.INFO)) {
1249: m_logger.log(Level.INFO,
1250: "unable to lock object - invalid user");
1251:
1252: }
1253: throw new InvalidLockOwnerException(
1254: "This object is locked by another user");
1255: } else {
1256: try {
1257:
1258: m_nLockUserId = nUserId;
1259:
1260: // as lock status is taken from the live version, if there is one
1261: //we lock the live version
1262: if (isLiveVersion() == true
1263: || this .getLiveVersion() == null) {
1264:
1265: UpdateStatement update = new UpdateStatement();
1266: update.addColumnValue(getInstanceColumnRef(
1267: CLMN_LOCK_USER, false), m_nLockUserId);
1268: update.addWhereCondition(getInstanceColumnRef(
1269: ATTRIB_ID, false), "=", m_nId);
1270:
1271: m_dsi.executeUpdate(update);
1272:
1273: } else {
1274: Editable live = getLiveVersion();
1275:
1276: live.lock(usr);
1277: }
1278:
1279: } catch (DataStoreException ds_e) {
1280: throw new EditException(ds_e.getLocalizedMessage());
1281: } catch (DataAccessException da_e) {
1282: throw new EditException(da_e.getLocalizedMessage());
1283: }
1284:
1285: // notify listeners
1286: EditEvent event = new EditEvent(this );
1287:
1288: Iterator iter = m_editlisteners.iterator();
1289:
1290: while (iter.hasNext()) {
1291: EditEventListener listener = (EditEventListener) iter
1292: .next();
1293:
1294: listener.workflowObjectLocked(event);
1295: }
1296: }
1297: }
1298:
1299: /* (non-Javadoc)
1300: * @see org.openharmonise.rm.resources.lifecycle.Editable#unlock(org.openharmonise.rm.resources.users.User)
1301: */
1302: public void unlock(User usr) throws EditException {
1303:
1304: boolean bCanUnlock = true;
1305: try {
1306: bCanUnlock = (getLockOwner().equals(usr) == true || AuthorizationValidator
1307: .isSuperUser(usr) == true);
1308: } catch (DataAccessException e) {
1309: throw new EditException(
1310: "Error occured accessing lock owner", e);
1311: } catch (AuthorizationException e) {
1312: throw new EditException(
1313: "Error occured testing super user status", e);
1314: }
1315:
1316: if (bCanUnlock == true) {
1317: boolean bIsLocked = false;
1318:
1319: if (m_logger.isLoggable(Level.INFO)) {
1320: m_logger.logp(Level.INFO, this .getClass().getName(),
1321: "unlock", "User " + usr.getId()
1322: + "unlocking object, id - " + m_nId
1323: + ", key - " + m_nObjectKey);
1324: }
1325:
1326: try {
1327: bIsLocked = isLocked();
1328: } catch (DataAccessException da_e) {
1329: throw new EditException(
1330: "Problem occurred accessing lock info", da_e);
1331: }
1332:
1333: if (bIsLocked == true) {
1334:
1335: try {
1336: // as lock status is taken from the live version, if there is one
1337: //we unlock the live version
1338: if (isLiveVersion() == true
1339: || getLiveVersion() == null) {
1340:
1341: try {
1342:
1343: UpdateStatement update = new UpdateStatement();
1344: update.addColumnValue(getInstanceColumnRef(
1345: CLMN_LOCK_USER, false), null);
1346: update.addWhereCondition(
1347: getInstanceColumnRef(ATTRIB_ID,
1348: false), "=", m_nId);
1349:
1350: m_dsi.executeUpdate(update);
1351: } catch (DataStoreException ds_e) {
1352: throw new EditException(
1353: "Problem occurred updating lock info",
1354: ds_e);
1355: }
1356: } else {
1357: getLiveVersion().unlock(usr);
1358: }
1359:
1360: m_nLockUserId = 0;
1361: } catch (DataAccessException e) {
1362: throw new EditException("DA problem unlocking", e);
1363: }
1364:
1365: // notify listeners
1366: EditEvent event = new EditEvent(this );
1367:
1368: Iterator iter = m_editlisteners.iterator();
1369:
1370: while (iter.hasNext()) {
1371: EditEventListener listener = (EditEventListener) iter
1372: .next();
1373:
1374: listener.workflowObjectUnlocked(event);
1375: }
1376: }
1377:
1378: } else {
1379: if (m_logger.isLoggable(Level.INFO)) {
1380: m_logger.log(Level.INFO,
1381: "Unable to unlock object - invalid user");
1382:
1383: }
1384: throw new InvalidLockOwnerException(
1385: "User not authorised to unlock");
1386: }
1387: }
1388:
1389: /* (non-Javadoc)
1390: * @see org.openharmonise.rm.resources.AbstractObject#getColumnRef(java.lang.String, java.lang.String, boolean)
1391: */
1392: public static ColumnRef getColumnRef(String sClassname,
1393: String sColumn, boolean bHist) throws DataStoreException {
1394: ColumnRef returnColRef = null;
1395: String sTable = getTableName(sClassname, bHist);
1396:
1397: return AbstractEditableObject.getObjectColumnRef(sTable,
1398: sColumn);
1399: }
1400:
1401: /* (non-Javadoc)
1402: * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
1403: */
1404: public ColumnRef getInstanceColumnRef(String sColumn,
1405: boolean bIsHist) throws DataStoreException {
1406: String sDBTable = getTableName(bIsHist);
1407:
1408: return getObjectColumnRef(sDBTable, sColumn);
1409: }
1410:
1411: /* (non-Javadoc)
1412: * @see org.openharmonise.rm.resources.AbstractObject#getObjectColumnRef(java.lang.String, java.lang.String)
1413: */
1414: public static ColumnRef getObjectColumnRef(String sTable,
1415: String sColumn) throws DataStoreException {
1416: ColumnRef returnColRef = null;
1417:
1418: if (sColumn.equals(TAG_VERSION) == true
1419: || sColumn.equals(CLMN_VERSION_NUMBER) == true) {
1420: returnColRef = new ColumnRef(sTable, CLMN_VERSION_NUMBER,
1421: ColumnRef.NUMBER);
1422: } else if (sColumn.equals(TAG_DISPLAY_NAME) == true
1423: || sColumn.equals(CLMN_DISPLAY_NAME) == true) {
1424: returnColRef = new ColumnRef(sTable, CLMN_DISPLAY_NAME,
1425: ColumnRef.TEXT);
1426: } else if (sColumn.equals(TAG_VERSION_COMMENT) == true
1427: || sColumn.equals(CLMN_VERSION_COMMENT) == true) {
1428: returnColRef = new ColumnRef(sTable, CLMN_VERSION_COMMENT,
1429: ColumnRef.TEXT);
1430: } else if (sColumn.equals(TAG_LIVE_VERSION) == true
1431: || sColumn.equals(CLMN_LIVE_ID) == true) {
1432: returnColRef = new ColumnRef(sTable, CLMN_LIVE_ID,
1433: ColumnRef.NUMBER);
1434: } else if (sColumn.equals(TAG_STATUS) == true
1435: || sColumn.equals(CLMN_STATUS) == true) {
1436: returnColRef = new ColumnRef(sTable, CLMN_STATUS,
1437: ColumnRef.NUMBER);
1438: } else if (sColumn.equals(TAG_VERSION_DATE) == true
1439: || sColumn.equals(CLMN_VERSION_DATE) == true) {
1440: returnColRef = new ColumnRef(sTable, CLMN_VERSION_DATE,
1441: ColumnRef.DATE);
1442: } else if (sColumn.equals(CLMN_HISTORY_DATE)) {
1443: returnColRef = new ColumnRef(sTable, CLMN_HISTORY_DATE,
1444: ColumnRef.DATE);
1445: } else if (sColumn.equals(CLMN_LOCK_USER)) {
1446: returnColRef = new ColumnRef(sTable, CLMN_LOCK_USER,
1447: ColumnRef.NUMBER);
1448: }
1449:
1450: if (returnColRef != null) {
1451: return returnColRef;
1452: } else {
1453: return AbstractObject.getObjectColumnRef(sTable, sColumn);
1454: }
1455: }
1456:
1457: /* (non-Javadoc)
1458: * @see java.lang.Object#clone()
1459: */
1460: public Object clone() {
1461: AbstractEditableObject other = null;
1462: try {
1463:
1464: if (!m_bIsPopulated) {
1465: populateFromDatabase();
1466: }
1467:
1468: other = (AbstractEditableObject) super .clone();
1469:
1470: if (this .getVersionDate() != null) {
1471: other.setVersionDate((java.util.Date) getVersionDate()
1472: .clone());
1473: }
1474:
1475: } catch (DataAccessException e) {
1476: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1477: } catch (PopulateException e) {
1478: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1479: }
1480:
1481: return other;
1482:
1483: }
1484:
1485: /* (non-Javadoc)
1486: * @see org.openharmonise.rm.resources.AbstractObject#clear()
1487: */
1488: public void clear() {
1489: m_nVersionNumber = 0;
1490: m_sVersionComment = "";
1491: m_sDisplayName = "";
1492: m_dtVersionDate = null;
1493: m_status = Status.UNKNOWN;
1494: m_nLockUserId = NOTDBSAVED_ID;
1495: m_nLiveId = NOTDBSAVED_ID;
1496:
1497: super .clear();
1498: }
1499:
1500: /* (non-Javadoc)
1501: * @see org.openharmonise.rm.resources.lifecycle.Editable#archive()
1502: */
1503: public Editable archive() throws EditException {
1504: AbstractEditableObject newObj = null;
1505:
1506: if (m_logger.isLoggable(Level.INFO)) {
1507: m_logger.logp(Level.INFO, this .getClass().getName(),
1508: "archive", "Archiving object (id - " + m_nId
1509: + ", key - " + m_nObjectKey + ")");
1510:
1511: }
1512:
1513: //clear the cached pending
1514: m_pending = null;
1515:
1516: try {
1517: fullPopulate();
1518:
1519: //if it's a live version we'll archive it
1520: //otherwise it'll just be a delete
1521: if (isLiveVersion() == true) {
1522:
1523: // create a historical version of this Document, then save it
1524: newObj = (AbstractEditableObject) clone();
1525: try {
1526: newObj.markAsNew();
1527: } catch (PopulateException e) {
1528: throw new EditException(
1529: "Problem occurring marking object as new: ",
1530: e);
1531: }
1532: newObj.setLiveVersion(this );
1533: newObj.setHistorical(true);
1534: newObj.save();
1535: }
1536: } catch (PopulateException e) {
1537: throw new EditException(e.getLocalizedMessage(), e);
1538: } catch (DataAccessException e) {
1539: throw new EditException(e.getLocalizedMessage(), e);
1540: }
1541:
1542: // notify listeners before complete deletion so that listeners
1543: // that maybe removed during deletion know about the archive event
1544: EditEvent event = new EditEvent(this );
1545: event.setResult(newObj);
1546:
1547: Iterator iter = new ArrayList(m_editlisteners).iterator();
1548:
1549: while (iter.hasNext()) {
1550: EditEventListener listener = (EditEventListener) iter
1551: .next();
1552:
1553: listener.workflowObjectArchived(event);
1554: }
1555:
1556: try {
1557: HarmoniseIndexer.getInstance().deleteFromIndex(this );
1558: // now delete the original Document (without deleting history!!)
1559: delete(false);
1560: } catch (DataStoreException ds_e) {
1561: throw new EditException(
1562: "Problem ocurred deleting object from datastore",
1563: ds_e);
1564: } catch (PopulateException pop_e) {
1565: throw new EditException(pop_e.getLocalizedMessage(), pop_e);
1566: } catch (DataAccessException da_e) {
1567: throw new EditException(da_e.getLocalizedMessage(), da_e);
1568: } catch (HarmoniseIndexerException e) {
1569: throw new EditException(e);
1570: }
1571:
1572: return (Editable) newObj;
1573: }
1574:
1575: /**
1576: * Acquire a lock on child addition and removal
1577: *
1578: * Note: this method provides a mechanism for external
1579: * classes to implement locking on the management of
1580: * children but does NOT guarantee that other threads
1581: * cannot manipulate the children of the collection
1582: *
1583: * @throws EditException
1584: */
1585: public void acquireEditWriteLock() throws EditException {
1586: try {
1587: m_edit_lock.writeLock().acquire();
1588:
1589: m_lockThread = Thread.currentThread();
1590:
1591: } catch (InterruptedException e) {
1592: throw new EditException(e);
1593: }
1594: }
1595:
1596: /**
1597: * Release lock on child additions and removals
1598: *
1599: */
1600: public void releaseEditWriteLock() {
1601: m_edit_lock.writeLock().release();
1602: m_lockThread = null;
1603: }
1604:
1605: /* (non-Javadoc)
1606: * @see org.openharmonise.rm.resources.lifecycle.Editable#save()
1607: */
1608: public Editable save() throws EditException {
1609:
1610: if (isLockThread() == false) {
1611: throw new EditException(
1612: "This object is locked by another thread");
1613: }
1614:
1615: Editable result = this ;
1616: boolean bNotifyListeners = true;
1617:
1618: // ensure we have a full copy
1619: if (isPopulated() == false) {
1620: try {
1621:
1622: this .populateFromDatabase();
1623: } catch (PopulateException pop_e) {
1624: throw new EditException(
1625: "Problem occured populating object for save",
1626: pop_e);
1627: }
1628: }
1629:
1630: if (m_nId == NOTDBSAVED_ID) {
1631:
1632: if (m_logger.isLoggable(Level.INFO)) {
1633: try {
1634: m_logger.logp(Level.INFO,
1635: this .getClass().getName(), "save",
1636: "saving new version of " + getName());
1637: } catch (DataAccessException e) {
1638: m_logger.log(Level.WARNING,
1639: e.getLocalizedMessage(), e);
1640: }
1641: }
1642:
1643: String sTable = getDBTableName();
1644: boolean bIsHist = isHistorical();
1645:
1646: try {
1647:
1648: InsertStatement insert = new InsertStatement();
1649:
1650: // For historical documents, the id is the history_id (as it is unique)
1651: // and the parent is stored in the id column, as it is the persistant id
1652: if (bIsHist == false) {
1653: m_nId = m_dsi
1654: .getSequenceNextValue(PRE_SEQ + sTable);
1655: m_nObjectKey = m_dsi.getSequenceNextValue(PRE_SEQ
1656: + sTable + EXT_KEY);
1657: // increment version number
1658: m_nVersionNumber++;
1659: } else {
1660: sTable = getHistoricalDBTableName();
1661: m_nId = m_nLiveId;
1662: m_nLiveId = NOTDBSAVED_ID;
1663: }
1664:
1665: m_status = Status.UNAPPROVED;
1666:
1667: insert.setTable(sTable);
1668:
1669: addDataToSave(insert);
1670:
1671: m_dsi.execute(insert);
1672:
1673: saveCoreData();
1674:
1675: } catch (DataStoreException ds_e) {
1676: throw new EditException(
1677: "A problem occurred saving data to DB", ds_e);
1678: } catch (SQLException sql_e) {
1679: throw new EditException(
1680: "A problem occurred saving data to DB", sql_e);
1681: }
1682:
1683: m_bIsChanged = false;
1684: m_bIsPopulated = true;
1685: result = (Editable) this ;
1686: // cache new object
1687: try {
1688: CacheHandler.getInstance(m_dsi).addToCache(this );
1689: } catch (CacheException e) {
1690: // assume the object hasn't been cached but we don't want
1691: // to break execution just cause there's been a problem
1692: // caching the object. do we?
1693: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1694: }
1695:
1696: } else {
1697: try {
1698:
1699: if (isChanged() == true && isLiveVersion() == true) {
1700: // create a new object and save it
1701: AbstractEditableObject objNew = (AbstractEditableObject) this
1702: .clone();
1703: try {
1704: objNew.markAsNew();
1705: } catch (PopulateException e) {
1706: throw new EditException(
1707: "Problem occurring marking object as new: ",
1708: e);
1709: }
1710:
1711: objNew.setLiveVersion(this );
1712: objNew.save();
1713:
1714: // delete any changes made to this object that are for the new object
1715: clear();
1716:
1717: result = (Editable) objNew;
1718: } else if (isChanged() == true
1719: && isLiveVersion() == false) {
1720: update();
1721:
1722: } else {
1723: // nothing's changed so nothing to do
1724: bNotifyListeners = false;
1725: }
1726: } catch (EditException ed_e) {
1727: throw ed_e;
1728: } catch (DataAccessException da_e) {
1729: throw new EditException(
1730: "Problem accessing data on object", da_e);
1731: } catch (DataStoreException ds_e) {
1732: throw new EditException("Problem updating object", ds_e);
1733: }
1734: }
1735:
1736: saveNonCoreData();
1737:
1738: if (bNotifyListeners == true) {
1739: // notify listeners
1740: EditEvent event = new EditEvent(this , result);
1741:
1742: Iterator iter = m_editlisteners.iterator();
1743:
1744: while (iter.hasNext()) {
1745: EditEventListener listener = (EditEventListener) iter
1746: .next();
1747:
1748: listener.workflowObjectSaved(event);
1749: }
1750: }
1751:
1752: return result;
1753: }
1754:
1755: /**
1756: * Returns <code>true</code> if a write lock has been acquired on
1757: * this object and the current thread acquired that lock, or there
1758: * is no write lock currently acquired.
1759: *
1760: * @return <code>true</code> if a write lock has been acquired on
1761: * this object and the current thread acquired that lock, or there
1762: * is no write lock currently acquired.
1763: */
1764: protected boolean isLockThread() {
1765: return m_lockThread == null
1766: || m_lockThread == Thread.currentThread();
1767: }
1768:
1769: /* (non-Javadoc)
1770: * @see org.openharmonise.rm.resources.lifecycle.Editable#createNewVersion()
1771: */
1772: public Editable createNewVersion() throws EditException {
1773: AbstractEditableObject newVersion = this ;
1774:
1775: try {
1776: if (isLiveVersion() == true) {
1777: //check there is no pending versions already
1778: if (getPendingVersions().size() > 0) {
1779: if (m_logger.isLoggable(Level.WARNING)) {
1780: m_logger.logp(Level.WARNING, this .getClass()
1781: .getName(), "createNewVersion",
1782: "Can't create new version as pending exists, id - "
1783: + m_nId + ", key - "
1784: + m_nObjectKey);
1785:
1786: }
1787: throw new EditException(
1788: "Can't create new version, there is already an existing pending version");
1789: }
1790:
1791: if (m_logger.isLoggable(Level.INFO)) {
1792: m_logger.logp(Level.INFO,
1793: this .getClass().getName(),
1794: "createNewVersion",
1795: "Creating new version, id - " + m_nId
1796: + ", key - " + m_nObjectKey);
1797:
1798: }
1799:
1800: newVersion = (AbstractEditableObject) this .clone();
1801:
1802: newVersion.markAsNew();
1803:
1804: newVersion.setLiveVersion(this );
1805: newVersion.save();
1806: } else {
1807: if (m_logger.isLoggable(Level.INFO)) {
1808: m_logger
1809: .logp(Level.INFO,
1810: this .getClass().getName(),
1811: "createNewVersion",
1812: "Can't create new version as object is not live, id - "
1813: + m_nId + ", key - "
1814: + m_nObjectKey);
1815:
1816: }
1817: }
1818: } catch (DataAccessException e) {
1819: throw new EditException("Data access error", e);
1820: } catch (PopulateException e) {
1821: throw new EditException("Population error", e);
1822: }
1823:
1824: return newVersion;
1825: }
1826:
1827: /* (non-Javadoc)
1828: * @see org.openharmonise.rm.resources.lifecycle.Editable#addEditEventListener(org.openharmonise.rm.resources.lifecycle.EditEventListener)
1829: */
1830: public void addEditEventListener(EditEventListener listener) {
1831: if (m_editlisteners.contains(listener) == false
1832: && listener != this ) {
1833: m_editlisteners.add(listener);
1834: }
1835: }
1836:
1837: /* (non-Javadoc)
1838: * @see org.openharmonise.rm.resources.lifecycle.Editable#removeEditEventListener(org.openharmonise.rm.resources.lifecycle.EditEventListener)
1839: */
1840: public void removeEditEventListener(EditEventListener listener) {
1841: m_editlisteners.remove(listener);
1842: }
1843:
1844: /*----------------------------------------------------------------------------
1845: Protected Methods
1846: -----------------------------------------------------------------------------*/
1847:
1848: /**
1849: * Save data external to the main object DB table yet part of
1850: * it's core data to the database.
1851: *
1852: * @throws EditException if an error occurs
1853: */
1854: protected abstract void saveCoreData() throws EditException;
1855:
1856: /**
1857: * Saves data external to the main object DB table and not part of
1858: * it's core data gets saved to the database.
1859: *
1860: * @throws EditException if an error occurs
1861: */
1862: protected abstract void saveNonCoreData() throws EditException;
1863:
1864: /* (non-Javadoc)
1865: * @see org.openharmonise.rm.resources.AbstractObject#addColumnsToPopulateQuery(org.openharmonise.commons.dsi.dml.SelectStatement, boolean)
1866: */
1867: protected void addColumnsToPopulateQuery(SelectStatement select,
1868: boolean bIsHist) throws DataStoreException {
1869:
1870: try {
1871: ColumnRefCache cache = ColumnRefCache.getInstance();
1872:
1873: select.addSelectColumn(cache.getColumnRef(this ,
1874: TAG_DISPLAY_NAME, bIsHist));
1875:
1876: select.addSelectColumn(cache.getColumnRef(this , TAG_STATUS,
1877: bIsHist));
1878: select.addSelectColumn(cache.getColumnRef(this ,
1879: TAG_VERSION, bIsHist));
1880: select.addSelectColumn(cache.getColumnRef(this ,
1881: TAG_VERSION_COMMENT, bIsHist));
1882: select.addSelectColumn(cache.getColumnRef(this ,
1883: TAG_VERSION_DATE, bIsHist));
1884: select.addSelectColumn(cache.getColumnRef(this ,
1885: TAG_LIVE_VERSION, bIsHist));
1886:
1887: if (bIsHist == true) {
1888: select.addSelectColumn(cache.getColumnRef(this ,
1889: CLMN_HISTORY_DATE, bIsHist));
1890: } else {
1891: select.addSelectColumn(cache.getColumnRef(this ,
1892: CLMN_LOCK_USER, bIsHist));
1893: }
1894: } catch (CacheException e) {
1895: throw new DataStoreException("cache error", e);
1896: }
1897:
1898: super .addColumnsToPopulateQuery(select, bIsHist);
1899:
1900: }
1901:
1902: /**
1903: * Deletes object data from data store. If <code>bDeleteHist</code> is
1904: * <code>true</code> then the archived data will also be deleted.
1905: *
1906: * @param bDeleteHist <code>true</code> if the the archived data should be deleted
1907: * @throws DataStoreException if an error occurs
1908: */
1909: protected void delete(boolean bDeleteHist)
1910: throws DataStoreException, DataAccessException,
1911: EditException, PopulateException {
1912:
1913: if (m_nObjectKey <= 0 && isPopulated() == false) {
1914: populateFromDatabase();
1915: }
1916:
1917: String sTable = getDBTableName();
1918: boolean bIsHist = isHistorical();
1919:
1920: if (bIsHist == true) {
1921: sTable = getHistoricalDBTableName();
1922: }
1923:
1924: DeleteStatement deleteStmt = new DeleteStatement();
1925:
1926: deleteStmt.setTable(sTable);
1927: deleteStmt.addWhereCondition(getInstanceColumnRef(ATTRIB_KEY,
1928: bIsHist), "=", m_nObjectKey);
1929:
1930: m_dsi.execute(deleteStmt);
1931: deleteStmt.clear();
1932:
1933: int i = 0;
1934:
1935: if (bDeleteHist == true) {
1936: AbstractEditableObject nextObj = null;
1937: Iterator iter = null;
1938:
1939: List listHistorical = getHistoricalVersions();
1940:
1941: iter = listHistorical.iterator();
1942:
1943: while (iter.hasNext()) {
1944: nextObj = (AbstractEditableObject) iter.next();
1945:
1946: // set delete history to false so it doesn't cascade
1947: nextObj.delete(false);
1948: }
1949:
1950: // if this isn't an historical version get rid of everything else
1951: if (bIsHist == false) {
1952: // unapproved versions
1953: List pends = getPendingVersions();
1954:
1955: iter = pends.iterator();
1956:
1957: while (iter.hasNext()) {
1958: nextObj = (AbstractEditableObject) iter.next();
1959: nextObj.delete(false);
1960: }
1961:
1962: }
1963: }
1964:
1965: try {
1966: //ensure that object is not still in the cache
1967: CacheHandler.getInstance(m_dsi).getCache(getClass())
1968: .removeObjectFromCache(String.valueOf(m_nId));
1969: } catch (CacheException e) {
1970: throw new EditException(e);
1971: }
1972:
1973: // set everything to its default states
1974: m_nId = NOTDBSAVED_ID;
1975: m_nObjectKey = NOTDBSAVED_KEY;
1976: }
1977:
1978: /* (non-Javadoc)
1979: * @see org.openharmonise.rm.resources.AbstractObject#populateFromResultSetRow(java.sql.ResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
1980: */
1981: protected void populateFromResultSetRow(ResultSet rs,
1982: SelectStatement select) throws PopulateException {
1983:
1984: if (isPopulated() == false) {
1985:
1986: String sTemp = null;
1987: int nTemp = -1;
1988: java.util.Date dTemp = null;
1989: ColumnRef colref = null;
1990:
1991: try {
1992: ColumnRefCache cache = ColumnRefCache.getInstance();
1993:
1994: boolean bIsHist = isHistorical();
1995:
1996: ColumnRef dispNameCol = cache.getColumnRef(this ,
1997: CLMN_DISPLAY_NAME, bIsHist);
1998:
1999: if (select.containsSelectColumn(dispNameCol) == true) {
2000:
2001: sTemp = rs.getString(select
2002: .getResultSetIndex(dispNameCol));
2003:
2004: if ((sTemp != null) && (sTemp.length() > 0)) {
2005: if ((m_sDisplayName == null)
2006: || (m_sDisplayName.length() == 0)) {
2007: m_sDisplayName = sTemp;
2008: } else if (m_sDisplayName.equals(sTemp) == false) {
2009: m_bIsChanged = true;
2010: }
2011: }
2012: }
2013:
2014: colref = cache.getColumnRef(this , CLMN_STATUS, bIsHist);
2015:
2016: if (select.containsSelectColumn(colref) == true) {
2017:
2018: nTemp = rs.getInt(select.getResultSetIndex(colref));
2019:
2020: if (m_status == Status.UNKNOWN) {
2021: m_status = Status.getStatus(nTemp);
2022: } else if (m_status.getIntValue() != nTemp) {
2023: setIsChanged(true);
2024: }
2025:
2026: }
2027:
2028: colref = cache.getColumnRef(this , CLMN_VERSION_NUMBER,
2029: bIsHist);
2030:
2031: if (select.containsSelectColumn(colref) == true) {
2032: nTemp = rs.getInt(select.getResultSetIndex(colref));
2033:
2034: if (nTemp >= 0) {
2035: setVersionNumber(nTemp);
2036: }
2037: }
2038:
2039: colref = cache.getColumnRef(this , CLMN_VERSION_COMMENT,
2040: bIsHist);
2041:
2042: if (select.containsSelectColumn(colref) == true) {
2043: sTemp = rs.getString(select
2044: .getResultSetIndex(colref));
2045:
2046: if ((sTemp != null) && (sTemp.length() > 0)) {
2047: this .setVersionComment(sTemp);
2048: }
2049: }
2050:
2051: colref = cache.getColumnRef(this , CLMN_VERSION_DATE,
2052: bIsHist);
2053:
2054: if (select.containsSelectColumn(colref) == true) {
2055: dTemp = rs.getTimestamp(select
2056: .getResultSetIndex(colref));
2057:
2058: if (dTemp != null) {
2059: this .setVersionDate(dTemp);
2060: }
2061: }
2062:
2063: if (bIsHist == false) {
2064:
2065: colref = cache.getColumnRef(this , TAG_LIVE_VERSION,
2066: bIsHist);
2067:
2068: if (select.containsSelectColumn(colref) == true) {
2069: nTemp = rs.getInt(select
2070: .getResultSetIndex(colref));
2071:
2072: if (nTemp >= 0) {
2073: m_nLiveId = nTemp;
2074: }
2075: }
2076: } else {
2077: m_nLiveId = m_nId;
2078: }
2079:
2080: colref = cache.getColumnRef(this , CLMN_LOCK_USER,
2081: bIsHist);
2082:
2083: if (select.containsSelectColumn(colref) == true) {
2084: nTemp = rs.getInt(select.getResultSetIndex(colref));
2085:
2086: if (nTemp > 0) {
2087: m_nLockUserId = nTemp;
2088: }
2089: }
2090:
2091: if (bIsHist == true) {
2092: colref = cache.getColumnRef(this ,
2093: CLMN_HISTORY_DATE, bIsHist);
2094:
2095: if (select.containsSelectColumn(colref) == true) {
2096: dTemp = rs.getTimestamp(select
2097: .getResultSetIndex(colref));
2098:
2099: if (dTemp != null) {
2100: this .m_dtHistDate = dTemp;
2101: }
2102: }
2103: }
2104: } catch (SQLException eSQL) {
2105: throw new PopulateException("sql error", eSQL);
2106: } catch (CacheException e) {
2107: throw new PopulateException("cache error", e);
2108: }
2109:
2110: super .populateFromResultSetRow(rs, select);
2111:
2112: }
2113:
2114: }
2115:
2116: /**
2117: * Updates data in database.
2118: *
2119: * @throws DataStoreException if any database errors occur
2120: * @throws EditException if any errors occur processing the data
2121: */
2122: protected void update() throws DataStoreException, EditException {
2123:
2124: if (m_logger.isLoggable(Level.INFO)) {
2125: try {
2126: m_logger.logp(Level.INFO, this .getClass().getName(),
2127: "update", "updating object " + getKey());
2128: } catch (DataAccessException e) {
2129: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
2130: }
2131: }
2132:
2133: UpdateStatement update = new UpdateStatement();
2134:
2135: addDataToSave(update);
2136:
2137: update.addWhereCondition(getInstanceColumnRef(ATTRIB_KEY,
2138: isHistorical()), "=", m_nObjectKey);
2139:
2140: m_dsi.execute(update);
2141:
2142: m_bIsChanged = false;
2143:
2144: }
2145:
2146: /**
2147: *
2148: * Adds data to insert statement which will be executed in the
2149: * <code>save()</code> method.
2150: *
2151: * @param insert the insert statement
2152: * @throws DataStoreException if an error occurs
2153: */
2154: protected void addDataToSave(InsertStatement insert)
2155: throws DataStoreException {
2156:
2157: boolean bIsHist = isHistorical();
2158:
2159: insert.addColumnValue(this .getInstanceColumnRef(ATTRIB_ID,
2160: bIsHist), m_nId);
2161: insert.addColumnValue(this .getInstanceColumnRef(ATTRIB_KEY,
2162: bIsHist), m_nObjectKey);
2163: insert.addColumnValue(this .getInstanceColumnRef(
2164: TAG_LIVE_VERSION, bIsHist), m_nLiveId);
2165:
2166: java.util.Date dtNow = new java.util.Date();
2167:
2168: if (bIsHist == false) {
2169: m_dtVersionDate = (java.util.Date) dtNow.clone();
2170:
2171: insert.addColumnValue(getInstanceColumnRef(
2172: CLMN_VERSION_DATE, bIsHist), m_dtVersionDate);
2173: } else {
2174: insert.addColumnValue(getInstanceColumnRef(
2175: CLMN_VERSION_DATE, bIsHist), m_dtVersionDate);
2176: insert.addColumnValue(getInstanceColumnRef(
2177: CLMN_HISTORY_DATE, bIsHist), dtNow);
2178: }
2179:
2180: insert.addColumnValue(getInstanceColumnRef(CLMN_VERSION_NUMBER,
2181: bIsHist), m_nVersionNumber);
2182:
2183: if (m_sVersionComment != null) {
2184: insert.addColumnValue(getInstanceColumnRef(
2185: CLMN_VERSION_COMMENT, bIsHist), m_sVersionComment);
2186: }
2187:
2188: insert.addColumnValue(
2189: getInstanceColumnRef(CLMN_STATUS, bIsHist), m_status
2190: .getIntValue());
2191:
2192: if (m_sName != null) {
2193: insert.addColumnValue(this .getInstanceColumnRef(TAG_NAME,
2194: bIsHist), m_sName);
2195: }
2196:
2197: if (m_sDisplayName != null) {
2198: insert.addColumnValue(this .getInstanceColumnRef(
2199: TAG_DISPLAY_NAME, bIsHist), m_sDisplayName);
2200: }
2201:
2202: if (m_sSummary != null) {
2203: insert.addColumnValue(this .getInstanceColumnRef(
2204: TAG_SUMMARY, bIsHist), m_sSummary);
2205: }
2206:
2207: insert.addColumnValue(this .getInstanceColumnRef(ATTRIB_TYPE,
2208: bIsHist), this .m_sType);
2209: }
2210:
2211: /**
2212: * Updates the database with the new status value and any
2213: * other relavent changes, such as id, key and live id.
2214: *
2215: * @throws PopulateException if an error occurs
2216: */
2217: protected void updateDBStatus() throws PopulateException {
2218:
2219: try {
2220:
2221: UpdateStatement update = new UpdateStatement();
2222:
2223: update.addColumnValue(this .getInstanceColumnRef(TAG_STATUS,
2224: false), m_status.getIntValue());
2225: update.addColumnValue(this .getInstanceColumnRef(ATTRIB_ID,
2226: false), m_nId);
2227: update.addColumnValue(this .getInstanceColumnRef(
2228: TAG_LIVE_VERSION, false), m_nLiveId);
2229: update.addWhereCondition(this .getInstanceColumnRef(
2230: ATTRIB_KEY, false), "=", m_nObjectKey);
2231:
2232: this .m_dsi.execute(update);
2233:
2234: } catch (DataStoreException e) {
2235: throw new PopulateException(e.getLocalizedMessage());
2236: }
2237: }
2238:
2239: /*----------------------------------------------------------------------------
2240: Private Methods
2241: -----------------------------------------------------------------------------*/
2242:
2243: /**
2244: * Sets the status of this object.
2245: *
2246: * @param the status
2247: */
2248: private void setStatus(Status status) {
2249: m_status = status;
2250: }
2251:
2252: /**
2253: * Sets the version number.
2254: *
2255: * @param nVersionNumber The version number
2256: */
2257: private void setVersionNumber(int nVersionNumber) {
2258: m_nVersionNumber = nVersionNumber;
2259: }
2260:
2261: /**
2262: * Sets the version date.
2263: *
2264: * @param nVersionNumber the version date
2265: */
2266: private void setVersionDate(java.util.Date dtDate) {
2267: m_dtVersionDate = dtDate;
2268: }
2269:
2270: /**
2271: * Sets the live version of this resource.
2272: *
2273: * @param liveVersion the live version of this object
2274: */
2275: private void setLiveVersion(AbstractEditableObject liveVersion) {
2276: //ensure live version is indeed the same type
2277: if ((this .getClass().isInstance(liveVersion)) == false) {
2278: throw new IllegalArgumentException();
2279: }
2280:
2281: if (m_nId <= NOTDBSAVED_ID) {
2282: m_nLiveId = liveVersion.getId();
2283: }
2284: }
2285:
2286: /* (non-Javadoc)
2287: * @see org.openharmonise.rm.resources.AbstractObject#isKeySupported()
2288: */
2289: protected boolean isKeySupported() {
2290: return true;
2291: }
2292:
2293: /* (non-Javadoc)
2294: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectLocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2295: */
2296: public void workflowObjectLocked(EditEvent event) {
2297: // nothing to do
2298:
2299: }
2300:
2301: /* (non-Javadoc)
2302: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectReactivated(org.openharmonise.rm.resources.lifecycle.EditEvent)
2303: */
2304: public void workflowObjectReactivated(EditEvent event) {
2305: // nothing to do
2306:
2307: }
2308:
2309: /* (non-Javadoc)
2310: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectSaved(org.openharmonise.rm.resources.lifecycle.EditEvent)
2311: */
2312: public void workflowObjectSaved(EditEvent event) {
2313: // nothing to do
2314:
2315: }
2316:
2317: /* (non-Javadoc)
2318: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectStatusChanged(org.openharmonise.rm.resources.lifecycle.EditEvent)
2319: */
2320: public void workflowObjectStatusChanged(EditEvent event) {
2321: // nothing to do
2322:
2323: }
2324:
2325: /* (non-Javadoc)
2326: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectUnlocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2327: */
2328: public void workflowObjectUnlocked(EditEvent event) {
2329: // nothing to do
2330:
2331: }
2332: }
|