KickJava   Java API By Example, From Geeks To Geeks.

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


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.lang.reflect.InvocationTargetException JavaDoc;
22 import java.sql.*;
23 import java.text.SimpleDateFormat JavaDoc;
24 import java.util.*;
25 import java.util.Date JavaDoc;
26 import java.util.logging.*;
27
28 import org.openharmonise.commons.cache.*;
29 import org.openharmonise.commons.dsi.*;
30 import org.openharmonise.commons.dsi.dml.*;
31 import org.openharmonise.rm.*;
32 import org.openharmonise.rm.commands.InvalidCommandException;
33 import org.openharmonise.rm.dsi.*;
34 import org.openharmonise.rm.factory.*;
35 import org.openharmonise.rm.publishing.*;
36 import org.openharmonise.rm.resources.lifecycle.*;
37 import org.openharmonise.rm.resources.publishing.*;
38 import org.openharmonise.rm.resources.users.User;
39 import org.openharmonise.rm.search.Search;
40 import org.openharmonise.rm.security.authorization.AuthorizationValidator;
41 import org.w3c.dom.*;
42
43
44 /**
45  * Abstract class that provides the necessary functionality for objects
46  * which can be children in a parent-child relationship within Harmonise.
47  *
48  *
49  * @author Michael Bell
50  * @version $Revision: 1.7 $
51  *
52  */

53 public abstract class AbstractChildObject
54     extends AbstractProfiledObject
55     implements Editable, Publishable, DataStoreObject, Cloneable JavaDoc {
56
57     //XML constants
58

59     /**
60      * Name of XML attribute which specifies whether a parent object is the
61      * default parent
62      */

63     public static final String JavaDoc ATTRIB_DEFAULT = "default";
64     
65     /**
66      * Name of XML attribute which determines whether all parent objects
67      * should be published
68      */

69     public static final String JavaDoc ATTRIB_SHOWALL = "showAll";
70     
71     /**
72      * Path tag name
73      */

74     public static final String JavaDoc TAG_PATH = "Path";
75     
76     /**
77      * Group tag name
78      */

79     public static final String JavaDoc TAG_GROUP = "Group";
80
81     //DB constants
82
/**
83      * Relationship table default link column name
84      */

85     protected static final String JavaDoc CLMN_DEFAULT_LINK = "default_link";
86     
87     /**
88      * Relationship table path column name
89      */

90     protected static final String JavaDoc CLMN_PATH = "path";
91     
92     /**
93      * Relationship table parent key column name
94      */

95     protected static final String JavaDoc CLMN_PARENT_KEY = "parent_key";
96     
97     /**
98      * Relationship table child key column name
99      */

100     protected static final String JavaDoc CLMN_CHILD_KEY = "child_key";
101     
102     /**
103      * Relationship table date column name
104      */

105     protected static final String JavaDoc CLMN_DATE = "date";
106     
107     /**
108      * String used for composing relationship table names.
109      *
110      * Note: the pattern for relationship table names is
111      * 'parentObj.getTableName() + JOIN_TO + childObj.getTableName()'
112      */

113     public static final String JavaDoc JOIN_TO = "_2_";
114
115     /**
116      * Archive timestamp format, used in composing archived child names in
117      * the case of a duplicate name
118      */

119     public static final String JavaDoc ARCHIVE_TIMESTAMP_FORMAT = "yyyy-MM-dd_HH-mm";
120
121     /**
122      * Constant value for default attribute when insantiating object
123      * with XML, specifically this value indicates that the parent
124      * object should be added as the default parent
125      */

126     protected static final String JavaDoc IS_DEFAULT_GROUP = "1";
127     
128     /**
129      * Map of child class to parent classes. Used to cache info.
130      */

131     protected static Map m_child_parent_mappings = new Hashtable();
132     
133     /**
134      * <code>Map</code> of parents of this child object
135      */

136     protected Map m_groups = null;
137     
138     /**
139      * The list of parent objects to save on the next <code>save()</code>
140      * operation
141      */

142     protected List m_groups_to_save;
143     
144     /**
145      * The identifier of the default parent
146      */

147     protected int m_defaultGroup = -1;
148     
149     /**
150      * The name of the class that may act as parent to this object
151      */

152     protected String JavaDoc m_sGroupClass = null;
153     
154     /**
155      * The <code>boolean</code> flag which indicates whether this object has
156      * populated it's <code>Map</code> of parents
157      */

158     protected boolean m_bIsGroupsPopulated = false;
159     
160     /**
161      * The path of this object.
162      *
163      * Note: this is only used if the object is historical, otherwise the
164      * path is built on the fly from it's current relationships
165      */

166     protected String JavaDoc m_sPath = null;
167     
168     //separator constant
169
/**
170      * The Harmonise path-separator character
171      */

172     public static final String JavaDoc separator = "/";
173     
174     /**
175      * Logger for this class
176      */

177     private static final Logger m_logger = Logger.getLogger(AbstractChildObject.class.getName());
178
179     //initialiser block
180
{
181         m_sGroupClass = getParentObjectClassName();
182         m_groups = new HashMap();
183         m_groups_to_save = new Vector();
184     }
185
186     /**
187      * Constructs a new or anonymous instance without an interface
188      * to the database.
189      */

190     public AbstractChildObject() {
191         super();
192     }
193
194     /**
195      * Constructor for a new or anonymous instance.
196      *
197      * @param dbintrf the data store interface
198      */

199     public AbstractChildObject(AbstractDataStoreInterface dbintrf) {
200         super(dbintrf);
201     }
202
203     /**
204      * Standard constructor for an existing resource,
205      * registering an <code>AbstractDataStoreInterface</code> to use
206      * with all database communications.
207      *
208      * @param dbintrf the interface to the database
209      * @param nId the id of the object
210      */

211     public AbstractChildObject(AbstractDataStoreInterface dbintrf, int nId) {
212         super(dbintrf, nId);
213     }
214
215     /**
216      * Standard constructor for an existing resource which may be historical.
217      *
218      * @param dbintrf the interface to the database
219      * @param nId the id of the object
220      * @param nKey the unique key of the resource
221      * @param bIsHist <code>true</code> if the object is historical
222      */

223     public AbstractChildObject(
224         AbstractDataStoreInterface dbintrf,
225         int nId,
226         int nKey,
227         boolean bIsHist) {
228         super(dbintrf, nId,nKey, bIsHist);
229     }
230
231     /* (non-Javadoc)
232      * @see org.openharmonise.rm.resources.AbstractObject#markAsNew()
233      */

234     public void markAsNew() throws PopulateException {
235         super.markAsNew();
236         m_groups_to_save = new Vector(m_groups.values());
237     }
238
239     /* (non-Javadoc)
240      * @see java.lang.Object#clone()
241      */

242     public Object JavaDoc clone() {
243         try {
244             if (m_bIsPopulated == false) {
245                 populateFromDatabase();
246             }
247
248             AbstractChildObject other = (AbstractChildObject) super.clone();
249
250             if (m_groups != null) {
251                 other.m_groups = new HashMap(m_groups);
252             }
253
254             return other;
255         } catch (PopulateException e) {
256             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
257
258             return null;
259         }
260     }
261
262     /* (non-Javadoc)
263      * @see org.openharmonise.rm.resources.AbstractObject#clear()
264      */

265     public void clear() {
266         //break ties from group object to this object
267
Collection parent_groups = m_groups.values();
268
269         Iterator iter = parent_groups.iterator();
270
271         while (iter.hasNext() == true) {
272             CachePointer ptr = (CachePointer) iter.next();
273
274             try {
275                 if (this instanceof AbstractParentObject) {
276                     ((AbstractParentObject) ptr.getObject()).clearChildren();
277                 } else {
278                     ((AbstractParentObject) ptr.getObject()).clearChildren();
279                 }
280             } catch (CacheException e) {
281                 throw new IllegalStateException JavaDoc(
282                     "Problem occured getting object from the cache:"
283                         + e.getLocalizedMessage());
284             }
285         }
286
287         super.clear();
288         m_groups.clear();
289         m_groups_to_save.clear();
290         m_defaultGroup = -1;
291         m_bIsGroupsPopulated = false;
292     }
293
294     /**
295      * Returns the 'real' parent of this child object.
296      *
297      * <p>Note: Real can be understood to mean
298      * the default or main parent of this child.</p>
299      *
300      * @return the 'real' parent of this child object.
301      * @throws DataAccessException if an error occurs populating this object
302      * or accessing it's live version
303      */

304     public AbstractParentObject getRealParent() throws DataAccessException {
305         AbstractParentObject defGroup = null;
306
307         if(isLiveVersion() == true || (getLiveVersion() == null && isHistorical() == false)) {
308             
309             if (m_bIsGroupsPopulated == false) {
310     
311                 try {
312                     populateGroupsFromDatabase();
313                 } catch (PopulateException e) {
314                     throw new DataAccessException(
315                         "Error occured accessing parents",e);
316                 }
317             }
318     
319             if(m_defaultGroup > 0) {
320                 CachePointer ptr =
321                             (CachePointer) m_groups.get(String.valueOf(m_defaultGroup));
322     
323                 if (ptr != null) {
324                     try {
325                         defGroup = (AbstractParentObject) ptr.getObject();
326                     } catch (CacheException e) {
327                         throw new DataAccessException(
328                             "Error occured getting parent",e);
329                     }
330                 }
331     
332                 if ((defGroup == null) && (m_groups.size() > 0)) {
333                     defGroup = (AbstractParentObject) getParents().get(0);
334                 }
335             }
336         } else if(isHistorical() == true && getLiveVersion() == null) {
337             
338             //need to account for the fact that the parent collection
339
//itself may be historical so, we drill up to get a live
340
//collection somewhere in the hierarchy and then drill
341
//back down to find the desired collection
342

343             String JavaDoc sTmpPath = m_sPath;
344             Stack pathStack = new Stack();
345             AbstractParentObject tmpParent = null;
346             
347             while(defGroup == null && sTmpPath != null && sTmpPath.length() > 1) {
348                 
349                 if(tmpParent == null) {
350                     try {
351                         tmpParent = (AbstractParentObject) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, getParentObjectClassName(), sTmpPath);
352                     } catch (HarmoniseFactoryException e) {
353                         throw new DataAccessException(e);
354                     }
355                 }
356                 
357                 if(tmpParent == null) {
358                     int nLastSlashIndex = sTmpPath.lastIndexOf(separator);
359                     sTmpPath = sTmpPath.substring(0, nLastSlashIndex);
360                     nLastSlashIndex = sTmpPath.lastIndexOf(separator);
361                     String JavaDoc sName = sTmpPath.substring(nLastSlashIndex + 1,sTmpPath.length());
362                     pathStack.push(sName);
363                 } else if(pathStack.size() == 0) {
364                     defGroup = tmpParent;
365                 } else {
366                     String JavaDoc sName = (String JavaDoc) pathStack.pop();
367                     tmpParent = (AbstractParentObject) tmpParent.getArchivedChildByName(sName);
368                 }
369             }
370             
371         } else {
372             defGroup = ((AbstractChildObject)getLiveVersion()).getRealParent();
373         }
374         
375
376         return defGroup;
377     }
378
379     /**
380      * Returns <code>true</code> if the specified <code>AbstractParentObject</code>
381      * is the 'real' parent of this child object.
382      *
383      * @param obj the parent object
384      * @return <code>true</code> if the specified <code>AbstractParentObject</code>
385      * is the 'real' parent of this child object.
386      * @throws DataAccessException if an error occurs accessing the real parent
387      */

388     public boolean isRealParent(AbstractParentObject obj)
389         throws DataAccessException {
390         boolean isDefault = false;
391         AbstractParentObject defObj = getRealParent();
392
393         if ((defObj != null) && (defObj.getId() == obj.getId())) {
394             isDefault = true;
395         }
396
397         return isDefault;
398     }
399
400     /**
401      * Returns the path string which specifies the default location in the
402      * hierarchy of parent-child relationships of this object.
403      *
404      * @return the path string which specifies the default location
405      * @throws DataAccessException if an error occurs accessing the real
406      * parent
407      */

408     public String JavaDoc getPath() throws DataAccessException {
409         String JavaDoc sPath = null;
410     
411         if (isPopulated() == false) {
412            try {
413                 populateFromDatabase();
414              } catch (PopulateException e) {
415                throw new DataAccessException("Error populating object:", e);
416              }
417         }
418         
419         if (isHistorical() == true) {
420           sPath = m_sPath;
421         } else {
422             AbstractParentObject parent = getRealParent();
423       
424             if (parent != null) {
425                 sPath = parent.getFullPath();
426             }
427         }
428     
429         return sPath;
430     }
431
432     /**
433      * Returns the complete path string, which includes the name of this
434      * object, which specifies the default location in the hierarchy of
435      * parent-child relationships of this object.
436      *
437      * @return the complete path string of this object
438      * @throws DataAccessException if an error occurs getting the main path
439      * information
440      */

441     public String JavaDoc getFullPath() throws DataAccessException {
442         StringBuffer JavaDoc sFullPath = new StringBuffer JavaDoc();
443
444         sFullPath.append(getPath());
445
446         //add seperator if necessary
447
if(sFullPath.length() > 1) {
448             sFullPath.append(separator);
449         }
450         
451         sFullPath.append(getName());
452         
453         return sFullPath.toString();
454     }
455     
456     /**
457      * Returns a list of of all the paths to this child object.
458      *
459      * @return a list of of all the paths to this child object
460      * @throws DataAccessException if an error occurs building any
461      * of the paths
462      */

463     public List getAllPaths() throws DataAccessException {
464         ArrayList paths = new ArrayList();
465         
466         List parents = getParents();
467         
468         if(isHistorical() == false && parents.size() > 0) {
469             Iterator iter = parents.iterator();
470             
471             while (iter.hasNext()) {
472                 AbstractChildObject child = (AbstractChildObject) iter.next();
473                 paths.addAll(child.getAllFullPaths());
474             }
475         } else {
476             paths.add(getPath());
477         }
478         
479         
480         return paths;
481     }
482     
483     /**
484      * Returns a list of all possible full paths for this child.
485      *
486      * @return a list of all possible full paths for this child
487      * @throws DataAccessException if an error occurs building any
488      * of the paths
489      */

490     public List getAllFullPaths() throws DataAccessException {
491         ArrayList paths = new ArrayList();
492         
493         List parents = getParents();
494         
495         if(isHistorical() == false && parents.size() > 0) {
496             Iterator iter = parents.iterator();
497
498             while (iter.hasNext()) {
499                 AbstractChildObject child = (AbstractChildObject) iter.next();
500     
501                 List childPaths = child.getAllFullPaths();
502     
503                 Iterator pathIter = childPaths.iterator();
504     
505                 while (pathIter.hasNext()) {
506                     String JavaDoc path = (String JavaDoc) pathIter.next();
507                     StringBuffer JavaDoc sFullPath = new StringBuffer JavaDoc();
508                     sFullPath.append(path).append(separator).append(m_sName);
509                     paths.add(sFullPath.toString());
510                 }
511             }
512             
513         } else {
514             paths.add(getFullPath());
515         }
516
517         return paths;
518     }
519
520     /**
521      * Returns a list of all this child's parent objects.
522      *
523      * @return a list of all this child's parent objects.
524      * @throws DataAccessException if an error occurs populating the
525      * parent objects
526      */

527     public List getParents() throws DataAccessException {
528         List groups = new Vector();
529         if(isLiveVersion() == true || getLiveVersion() == null) {
530             if (this.m_bIsGroupsPopulated == false) {
531                 try {
532                     this.populateGroupsFromDatabase();
533                 } catch (PopulateException e) {
534                     throw new DataAccessException(e.getLocalizedMessage(),e);
535                 }
536             }
537     
538             Iterator iter = m_groups.values().iterator();
539     
540             while (iter.hasNext()) {
541                 CachePointer ptr = (CachePointer) iter.next();
542     
543                 try {
544                     groups.add(ptr.getObject());
545                 } catch (CacheException e) {
546                     throw new DataAccessException(
547                         "Error occured getting object from cache",e);
548                 }
549             }
550         } else {
551             AbstractChildObject live = (AbstractChildObject)getLiveVersion();
552             
553             if(live != null && live != this) {
554                 groups = live.getParents();
555             }
556             
557         }
558
559         return groups;
560     }
561
562     /* (non-Javadoc)
563      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
564      */

565     public void populate(Element xmlElement, State state)
566         throws PopulateException {
567         String JavaDoc sTagName = xmlElement.getTagName();
568
569         if (sTagName.equals(TAG_GROUP)) {
570             NodeList nodes = xmlElement.getChildNodes();
571
572             for (int i = 0; i < nodes.getLength(); i++) {
573                 if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
574                     Element node = (Element) nodes.item(i);
575
576                     try {
577
578                         AbstractParentObject grpObj =
579                             (
580                                 AbstractParentObject) HarmoniseObjectFactory
581                                     .instantiatePublishableObject(
582                                 this.m_dsi,
583                                 node,
584                                 state);
585                         try{
586                             if(this.isLiveVersion()==false){
587                                 acquireEditWriteLock();
588                                 User user = state.getLoggedInUser();
589                                 if(user == null){
590                                     throw new PopulateException("Unable to process object without without specifying a user");
591                                 }
592                                 try {
593                                     boolean bIsAvailable = AuthorizationValidator.isCommandAvailable(user, (AbstractEditableObject) this, "Save");
594                                     if(bIsAvailable == false){
595                                         throw new PopulateException("Save is not authorised for this object");
596                                     }
597                                 } catch (org.openharmonise.rm.security.authorization.AuthorizationException e) {
598                                     throw new PopulateException("There was an authorisation problem" + this.getClass(),e);
599                                 }
600                                 save();
601                                 releaseEditWriteLock();
602                             }
603                         } catch (Exception JavaDoc e){
604                             throw new PopulateException(
605                                     "There was a problem saving this object",e);
606                         }
607                         if (node.getAttribute(ATTRIB_DEFAULT).equals(IS_DEFAULT_GROUP)) {
608                             AbstractParentObject parent = getRealParent();
609                             if(parent != null){
610                                 parent.acquireEditWriteLock();
611                                 parent.removeChild(this);
612                                 parent.saveNonCoreData();
613                                 parent.releaseEditWriteLock();
614                             }
615                             grpObj.acquireEditWriteLock();
616                             grpObj.addChild(this);
617                             grpObj.saveNonCoreData();
618                             grpObj.releaseEditWriteLock();
619                         } else {
620                             grpObj.acquireEditWriteLock();
621                             grpObj.addChild(this, true);
622                             grpObj.saveNonCoreData();
623                             grpObj.releaseEditWriteLock();
624                         }
625                     } catch (InvalidChildException ig_e) {
626                         throw new PopulateException(
627                             "Invalid child", ig_e);
628                     } catch (HarmoniseFactoryException f_e) {
629                         throw new PopulateException(
630                             "Invalid parent for object",f_e);
631                     } catch (DataAccessException e) {
632                         throw new PopulateException(
633                             "There was a problem populating parent",e);
634                     } catch (EditException e) {
635                         throw new PopulateException(
636                                 "There was a problem editing",e);
637                     }
638                 }
639             }
640         } else {
641             super.populate(xmlElement, state);
642         }
643     }
644
645     /* (non-Javadoc)
646      * @see org.openharmonise.rm.resources.AbstractObject#getColumnRef(java.lang.String, java.lang.String, boolean)
647      */

648     public static ColumnRef getColumnRef(
649         String JavaDoc sClassname,
650         String JavaDoc sColumn,
651         boolean bHist)
652         throws DataStoreException {
653         ColumnRef returnColRef = null;
654         String JavaDoc sTable = getTableName(sClassname,bHist);
655
656         return AbstractChildObject.getObjectColumnRef(sTable, sColumn);
657     }
658     
659     /* (non-Javadoc)
660      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
661      */

662     public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
663         throws DataStoreException {
664         String JavaDoc sDBTable = getTableName(bIsHist);
665
666         if(bIsHist == false && (sColumn.equals(CLMN_PATH) == true || sColumn.equals(TAG_PATH) == true)) {
667             throw new InvalidColumnReferenceException("Path only valid for historical objects");
668         }
669
670         return getObjectColumnRef(sDBTable, sColumn);
671     }
672
673     /* (non-Javadoc)
674      * @see org.openharmonise.rm.resources.AbstractObject#getObjectColumnRef(java.lang.String, java.lang.String)
675      */

676     public static ColumnRef getObjectColumnRef(String JavaDoc sTable, String JavaDoc sColumn)
677         throws DataStoreException {
678         ColumnRef returnColRef = null;
679
680         if (sColumn.equals(ATTRIB_DEFAULT) == true
681             || sColumn.equals(CLMN_DEFAULT_LINK) == true) {
682             returnColRef = new ColumnRef(sTable, CLMN_DEFAULT_LINK, ColumnRef.NUMBER);
683         } else if (
684             sColumn.equals(CLMN_PATH) == true || sColumn.equals(TAG_PATH) == true) {
685             returnColRef = new ColumnRef(sTable, CLMN_PATH, ColumnRef.TEXT);
686         }
687
688         if (returnColRef != null) {
689             return returnColRef;
690         } else {
691             return AbstractEditableObject.getObjectColumnRef(sTable,sColumn);
692         }
693     }
694
695     /* (non-Javadoc)
696      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
697      */

698     public org.w3c.dom.Element JavaDoc publish(
699         Element topEl,
700         HarmoniseOutput xmlDoc,
701         State state)
702         throws PublishException {
703         Element docEl = null;
704         NodeList nodes = null;
705         Text txt = null;
706         String JavaDoc sTagName = topEl.getTagName();
707
708         if (sTagName.equals(TAG_GROUP)) {
709             docEl = xmlDoc.createElement(TAG_GROUP);
710
711             NodeList nlChildren = topEl.getChildNodes();
712             Node nTemp = null;
713
714             for (int j = 0; j < nlChildren.getLength(); j++) {
715                 nTemp = nlChildren.item(j);
716
717                 if (nTemp.getNodeType() != Node.ELEMENT_NODE) {
718                     continue;
719                 } else if (nTemp.getNodeName().equals(Template.TAG_TEMPLATE)) {
720                     if (m_bIsGroupsPopulated == false) {
721                         try {
722
723                             populateGroupsFromDatabase();
724                         } catch (PopulateException pop_e) {
725                             throw new PublishException(
726                                 "Error occured populating parents:"
727                                     + pop_e.getLocalizedMessage());
728                         }
729                     }
730
731                     if (m_groups.isEmpty() == false) {
732                         Template grpTemplate = null;
733                         try {
734                             grpTemplate = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, Template.class.getName(), Integer.parseInt(
735                                     ((Element) nTemp).getAttribute(AbstractObject.ATTRIB_ID)));
736                         } catch (NumberFormatException JavaDoc e) {
737                             throw new PublishException(e);
738                         } catch (HarmoniseFactoryException e) {
739                             throw new PublishException(e);
740                         }
741                         int nPageId = -1;
742
743                         NodeList pageNodes =
744                             ((Element) nTemp).getElementsByTagName(WebPage.TAG_PAGE);
745
746                         if (pageNodes.getLength() > 0) {
747                             nPageId =
748                                 Integer.parseInt(
749                                     ((Element) pageNodes.item(0)).getAttribute(
750                                         AbstractObject.ATTRIB_ID));
751                         }
752
753                         if (grpTemplate == null) {
754                             throw new PublishException("No template supplied.");
755                         }
756
757                         if (topEl.hasAttribute(AbstractChildObject.ATTRIB_SHOWALL)) {
758                             try {
759
760                                 List groups = getParents();
761
762                                 for (int i = 0; i < groups.size(); i++) {
763                                     Publishable pObj = (Publishable) groups.get(i);
764                                     Element grpEl = pObj.publish(grpTemplate, xmlDoc, state);
765
766                                     if (((AbstractObject) pObj).getId() == this.m_defaultGroup) {
767                                         grpEl.setAttribute(
768                                             AbstractChildObject.ATTRIB_DEFAULT,
769                                             "true");
770                                     }
771
772                                     if (nPageId > 0) {
773                                         xmlDoc.addPageIdToLinkNode(
774                                             state.getLoggedInUser(),
775                                             grpEl,
776                                             nPageId);
777                                     }
778
779                                     docEl.appendChild(grpEl);
780                                 }
781                             } catch (DataAccessException da_e) {
782                                 throw new PublishException(
783                                     "Error occured accessing parents:"
784                                         + da_e.getLocalizedMessage());
785                             }
786                         } else {
787                             try {
788
789                                 Element grpEl =
790                                     ((Publishable) getRealParent()).publish(
791                                         grpTemplate,
792                                         xmlDoc,
793                                         state);
794
795                                 if (nPageId > 0) {
796                                     xmlDoc.addPageIdToLinkNode(
797                                         state.getLoggedInUser(),
798                                         grpEl,
799                                         nPageId);
800                                 }
801
802                                 docEl.appendChild(grpEl);
803                             } catch (DataAccessException da_e) {
804                                 throw new PublishException(
805                                     "Error occured getting parent of object:"
806                                         + da_e.getLocalizedMessage());
807                             }
808                         }
809                     }
810                 } else if (nTemp.getNodeName().equals(TAG_AVAILABLEOPTIONS)) {
811                     Element elAvOpt = xmlDoc.createElement(TAG_AVAILABLEOPTIONS);
812
813                     NodeList nlList =
814                         ((Element) nTemp).getElementsByTagName(Search.TAG_LIST);
815
816                     if (nlList.getLength() > 0) {
817                         Element elList = (Element) nlList.item(0);
818                         try {
819
820                             Publishable list =
821                                 HarmoniseObjectFactory.instantiatePublishableObject(
822                                     this.m_dsi,
823                                     elList,
824                                     state);
825
826                             elAvOpt.appendChild(
827                                 ((Search) list).publish(elList, xmlDoc, state));
828                         } catch (HarmoniseFactoryException e) {
829                             throw new PublishException(
830                                 "Error instantiating list:" + e.getLocalizedMessage());
831                         }
832                     } else {
833                         throw new PublishException("No other implementation for available options");
834                     }
835
836                     docEl.appendChild(elAvOpt);
837                 }
838             }
839         } else if (sTagName.equals(TAG_PATH)) {
840             try {
841
842                 docEl = xmlDoc.createElement(TAG_PATH);
843                 txt = xmlDoc.createTextNode(getPath());
844                 docEl.appendChild(txt);
845             } catch (DataAccessException da_e) {
846                 throw new PublishException(
847                     "Error occured getting path:" + da_e.getLocalizedMessage());
848             }
849         } else {
850             // if we don't know about the tag, pass it up
851
docEl = super.publish(topEl, xmlDoc, state);
852         }
853
854         // recurse through the children if there are any
855
Element formEl;
856         Element el;
857
858         if (nodes != null) {
859             for (int i = 0; i < nodes.getLength(); i++) {
860                 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
861                     continue;
862                 }
863
864                 formEl = (Element) nodes.item(i);
865                 el = publish(formEl, xmlDoc, state);
866
867                 if (el != null) {
868                     try {
869                         docEl.appendChild(el);
870                     } catch (org.w3c.dom.DOMException JavaDoc e) {
871                         throw new PublishException(el.getTagName() + ":" + e.getMessage());
872                     }
873                 }
874             }
875         }
876
877         return docEl;
878     }
879
880     /* (non-Javadoc)
881      * @see org.openharmonise.rm.resources.AbstractObject#isChanged()
882      */

883     public boolean isChanged() throws DataAccessException {
884         boolean bReturn = super.isChanged();
885
886         if (m_bIsGroupsPopulated == false && bReturn == false) {
887
888             try {
889                 populateGroupsFromDatabase();
890             } catch (PopulateException e) {
891                 throw new DataAccessException(
892                     "Error occured while populating parents:" + e.getLocalizedMessage());
893             }
894
895             bReturn = (m_groups_to_save.size() > 0);
896         }
897
898         return bReturn;
899     }
900
901     /*----------------------------------------------------------------------------
902     Protected Methods
903     -----------------------------------------------------------------------------*/

904
905     /* (non-Javadoc)
906      * @see org.openharmonise.rm.resources.AbstractEditableObject#delete(boolean)
907      */

908     protected void delete(boolean bDeleteHist)
909         throws DataStoreException, DataAccessException, EditException, PopulateException {
910         //ensure groups are populated
911
if (m_bIsGroupsPopulated == false) {
912             populateGroupsFromDatabase();
913         }
914
915         //loop through groups and remove child from each group
916
Iterator iter = m_groups.values().iterator();
917
918         while (iter.hasNext()) {
919             try {
920                 AbstractParentObject parent = (AbstractParentObject) ((CachePointer)iter.next()).getObject();
921                 
922                 parent.removeChild(this);
923                 
924                 parent.saveNonCoreData();
925             } catch (CacheException e) {
926                 throw new EditException("Error occurred getting object from cache:", e);
927             }
928         }
929
930         super.delete(bDeleteHist);
931     }
932
933     /* (non-Javadoc)
934      * @see org.openharmonise.rm.resources.AbstractEditableObject#saveCoreData()
935      */

936     protected void saveCoreData() throws EditException {
937         
938         updateParents();
939         
940         super.saveCoreData();
941     }
942
943     /* (non-Javadoc)
944      * @see org.openharmonise.rm.resources.AbstractEditableObject#update()
945      */

946     protected void update() throws EditException, DataStoreException {
947         super.update();
948
949         updateParents();
950         
951     }
952
953     /**
954      * Updates all parents if this child object has added itself
955      * to any parent objects, only necessary if <code>populate</code>
956      * has been called.
957      *
958      * @throws EditException if an error occurs adding this child to a parent
959      */

960     protected void updateParents() throws EditException {
961         if (m_groups_to_save.isEmpty() == false) {
962             Iterator iter = m_groups_to_save.iterator();
963
964             while (iter.hasNext()) {
965                 try {
966                     AbstractParentObject parent = (AbstractParentObject)((CachePointer) iter.next()).getObject();
967                     
968                     parent.saveNonCoreData();
969                 } catch (CacheException e) {
970                     throw new EditException("Error occurred getting object from cache:", e);
971                 }
972             }
973
974             m_groups_to_save.clear();
975         }
976     }
977
978     /* (non-Javadoc)
979      * @see org.openharmonise.rm.resources.AbstractObject#fullPopulate()
980      */

981     protected void fullPopulate() throws PopulateException {
982         if (m_bIsGroupsPopulated == false) {
983             populateGroupsFromDatabase();
984         }
985
986         super.fullPopulate();
987     }
988
989     /**
990      * Populates this object's store of parents from database.
991      *
992      * @throws PopulateException if an error occurs populating this object
993      */

994     protected void populateGroupsFromDatabase() throws PopulateException {
995         if (m_bIsPopulated == false) {
996             populateFromDatabase();
997         }
998
999         if (this.m_bIsGroupsPopulated == true) {
1000            return;
1001        }
1002
1003        if (m_groups == null) {
1004            m_groups = new HashMap();
1005        }
1006
1007        if (this.m_nId != AbstractObject.NOTDBSAVED_ID) {
1008            SelectStatement select = new SelectStatement();
1009
1010            ColumnRef typeColref;
1011            ColumnRef idColref;
1012            ColumnRef defaultColref;
1013            try {
1014                idColref =
1015                    AbstractObject.getColumnRef(getParentObjectClassName(), ATTRIB_ID);
1016                defaultColref = getParentChildJoinColumnRef(ATTRIB_DEFAULT);
1017                getInstanceColumnRef(AbstractChildObject.ATTRIB_DEFAULT, false);
1018                typeColref =
1019                    AbstractObject.getColumnRef(getParentObjectClassName(), ATTRIB_TYPE);
1020
1021                select.addSelectColumn(idColref); //1
1022
select.addSelectColumn(defaultColref); //2
1023
select.addSelectColumn(typeColref); //3
1024

1025                Collection coreRefs =
1026                    AbstractParentObject.getCoreColumnRefs(
1027                        this.getParentObjectClassName());
1028                Iterator iter = coreRefs.iterator();
1029
1030                while (iter.hasNext() == true) {
1031                    select.addSelectColumn((ColumnRef) iter.next());
1032                }
1033
1034                // key in the group table
1035
ColumnRef joinColumn1 =
1036                    AbstractObject.getColumnRef(
1037                        getParentObjectClassName(),
1038                        AbstractObject.ATTRIB_KEY);
1039
1040                // key for the group in the join table
1041
ColumnRef joinColumn2 = getParentChildJoinColumnRef(TAG_GROUP);
1042                select.addJoinCondition(joinColumn1, joinColumn2);
1043
1044                ColumnRef whereColumn =
1045                    getParentChildJoinColumnRef(AbstractParentObject.TAG_CHILDREN);
1046
1047                select.addWhereCondition(whereColumn, "=", m_nObjectKey);
1048            } catch (DataStoreException ds_e) {
1049                throw new PopulateException(
1050                    "Error occured building query:",ds_e);
1051            }
1052
1053            ResultSet rs = null;
1054
1055            try {
1056
1057                rs = m_dsi.execute(select);
1058
1059                while (rs.next()) {
1060                    int nId = rs.getInt(idColref.getColumn());
1061
1062                    AbstractParentObject tmpDSO =
1063                        (
1064                            AbstractParentObject) HarmoniseObjectFactory
1065                                .instantiatePublishableObject(
1066                            this.m_dsi,
1067                            rs.getString(typeColref.getColumn()),
1068                            nId);
1069
1070                    addEditEventListener(tmpDSO);
1071
1072                    try {
1073                        CachePointer pointer =
1074                            CacheHandler.getInstance(m_dsi).getCachePointer(tmpDSO);
1075
1076                        if (tmpDSO.isPopulated() == false) {
1077                            tmpDSO.populateFromResultSetRow(rs, select);
1078                        }
1079
1080                        m_groups.put(String.valueOf(nId), pointer);
1081
1082                        if (rs.getBoolean(defaultColref.getColumn()) == true) {
1083                            this.m_defaultGroup = nId;
1084                        }
1085                    } catch (CacheException e1) {
1086                        throw new PopulateException(
1087                            "Had problems getting pointer from cache",e1);
1088                    }
1089                }
1090
1091                m_bIsGroupsPopulated = true;
1092            } catch (SQLException e) {
1093                throw new PopulateException(
1094                    "Error occured processing query",e);
1095            } catch (HarmoniseFactoryException e) {
1096                throw new PopulateException(
1097                    "Error instantiatiing new parent object",e);
1098            } catch (DataStoreException e) {
1099                throw new PopulateException(
1100                    "Error occured processing query",e);
1101            } finally {
1102                if (rs != null) {
1103                    try {
1104                        rs.close();
1105                    } catch (SQLException sql_e) {
1106                        throw new PopulateException(
1107                            "Error occured closing result set",sql_e);
1108                    }
1109                }
1110            }
1111        }
1112    }
1113
1114    /**
1115     * Creates an <code>AbstractParentObject</code> from the specified path.
1116     *
1117     * @param sFullPath the path describing the location of the parent object
1118     * @return the parent object
1119     * @throws EditException if an error occurs creating the object
1120     */

1121    protected AbstractParentObject createGroupFromPath(String JavaDoc sFullPath)
1122        throws EditException {
1123        AbstractParentObject group = null;
1124        ResultSet rs = null;
1125
1126        String JavaDoc sGroupName = sFullPath.substring(sFullPath.lastIndexOf('/') + 1);
1127        String JavaDoc sPath = sFullPath.substring(0, sFullPath.lastIndexOf('/'));
1128
1129        //first try get group from the factory, i.e. from live table
1130
try {
1131            group =
1132                (AbstractParentObject) HarmoniseObjectFactory.instantiateHarmoniseObject(
1133                    m_dsi,
1134                    this.getParentObjectClassName(),
1135                    sFullPath);
1136        } catch (HarmoniseFactoryException e) {
1137            throw new EditException(
1138                "Error occured getting object from factory",e);
1139        }
1140
1141        // if we didn't find it, look in history
1142
if (group == null) {
1143            Class JavaDoc groupClass;
1144            try {
1145                // create an archived version of the group to use to find archived groups
1146
groupClass = Class.forName(getParentObjectClassName());
1147                Class JavaDoc[] paramTypesHistory =
1148                    { AbstractDataStoreInterface.class, boolean.class };
1149                java.lang.reflect.Constructor JavaDoc ctorHistory =
1150                    groupClass.getConstructor(paramTypesHistory);
1151                Object JavaDoc[] paramsHistory = { m_dsi, new Boolean JavaDoc(true)};
1152                AbstractParentObject archivedGroupObject =
1153                    (AbstractParentObject) ctorHistory.newInstance(paramsHistory);
1154
1155                // get all the constructors we need
1156
Class JavaDoc[] paramTypes =
1157                    { AbstractDataStoreInterface.class, int.class, boolean.class };
1158                java.lang.reflect.Constructor JavaDoc ctorExists =
1159                    groupClass.getConstructor(paramTypes);
1160
1161                // find the group in history
1162
SelectStatement select = new SelectStatement();
1163                select.addSelectColumn(
1164                    archivedGroupObject.getInstanceColumnRef(
1165                        AbstractObject.ATTRIB_ID,
1166                        false));
1167                select.addSelectColumn(
1168                    archivedGroupObject.getInstanceColumnRef(
1169                        AbstractObject.ATTRIB_KEY,
1170                        false));
1171                select.addWhereCondition(
1172                    archivedGroupObject.getInstanceColumnRef(CLMN_PATH, false),
1173                    "=",
1174                    sPath);
1175                select.addWhereCondition(
1176                    archivedGroupObject.getInstanceColumnRef(TAG_NAME, false),
1177                    "=",
1178                    sGroupName);
1179
1180                rs = m_dsi.execute(select);
1181
1182                if (rs.next()) {
1183                    Object JavaDoc[] params =
1184                        { m_dsi, new Integer JavaDoc(rs.getInt(1)), new Boolean JavaDoc(true)};
1185                    group = (AbstractParentObject) ctorExists.newInstance(params);
1186                    group.setKey(rs.getInt(2));
1187
1188                    AbstractChildObject reactivated =
1189                        (AbstractChildObject) group.reactivate();
1190
1191                    AbstractParentObject parent = createGroupFromPath(sPath);
1192                    
1193                    parent.acquireEditWriteLock();
1194                    try {
1195                        parent.addChild(reactivated);
1196
1197                        parent.saveNonCoreData();
1198                    } finally {
1199                        parent.releaseEditWriteLock();
1200                    }
1201                }
1202
1203                rs.close();
1204            } catch (SecurityException JavaDoc e1) {
1205                throw new EditException(
1206                    "Security exception",e1);
1207            } catch (IllegalArgumentException JavaDoc e1) {
1208                throw new EditException(
1209                    "IllegalArgumentException",e1);
1210            } catch (InvalidChildException e1) {
1211                throw new EditException(
1212                    "InvalidGroupException",e1);
1213            } catch (PopulateException e1) {
1214                throw new EditException(
1215                    "PopulateException",e1);
1216            } catch (ClassNotFoundException JavaDoc e1) {
1217                throw new EditException(
1218                    "ClassNotFoundException",e1);
1219            } catch (NoSuchMethodException JavaDoc e1) {
1220                throw new EditException(
1221                    "NoSuchMethodException",e1);
1222            } catch (InstantiationException JavaDoc e1) {
1223                throw new EditException(
1224                    "InstantiationException",e1);
1225            } catch (IllegalAccessException JavaDoc e1) {
1226                throw new EditException(
1227                    "IllegalAccessException",e1);
1228            } catch (InvocationTargetException JavaDoc e1) {
1229                throw new EditException(
1230                    "InvocationTargetException",e1);
1231            } catch (DataStoreException e1) {
1232                throw new EditException(
1233                    "DataStoreException",e1);
1234            } catch (SQLException e1) {
1235                throw new EditException("SQLException",e1);
1236            }
1237
1238            // if we still haven't found it, it doesn't exist anywhere,
1239
// create a new one with the same name
1240
if (group == null) {
1241                try {
1242                    Class JavaDoc[] dsiParamTypes = { AbstractDataStoreInterface.class };
1243                    java.lang.reflect.Constructor JavaDoc ctorNew =
1244                        groupClass.getConstructor(dsiParamTypes);
1245                    Object JavaDoc[] params = { m_dsi };
1246                    group = (AbstractParentObject) ctorNew.newInstance(params);
1247
1248                    group.setName(sGroupName);
1249
1250                    // save and approve it
1251
group.save();
1252
1253                    AbstractParentObject parent = createGroupFromPath(sPath);
1254
1255                    parent.acquireEditWriteLock();
1256                    try {
1257                        parent.addChild(group);
1258
1259                        parent.save();
1260                    } finally {
1261                        parent.releaseEditWriteLock();
1262                    }
1263                    
1264                    group.changeStatus(Status.APPROVED);
1265                } catch (SecurityException JavaDoc e2) {
1266                    throw new EditException(
1267                        "Security exception:" + e2.getLocalizedMessage());
1268                } catch (IllegalArgumentException JavaDoc e2) {
1269                    throw new EditException(
1270                        "IllegalArgumentException:" + e2.getLocalizedMessage());
1271                } catch (InvalidChildException e2) {
1272                    throw new EditException(
1273                        "InvalidGroupException:" + e2.getLocalizedMessage());
1274                } catch (PopulateException e2) {
1275                    throw new EditException(
1276                        "PopulateException:" + e2.getLocalizedMessage());
1277                } catch (NoSuchMethodException JavaDoc e2) {
1278                    throw new EditException(
1279                        "NoSuchMethodException:" + e2.getLocalizedMessage());
1280                } catch (InstantiationException JavaDoc e2) {
1281                    throw new EditException(
1282                        "InstantiationException:" + e2.getLocalizedMessage());
1283                } catch (IllegalAccessException JavaDoc e2) {
1284                    throw new EditException(
1285                        "IllegalAccessException:" + e2.getLocalizedMessage());
1286                } catch (InvocationTargetException JavaDoc e2) {
1287                    throw new EditException(
1288                        "InvocationTargetException:" + e2.getLocalizedMessage());
1289                } catch (InvalidNameException e) {
1290                    throw new EditException(
1291                        "InvocationTargetException:" + e.getLocalizedMessage());
1292                }
1293            }
1294        }
1295
1296        return group;
1297    }
1298
1299    /* (non-Javadoc)
1300     * @see org.openharmonise.rm.resources.AbstractEditableObject#addDataToSave(org.openharmonise.commons.dsi.dml.InsertStatement)
1301     */

1302    protected void addDataToSave(InsertStatement insert)
1303        throws DataStoreException {
1304
1305        if (isHistorical() == true) {
1306            try {
1307                insert.addColumnValue(
1308                    this.getInstanceColumnRef(TAG_PATH, true),
1309                    getPath());
1310            } catch (DataAccessException e) {
1311                throw new DataStoreException(
1312                    "Error occured getting path",e);
1313            }
1314        }
1315
1316        super.addDataToSave(insert);
1317    }
1318
1319    /**
1320     * Returns the column reference for a column in the parent-child
1321     * relationship table.
1322     *
1323     * @param sCol the column, tag or attribute name
1324     * @return the corresponding column reference
1325     * @throws DataStoreException if an error occurs getting the column reference
1326     * @throws InvalidColumnReferenceException if the given column name is
1327     * invalid
1328     */

1329    protected ColumnRef getParentChildJoinColumnRef(String JavaDoc sCol)
1330        throws DataStoreException {
1331        ColumnRef colref = null;
1332
1333        String JavaDoc sGroupTableName = null;
1334
1335        sGroupTableName =
1336            DatabaseInfo.getInstance().getTableName(getParentObjectClassName());
1337
1338        StringBuffer JavaDoc sbuf =
1339            new StringBuffer JavaDoc(sGroupTableName).append(JOIN_TO).append(
1340                getDBTableName());
1341
1342        String JavaDoc sTable = sbuf.toString();
1343
1344        if (sCol.equals(CLMN_CHILD_KEY) == true
1345            || sCol.equals(AbstractParentObject.TAG_CHILDREN)) {
1346            colref = new ColumnRef(sTable, CLMN_CHILD_KEY, ColumnRef.NUMBER);
1347        } else if (
1348            sCol.equals(CLMN_PARENT_KEY) == true || sCol.equals(TAG_GROUP) == true) {
1349            colref = new ColumnRef(sTable, CLMN_PARENT_KEY, ColumnRef.NUMBER);
1350        } else if (sCol.equals(CLMN_DATE) == true) {
1351            colref = new ColumnRef(sTable, CLMN_DATE, ColumnRef.DATE);
1352        } else if (
1353            sCol.equals(CLMN_DEFAULT_LINK) == true
1354                || sCol.equals(ATTRIB_DEFAULT) == true) {
1355            colref = new ColumnRef(sTable, CLMN_DEFAULT_LINK, ColumnRef.NUMBER);
1356        }
1357
1358        if (colref == null) {
1359            throw new InvalidColumnReferenceException();
1360        }
1361
1362        return colref;
1363    }
1364
1365    /**
1366     * Adds the specified parent object to this child's list of parents
1367     *
1368     * @param group the new parent object
1369     * @throws PopulateException if there is an erorr populating the list of
1370     * parent objects
1371     */

1372    protected void addParent(AbstractParentObject group)
1373        throws PopulateException {
1374        if (this.m_bIsGroupsPopulated == false) {
1375            populateGroupsFromDatabase();
1376        }
1377        
1378        try {
1379            CachePointer ptr = CacheHandler.getInstance(m_dsi).getCachePointer(group);
1380        
1381
1382            if (m_groups.containsValue(group) == false) {
1383                m_groups.put(String.valueOf(group.getId()), ptr);
1384            }
1385        } catch (CacheException e) {
1386            throw new PopulateException("cache pointer problem",e);
1387        }
1388    }
1389
1390    /**
1391     * Removes the specified parent object from this child's list of parents.
1392     *
1393     * @param group the parent object to remove
1394     * @throws PopulateException if there is an erorr populating the list of
1395     * parent objects
1396     */

1397    protected void removeParent(AbstractParentObject group)
1398        throws PopulateException {
1399        if (this.m_bIsGroupsPopulated == false) {
1400            this.populateGroupsFromDatabase();
1401        }
1402
1403        String JavaDoc sKey = String.valueOf(group.getId());
1404
1405        if (m_groups.containsKey(sKey) == true) {
1406            m_groups.remove(m_groups.get(sKey));
1407        }
1408    }
1409
1410    /**
1411     * Returns the name of the class that may act as parent to this object.
1412     *
1413     * @return the name of the class that may act as parent to this object
1414     */

1415    abstract public String JavaDoc getParentObjectClassName();
1416
1417    /**
1418     * Adds and sets the given parent object as the 'real'/default
1419     * parent of this child object.
1420     *
1421     * @param group the default parent object
1422     * @throws PopulateException if there is an error adding this
1423     * parent object
1424     */

1425    protected void setRealParent(AbstractParentObject group)
1426        throws PopulateException {
1427
1428        int nId = group.getId();
1429        String JavaDoc sId = String.valueOf(nId);
1430
1431        addParent(group);
1432
1433        m_defaultGroup = nId;
1434    }
1435
1436    /* (non-Javadoc)
1437     * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
1438     */

1439    public Editable changeStatus(Status status) throws EditException {
1440        
1441        Editable result = null;
1442        
1443        try {
1444            if(getStatus() == Status.UNAPPROVED && status == Status.APPROVED) {
1445                AbstractChildObject live = (AbstractChildObject) this.getLiveVersion();
1446                
1447                if(live != null) {
1448                    List parents = live.getParents();
1449                    AbstractParentObject realParent = live.getRealParent();
1450                    
1451                    result = super.changeStatus(status);
1452                    
1453                    Iterator iter = parents.iterator();
1454                    
1455                    while (iter.hasNext()) {
1456                        AbstractParentObject tmpParent = (AbstractParentObject) iter.next();
1457                        int nPos = tmpParent.indexOf(live);
1458                        
1459                        tmpParent.acquireEditWriteLock();
1460                        try {
1461                            if(tmpParent.equals(realParent) == true) {
1462                                tmpParent.addChild(nPos,this);
1463                            } else {
1464                                tmpParent.addChild(nPos,this, true);
1465                            }
1466                            
1467                            tmpParent.saveNonCoreData();
1468                        } finally {
1469                            tmpParent.releaseEditWriteLock();
1470                        }
1471                    }
1472                } else {
1473                    result = super.changeStatus(status);
1474                }
1475                
1476            } else {
1477                result = super.changeStatus(status);
1478            }
1479        } catch (DataAccessException e) {
1480            throw new EditException(e.getLocalizedMessage(),e);
1481        } catch (InvalidChildException e) {
1482            throw new EditException(e.getLocalizedMessage(),e);
1483        } catch (PopulateException e) {
1484            throw new EditException(e.getLocalizedMessage(),e);
1485        }
1486        
1487        return result;
1488    }
1489
1490    /* (non-Javadoc)
1491     * @see org.openharmonise.rm.resources.lifecycle.Editable#archive()
1492     */

1493    public Editable archive() throws EditException {
1494        try {
1495            AbstractParentObject parent = getRealParent();
1496            
1497            if(parent != null && parent.getArchivedChildByName(m_sName) != null) {
1498                
1499                Date JavaDoc now = new Date JavaDoc();
1500                SimpleDateFormat JavaDoc format = new SimpleDateFormat JavaDoc(ARCHIVE_TIMESTAMP_FORMAT);
1501                
1502                StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
1503                
1504                sbuf.append(m_sName).append("_").append(format.format(now));
1505                
1506                m_sName = sbuf.toString();
1507            }
1508            
1509                m_sPath = getPath();
1510        } catch (DataAccessException e) {
1511            throw new EditException(e.getLocalizedMessage(),e);
1512        }
1513        
1514        return super.archive();
1515    }
1516
1517    /* (non-Javadoc)
1518     * @see org.openharmonise.rm.resources.AbstractObject#addColumnsToPopulateQuery(org.openharmonise.commons.dsi.dml.SelectStatement, boolean)
1519     */

1520    protected void addColumnsToPopulateQuery(
1521        SelectStatement select,
1522        boolean bIsHist)
1523        throws DataStoreException {
1524        if(isHistorical() == true) {
1525            select.addSelectColumn(getInstanceColumnRef(TAG_PATH, true));
1526        }
1527        super.addColumnsToPopulateQuery(select, bIsHist);
1528    }
1529
1530    /* (non-Javadoc)
1531     * @see org.openharmonise.rm.resources.AbstractObject#populateFromResultSetRow(java.sql.ResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
1532     */

1533    protected void populateFromResultSetRow(
1534        ResultSet rs,
1535        SelectStatement select)
1536        throws PopulateException {
1537        if(isHistorical() == true) {
1538            try {
1539                ColumnRef pathRef = getInstanceColumnRef(TAG_PATH, true);
1540                
1541                if(select.containsSelectColumn(pathRef) == true) {
1542                    m_sPath = rs.getString(select.getResultSetIndex(pathRef));
1543                }
1544            } catch (DataStoreException e) {
1545                throw new PopulateException(e.getLocalizedMessage(),e);
1546            } catch (SQLException e) {
1547                throw new PopulateException(e.getLocalizedMessage(),e);
1548            }
1549        }
1550        super.populateFromResultSetRow(rs, select);
1551    }
1552
1553    /* (non-Javadoc)
1554     * @see org.openharmonise.rm.resources.lifecycle.Editable#reactivate()
1555     */

1556    public Editable reactivate() throws EditException {
1557        
1558        AbstractParentObject parent = null;
1559        
1560        try {
1561            if(getLiveVersion() == null) {
1562                parent = getRealParent();
1563            }
1564        } catch (DataAccessException e) {
1565            throw new EditException(e.getLocalizedMessage(),e);
1566        }
1567        
1568        AbstractChildObject child = (AbstractChildObject) super.reactivate();
1569        
1570        try {
1571            if(parent != null) {
1572                parent.acquireEditWriteLock();
1573                try {
1574                    parent.addChild(child);
1575                    parent.saveNonCoreData();
1576                } finally {
1577                    parent.releaseEditWriteLock();
1578                }
1579            }
1580        } catch (InvalidChildException e) {
1581            throw new EditException(e.getLocalizedMessage(),e);
1582        } catch (PopulateException e) {
1583            throw new EditException(e.getLocalizedMessage(),e);
1584        }
1585        
1586        return child;
1587    }
1588    
1589    /**
1590     * Returns the class name of parent object for the given
1591     * child object of type <i>sChildClassname</i>.
1592     *
1593     * @param sChildClassname the child object class name
1594     * @return the class name of parent object
1595     * @throws DataAccessException if an error occurs
1596     */

1597    static public String JavaDoc getParentObjectClassName(String JavaDoc sChildClassname) throws DataAccessException {
1598        
1599        String JavaDoc sParentClassName = (String JavaDoc) m_child_parent_mappings.get(sChildClassname);
1600        
1601        try {
1602            if(sParentClassName == null) {
1603                Class JavaDoc clss = Class.forName(sChildClassname);
1604                
1605                if(AbstractChildObject.class.isAssignableFrom(clss)) {
1606                    
1607                    AbstractChildObject child =
1608                        (AbstractChildObject)clss.newInstance();
1609                    
1610                    sParentClassName = child.getParentObjectClassName();
1611                    m_child_parent_mappings.put(sChildClassname, sParentClassName);
1612                }
1613            }
1614        } catch (InstantiationException JavaDoc e) {
1615            throw new DataAccessException(e);
1616        } catch (IllegalAccessException JavaDoc e) {
1617            throw new DataAccessException(e);
1618        } catch (ClassNotFoundException JavaDoc e) {
1619            throw new DataAccessException(e);
1620        }
1621        
1622        return sParentClassName;
1623    }
1624
1625}
Popular Tags