Source Code Cross Referenced for AbstractParentObject.java in  » Content-Management-System » harmonise » org » openharmonise » rm » resources » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » harmonise » org.openharmonise.rm.resources 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.rm.*;
0029:        import org.openharmonise.rm.dsi.*;
0030:        import org.openharmonise.rm.factory.*;
0031:        import org.openharmonise.rm.publishing.*;
0032:        import org.openharmonise.rm.resources.lifecycle.*;
0033:        import org.openharmonise.rm.resources.publishing.*;
0034:        import org.openharmonise.rm.search.Search;
0035:        import org.w3c.dom.*;
0036:
0037:        /**
0038:         * Abstract class that provides the necessary functionality for objects
0039:         * which can be parents in a parent-child relationship within Harmonise.
0040:         * Children are indexed so that the order of children can be managed.
0041:         * 
0042:         * @author Michael Bell
0043:         * @version $Revision: 1.6.2.1 $
0044:         */
0045:        public abstract class AbstractParentObject extends AbstractChildObject
0046:                implements  Editable, Publishable, DataStoreObject, Cloneable,
0047:                EditEventListener {
0048:
0049:            //DB constant
0050:            /**
0051:             * Relationship table position column name
0052:             */
0053:            private static final String CLMN_POSITION = "pos";
0054:
0055:            //Constants used for accessing children by type
0056:            /**
0057:             * Constant for branch node type
0058:             */
0059:            public static final int BRANCH_NODES = 1;
0060:
0061:            /**
0062:             * Constant for all node types
0063:             */
0064:            public static final int LEAF_NODES = 2;
0065:
0066:            /**
0067:             * Constant for leaf node types
0068:             */
0069:            public static final int ALL_NODES = 3;
0070:
0071:            //XML constants
0072:            /**
0073:             * Children tag name
0074:             */
0075:            public static final String TAG_CHILDREN = "Children";
0076:
0077:            /**
0078:             * Contents tag name
0079:             */
0080:            public static final String TAG_CONTENTS = "Contents";
0081:
0082:            /**
0083:             * Sub-groups tag name
0084:             */
0085:            public static final String TAG_SUBGROUPS = "SubGroups";
0086:
0087:            /**
0088:             * Attach tag name
0089:             */
0090:            public static final String TAG_ATTACH = "Attach";
0091:
0092:            /**
0093:             * Detach tag name
0094:             */
0095:            public final String TAG_DETACH = "Detach";
0096:
0097:            //Member variables
0098:            /**
0099:             * List of <code>OrderableCachePointer</code> objects 
0100:             * referencing the children of this object
0101:             */
0102:            protected List m_children = null;
0103:
0104:            /**
0105:             * The maximum value of index for children of this object
0106:             */
0107:            protected int m_nMaxIndex = -1;
0108:
0109:            /**
0110:             * List of <code>OrderableCachePointer</code> objects 
0111:             * referencing the children to be added on the 
0112:             * next <code>save()</code> operation
0113:             */
0114:            protected List m_add_children = null;
0115:
0116:            /**
0117:             * List of <code>OrderableCachePointer</code> objects 
0118:             * referencing the children to be removed on the next 
0119:             * <code>save()</code> operation
0120:             */
0121:            protected List m_remove_children = null;
0122:
0123:            /**
0124:             * List of ids of children of those to be added for which this object is the 'real' parent
0125:             */
0126:            protected List m_add_real_children = null;
0127:
0128:            /**
0129:             * List of ids of children of this object for which this object is the 'real' parent
0130:             */
0131:            protected List m_real_children = null;
0132:
0133:            /**
0134:             * <code>boolean</code> flag which indicates whether the list of 
0135:             * children of this object has been populated
0136:             */
0137:            protected boolean m_bIsChildrenPopulated = false;
0138:
0139:            /**
0140:             * List of archived children
0141:             */
0142:            protected List m_archivedChildren = null;
0143:
0144:            /**
0145:             * List of archived descendants
0146:             */
0147:            protected List m_allArchivedChildren = null;
0148:
0149:            /**
0150:             * <code>boolean</code> flag which indicates whether the list of 
0151:             * children of this object is to be changed on the next 
0152:             * <code>save()</code> operation
0153:             */
0154:            protected boolean m_bIsContentsChanged = false;
0155:
0156:            /**
0157:             * <code>boolean</code> flag which indicates whether the list of
0158:             * archived children has been populated
0159:             */
0160:            protected boolean m_bIsArchivedChildrenPopulated = false;
0161:
0162:            /**
0163:             * <code>boolean</code> flag which indicates whether the list
0164:             * of all archived descendants has been populated
0165:             */
0166:            protected boolean m_bIsAllArchivedChildrenPopulated = false;
0167:
0168:            /**
0169:             * Logger for this class
0170:             */
0171:            private static Logger m_logger = Logger
0172:                    .getLogger(AbstractParentObject.class.getName());
0173:
0174:            //initialiser block
0175:            {
0176:                m_children = new Vector();
0177:                m_add_children = new Vector();
0178:                m_remove_children = new Vector();
0179:                m_add_real_children = new Vector();
0180:                m_real_children = new Vector();
0181:                m_archivedChildren = new Vector();
0182:                m_allArchivedChildren = new Vector();
0183:            }
0184:
0185:            /** 
0186:             * Constructs a new or anonymous instance without an interface
0187:             * to the database.
0188:             */
0189:            public AbstractParentObject() {
0190:                super ();
0191:            }
0192:
0193:            /** 
0194:             * Constructor for a new or anonymous instance.
0195:             *
0196:             * @param dbintrf the data store interface
0197:             */
0198:            public AbstractParentObject(AbstractDataStoreInterface dbintrf) {
0199:                super (dbintrf);
0200:            }
0201:
0202:            /**
0203:             * Constructs an existing resource which may be historical.
0204:             * 
0205:             * @param dbintrf the interface to the database
0206:             * @param nId the id of the resource
0207:             * @param nKey the unique key of the resource
0208:             * @param bIsHist <code>true</code> if the resource is historical
0209:             */
0210:            public AbstractParentObject(AbstractDataStoreInterface dbintrf,
0211:                    int nId, int nKey, boolean bIsHist) {
0212:                super (dbintrf, nId, nKey, bIsHist);
0213:            }
0214:
0215:            /** 
0216:             * Standard constructor for an existing resource,
0217:             * registering an <code>AbstractDataStoreInterface</code> to use 
0218:             * with all database communications.
0219:             *
0220:             * @param dbintrf the interface to the database
0221:             * @param nId the id of the resource
0222:             */
0223:            public AbstractParentObject(AbstractDataStoreInterface dbintrf,
0224:                    int nId) {
0225:                super (dbintrf, nId);
0226:            }
0227:
0228:            /* (non-Javadoc)
0229:             * @see org.openharmonise.rm.resources.AbstractChildObject#getPath()
0230:             */
0231:            public String getPath() throws DataAccessException {
0232:                String sPath = null;
0233:
0234:                AbstractParentObject parent = getRealParent();
0235:
0236:                //if it has no real parent return the root slash
0237:                if (parent == null) {
0238:                    sPath = separator;
0239:                } else {
0240:                    sPath = super .getPath();
0241:                }
0242:
0243:                return sPath;
0244:            }
0245:
0246:            /* (non-Javadoc)
0247:             * @see org.openharmonise.rm.resources.AbstractObject#markAsNew()
0248:             */
0249:            public void markAsNew() throws PopulateException {
0250:                super .markAsNew();
0251:                m_bIsContentsChanged = false;
0252:
0253:                clearChildren();
0254:                clearArchivedChildren();
0255:            }
0256:
0257:            /* (non-Javadoc)
0258:             * @see java.lang.Object#clone()
0259:             */
0260:            public Object clone() {
0261:                AbstractParentObject other = null;
0262:
0263:                try {
0264:                    if (m_bIsChildrenPopulated == false) {
0265:                        populateChildrenFromDatabase();
0266:                    }
0267:
0268:                    other = (AbstractParentObject) super .clone();
0269:
0270:                    //the Lists below are cloned in the 'set' methods
0271:                    if (m_children != null) {
0272:                        other.setChildren(m_children);
0273:                    }
0274:
0275:                } catch (InvalidChildException e) {
0276:                    throw new IllegalStateException(
0277:                            "Problem occured adding child to clone:"
0278:                                    + e.getLocalizedMessage());
0279:                } catch (PopulateException e) {
0280:                    throw new IllegalStateException(
0281:                            "Problem occured populating:"
0282:                                    + e.getLocalizedMessage());
0283:                }
0284:
0285:                return other;
0286:            }
0287:
0288:            /**
0289:             * Clears all stored lists of children.
0290:             *
0291:             */
0292:            public void clearChildren() {
0293:                m_bIsChildrenPopulated = false;
0294:                m_children = null;
0295:                m_real_children = null;
0296:            }
0297:
0298:            /* (non-Javadoc)
0299:             * @see org.openharmonise.rm.resources.AbstractObject#clear()
0300:             */
0301:            public void clear() {
0302:                super .clear();
0303:                m_bIsContentsChanged = false;
0304:
0305:                clearChildren();
0306:                clearArchivedChildren();
0307:            }
0308:
0309:            /* (non-Javadoc)
0310:             * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
0311:             */
0312:            public org.w3c.dom.Element publish(Element topEl,
0313:                    HarmoniseOutput xmlDoc, State state)
0314:                    throws PublishException {
0315:                Element docEl = null;
0316:                NodeList nodes = null;
0317:                Text txt = null;
0318:                String sTagName = topEl.getTagName();
0319:
0320:                if (sTagName.equals(TAG_CONTENTS)) {
0321:                    docEl = xmlDoc.createElement(TAG_CONTENTS);
0322:                    nodes = topEl.getChildNodes();
0323:                } else if (sTagName.equals(TAG_SUBGROUPS)) {
0324:                    docEl = xmlDoc.createElement(TAG_SUBGROUPS);
0325:
0326:                    NodeList nlChildren = topEl.getChildNodes();
0327:                    Node nTemp = null;
0328:
0329:                    for (int j = 0; j < nlChildren.getLength(); j++) {
0330:                        nTemp = nlChildren.item(j);
0331:
0332:                        if (nTemp.getNodeType() != Node.ELEMENT_NODE) {
0333:                            continue;
0334:                        } else if (nTemp.getNodeName().equals(
0335:                                Template.TAG_TEMPLATE)) {
0336:                            List subGroups = null;
0337:                            try {
0338:                                subGroups = this 
0339:                                        .getChildrenByType(BRANCH_NODES);
0340:                            } catch (DataAccessException e) {
0341:                                throw new PublishException(
0342:                                        "Error occured getting branch children",
0343:                                        e);
0344:                            }
0345:
0346:                            int nPageId = -1;
0347:
0348:                            NodeList pageNodes = ((Element) nTemp)
0349:                                    .getElementsByTagName(WebPage.TAG_PAGE);
0350:
0351:                            if (pageNodes.getLength() > 0) {
0352:                                nPageId = Integer
0353:                                        .parseInt(((Element) pageNodes.item(0))
0354:                                                .getAttribute(AbstractObject.ATTRIB_ID));
0355:                            }
0356:
0357:                            if (subGroups.size() > 0) {
0358:                                Template grpTemplate = null;
0359:                                try {
0360:                                    grpTemplate = (Template) HarmoniseObjectFactory
0361:                                            .instantiateHarmoniseObject(
0362:                                                    m_dsi,
0363:                                                    Template.class.getName(),
0364:                                                    Integer
0365:                                                            .parseInt(((Element) nTemp)
0366:                                                                    .getAttribute(AbstractObject.ATTRIB_ID)));
0367:                                } catch (NumberFormatException e) {
0368:                                    throw new PublishException(e);
0369:                                } catch (HarmoniseFactoryException e) {
0370:                                    throw new PublishException(e);
0371:                                }
0372:
0373:                                if (grpTemplate == null) {
0374:                                    throw new PublishException(
0375:                                            "No template supplied.");
0376:                                }
0377:
0378:                                String sSubClassName = null;
0379:
0380:                                NodeList tmpNL = nTemp.getChildNodes();
0381:
0382:                                if (tmpNL.getLength() > 0) {
0383:                                    boolean bFound = false;
0384:                                    int k = 0;
0385:
0386:                                    while ((bFound == false)
0387:                                            && (k < tmpNL.getLength())) {
0388:                                        if (tmpNL.item(k).getNodeType() == Node.ELEMENT_NODE) {
0389:                                            Element tmpEl = (Element) tmpNL
0390:                                                    .item(k);
0391:
0392:                                            if (tmpEl.getTagName().equals(
0393:                                                    WebPage.TAG_PAGE) == false) {
0394:                                                bFound = true;
0395:                                                try {
0396:                                                    sSubClassName = HarmoniseObjectFactory
0397:                                                            .getClassName(
0398:                                                                    this .m_dsi,
0399:                                                                    tmpEl);
0400:                                                } catch (HarmoniseFactoryException e) {
0401:                                                    throw new PublishException(
0402:                                                            "Error occured getting data from factory",
0403:                                                            e);
0404:                                                }
0405:                                            }
0406:                                        }
0407:
0408:                                        k++;
0409:                                    }
0410:                                }
0411:
0412:                                if (sSubClassName == null) {
0413:                                    try {
0414:                                        sSubClassName = HarmoniseObjectFactory
0415:                                                .getClassName(
0416:                                                        this .m_dsi,
0417:                                                        grpTemplate
0418:                                                                .getTemplateRootElement());
0419:                                    } catch (HarmoniseFactoryException e) {
0420:                                        throw new PublishException(
0421:                                                "Error occured getting data from factory",
0422:                                                e);
0423:                                    } catch (DataAccessException e) {
0424:                                        throw new PublishException(
0425:                                                "Error occured getting data from Template",
0426:                                                e);
0427:                                    }
0428:                                }
0429:
0430:                                try {
0431:                                    Class objClass = Class
0432:                                            .forName(sSubClassName);
0433:
0434:                                    List matchedSubs = getChildrenByClass(objClass);
0435:
0436:                                    Iterator iter = matchedSubs.iterator();
0437:
0438:                                    while (iter.hasNext()) {
0439:                                        Publishable pObj = (Publishable) iter
0440:                                                .next();
0441:
0442:                                        boolean bPublishable = true;
0443:
0444:                                        PublishFilter filter = state
0445:                                                .getPublishFilter();
0446:                                        if (filter != null) {
0447:
0448:                                            bPublishable = filter.allowPublish(
0449:                                                    this , pObj);
0450:                                        }
0451:
0452:                                        if (bPublishable == true) {
0453:
0454:                                            Element grpEl = pObj.publish(
0455:                                                    grpTemplate, xmlDoc, state);
0456:
0457:                                            if (nPageId > 0) {
0458:                                                xmlDoc
0459:                                                        .addPageIdToLinkNode(
0460:                                                                state
0461:                                                                        .getLoggedInUser(),
0462:                                                                grpEl, nPageId);
0463:                                            }
0464:
0465:                                            docEl.appendChild(grpEl);
0466:                                        }
0467:                                    }
0468:                                } catch (DataAccessException e) {
0469:                                    throw new PublishException(
0470:                                            "Error occured getting data from Template",
0471:                                            e);
0472:                                } catch (DOMException e) {
0473:                                    throw new PublishException(
0474:                                            "DOMException occured", e);
0475:                                } catch (ClassNotFoundException e) {
0476:                                    throw new PublishException(
0477:                                            "Class not found", e);
0478:                                }
0479:                            }
0480:                        }
0481:                    }
0482:                } else if (sTagName.equals(TAG_CHILDREN)) {
0483:                    docEl = xmlDoc.createElement(TAG_CHILDREN);
0484:
0485:                    NodeList nlChildren = topEl.getChildNodes();
0486:                    Node nTemp = null;
0487:                    boolean bHistorical = false;
0488:                    String sHistorical = topEl.getAttribute(ATTRIB_HISTORICAL);
0489:
0490:                    if (sHistorical != null) {
0491:                        if (sHistorical.equals("1")) {
0492:                            bHistorical = true;
0493:                        }
0494:                    }
0495:
0496:                    for (int j = 0; j < nlChildren.getLength(); j++) {
0497:                        nTemp = nlChildren.item(j);
0498:
0499:                        if (nTemp.getNodeType() != Node.ELEMENT_NODE) {
0500:                            continue;
0501:                        } else if (nTemp.getNodeName().equals(
0502:                                Template.TAG_TEMPLATE)) {
0503:                            List children = null;
0504:
0505:                            try {
0506:                                if (bHistorical) {
0507:                                    children = this 
0508:                                            .getArchivedChildrenByType(LEAF_NODES);
0509:                                } else {
0510:                                    children = this 
0511:                                            .getChildrenByType(LEAF_NODES);
0512:                                }
0513:                            } catch (DataAccessException e) {
0514:                                throw new PublishException(
0515:                                        "Error occured accessing children", e);
0516:                            }
0517:
0518:                            if (children.size() > 0) {
0519:                                Template template = null;
0520:                                try {
0521:                                    template = (Template) HarmoniseObjectFactory
0522:                                            .instantiateHarmoniseObject(
0523:                                                    m_dsi,
0524:                                                    Template.class.getName(),
0525:                                                    Integer
0526:                                                            .parseInt(((Element) nTemp)
0527:                                                                    .getAttribute(AbstractObject.ATTRIB_ID)));
0528:                                } catch (NumberFormatException e) {
0529:                                    throw new PublishException(e);
0530:                                } catch (HarmoniseFactoryException e) {
0531:                                    throw new PublishException(e);
0532:                                }
0533:
0534:                                int nPageId = -1;
0535:
0536:                                NodeList pageNodes = ((Element) nTemp)
0537:                                        .getElementsByTagName(WebPage.TAG_PAGE);
0538:
0539:                                if (pageNodes.getLength() > 0) {
0540:                                    nPageId = Integer
0541:                                            .parseInt(((Element) pageNodes
0542:                                                    .item(0))
0543:                                                    .getAttribute(AbstractObject.ATTRIB_ID));
0544:                                }
0545:
0546:                                if (template == null) {
0547:                                    throw new PublishException(
0548:                                            "No template supplied.");
0549:                                }
0550:
0551:                                Iterator iter = children.iterator();
0552:                                while (iter.hasNext()) {
0553:                                    Publishable pObj = (Publishable) iter
0554:                                            .next();
0555:                                    Element chldEl = pObj.publish(template,
0556:                                            xmlDoc, state);
0557:
0558:                                    if (nPageId > 0) {
0559:                                        xmlDoc.addPageIdToLinkNode(state
0560:                                                .getLoggedInUser(), chldEl,
0561:                                                nPageId);
0562:                                    }
0563:
0564:                                    docEl.appendChild(chldEl);
0565:                                }
0566:                            }
0567:                        }
0568:                    }
0569:                } else if (sTagName.equals(Search.TAG_LIST)) {
0570:                    Search searchObj;
0571:                    try {
0572:                        searchObj = (Search) HarmoniseObjectFactory
0573:                                .instantiatePublishableObject(m_dsi, topEl,
0574:                                        state);
0575:                        searchObj.addConditionGroup(this );
0576:
0577:                        docEl = searchObj.publish(topEl, xmlDoc, state);
0578:                    } catch (HarmoniseFactoryException e) {
0579:                        throw new PublishException(
0580:                                "Error occured processing List element", e);
0581:                    }
0582:
0583:                } else {
0584:                    // if we don't know about the tag, pass it up
0585:                    docEl = super .publish(topEl, xmlDoc, state);
0586:                }
0587:
0588:                // recurse through the children if there are any
0589:                Element formEl;
0590:                Element el;
0591:
0592:                if (nodes != null) {
0593:                    for (int i = 0; i < nodes.getLength(); i++) {
0594:                        if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
0595:                            continue;
0596:                        }
0597:
0598:                        formEl = (Element) nodes.item(i);
0599:                        el = publish(formEl, xmlDoc, state);
0600:
0601:                        if (el != null) {
0602:                            try {
0603:                                docEl.appendChild(el);
0604:                            } catch (org.w3c.dom.DOMException e) {
0605:                                throw new PublishException(el.getTagName()
0606:                                        + ":" + e.getMessage());
0607:                            }
0608:                        }
0609:                    }
0610:                }
0611:
0612:                return docEl;
0613:            }
0614:
0615:            /* (non-Javadoc)
0616:             * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
0617:             */
0618:            public void populate(Element xmlElement, State state)
0619:                    throws PopulateException {
0620:                Element formEl = xmlElement;
0621:                String sTagName = formEl.getTagName();
0622:                int nId = -1;
0623:
0624:                if (sTagName.equals(TAG_CHILDREN)) {
0625:                    String sIdTemp = "";
0626:                    String sDefault = "";
0627:                    boolean bDefault = false;
0628:
0629:                    NodeList nlAttach = formEl.getElementsByTagName(TAG_ATTACH);
0630:
0631:                    if (nlAttach.getLength() > 0) {
0632:                        NodeList nlAttachObjects = ((Element) nlAttach.item(0))
0633:                                .getChildNodes();
0634:
0635:                        for (int j = 0; j < nlAttachObjects.getLength(); j++) {
0636:                            if (nlAttachObjects.item(j).getNodeType() != Node.ELEMENT_NODE) {
0637:                                continue;
0638:                            }
0639:
0640:                            sIdTemp = ((Element) nlAttachObjects.item(j))
0641:                                    .getAttribute(ATTRIB_ID);
0642:                            sDefault = ((Element) nlAttachObjects.item(j))
0643:                                    .getAttribute(ATTRIB_DEFAULT);
0644:
0645:                            if (!sIdTemp.equals("XXXX")) {
0646:
0647:                                if ((sDefault != null) && sDefault.equals("1")) {
0648:                                    bDefault = true;
0649:                                } else {
0650:                                    bDefault = false;
0651:                                }
0652:
0653:                                try {
0654:                                    addChild(
0655:                                            (AbstractChildObject) this 
0656:                                                    .getObjectFromFactory((Element) nlAttachObjects
0657:                                                            .item(j)), bDefault);
0658:                                } catch (InvalidChildException e) {
0659:                                    throw new PopulateException(
0660:                                            "Invalid child:"
0661:                                                    + e.getLocalizedMessage());
0662:                                } catch (HarmoniseFactoryException e) {
0663:                                    throw new PopulateException(
0664:                                            "Invalid child:"
0665:                                                    + e.getLocalizedMessage());
0666:                                }
0667:                            }
0668:                        }
0669:                    }
0670:
0671:                    NodeList nlDetach = formEl.getElementsByTagName(TAG_DETACH);
0672:
0673:                    if (nlDetach.getLength() > 0) {
0674:                        NodeList nlDetachObjects = ((Element) nlDetach.item(0))
0675:                                .getChildNodes();
0676:
0677:                        for (int j = 0; j < nlDetachObjects.getLength(); j++) {
0678:                            if (nlDetachObjects.item(j).getNodeType() != Node.ELEMENT_NODE) {
0679:                                continue;
0680:                            }
0681:
0682:                            sIdTemp = ((Element) nlDetachObjects.item(j))
0683:                                    .getAttribute(ATTRIB_ID);
0684:
0685:                            if (!sIdTemp.equals("XXXX")) {
0686:
0687:                                try {
0688:                                    removeChild((AbstractChildObject) this 
0689:                                            .getObjectFromFactory((Element) nlDetachObjects
0690:                                                    .item(j)));
0691:                                } catch (HarmoniseFactoryException e) {
0692:                                    throw new PopulateException(
0693:                                            "Error occured removing child from parent",
0694:                                            e);
0695:                                }
0696:                            }
0697:                        }
0698:                    }
0699:                } else {
0700:                    super .populate(formEl, state);
0701:                }
0702:            }
0703:
0704:            /**
0705:             * Adds the specified object as a child to this parent.
0706:             * 
0707:             * @param obj the child to be added
0708:             * @throws InvalidChildException if the child is an invalid child for this parent
0709:             * @throws PopulateException if there is an error populating the children of this object
0710:             */
0711:            public void addChild(AbstractChildObject obj)
0712:                    throws InvalidChildException, PopulateException {
0713:                addChild(-1, obj, false);
0714:            }
0715:
0716:            /**
0717:             * Inserts the specified child object at the specified position 
0718:             * in the list of children. Shifts the object currently at that 
0719:             * position (if any) and any subsequent objects to the 
0720:             * right (adds one to their indices). 
0721:             * 
0722:             * @param nIndex the desired index for the specified child
0723:             * @param obj the child to be added
0724:             * @throws InvalidChildException if the child is an invalid child for this parent
0725:             * @throws PopulateException if there is an error populating the children of this object
0726:             */
0727:            public void addChild(int nIndex, AbstractChildObject obj)
0728:                    throws InvalidChildException, PopulateException {
0729:                addChild(nIndex, obj, false);
0730:            }
0731:
0732:            /**
0733:             * Adds the specified object as a child to this parent. If 
0734:             * <code>bIsSoftLink</code> is true then the relationship is 
0735:             * weak, meaning this group is not the main group of the
0736:             * child.
0737:             * 
0738:             * @param obj the new child
0739:             * @param bIsSoftLink <code>true</code> if the relationship is weak
0740:             * @throws InvalidChildException if the new child is invalid
0741:             * @throws PopulateException  if there is an error populating the children of this object
0742:             */
0743:            public void addChild(AbstractChildObject obj, boolean bIsSoftLink)
0744:                    throws InvalidChildException, PopulateException {
0745:                addChild(-1, obj, bIsSoftLink);
0746:            }
0747:
0748:            /**
0749:             * Inserts the specified child object at the specified position 
0750:             * in the list of children. Shifts the object currently at that 
0751:             * position (if any) and any subsequent objects to the 
0752:             * right (adds one to their indices). The <code>boolean</code>
0753:             * value <code>bIsSoftLink</code> determines whether this parent
0754:             * is the default parent of the child, i.e. a value of <code>true</code>
0755:             * specifies a weak relationship and therefore the parent
0756:             * is not the default parent of the child.
0757:             * 
0758:             * @param nIndex the index of the new child
0759:             * @param obj the new child
0760:             * @param bIsSoftLink <code>true</code> if the relationship is weak
0761:             * @throws InvalidChildException if the new child is invalid
0762:             * @throws PopulateException  if there is an error populating the children of this object
0763:             */
0764:            public void addChild(int nIndex, AbstractChildObject obj,
0765:                    boolean bIsSoftLink) throws InvalidChildException,
0766:                    PopulateException {
0767:
0768:                try {
0769:                    if (isLiveVersion() == false) {
0770:                        throw new InvalidChildException(
0771:                                "Can't add child to non-live parent");
0772:                    }
0773:                } catch (DataAccessException e) {
0774:                    throw new PopulateException(e);
0775:                }
0776:
0777:                if (m_logger.isLoggable(Level.INFO)) {
0778:                    try {
0779:                        m_logger.logp(Level.INFO, this .getClass().getName(),
0780:                                "addChild", "Adding child (id - " + obj.getId()
0781:                                        + ",key - " + obj.getKey()
0782:                                        + ") to parent (id - " + m_nId
0783:                                        + ",key - " + m_nObjectKey + ")");
0784:                    } catch (DataAccessException e) {
0785:                        m_logger.log(Level.WARNING, "Trouble logging addChild",
0786:                                e);
0787:                    }
0788:                }
0789:
0790:                //initialise lists
0791:                if (m_add_children == null) {
0792:                    m_add_children = new Vector();
0793:                    m_add_real_children = new Vector();
0794:                }
0795:
0796:                //check for validity
0797:                if (obj == null) {
0798:                    if (m_logger.isLoggable(Level.INFO)) {
0799:                        m_logger.logp(Level.INFO, this .getClass().getName(),
0800:                                "addChild", "attempt to add null child");
0801:                    }
0802:                    throw new InvalidChildException("Null object");
0803:                }
0804:
0805:                if (isValidChild(obj) == false) {
0806:
0807:                    throw new InvalidChildException(this .getClass().getName()
0808:                            + " can't have " + obj.getClass().getName()
0809:                            + " descendent");
0810:
0811:                }
0812:
0813:                if (obj.getId() <= 0) {
0814:                    if (m_logger.isLoggable(Level.INFO)) {
0815:                        m_logger.logp(Level.INFO, this .getClass().getName(),
0816:                                "addChild", "Object has invalid id");
0817:                    }
0818:                    throw new InvalidChildException("Object has invalid id");
0819:                }
0820:
0821:                //populate lists if necessary
0822:                if (m_bIsChildrenPopulated == false) {
0823:                    populateChildrenFromDatabase();
0824:                }
0825:
0826:                try {
0827:                    //if object isn't already a child register it for addition
0828:                    if (isChild(obj) == false) {
0829:
0830:                        if (isNameAllowed(obj) == false) {
0831:                            throw new InvalidChildException("Duplicate name - "
0832:                                    + obj.getName());
0833:                        }
0834:
0835:                        if (obj instanceof  AbstractParentObject
0836:                                && obj.getParents().size() > 0) {
0837:                            try {
0838:                                List objpaths = obj.getAllFullPaths();
0839:
0840:                                Iterator iter = objpaths.iterator();
0841:
0842:                                while (iter.hasNext()) {
0843:                                    String sPath = (String) iter.next();
0844:                                    if (getPath().startsWith(sPath) == true) {
0845:                                        throw new InvalidChildException(
0846:                                                "Child is not allowed, it's an ancestor of this parent");
0847:                                    }
0848:                                }
0849:
0850:                            } catch (DataAccessException e) {
0851:                                throw new PopulateException(
0852:                                        "Problem occured validating child's path",
0853:                                        e);
0854:                            }
0855:                        }
0856:
0857:                        OrderableCachePointer ptr = new OrderableCachePointer(
0858:                                CacheHandler.getInstance(m_dsi)
0859:                                        .getCachePointer(obj));
0860:
0861:                        obj.addEditEventListener(this );
0862:
0863:                        if (nIndex < 0) {
0864:                            nIndex = getMaxIndex() + 1;
0865:                            setMaxIndex(nIndex);
0866:                        }
0867:
0868:                        ptr.setPosition(nIndex);
0869:
0870:                        //ensure a unique position
0871:                        if (nIndex < getMaxIndex() && getChild(nIndex) != null) {
0872:                            Set sortedSet = getOrderedChildPointers();
0873:                            Object[] array = sortedSet.toArray();
0874:
0875:                            //loop through those object with a higher index and reset 
0876:                            //ensuring that they'll be saved
0877:                            for (int i = nIndex; i < array.length; i++) {
0878:                                OrderableCachePointer tmpPtr = (OrderableCachePointer) array[i];
0879:                                OrderableCachePointer newPtr = new OrderableCachePointer(
0880:                                        tmpPtr);
0881:                                newPtr.setPosition(tmpPtr.getPosition() + 1);
0882:                                if (m_remove_children.contains(tmpPtr) == false) {
0883:                                    m_remove_children.add(tmpPtr);
0884:                                }
0885:                                if (m_add_children.contains(newPtr) == false) {
0886:                                    m_add_children.add(newPtr);
0887:
0888:                                    //ensure we keep default markers
0889:                                    Integer intId = new Integer(
0890:                                            ((AbstractChildObject) newPtr
0891:                                                    .getObject()).getId());
0892:                                    if (m_real_children.contains(intId)) {
0893:                                        m_add_real_children.add(intId);
0894:                                    }
0895:                                }
0896:                            }
0897:                        }
0898:
0899:                        m_add_children.add(ptr);
0900:
0901:                        if (bIsSoftLink == false) {
0902:                            m_add_real_children.add(new Integer(obj.getId()));
0903:                        }
0904:
0905:                        m_bIsContentsChanged = true;
0906:                    }
0907:                } catch (DataAccessException e) {
0908:                    throw new PopulateException(
0909:                            "Error occured accessing current children", e);
0910:                } catch (CacheException e) {
0911:                    throw new PopulateException(
0912:                            "Error occured getting cache pointer", e);
0913:                }
0914:            }
0915:
0916:            /**
0917:             * Returns <code>true</code> if the child name is allowed.
0918:             * 
0919:             * @param string the name of the new child
0920:             * @return <code>true</code> if the child name is allowed
0921:             * @throws DataAccessException if there is an error populating this object
0922:             * or obtaining the existing children from the appropriate cache
0923:             */
0924:            private boolean isNameAllowed(AbstractChildObject obj)
0925:                    throws DataAccessException {
0926:                boolean bIsAllowed = true;
0927:                String sName = obj.getName();
0928:
0929:                if (sName != null) {
0930:                    try {
0931:                        if (m_bIsChildrenPopulated == false) {
0932:                            populateChildrenFromDatabase();
0933:                        }
0934:
0935:                        Iterator iter = m_children.iterator();
0936:
0937:                        while (iter.hasNext() && bIsAllowed == true) {
0938:                            CachePointer ptr = (CachePointer) iter.next();
0939:
0940:                            AbstractChildObject child = (AbstractChildObject) ptr
0941:                                    .getObject();
0942:
0943:                            if (sName.equals(child.getName()) == true) {
0944:                                if (obj.getLiveVersion() != null
0945:                                        && obj.getLiveVersion().equals(child) == true) {
0946:                                    bIsAllowed = true;
0947:                                } else {
0948:                                    bIsAllowed = false;
0949:                                }
0950:
0951:                            }
0952:                        }
0953:                    } catch (CacheException e) {
0954:                        throw new DataAccessException(e.getLocalizedMessage(),
0955:                                e);
0956:                    } catch (PopulateException e) {
0957:                        throw new DataAccessException(e.getLocalizedMessage(),
0958:                                e);
0959:                    }
0960:                } else {
0961:                    bIsAllowed = false;
0962:                }
0963:
0964:                return bIsAllowed;
0965:            }
0966:
0967:            /**
0968:             * Returns <code>true</code> if the given object is a child of this object. 
0969:             * 
0970:             * @param child the potential child object
0971:             * @return <code>true</code> if the given object is a child of this object. 
0972:             * 
0973:             * @throws DataAccessException if there is an error populating the children of this object
0974:             */
0975:            public boolean isChild(AbstractChildObject child)
0976:                    throws DataAccessException {
0977:                if (m_bIsChildrenPopulated == false) {
0978:                    try {
0979:                        populateChildrenFromDatabase();
0980:                    } catch (PopulateException e) {
0981:                        throw new DataAccessException(
0982:                                "Error occured populating children", e);
0983:                    }
0984:                }
0985:
0986:                boolean bRtn = false;
0987:
0988:                //construct cache pointer so we can do a simple contains on m_children
0989:                CachePointer ptr = null;
0990:                try {
0991:                    ptr = CacheHandler.getInstance(m_dsi)
0992:                            .getCachePointer(child);
0993:                } catch (CacheException e) {
0994:                    throw new DataAccessException(
0995:                            "Error occured getting cache pointer:", e);
0996:                }
0997:
0998:                bRtn = m_children.contains(ptr);
0999:
1000:                return bRtn;
1001:            }
1002:
1003:            /**
1004:             * Returns the index of the given child object in the list
1005:             * of children.
1006:             * 
1007:             * @param child the child object
1008:             * @return the index of the given child object
1009:             * @throws DataAccessException if there is an error populating the children of this object
1010:             */
1011:            public int indexOf(AbstractChildObject child)
1012:                    throws DataAccessException {
1013:                if (m_bIsChildrenPopulated == false) {
1014:                    try {
1015:                        populateChildrenFromDatabase();
1016:                    } catch (PopulateException e) {
1017:                        throw new DataAccessException(
1018:                                "Error occured populating kids:"
1019:                                        + e.getLocalizedMessage());
1020:                    }
1021:                }
1022:
1023:                //construct cache pointer so we can search through m_children
1024:                OrderableCachePointer ptr = null;
1025:                try {
1026:                    ptr = getCachePointer(child);
1027:                } catch (CacheException e) {
1028:                    throw new DataAccessException(
1029:                            "Error occured getting cache pointer", e);
1030:                } catch (PopulateException e) {
1031:                    throw new DataAccessException(
1032:                            "Error occured getting cache pointer", e);
1033:                }
1034:
1035:                int nIndex = -1;
1036:
1037:                if (m_children.contains(ptr)) {
1038:                    nIndex = new ArrayList(getOrderedChildPointers())
1039:                            .indexOf(ptr);
1040:                }
1041:
1042:                return nIndex;
1043:            }
1044:
1045:            /**
1046:             * Sets the complete list of children of this object, children will be 
1047:             * saved with their order position taken from their index in the list.
1048:             * 
1049:             * @param children the list of <code>AbstractChildObject</code>
1050:             * @throws InvalidChildException if any of the new children is invalid
1051:             * @throws PopulateException if there is an error populating the children of this object
1052:             */
1053:            public void setChildren(List children)
1054:                    throws InvalidChildException, PopulateException {
1055:
1056:                if (m_bIsChildrenPopulated == false) {
1057:                    populateChildrenFromDatabase();
1058:                }
1059:
1060:                if (children.equals(m_children) == false) {
1061:                    m_add_children = new Vector();
1062:                    m_remove_children = new Vector();
1063:
1064:                    try {
1065:                        List curr_children = getChildren();
1066:
1067:                        //schedule any current children for deletion if not in the list
1068:                        Iterator iter = curr_children.iterator();
1069:
1070:                        while (iter.hasNext()) {
1071:                            AbstractChildObject tmpChild = (AbstractChildObject) iter
1072:                                    .next();
1073:                            if (children.contains(tmpChild) == false) {
1074:                                OrderableCachePointer ptr = getCachePointer(tmpChild);
1075:
1076:                                m_remove_children.add(ptr);
1077:                            }
1078:                        }
1079:                    } catch (DataAccessException e) {
1080:                        throw new PopulateException(
1081:                                "Error occured getting cache pointer", e);
1082:                    } catch (CacheException e) {
1083:                        throw new PopulateException(
1084:                                "Error occured getting cache pointer", e);
1085:                    }
1086:
1087:                    for (int i = 0; i < children.size(); i++) {
1088:
1089:                        AbstractChildObject child;
1090:                        try {
1091:                            child = (AbstractChildObject) children.get(i);
1092:                        } catch (ClassCastException e) {
1093:                            throw new InvalidChildException();
1094:                        }
1095:
1096:                        if (isValidChild(child) == false) {
1097:                            throw new InvalidChildException();
1098:                        }
1099:
1100:                        try {
1101:                            //if this child is a child already we have to see whether it has
1102:                            //changed position
1103:                            if (isChild(child) == true) {
1104:                                int nIndex = indexOf(child);
1105:                                OrderableCachePointer ptr = getCachePointer(child);
1106:
1107:                                if (nIndex != i && ptr.getPosition() != i) {
1108:                                    m_remove_children.add(ptr);
1109:                                } else {
1110:                                    //break out of loop cause there's nothing to change for this child
1111:                                    continue;
1112:                                }
1113:                            }
1114:                        } catch (DataAccessException e) {
1115:                            throw new PopulateException(
1116:                                    "Error occured getting cache pointer", e);
1117:                        } catch (CacheException e) {
1118:                            throw new PopulateException(
1119:                                    "Error occured getting cache pointer", e);
1120:                        }
1121:
1122:                        // construct cache pointer so we can search through m_children
1123:                        OrderableCachePointer ptr = null;
1124:                        try {
1125:                            ptr = new OrderableCachePointer(CacheHandler
1126:                                    .getInstance(m_dsi).getCachePointer(child));
1127:                        } catch (CacheException e) {
1128:                            throw new PopulateException(
1129:                                    "Error occured getting cache pointer", e);
1130:                        }
1131:                        ptr.setPosition(i);
1132:                        m_add_children.add(ptr);
1133:
1134:                        Integer intId = new Integer(child.getId());
1135:
1136:                        if (m_real_children.contains(intId) == true) {
1137:                            m_add_real_children.add(intId);
1138:                        }
1139:                    }
1140:                }
1141:
1142:                m_bIsContentsChanged = true;
1143:            }
1144:
1145:            /**
1146:             * Removes the scpecified child from this object's list of children.
1147:             * 
1148:             * @param obj the child to remove
1149:             * @throws PopulateException if an error occurs populating the children of this object
1150:             */
1151:            public void removeChild(AbstractChildObject obj)
1152:                    throws PopulateException {
1153:
1154:                if (m_logger.isLoggable(Level.INFO)) {
1155:                    try {
1156:                        m_logger.logp(Level.INFO, this .getClass().getName(),
1157:                                "removeChild", "Removing child "
1158:                                        + obj.getClass().getName() + ", key - "
1159:                                        + obj.getKey() + " from parent, key - "
1160:                                        + this .getKey());
1161:                    } catch (DataAccessException e) {
1162:                        m_logger.log(Level.WARNING,
1163:                                "Problem logging child removal", e);
1164:                    }
1165:                }
1166:
1167:                if (m_remove_children == null) {
1168:                    m_remove_children = new Vector();
1169:                }
1170:
1171:                String sClassName = obj.getClass().getName();
1172:
1173:                //if it's a valid child register it for removal
1174:                if (isValidChild(obj) == true) {
1175:                    if (m_bIsChildrenPopulated == false) {
1176:                        populateChildrenFromDatabase();
1177:                    }
1178:
1179:                    // construct cache pointer so we can do a simple remove on m_children
1180:                    CachePointer ptr = null;
1181:                    try {
1182:                        ptr = CacheHandler.getInstance(m_dsi).getCachePointer(
1183:                                obj);
1184:                    } catch (CacheException e) {
1185:                        throw new PopulateException(
1186:                                "Error occured getting cache pointer", e);
1187:                    }
1188:
1189:                    int nPtrIndex = m_children.indexOf(ptr);
1190:
1191:                    if (nPtrIndex >= 0) {
1192:                        OrderableCachePointer ordPtr = (OrderableCachePointer) m_children
1193:                                .get(nPtrIndex);
1194:
1195:                        if (m_remove_children.contains(ordPtr) == false) {
1196:                            m_remove_children.add(ordPtr);
1197:                        }
1198:
1199:                        Set sortedSet = getOrderedChildPointers();
1200:
1201:                        Object[] array = sortedSet.toArray();
1202:
1203:                        //loop through those object with a higher index and reset 
1204:                        //ensuring that they'll be saved
1205:
1206:                        int nIndex = ordPtr.getPosition();
1207:                        if (nIndex >= 0) {
1208:                            for (int i = nIndex; i < array.length; i++) {
1209:                                OrderableCachePointer tmpPtr = (OrderableCachePointer) array[i];
1210:                                if (tmpPtr.equals(ordPtr) == false) {
1211:                                    OrderableCachePointer newPtr = new OrderableCachePointer(
1212:                                            tmpPtr);
1213:                                    newPtr
1214:                                            .setPosition(tmpPtr.getPosition() - 1);
1215:
1216:                                    if (m_remove_children.contains(tmpPtr) == false) {
1217:                                        m_remove_children.add(tmpPtr);
1218:                                    }
1219:
1220:                                    if (m_add_children.contains(newPtr) == false) {
1221:                                        m_add_children.add(newPtr);
1222:                                        // ensure we keep default markers
1223:                                        try {
1224:                                            Integer intId = new Integer(
1225:                                                    ((AbstractChildObject) newPtr
1226:                                                            .getObject())
1227:                                                            .getId());
1228:                                            if (m_real_children.contains(intId)) {
1229:                                                m_add_real_children.add(intId);
1230:                                            }
1231:                                        } catch (CacheException e) {
1232:                                            throw new PopulateException(e
1233:                                                    .getLocalizedMessage(), e);
1234:                                        }
1235:                                    }
1236:                                }
1237:                            }
1238:                            resetMaxIndex();
1239:                        }
1240:                        m_bIsContentsChanged = true;
1241:                    }
1242:                }
1243:            }
1244:
1245:            /**
1246:             * @throws PopulateException
1247:             * 
1248:             */
1249:            private void resetMaxIndex() throws PopulateException {
1250:                populateChildrenFromDatabase();
1251:
1252:                Iterator iter = m_children.iterator();
1253:
1254:                int nMaxIndex = m_nMaxIndex;
1255:                while (iter.hasNext()) {
1256:                    OrderableCachePointer ptr = (OrderableCachePointer) iter
1257:                            .next();
1258:                    int nIndex = ptr.getPosition();
1259:                    if (nIndex > nMaxIndex) {
1260:                        nMaxIndex = nIndex;
1261:                    }
1262:                }
1263:                m_nMaxIndex = nMaxIndex;
1264:            }
1265:
1266:            /**
1267:             * Returns <code>true</code> if the given object is of a valid 
1268:             * type to become a child of this object.
1269:             * 
1270:             * @param childObj the child object to test
1271:             * @return <code>true</code> if the given object is of a valid 
1272:             * type to become a child of this object.
1273:             */
1274:            public boolean isValidChild(AbstractChildObject childObj) {
1275:
1276:                if (m_logger.isLoggable(Level.FINER)) {
1277:                    try {
1278:                        m_logger.logp(Level.FINER, this .getClass().getName(),
1279:                                "isValidChild", "Validating child - "
1280:                                        + childObj.getClass().getName()
1281:                                        + " key - " + childObj.getKey());
1282:                    } catch (DataAccessException e) {
1283:                        m_logger.log(Level.WARNING,
1284:                                "Error logging child validation", e);
1285:                    }
1286:                }
1287:
1288:                List classes = new ArrayList();
1289:                List classNames = getChildClassNames();
1290:
1291:                Iterator iter = classNames.iterator();
1292:                boolean bIsValid = false;
1293:                while (iter.hasNext() && bIsValid == false) {
1294:                    String sClassname = (String) iter.next();
1295:                    Class clss;
1296:                    try {
1297:                        clss = Class.forName(sClassname);
1298:                        if (clss.isAssignableFrom(childObj.getClass())) {
1299:                            bIsValid = true;
1300:                        }
1301:                    } catch (ClassNotFoundException e) {
1302:                        bIsValid = false;
1303:                    }
1304:
1305:                }
1306:
1307:                return bIsValid;
1308:            }
1309:
1310:            /**
1311:             * Returns all children that match the class specified.
1312:             * 
1313:             * @param clss the class to match children against
1314:             * @return a list of children  that match the specified class 
1315:             * @throws DataAccessException if there is an error accessing 
1316:             * the children of this parent
1317:             */
1318:            public List getChildrenByClass(Class clss)
1319:                    throws DataAccessException {
1320:                List rtn = new Vector();
1321:
1322:                Iterator iter = getChildren().iterator();
1323:
1324:                while (iter.hasNext()) {
1325:                    Object obj = iter.next();
1326:                    if (clss.isInstance(obj) == true) {
1327:                        rtn.add(obj);
1328:                    }
1329:                }
1330:
1331:                return rtn;
1332:            }
1333:
1334:            /**
1335:             * Returns a list of all children of the given type, 
1336:             * i.e. branch or leaf children.
1337:             * 
1338:             * @param nType the type code which determines which children 
1339:             * are returned
1340:             * @return a list of all children of the given type
1341:             * @throws DataAccessException if there is an error accessing 
1342:             * the children of this parent
1343:             */
1344:            public List getChildrenByType(int nType) throws DataAccessException {
1345:                List rtn = new Vector();
1346:
1347:                //if this is not a live version then get the kids from the live version
1348:                if (isLiveVersion() == false) {
1349:                    AbstractParentObject parent = (AbstractParentObject) getLiveVersion();
1350:
1351:                    if (parent != null) {
1352:                        rtn = parent.getChildrenByType(nType);
1353:                    }
1354:                } else {
1355:                    //populate kids if necessary
1356:                    if (m_bIsChildrenPopulated == false) {
1357:                        try {
1358:                            populateChildrenFromDatabase();
1359:                        } catch (PopulateException e) {
1360:                            throw new DataAccessException(
1361:                                    "Error occured populating kids:", e);
1362:                        }
1363:                    }
1364:
1365:                    rtn = new Vector();
1366:
1367:                    Iterator iter = m_children.iterator();
1368:
1369:                    //loop through getting object from cache pointers and adding to
1370:                    //list as appropriate
1371:                    while (iter.hasNext()) {
1372:                        CachePointer ptr = (CachePointer) iter.next();
1373:
1374:                        AbstractChildObject child = null;
1375:
1376:                        try {
1377:                            child = (AbstractChildObject) ptr.getObject();
1378:                        } catch (CacheException e) {
1379:                            throw new DataAccessException(
1380:                                    "Error occured getting object from cache:"
1381:                                            + e.getLocalizedMessage());
1382:                        }
1383:
1384:                        if (nType == ALL_NODES) {
1385:                            rtn.add(child);
1386:                        } else {
1387:
1388:                            if (nType == BRANCH_NODES
1389:                                    && child instanceof  AbstractParentObject) {
1390:                                rtn.add(child);
1391:                            } else if (nType == LEAF_NODES
1392:                                    && (child instanceof  AbstractParentObject) == false) {
1393:                                rtn.add(child);
1394:                            }
1395:                        }
1396:                    }
1397:                }
1398:
1399:                return rtn;
1400:            }
1401:
1402:            /**
1403:             * Returns a list of all children of this object.
1404:             * 
1405:             * @return a list of all children of this object
1406:             * @throws DataAccessException if there is an error accessing the children of this object
1407:             */
1408:            public List getChildren() throws DataAccessException {
1409:
1410:                if (m_logger.isLoggable(Level.FINE)) {
1411:                    m_logger.logp(Level.FINE, this .getClass().getName(),
1412:                            "getChildren", "Getting children for object, id - "
1413:                                    + m_nId + ", key - " + m_nObjectKey);
1414:                }
1415:
1416:                List rtn = getChildrenByType(ALL_NODES);
1417:
1418:                return rtn;
1419:            }
1420:
1421:            /**
1422:             * Returns the child with the specified name, otherwise returns a null.
1423:             * 
1424:             * @param string the name of the desired child object
1425:             * @returnthe child with the specified name, otherwise returns a <code>null</code>
1426:             */
1427:            public AbstractChildObject getChildByName(String sName)
1428:                    throws DataAccessException {
1429:                AbstractChildObject child = null;
1430:
1431:                if (isLiveVersion() == false) {
1432:                    AbstractParentObject parent = (AbstractParentObject) getLiveVersion();
1433:
1434:                    if (parent != null) {
1435:                        child = parent.getChildByName(sName);
1436:                    }
1437:                } else {
1438:                    //populate kids if necessary
1439:                    if (m_bIsChildrenPopulated == false) {
1440:                        try {
1441:                            populateChildrenFromDatabase();
1442:                        } catch (PopulateException e) {
1443:                            throw new DataAccessException(
1444:                                    "Error occured populating kids:", e);
1445:                        }
1446:                    }
1447:
1448:                    Iterator iter = m_children.iterator();
1449:
1450:                    try {
1451:                        while (iter.hasNext() == true && child == null) {
1452:                            CachePointer tmpPtr = (CachePointer) iter.next();
1453:                            AbstractChildObject tmpChild = (AbstractChildObject) tmpPtr
1454:                                    .getObject();
1455:
1456:                            if (tmpChild.getName().equals(sName)) {
1457:                                child = tmpChild;
1458:                            }
1459:                        }
1460:                    } catch (CacheException e) {
1461:                        throw new DataAccessException(e.getLocalizedMessage(),
1462:                                e);
1463:                    }
1464:
1465:                }
1466:
1467:                return child;
1468:            }
1469:
1470:            /**
1471:             * Returns the child of this parent object at the specified 
1472:             * index.
1473:             * 
1474:             * @param nIndex the index of the desired child object
1475:             * @return the index of the desired child object
1476:             * @throws DataAccessException if there is an error populating the children of this object
1477:             */
1478:            public AbstractChildObject getChild(int nIndex)
1479:                    throws DataAccessException {
1480:                AbstractChildObject child = null;
1481:
1482:                if (nIndex >= 0) {
1483:                    try {
1484:                        if (m_bIsChildrenPopulated == false) {
1485:                            populateChildrenFromDatabase();
1486:                        }
1487:
1488:                        Iterator iter = m_children.iterator();
1489:                        boolean bFound = false;
1490:                        while (iter.hasNext() && bFound == false) {
1491:                            OrderableCachePointer ptr = (OrderableCachePointer) iter
1492:                                    .next();
1493:                            if (ptr.getPosition() == nIndex) {
1494:                                child = (AbstractChildObject) ptr.getObject();
1495:                                bFound = true;
1496:                            }
1497:                        }
1498:                    } catch (PopulateException e) {
1499:                        throw new DataAccessException(
1500:                                "Error populating parent", e);
1501:                    } catch (CacheException e) {
1502:                        throw new DataAccessException(
1503:                                "Error getting object from cache", e);
1504:                    }
1505:                }
1506:
1507:                return child;
1508:            }
1509:
1510:            /**
1511:             * Returns the current maximum child index position.
1512:             * 
1513:             * Note: this isn't the same as size as there is no enforcement rules on
1514:             * index values being contiguous.
1515:             * 
1516:             * @return the current maximum child index position
1517:             * @throws DataAccessException if an error occurs populating the children of this object
1518:             */
1519:            public int getMaxIndex() throws DataAccessException {
1520:                if (m_nMaxIndex < 0 && m_bIsChildrenPopulated == false) {
1521:                    try {
1522:                        populateChildrenFromDatabase();
1523:                    } catch (PopulateException e) {
1524:                        throw new DataAccessException(
1525:                                "Error populating children", e);
1526:                    }
1527:                }
1528:
1529:                return m_nMaxIndex;
1530:            }
1531:
1532:            /**
1533:             * Sets the value of the field containing the maximum child index position.
1534:             * 
1535:             * @param nMax the maximum child index position
1536:             */
1537:            private void setMaxIndex(int nMax) {
1538:                m_nMaxIndex = nMax;
1539:            }
1540:
1541:            /**
1542:             * Returns the archived child with the specified name,
1543:             * otherwise returns a <code>null</code>.
1544:             * 
1545:             * @param sName the name of the archived child to return 
1546:             * @return the archived child with the specified name
1547:             * @throws DataAccessException if there is an error populating the list of archived children
1548:             */
1549:            public AbstractChildObject getArchivedChildByName(String sName)
1550:                    throws DataAccessException {
1551:                AbstractChildObject child = null;
1552:                List children = getArchivedChildren();
1553:
1554:                Iterator iter = children.iterator();
1555:
1556:                while (iter.hasNext() == true && child == null) {
1557:                    AbstractChildObject tmpChild = (AbstractChildObject) iter
1558:                            .next();
1559:
1560:                    if (tmpChild.getName().equals(sName)) {
1561:                        child = tmpChild;
1562:                    }
1563:                }
1564:
1565:                return child;
1566:            }
1567:
1568:            /**
1569:             * Returns a list of archived children which match the specified 
1570:             * <code>Class</code>.
1571:             * 
1572:             * @param clss the <code>Class</code> to match children by
1573:             * @return the list of archived children
1574:             * @throws DataAccessException if there is an error populating the 
1575:             * list of archived children
1576:             */
1577:            public List getArchivedChildrenByClass(Class clss)
1578:                    throws DataAccessException {
1579:                List rtn = new Vector();
1580:
1581:                Iterator iter = getArchivedChildren().iterator();
1582:
1583:                while (iter.hasNext()) {
1584:                    Object obj = iter.next();
1585:
1586:                    if (clss.isInstance(obj) == true) {
1587:                        rtn.add(obj);
1588:                    }
1589:                }
1590:
1591:                return rtn;
1592:            }
1593:
1594:            /**
1595:             * Returns a list of archived children matching the type specified, 
1596:             * i.e. leaf, branch or all children.
1597:             * 
1598:             * @param nType the type code of children to return
1599:             * @return a list of archived children matching the type specified
1600:             * @throws DataAccessException if there is an error populating the 
1601:             * list of archived children
1602:             */
1603:            public List getArchivedChildrenByType(int nType)
1604:                    throws DataAccessException {
1605:                List rtn = null;
1606:
1607:                if (nType == ALL_NODES) {
1608:                    rtn = getArchivedChildren();
1609:                } else {
1610:                    rtn = new Vector();
1611:
1612:                    List archive = getArchivedChildren();
1613:
1614:                    Iterator iter = archive.iterator();
1615:
1616:                    //loop through adding kids as appropriate
1617:                    while (iter.hasNext()) {
1618:                        AbstractChildObject child = (AbstractChildObject) iter
1619:                                .next();
1620:
1621:                        if (nType == BRANCH_NODES
1622:                                && child instanceof  AbstractParentObject) {
1623:                            rtn.add(child);
1624:                        } else if (nType == LEAF_NODES
1625:                                && (child instanceof  AbstractParentObject) == false) {
1626:                            rtn.add(child);
1627:                        }
1628:                    }
1629:                }
1630:
1631:                return rtn;
1632:            }
1633:
1634:            /**
1635:             * Returns a list of archived descendants matching the specified 
1636:             * <code>Class</code>.
1637:             * 
1638:             * @param clss the <code>Class</code> to match by
1639:             * @return the list of archived descendants matching the specified 
1640:             * <code>Class</code>
1641:             * @throws DataAccessException if there is an error populating the 
1642:             * list of archived children
1643:             */
1644:            public List getAllArchivedChildrenByClass(Class clss)
1645:                    throws DataAccessException {
1646:                List rtn = new Vector();
1647:
1648:                Iterator iter = getAllArchivedChildren().iterator();
1649:
1650:                while (iter.hasNext()) {
1651:                    Object obj = iter.next();
1652:
1653:                    if (clss.isInstance(obj) == true) {
1654:                        rtn.add(obj);
1655:                    }
1656:                }
1657:
1658:                return rtn;
1659:            }
1660:
1661:            /**
1662:             * Returns a list of all archived descendants, i.e. of this object and 
1663:             * its branch children, of the specified type, i.e. leaf, branch or all 
1664:             * children
1665:             * 
1666:             * @param nType the type code of children to return
1667:             * @return a list of all archived descendants of the specified type
1668:             * @throws DataAccessException if there is an error populating the 
1669:             * list of archived children
1670:             */
1671:            public List getAllArchivedChildrenByType(int nType)
1672:                    throws DataAccessException {
1673:                List rtn = null;
1674:
1675:                if (nType == ALL_NODES) {
1676:                    rtn = this .getAllArchivedChildren();
1677:                } else {
1678:                    rtn = new Vector();
1679:
1680:                    List archive = this .getAllArchivedChildren();
1681:
1682:                    Iterator iter = archive.iterator();
1683:
1684:                    //loop though adding kids as appropriate
1685:                    while (iter.hasNext()) {
1686:                        AbstractChildObject child = (AbstractChildObject) iter
1687:                                .next();
1688:
1689:                        if (nType == BRANCH_NODES
1690:                                && child instanceof  AbstractParentObject) {
1691:                            rtn.add(child);
1692:                        } else if (nType == LEAF_NODES
1693:                                && (child instanceof  AbstractParentObject) == false) {
1694:                            rtn.add(child);
1695:                        }
1696:                    }
1697:                }
1698:
1699:                return rtn;
1700:            }
1701:
1702:            /**
1703:             * Returns <code>true</code> if this parent is a top level parent 
1704:             * in the hierarchy of relationships,
1705:             * i.e. if it is not a child of another parent
1706:             * 
1707:             * @return <code>true</code> if this parent is a top level parent
1708:             */
1709:            public boolean isTopLevel() {
1710:                boolean bIsTopLevel = false;
1711:
1712:                try {
1713:                    bIsTopLevel = (this .getParents().size() == 0);
1714:                } catch (Exception e) {
1715:                    m_logger.log(Level.WARNING, e.getMessage(), e);
1716:                }
1717:
1718:                return bIsTopLevel;
1719:            }
1720:
1721:            /* (non-Javadoc)
1722:             * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
1723:             */
1724:            public Editable changeStatus(Status status) throws EditException {
1725:                boolean bIsUnApproved = false;
1726:
1727:                try {
1728:                    if (getStatus() == Status.UNAPPROVED) {
1729:                        bIsUnApproved = true;
1730:                    }
1731:                } catch (DataAccessException e) {
1732:                    throw new EditException("Error occured getting status:"
1733:                            + e.getLocalizedMessage());
1734:                }
1735:
1736:                if ((bIsUnApproved == true) && (status == Status.APPROVED)) {
1737:                    // if there is a live version copy the child group links
1738:                    AbstractParentObject live = null;
1739:                    try {
1740:                        live = (AbstractParentObject) getLiveVersion();
1741:                    } catch (DataAccessException e) {
1742:                        throw new EditException(
1743:                                "Error occured finding live version", e);
1744:                    }
1745:
1746:                    if (live != null) {
1747:                        try {
1748:                            List childClassNames = getChildClassNames();
1749:                            Iterator iter = childClassNames.iterator();
1750:                            UpdateStatement update = new UpdateStatement();
1751:                            int nParentKey = live.getKey();
1752:
1753:                            while (iter.hasNext()) {
1754:                                String sClassname = (String) iter.next();
1755:                                String sTable = DatabaseInfo.getInstance()
1756:                                        .getTableName(sClassname);
1757:
1758:                                ColumnRef colGroup = getGroupChildJoinColumnRef(
1759:                                        sTable, TAG_GROUP);
1760:
1761:                                update.addColumnValue(colGroup,
1762:                                        this .m_nObjectKey);
1763:                                update.addWhereCondition(colGroup, "=",
1764:                                        nParentKey);
1765:
1766:                                m_dsi.execute(update);
1767:
1768:                                update.clear();
1769:                            }
1770:
1771:                            live.clearChildren();
1772:
1773:                        } catch (DataStoreException dse) {
1774:                            throw new EditException(
1775:                                    "Error occured updating DB", dse);
1776:                        } catch (DataAccessException dae) {
1777:                            throw new EditException(
1778:                                    "Error accessing data for update", dae);
1779:                        }
1780:                    }
1781:                }
1782:
1783:                return super .changeStatus(status);
1784:            }
1785:
1786:            /**
1787:             * Returns a list of top level parent objects of a specified object type.
1788:             * 
1789:             * @param dbinterf the data store interface
1790:             * @param grpObj an instance of the type of object to be returned
1791:             * @return a list of top level parent objects
1792:             * @throws DataAccessException if there is any errors building the 
1793:             * list of objects
1794:             */
1795:            public static List getTopLevelGroups(
1796:                    AbstractDataStoreInterface dbinterf,
1797:                    AbstractParentObject grpObj) throws DataAccessException {
1798:                Vector vTopLevelGroups = new Vector(16);
1799:                ResultSet rs = null;
1800:
1801:                try {
1802:                    String sTable = null;
1803:                    try {
1804:                        sTable = DatabaseInfo.getInstance().getTableName(
1805:                                grpObj.getClass().getName());
1806:                    } catch (DataStoreException e) {
1807:                        throw new DataAccessException(
1808:                                "Error getting table name", e);
1809:                    }
1810:
1811:                    SelectStatement nestedSelect = new SelectStatement();
1812:
1813:                    nestedSelect.addSelectColumn(grpObj
1814:                            .getGroupChildJoinColumnRef(sTable, TAG_CHILDREN));
1815:
1816:                    SelectStatement select = new SelectStatement();
1817:
1818:                    select.addSelectColumn(grpObj.getInstanceColumnRef(
1819:                            ATTRIB_ID, false));
1820:
1821:                    select.addWhereCondition(grpObj.getInstanceColumnRef(
1822:                            ATTRIB_KEY, false), "NOT IN", nestedSelect);
1823:
1824:                    select.addWhereCondition(grpObj.getInstanceColumnRef(
1825:                            ATTRIB_TYPE, false), "=", grpObj.getClass()
1826:                            .getName());
1827:
1828:                    rs = dbinterf.execute(select);
1829:
1830:                    while (rs.next()) {
1831:                        Publishable topObj = HarmoniseObjectFactory
1832:                                .instantiatePublishableObject(dbinterf, grpObj
1833:                                        .getClass().getName(), rs.getInt(1));
1834:                        vTopLevelGroups.addElement(topObj);
1835:                    }
1836:                } catch (DataStoreException e) {
1837:                    throw new DataAccessException(
1838:                            "Error occured building query", e);
1839:                } catch (HarmoniseFactoryException e) {
1840:                    throw new DataAccessException(
1841:                            "Error occured instantiating object from factory",
1842:                            e);
1843:                } catch (SQLException e) {
1844:                    throw new DataAccessException("SQL error", e);
1845:                } finally {
1846:                    if (rs != null) {
1847:                        try {
1848:                            rs.close();
1849:                        } catch (SQLException e) {
1850:                            throw new DataAccessException(
1851:                                    "Error occured closing result set", e);
1852:                        }
1853:                    }
1854:                }
1855:
1856:                return vTopLevelGroups;
1857:            }
1858:
1859:            /**
1860:             * Returns a list of class names of classes that can be children of this 
1861:             * object.
1862:             */
1863:            abstract public List getChildClassNames();
1864:
1865:            /**
1866:             * Returns a list all archived children of this parent object
1867:             *
1868:             * @return the list of archived children
1869:             * @throws DataAccessException if there is an error populating the 
1870:             * list of archived children
1871:             */
1872:            public List getArchivedChildren() throws DataAccessException {
1873:                try {
1874:
1875:                    if (isLiveVersion() == false) {
1876:                        AbstractParentObject liveVersion = (AbstractParentObject) getLiveVersion();
1877:
1878:                        if (liveVersion != null) {
1879:                            m_archivedChildren = liveVersion
1880:                                    .getArchivedChildren();
1881:                        } else if (isHistorical() == true) {
1882:                            if (m_bIsArchivedChildrenPopulated == false) {
1883:                                populateArchivedChildrenFromDatabase(false);
1884:                            }
1885:                        } else {
1886:                            m_archivedChildren = new Vector();
1887:                        }
1888:                    } else {
1889:                        if (m_bIsArchivedChildrenPopulated == false) {
1890:                            populateArchivedChildrenFromDatabase(false);
1891:                        }
1892:                    }
1893:                } catch (PopulateException e) {
1894:                    throw new DataAccessException(
1895:                            "Error occured populating archived children", e);
1896:                }
1897:
1898:                //return a differnet List to protect the memeber variable from modification
1899:                return new ArrayList(m_archivedChildren);
1900:            }
1901:
1902:            /*----------------------------------------------------------------------------
1903:            Protected Methods
1904:            -----------------------------------------------------------------------------*/
1905:
1906:            /**
1907:             * Returns the column reference for a column in the parent-child 
1908:             * relationship table.
1909:             * 
1910:             * @param sChildTableName the relationship table name
1911:             * @param sCol the column, tag or attribute name
1912:             * @return the corresponding column reference
1913:             * @throws DataStoreException if the <code>sCol</code> reference is invalid
1914:             */
1915:            protected ColumnRef getGroupChildJoinColumnRef(
1916:                    String sChildTableName, String sCol)
1917:                    throws DataStoreException {
1918:                ColumnRef colref = null;
1919:
1920:                StringBuffer sbuf = new StringBuffer(getDBTableName()).append(
1921:                        JOIN_TO).append(sChildTableName);
1922:
1923:                String sTable = sbuf.toString();
1924:
1925:                if (sCol.equals(CLMN_CHILD_KEY) == true
1926:                        || sCol.equals(AbstractParentObject.TAG_CHILDREN)) {
1927:                    colref = new ColumnRef(sTable, CLMN_CHILD_KEY,
1928:                            ColumnRef.NUMBER);
1929:                } else if (sCol.equals(CLMN_PARENT_KEY) == true
1930:                        || sCol.equals(TAG_GROUP) == true) {
1931:                    colref = new ColumnRef(sTable, CLMN_PARENT_KEY,
1932:                            ColumnRef.NUMBER);
1933:                } else if (sCol.equals(CLMN_DATE) == true) {
1934:                    colref = new ColumnRef(sTable, CLMN_DATE, ColumnRef.DATE);
1935:                } else if (sCol.equals(CLMN_DEFAULT_LINK) == true
1936:                        || sCol.equals(ATTRIB_DEFAULT) == true) {
1937:                    colref = new ColumnRef(sTable, CLMN_DEFAULT_LINK,
1938:                            ColumnRef.NUMBER);
1939:                } else if (sCol.equals(CLMN_POSITION) == true) {
1940:                    colref = new ColumnRef(sTable, CLMN_POSITION,
1941:                            ColumnRef.NUMBER);
1942:                }
1943:
1944:                if (colref == null) {
1945:                    throw new InvalidColumnReferenceException();
1946:                }
1947:
1948:                return colref;
1949:            }
1950:
1951:            /* (non-Javadoc)
1952:             * @see org.openharmonise.rm.resources.AbstractEditableObject#delete(boolean)
1953:             */
1954:            protected void delete(boolean bDeleteHist)
1955:                    throws DataStoreException, DataAccessException,
1956:                    EditException, PopulateException {
1957:
1958:                try {
1959:                    List children = getChildren();
1960:
1961:                    if (children.isEmpty() == false) {
1962:                        while (children.size() > 0) {
1963:                            AbstractChildObject child = (AbstractChildObject) children
1964:                                    .get(0);
1965:
1966:                            if (child.getRealParent().equals(this )) {
1967:                                child.delete(bDeleteHist);
1968:                            } else {
1969:                                removeChild(child);
1970:                                saveNonCoreData();
1971:                            }
1972:                        }
1973:
1974:                        m_children.clear();
1975:                    }
1976:                } catch (DataAccessException e) {
1977:                    throw new EditException("Error occured accesing data", e);
1978:                } catch (PopulateException e) {
1979:                    throw new EditException("Error occured populating object",
1980:                            e);
1981:                } catch (DataStoreException e) {
1982:                    throw new EditException(
1983:                            "Error occured deleting branch child", e);
1984:                }
1985:
1986:                super .delete(bDeleteHist);
1987:            }
1988:
1989:            /* (non-Javadoc)
1990:             * @see org.openharmonise.rm.resources.AbstractEditableObject#saveNonCoreData()
1991:             */
1992:            protected void saveNonCoreData() throws EditException {
1993:                boolean bIsApproved = false;
1994:
1995:                if (isLockThread() == false) {
1996:                    throw new EditException(
1997:                            "This object has been locked by another thread");
1998:                }
1999:
2000:                try {
2001:                    if (getStatus() == Status.APPROVED) {
2002:                        bIsApproved = true;
2003:                    }
2004:                } catch (DataAccessException e) {
2005:                    throw new EditException("Error occured getting status", e);
2006:                }
2007:
2008:                if (bIsApproved == true && isHistorical() == false) {
2009:                    //ensure children variables populated for resave
2010:                    try {
2011:                        populateChildrenFromDatabase();
2012:                    } catch (PopulateException e) {
2013:                        throw new EditException(
2014:                                "Error occured populating object", e);
2015:                    }
2016:
2017:                    //save changes in content (ie group children, link data) without creating unapproved version.
2018:                    if (m_bIsContentsChanged == true) {
2019:                        //remove children to be removed
2020:                        DeleteStatement delete = new DeleteStatement();
2021:
2022:                        Iterator remove_iter = new Vector(m_remove_children)
2023:                                .listIterator();
2024:
2025:                        while (remove_iter.hasNext()) {
2026:                            try {
2027:                                OrderableCachePointer ptr = (OrderableCachePointer) remove_iter
2028:                                        .next();
2029:                                AbstractChildObject child = (AbstractChildObject) ptr
2030:                                        .getObject();
2031:
2032:                                if (m_logger.isLoggable(Level.FINER)) {
2033:                                    m_logger.logp(Level.FINER, this .getClass()
2034:                                            .getName(), "saveNonCoreData",
2035:                                            "Deleteing DB child entry for "
2036:                                                    + child.getClass()
2037:                                                            .getName()
2038:                                                    + ", id - " + child.getId()
2039:                                                    + "posn -"
2040:                                                    + ptr.getPosition()
2041:                                                    + "for parent ,id - "
2042:                                                    + getId());
2043:                                }
2044:
2045:                                // if the m_add_children vector also contains
2046:                                // the object to be removed, then
2047:                                // remove it from the m_add_children vector
2048:                                if (m_add_children.contains(ptr) == true) {
2049:                                    m_add_children.remove(ptr);
2050:                                }
2051:
2052:                                child.removeParent(this );
2053:                                child.removeEditEventListener(this );
2054:
2055:                                Integer intId = new Integer(child.getId());
2056:                                boolean bIsReal = m_real_children
2057:                                        .contains(intId);
2058:
2059:                                delete
2060:                                        .addWhereCondition(
2061:                                                getGroupChildJoinColumnRef(
2062:                                                        child.getDBTableName(),
2063:                                                        TAG_CHILDREN), "=",
2064:                                                child.getKey());
2065:                                delete.addWhereCondition(
2066:                                        getGroupChildJoinColumnRef(child
2067:                                                .getDBTableName(), TAG_GROUP),
2068:                                        "=", m_nObjectKey);
2069:                                delete.addWhereCondition(
2070:                                        getGroupChildJoinColumnRef(child
2071:                                                .getDBTableName(),
2072:                                                CLMN_POSITION), "=", ptr
2073:                                                .getPosition());
2074:
2075:                                m_dsi.execute(delete);
2076:
2077:                                delete.clear();
2078:
2079:                                m_children.remove(ptr);
2080:
2081:                                if (bIsReal == true) {
2082:                                    m_real_children.remove(intId);
2083:                                }
2084:                            } catch (DataAccessException e) {
2085:                                throw new EditException(
2086:                                        "Error accessing child data", e);
2087:                            } catch (CacheException e) {
2088:                                throw new EditException(
2089:                                        "Error getting object from cache", e);
2090:                            } catch (DataStoreException e) {
2091:                                throw new EditException(
2092:                                        "Error deleting data from DB", e);
2093:                            } catch (PopulateException e) {
2094:                                throw new EditException(
2095:                                        "Error removing groups as parent from child",
2096:                                        e);
2097:                            }
2098:                        }
2099:
2100:                        //clear list
2101:                        m_remove_children.clear();
2102:
2103:                        InsertStatement insert = new InsertStatement();
2104:
2105:                        //insert new children
2106:                        Iterator iter = this .m_add_children.listIterator();
2107:
2108:                        int nDefault = 0;
2109:
2110:                        while (iter.hasNext()) {
2111:                            try {
2112:                                OrderableCachePointer ptr = (OrderableCachePointer) iter
2113:                                        .next();
2114:                                AbstractChildObject child = (AbstractChildObject) ptr
2115:                                        .getObject();
2116:
2117:                                if (m_logger.isLoggable(Level.FINER)) {
2118:                                    m_logger.logp(Level.FINER, this .getClass()
2119:                                            .getName(), "saveNonCoreData",
2120:                                            "Adding DB child entry for "
2121:                                                    + child.getClass()
2122:                                                            .getName()
2123:                                                    + ", id - " + child.getId()
2124:                                                    + " for parent ,id - "
2125:                                                    + getId());
2126:                                }
2127:
2128:                                Integer intId = new Integer(child.getId());
2129:                                boolean bIsReal = m_add_real_children
2130:                                        .contains(intId);
2131:
2132:                                if (bIsReal == true) {
2133:                                    child.setRealParent(this );
2134:                                } else {
2135:                                    child.addParent(this );
2136:                                }
2137:                                child.addEditEventListener(this );
2138:
2139:                                insert
2140:                                        .addColumnValue(
2141:                                                getGroupChildJoinColumnRef(
2142:                                                        child.getDBTableName(),
2143:                                                        TAG_CHILDREN), child
2144:                                                        .getKey());
2145:                                insert.addColumnValue(
2146:                                        getGroupChildJoinColumnRef(child
2147:                                                .getDBTableName(), TAG_GROUP),
2148:                                        m_nObjectKey);
2149:
2150:                                nDefault = 0;
2151:
2152:                                if (bIsReal == true) {
2153:                                    nDefault = 1;
2154:                                }
2155:
2156:                                insert
2157:                                        .addColumnValue(
2158:                                                getGroupChildJoinColumnRef(
2159:                                                        child.getDBTableName(),
2160:                                                        AbstractChildObject.CLMN_DEFAULT_LINK),
2161:                                                nDefault);
2162:
2163:                                insert.addColumnValue(
2164:                                        getGroupChildJoinColumnRef(child
2165:                                                .getDBTableName(),
2166:                                                CLMN_POSITION), ptr
2167:                                                .getPosition());
2168:
2169:                                m_dsi.execute(insert);
2170:
2171:                                insert.clear();
2172:                                m_children.add(ptr);
2173:                                if (bIsReal == true) {
2174:                                    m_real_children.add(intId);
2175:                                }
2176:
2177:                                iter.remove();
2178:
2179:                            } catch (DataAccessException e) {
2180:                                throw new EditException(
2181:                                        "Error occured accessing data", e);
2182:                            } catch (DataStoreException e) {
2183:                                throw new EditException(
2184:                                        "Error occured inserting child data to DB",
2185:                                        e);
2186:                            } catch (CacheException e) {
2187:                                throw new EditException(
2188:                                        "Error occured getting object from cache",
2189:                                        e);
2190:                            } catch (PopulateException e) {
2191:                                throw new EditException(
2192:                                        "Error occured adding group to child",
2193:                                        e);
2194:                            }
2195:
2196:                        }
2197:
2198:                        //clear 'add' lists
2199:                        m_add_children.clear();
2200:                        m_add_real_children.clear();
2201:
2202:                        //get sorted kids so we don't order them all the time
2203:                        m_children = new ArrayList(getOrderedChildPointers());
2204:
2205:                        m_bIsContentsChanged = false;
2206:                    }
2207:                }
2208:            }
2209:
2210:            /* (non-Javadoc)
2211:             * @see org.openharmonise.rm.resources.AbstractObject#fullPopulate()
2212:             */
2213:            protected void fullPopulate() throws PopulateException {
2214:                if (m_bIsChildrenPopulated == false) {
2215:                    populateChildrenFromDatabase();
2216:                }
2217:
2218:                super .fullPopulate();
2219:            }
2220:
2221:            /**
2222:             * Adds the object which the given XML element represents as a 
2223:             * child to this parent object.
2224:             * 
2225:             * @param el the XML element representing the new child
2226:             * @throws InvalidChildException if the new child is invalid for this 
2227:             * parent
2228:             * @throws PopulateException if there is an error creating an object 
2229:             * from the XML element
2230:             */
2231:            protected void addChild(Element el) throws InvalidChildException,
2232:                    PopulateException {
2233:
2234:                AbstractChildObject obj;
2235:                try {
2236:                    obj = (AbstractChildObject) HarmoniseObjectFactory
2237:                            .instantiatePublishableObject(this .m_dsi, el, null);
2238:
2239:                    this .addChild(obj);
2240:                } catch (HarmoniseFactoryException e) {
2241:                    throw new PopulateException(
2242:                            "Problem occured creating object from XML element",
2243:                            e);
2244:                }
2245:
2246:            }
2247:
2248:            /**
2249:             * Removes the object which is represented by the given XML element 
2250:             * from the children of this object.
2251:             * 
2252:             * @param el the XML element representing a child
2253:             * @throws PopulateException if an error occurs creating an object from the XML element
2254:             */
2255:            protected void removeChild(Element el) throws PopulateException {
2256:
2257:                try {
2258:                    AbstractChildObject obj = (AbstractChildObject) HarmoniseObjectFactory
2259:                            .instantiatePublishableObject(this .m_dsi, el, null);
2260:
2261:                    removeChild(obj);
2262:                } catch (HarmoniseFactoryException e) {
2263:                    throw new PopulateException(
2264:                            "Error occured creating object from XML", e);
2265:                }
2266:
2267:            }
2268:
2269:            /*----------------------------------------------------------------------------
2270:            Private Functions
2271:            -----------------------------------------------------------------------------*/
2272:
2273:            /**
2274:             * Clears the list of archived children.
2275:             * 
2276:             */
2277:            private void clearArchivedChildren() {
2278:                m_archivedChildren = null;
2279:                m_allArchivedChildren = null;
2280:                m_bIsArchivedChildrenPopulated = false;
2281:                m_bIsAllArchivedChildrenPopulated = false;
2282:            }
2283:
2284:            /**
2285:             * Returns all archived descendants of this object.
2286:             *
2287:             * @return the list of archived descendants
2288:             * @throws DataAccessException if an error occurs while populating the 
2289:             * list of archived descendants
2290:             */
2291:            private List getAllArchivedChildren() throws DataAccessException {
2292:                try {
2293:                    if (isPopulated() == false) {
2294:                        populateFromDatabase();
2295:                    }
2296:
2297:                    if (isLiveVersion() == false) {
2298:                        AbstractParentObject liveVersion = (AbstractParentObject) getLiveVersion();
2299:
2300:                        if (liveVersion != null) {
2301:                            m_allArchivedChildren = liveVersion
2302:                                    .getAllArchivedChildren();
2303:                        } else {
2304:                            m_allArchivedChildren = new Vector();
2305:                        }
2306:                    } else {
2307:                        if (m_bIsAllArchivedChildrenPopulated == false) {
2308:                            populateArchivedChildrenFromDatabase(true);
2309:                        }
2310:                    }
2311:                } catch (PopulateException e) {
2312:                    throw new DataAccessException(
2313:                            "Error occured populating archived children", e);
2314:                }
2315:
2316:                return new ArrayList(m_allArchivedChildren);
2317:            }
2318:
2319:            /**
2320:             * Returns an object from the factory appropriate to the 
2321:             * given element.
2322:             * 
2323:             * @param el the XML representing an object
2324:             * @return the object created from the XML element
2325:             * @throws HarmoniseFactoryException if an error occurs accessing the object
2326:             * from the <code>HarmoniseObjectFactory</code>
2327:             */
2328:            private Object getObjectFromFactory(Element el)
2329:                    throws HarmoniseFactoryException {
2330:                return (Object) HarmoniseObjectFactory
2331:                        .instantiatePublishableObject(this .m_dsi, el, null);
2332:            }
2333:
2334:            /**
2335:             * Returns <code>true</code> if specified child is a child of this object
2336:             * and is not a <code>AbstractParentObject</code>.
2337:             * @param child the child object
2338:             * @return <code>true</code> if specified child is a child of this object
2339:             * and is not a <code>AbstractParentObject</code>
2340:             * @throws DataAccessException if there is an error populating the list of children
2341:             */
2342:            private boolean isLeafChild(AbstractChildObject child)
2343:                    throws DataAccessException {
2344:                //fill data member
2345:                if (m_bIsChildrenPopulated == false) {
2346:                    try {
2347:                        populateChildrenFromDatabase();
2348:                    } catch (PopulateException e) {
2349:                        throw new DataAccessException(
2350:                                "Error occured populating kids:"
2351:                                        + e.getLocalizedMessage());
2352:                    }
2353:                }
2354:
2355:                return (m_children.contains(child) && (child instanceof  AbstractParentObject) == false);
2356:            }
2357:
2358:            /**
2359:             * Populates this object's list of children from the database.
2360:             * 
2361:             * @throws PopulateException if an error occurs populating list
2362:             */
2363:            private synchronized void populateChildrenFromDatabase()
2364:                    throws PopulateException {
2365:                if (m_bIsChildrenPopulated == false) {
2366:
2367:                    if (m_logger.isLoggable(Level.FINER)) {
2368:                        m_logger.logp(Level.FINER, this .getClass().getName(),
2369:                                "populateChildrenFromDatabase",
2370:                                "populating children for parent, id - " + m_nId
2371:                                        + ", key - " + m_nObjectKey);
2372:                    }
2373:
2374:                    if (isPopulated() == false) {
2375:                        populateFromDatabase();
2376:                    }
2377:
2378:                    if (m_children == null) {
2379:                        m_children = new Vector();
2380:                    }
2381:
2382:                    if (m_real_children == null) {
2383:                        m_real_children = new Vector();
2384:                    }
2385:
2386:                    List childClassNames = getChildClassNames();
2387:
2388:                    if ((this .m_nId != AbstractObject.NOTDBSAVED_ID)
2389:                            && childClassNames != null
2390:                            && childClassNames.size() > 0) {
2391:                        SelectStatement select = new SelectStatement();
2392:
2393:                        Iterator iter = childClassNames.iterator();
2394:                        while (iter.hasNext()) {
2395:
2396:                            ColumnRef idColref;
2397:                            ColumnRef typeColref;
2398:                            ColumnRef linkColref;
2399:                            try {
2400:                                String sChildClassName = (String) iter.next();
2401:
2402:                                String sChildTableName = null;
2403:
2404:                                try {
2405:                                    sChildTableName = DatabaseInfo
2406:                                            .getInstance().getTableName(
2407:                                                    sChildClassName);
2408:                                } catch (DataStoreException e) {
2409:                                    throw new PopulateException(
2410:                                            "Error getting table name", e);
2411:                                }
2412:
2413:                                idColref = getColumnRef(sChildClassName,
2414:                                        ATTRIB_ID);
2415:
2416:                                linkColref = getGroupChildJoinColumnRef(
2417:                                        sChildTableName,
2418:                                        AbstractChildObject.CLMN_DEFAULT_LINK);
2419:                                typeColref = getColumnRef(sChildClassName,
2420:                                        ATTRIB_TYPE);
2421:
2422:                                select.addSelectColumn(idColref); //1
2423:                                select.addSelectColumn(linkColref); //2
2424:                                select.addSelectColumn(typeColref); //3
2425:                                ColumnRef posCol = getGroupChildJoinColumnRef(
2426:                                        sChildTableName, CLMN_POSITION);
2427:                                select.addSelectColumn(posCol); //4
2428:
2429:                                Collection coreRefs = AbstractParentObject
2430:                                        .getCoreColumnRefs(sChildClassName);
2431:                                Iterator resIter = coreRefs.iterator();
2432:
2433:                                while (resIter.hasNext() == true) {
2434:                                    select.addSelectColumn((ColumnRef) resIter
2435:                                            .next());
2436:                                }
2437:
2438:                                select.setOrderBy(posCol);
2439:
2440:                                //join children to join table
2441:                                ColumnRef joinColumn1 = getColumnRef(
2442:                                        sChildClassName,
2443:                                        AbstractObject.ATTRIB_KEY);
2444:                                ColumnRef joinColumn2 = getGroupChildJoinColumnRef(
2445:                                        sChildTableName, TAG_CHILDREN);
2446:
2447:                                select.addJoinCondition(joinColumn1,
2448:                                        joinColumn2);
2449:
2450:                                ColumnRef whereColumn = getGroupChildJoinColumnRef(
2451:                                        sChildTableName, TAG_GROUP);
2452:
2453:                                select.addWhereCondition(whereColumn, "=",
2454:                                        m_nObjectKey);
2455:                                select.setOrderBy(joinColumn2);
2456:                            } catch (DataStoreException e) {
2457:                                throw new PopulateException(
2458:                                        "Error occured building query", e);
2459:                            }
2460:
2461:                            ResultSet rs = null;
2462:
2463:                            try {
2464:                                rs = m_dsi.execute(select);
2465:
2466:                                int nId = 0;
2467:
2468:                                while (rs.next()) {
2469:                                    nId = rs.getInt(idColref.getColumn());
2470:
2471:                                    AbstractProfiledObject tmpChild = (AbstractProfiledObject) HarmoniseObjectFactory
2472:                                            .instantiatePublishableObject(
2473:                                                    this .m_dsi,
2474:                                                    rs.getString(typeColref
2475:                                                            .getColumn()), nId);
2476:
2477:                                    tmpChild.addEditEventListener(this );
2478:
2479:                                    if (tmpChild.isPopulated() == false) {
2480:                                        tmpChild.populateFromResultSetRow(rs,
2481:                                                select);
2482:                                    }
2483:
2484:                                    OrderableCachePointer ptr = null;
2485:
2486:                                    ptr = new OrderableCachePointer(
2487:                                            CacheHandler.getInstance(m_dsi)
2488:                                                    .getCachePointer(tmpChild));
2489:
2490:                                    int nIndex = rs.getInt(4);
2491:
2492:                                    if (nIndex > m_nMaxIndex) {
2493:                                        m_nMaxIndex = nIndex;
2494:                                    }
2495:
2496:                                    ptr.setPosition(nIndex);
2497:
2498:                                    m_children.add(ptr);
2499:
2500:                                    if (rs.getBoolean(linkColref.getColumn())) {
2501:                                        m_real_children.add(new Integer(nId));
2502:                                    }
2503:                                }
2504:
2505:                                //sort now so we don't have to do it all the time
2506:                                m_children = new ArrayList(
2507:                                        getOrderedChildPointers());
2508:                            } catch (HarmoniseFactoryException e) {
2509:                                throw new PopulateException(
2510:                                        "Error occured instantiating object from factory",
2511:                                        e);
2512:                            } catch (DataStoreException e) {
2513:                                throw new PopulateException(
2514:                                        "Error occured processing query", e);
2515:                            } catch (SQLException e) {
2516:                                throw new PopulateException("SQL error", e);
2517:                            } catch (CacheException e) {
2518:                                throw new PopulateException(
2519:                                        "Error occured getting cache pointer",
2520:                                        e);
2521:                            } finally {
2522:                                if (rs != null) {
2523:                                    try {
2524:                                        rs.close();
2525:                                    } catch (SQLException e) {
2526:                                        throw new PopulateException(
2527:                                                "Error occured closing result set",
2528:                                                e);
2529:                                    }
2530:                                }
2531:
2532:                                m_bIsChildrenPopulated = true;
2533:                            }
2534:                            select.clear();
2535:                        }
2536:
2537:                    } else {
2538:                        m_bIsChildrenPopulated = true;
2539:                    }
2540:                }
2541:            }
2542:
2543:            /**
2544:             * Populates the list of archived children or descendants from the database.
2545:             * 
2546:             * @param bAllChildren <code>true</code> if the archived descendant list 
2547:             * should be populated, otherwise the list of archived children will be populated
2548:             * @throws PopulateException if an error occurs populating the list
2549:             */
2550:            private void populateArchivedChildrenFromDatabase(
2551:                    boolean bAllChildren) throws PopulateException {
2552:
2553:                List archive = null;
2554:
2555:                if (bAllChildren == true) {
2556:                    if (m_allArchivedChildren == null) {
2557:                        m_allArchivedChildren = new Vector();
2558:                    }
2559:
2560:                    archive = m_allArchivedChildren;
2561:                } else {
2562:                    if (m_archivedChildren == null) {
2563:                        m_archivedChildren = new Vector();
2564:                    }
2565:
2566:                    archive = m_archivedChildren;
2567:                }
2568:
2569:                List children = null;
2570:                try {
2571:                    children = getChildren();
2572:                } catch (DataAccessException e) {
2573:                    throw new PopulateException(
2574:                            "Error occured getting children", e);
2575:                }
2576:
2577:                // get the constructor we need
2578:                List classNames = this .getChildClassNames();
2579:
2580:                Iterator iter = classNames.iterator();
2581:
2582:                while (iter.hasNext()) {
2583:
2584:                    String sClassname = (String) iter.next();
2585:                    Class childClass = null;
2586:                    try {
2587:                        childClass = Class.forName(sClassname);
2588:                    } catch (ClassNotFoundException e) {
2589:                        throw new PopulateException(
2590:                                "Error occured getting class for child", e);
2591:                    }
2592:
2593:                    SelectStatement select = new SelectStatement();
2594:
2595:                    try {
2596:                        ColumnRef histIdColumn = AbstractObject.getColumnRef(
2597:                                sClassname, AbstractObject.ATTRIB_ID, true);
2598:
2599:                        select.addSelectColumn(histIdColumn);
2600:                        select.addSelectColumn(AbstractObject.getColumnRef(
2601:                                sClassname, AbstractObject.TAG_NAME, true));
2602:                        select.addSelectColumn(AbstractEditableObject
2603:                                .getColumnRef(sClassname,
2604:                                        AbstractEditableObject.TAG_VERSION,
2605:                                        true));
2606:                        select
2607:                                .addSelectColumn(AbstractEditableObject
2608:                                        .getColumnRef(
2609:                                                sClassname,
2610:                                                AbstractEditableObject.TAG_VERSION_COMMENT,
2611:                                                true));
2612:                        select
2613:                                .addSelectColumn(AbstractEditableObject
2614:                                        .getColumnRef(
2615:                                                sClassname,
2616:                                                AbstractEditableObject.TAG_VERSION_DATE,
2617:                                                true));
2618:                        select.addSelectColumn(AbstractEditableObject
2619:                                .getColumnRef(sClassname,
2620:                                        AbstractObject.ATTRIB_KEY, true));
2621:
2622:                        ColumnRef whereColumn = AbstractChildObject
2623:                                .getColumnRef(sClassname,
2624:                                        AbstractChildObject.TAG_PATH, true);
2625:
2626:                        if (bAllChildren) {
2627:                            select.addWhereCondition(whereColumn, "LIKE",
2628:                                    getFullPath() + "%");
2629:                        } else {
2630:                            select.addWhereCondition(whereColumn, "=",
2631:                                    getFullPath());
2632:                        }
2633:
2634:                        ColumnRef liveIdColumn = AbstractObject.getColumnRef(
2635:                                sClassname, ATTRIB_ID);
2636:
2637:                        //hist id not in live id list
2638:                        SelectStatement nestedSelect = new SelectStatement();
2639:
2640:                        nestedSelect.addSelectColumn(liveIdColumn);
2641:
2642:                        select.addWhereCondition(histIdColumn, "not in",
2643:                                nestedSelect);
2644:
2645:                        ColumnRef parentIdColumn = AbstractEditableObject
2646:                                .getColumnRef(sClassname, TAG_LIVE_VERSION,
2647:                                        false);
2648:
2649:                        //hist id not in live parent_id list
2650:                        SelectStatement nestedSelect2 = new SelectStatement();
2651:
2652:                        nestedSelect2.addSelectColumn(parentIdColumn);
2653:
2654:                        select.addWhereCondition(histIdColumn, "not in",
2655:                                nestedSelect2);
2656:
2657:                        select.addOrderBy(AbstractObject.getColumnRef(
2658:                                sClassname, AbstractObject.ATTRIB_KEY, true),
2659:                                SelectStatement.ORDER_DESCENDING);
2660:
2661:                    } catch (DataAccessException e) {
2662:                        throw new PopulateException(
2663:                                "Error occured accessing data", e);
2664:                    } catch (DataStoreException e) {
2665:                        throw new PopulateException(
2666:                                "Error occured building query", e);
2667:                    }
2668:
2669:                    ResultSet rs = null;
2670:
2671:                    try {
2672:                        rs = m_dsi.execute(select);
2673:
2674:                        Vector ids = new Vector();
2675:
2676:                        while (rs.next()) {
2677:                            int nId = rs.getInt(1);
2678:                            Integer intId = new Integer(nId);
2679:
2680:                            if (ids.contains(intId) == false) {
2681:                                AbstractChildObject obj = (AbstractChildObject) childClass
2682:                                        .newInstance();
2683:
2684:                                obj.setDataStoreInterface(m_dsi);
2685:                                obj.setId(nId);
2686:                                obj.setHistorical(true);
2687:
2688:                                obj.populateFromResultSetRow(rs, select);
2689:
2690:                                obj.setRealParent(this );
2691:                                obj.addEditEventListener(this );
2692:
2693:                                archive.add(obj);
2694:                                ids.add(intId);
2695:                            }
2696:                        }
2697:                    } catch (SQLException e) {
2698:                        throw new PopulateException("SQL error", e);
2699:                    } catch (IllegalArgumentException e) {
2700:                        throw new PopulateException("Illegal argument error", e);
2701:                    } catch (InstantiationException e) {
2702:                        throw new PopulateException("Instantiation error", e);
2703:                    } catch (IllegalAccessException e) {
2704:                        throw new PopulateException("Illegal access error", e);
2705:                    } catch (DataStoreException e) {
2706:                        throw new PopulateException(
2707:                                "Error occured processing query", e);
2708:                    } finally {
2709:                        if (rs != null) {
2710:                            try {
2711:                                rs.close();
2712:                            } catch (SQLException e) {
2713:                                throw new PopulateException(
2714:                                        "Error occured closing result set", e);
2715:                            }
2716:                        }
2717:
2718:                        if (bAllChildren) {
2719:                            m_bIsAllArchivedChildrenPopulated = true;
2720:                        } else {
2721:                            m_bIsArchivedChildrenPopulated = true;
2722:                        }
2723:                    }
2724:
2725:                }
2726:            }
2727:
2728:            /* (non-Javadoc)
2729:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectArchived(org.openharmonise.rm.resources.lifecycle.EditEvent)
2730:             */
2731:            public void workflowObjectArchived(EditEvent event) {
2732:                Editable source = (Editable) event.getSource();
2733:
2734:                //if source is a child act accordingly
2735:                if (source instanceof  AbstractChildObject) {
2736:                    AbstractChildObject childSource = (AbstractChildObject) source;
2737:
2738:                    //if child is a valid child of this parent clear all archived children lists
2739:                    //so that they can be repopulated if necessary
2740:                    //Note: there is no way to check whether it's valid to add the result
2741:                    //of the event to the archived lists as the original child will no longer
2742:                    //be a child of the parent
2743:                    if (isValidChild(childSource) == true) {
2744:
2745:                        if (m_bIsArchivedChildrenPopulated == true) {
2746:                            m_bIsArchivedChildrenPopulated = false;
2747:                            m_archivedChildren.clear();
2748:                        }
2749:
2750:                        if (m_bIsAllArchivedChildrenPopulated == true) {
2751:                            m_bIsAllArchivedChildrenPopulated = false;
2752:                            m_allArchivedChildren.clear();
2753:                        }
2754:                    }
2755:
2756:                }
2757:
2758:                super .workflowObjectArchived(event);
2759:
2760:            }
2761:
2762:            /* (non-Javadoc)
2763:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectLocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2764:             */
2765:            public void workflowObjectLocked(EditEvent event) {
2766:                super .workflowObjectLocked(event);
2767:            }
2768:
2769:            /* (non-Javadoc)
2770:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectReactivated(org.openharmonise.rm.resources.lifecycle.EditEvent)
2771:             */
2772:            public void workflowObjectReactivated(EditEvent event) {
2773:                Object src = event.getSource();
2774:
2775:                //if source of event has been archived it's no longer 
2776:                //valid it to have listed in the archive
2777:                if (src instanceof  AbstractChildObject) {
2778:
2779:                    if (m_bIsAllArchivedChildrenPopulated == true) {
2780:                        m_allArchivedChildren.remove(src);
2781:                    }
2782:
2783:                    if (m_bIsArchivedChildrenPopulated == true) {
2784:                        m_archivedChildren.remove(src);
2785:                    }
2786:                }
2787:
2788:                super .workflowObjectReactivated(event);
2789:            }
2790:
2791:            /* (non-Javadoc)
2792:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectSaved(org.openharmonise.rm.resources.lifecycle.EditEvent)
2793:             */
2794:            public void workflowObjectSaved(EditEvent event) {
2795:                super .workflowObjectSaved(event);
2796:            }
2797:
2798:            /* (non-Javadoc)
2799:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectStatusChanged(org.openharmonise.rm.resources.lifecycle.EditEvent)
2800:             */
2801:            public void workflowObjectStatusChanged(EditEvent event) {
2802:
2803:                super .workflowObjectStatusChanged(event);
2804:            }
2805:
2806:            /* (non-Javadoc)
2807:             * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectUnlocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
2808:             */
2809:            public void workflowObjectUnlocked(EditEvent event) {
2810:                super .workflowObjectUnlocked(event);
2811:
2812:            }
2813:
2814:            /**
2815:             * Subclass of <code>CachePointer</code> which stores position data,
2816:             * allowing an orderable list to be created and maintained.
2817:             * 
2818:             * @author Michael Bell
2819:             * @version $Revision: 1.6.2.1 $
2820:             *
2821:             */
2822:            private class OrderableCachePointer extends CachePointer {
2823:
2824:                /**
2825:                 * Index of this cache pointer in list
2826:                 */
2827:                private int m_nPosition = -1;
2828:
2829:                /**
2830:                 * Constructs a cache pointer which does not reference any object
2831:                 */
2832:                public OrderableCachePointer() {
2833:                    super ();
2834:                }
2835:
2836:                /**
2837:                 * Constructs an orderable cache pointer based in the specified
2838:                 * <code>CachePointer</code>
2839:                 * 
2840:                 * @param ptr the <code>CachePointer</code> to base this object on
2841:                 */
2842:                public OrderableCachePointer(CachePointer ptr) {
2843:                    this .setCache(ptr.getCache());
2844:                    this .setKey(ptr.getKey());
2845:                }
2846:
2847:                /**
2848:                 * Constructs a cache pointer which references the object found in
2849:                 * cache <code>cache</code> with cache key <code>key</code>.
2850:                 * 
2851:                 * @param key the cache key
2852:                 * @param cache the cache
2853:                 */
2854:                public OrderableCachePointer(Object key, AbstractCache cache) {
2855:                    super (key, cache);
2856:                }
2857:
2858:                /**
2859:                 * Returns the index of this cache pointer
2860:                 * 
2861:                 * @return the index of this cache pointer
2862:                 */
2863:                public int getPosition() {
2864:                    return m_nPosition;
2865:                }
2866:
2867:                /**
2868:                 * Sets the index of this cache pointer
2869:                 * 
2870:                 * @param i the index of this cache pointer
2871:                 */
2872:                public void setPosition(int i) {
2873:                    m_nPosition = i;
2874:                }
2875:
2876:                /* (non-Javadoc)
2877:                 * @see java.lang.Object#toString()
2878:                 */
2879:                public String toString() {
2880:                    String result = null;
2881:
2882:                    StringBuffer strbuf = new StringBuffer();
2883:
2884:                    try {
2885:                        strbuf.append(
2886:                                ((AbstractChildObject) getObject()).getName())
2887:                                .append(" ").append(m_nPosition);
2888:                        result = strbuf.toString();
2889:                    } catch (DataAccessException e) {
2890:                        m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
2891:                    } catch (CacheException e) {
2892:                        m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
2893:                    }
2894:
2895:                    return result;
2896:                }
2897:
2898:                /**
2899:                 * Returns a cache pointer which references the given 
2900:                 * child object
2901:                 * 
2902:                 * @param child the child object
2903:                 * @return an cache pointer
2904:                 * @throws PopulateException if there is an error populating the list of 
2905:                 * children
2906:                 * @throws CacheException if there is an error accessing the object held 
2907:                 * in an orderable cache pointer
2908:                 */
2909:                public CachePointer getCachePointer() {
2910:                    return new CachePointer(this .getKey(), this .getCache());
2911:                }
2912:
2913:                /* (non-Javadoc)
2914:                 * @see java.lang.Object#equals(java.lang.Object)
2915:                 */
2916:                public boolean equals(Object obj) {
2917:                    boolean bEq = false;
2918:
2919:                    if (obj instanceof  CachePointer) {
2920:                        CachePointer ptr = (CachePointer) obj;
2921:
2922:                        if (this  == ptr) {
2923:                            bEq = true;
2924:                        } else if (ptr.getCache().equals(m_cache) == true
2925:                                && ptr.getKey().equals(m_cache_key) == true) {
2926:                            bEq = true;
2927:
2928:                            if (ptr instanceof  OrderableCachePointer
2929:                                    && bEq == true
2930:                                    && ((OrderableCachePointer) ptr).m_nPosition != this .m_nPosition) {
2931:                                bEq = false;
2932:                            }
2933:                        }
2934:                    }
2935:
2936:                    return bEq;
2937:                }
2938:
2939:            }
2940:
2941:            /**
2942:             * 
2943:             * Comparator class for <code>OrderableCachePointer</code> sorting
2944:             * 
2945:             * @author Michael Bell
2946:             * @version $Revision: 1.6.2.1 $
2947:             *
2948:             */
2949:            private class OrderableCachePointerComparator implements  Comparator {
2950:
2951:                /* (non-Javadoc)
2952:                 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
2953:                 */
2954:                public int compare(Object arg1, Object arg2) {
2955:                    OrderableCachePointer ptr1 = (OrderableCachePointer) arg1;
2956:                    OrderableCachePointer ptr2 = (OrderableCachePointer) arg2;
2957:
2958:                    int nCompare = 0;
2959:                    int nPos1 = ptr1.getPosition();
2960:                    int nPos2 = ptr2.getPosition();
2961:
2962:                    if (nPos1 != nPos2) {
2963:
2964:                        //makre sure that any index of -1 gets pushed to the end 
2965:                        //of the list
2966:                        if (nPos2 == -1) {
2967:                            nCompare = 1;
2968:                        } else {
2969:                            nCompare = nPos1 - nPos2;
2970:                        }
2971:
2972:                    } else {
2973:
2974:                        try {
2975:                            AbstractChildObject child1 = (AbstractChildObject) ptr1
2976:                                    .getObject();
2977:                            AbstractChildObject child2 = (AbstractChildObject) ptr2
2978:                                    .getObject();
2979:
2980:                            nCompare = child1.compareTo(child2);
2981:                        } catch (CacheException e) {
2982:                            m_logger.log(Level.WARNING,
2983:                                    e.getLocalizedMessage(), e);
2984:                            nCompare = 0;
2985:                        }
2986:                    }
2987:
2988:                    return nCompare;
2989:                }
2990:
2991:            }
2992:
2993:            /**
2994:             * Returns an ordered set of this object's children
2995:             * 
2996:             * @return an ordered set of this object's children
2997:             */
2998:            private Set getOrderedChildPointers() {
2999:                TreeSet sortedSet = new TreeSet(
3000:                        new OrderableCachePointerComparator());
3001:                sortedSet.addAll(m_children);
3002:
3003:                return sortedSet;
3004:            }
3005:
3006:            /**
3007:             * Returns an orderable cache pointer which references the given 
3008:             * child object.
3009:             * 
3010:             * @param child the child object
3011:             * @return an orderable cache pointer
3012:             * @throws PopulateException if there is an error populating the list of 
3013:             * children
3014:             * @throws CacheException if there is an error accessing the object held 
3015:             * in an orderable cache pointer
3016:             */
3017:            private OrderableCachePointer getCachePointer(
3018:                    AbstractChildObject child) throws PopulateException,
3019:                    CacheException {
3020:                if (m_bIsChildrenPopulated == false) {
3021:                    populateChildrenFromDatabase();
3022:                }
3023:                OrderableCachePointer result = null;
3024:                Iterator iter = m_children.iterator();
3025:                boolean bFound = false;
3026:                while (iter.hasNext() && bFound == false) {
3027:                    OrderableCachePointer ptr = (OrderableCachePointer) iter
3028:                            .next();
3029:
3030:                    if (((AbstractChildObject) ptr.getObject()).getId() == child
3031:                            .getId()
3032:                            && ((AbstractChildObject) ptr.getObject())
3033:                                    .getClass().equals(child.getClass())) {
3034:                        bFound = true;
3035:                        result = ptr;
3036:                    }
3037:                }
3038:
3039:                return result;
3040:            }
3041:
3042:            /* (non-Javadoc)
3043:             * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
3044:             */
3045:            public ColumnRef getInstanceColumnRef(String sColumn,
3046:                    boolean bIsHist) throws DataStoreException {
3047:                ColumnRef returnColRef = null;
3048:
3049:                if (sColumn.equals(TAG_SUBGROUPS) == true) {
3050:                    returnColRef = this 
3051:                            .getParentChildJoinColumnRef(TAG_CHILDREN);
3052:                } else if (sColumn.equals(TAG_GROUP) == true) {
3053:                    returnColRef = this.getParentChildJoinColumnRef(sColumn);
3054:                }
3055:
3056:                if (returnColRef != null) {
3057:                    return returnColRef;
3058:                } else {
3059:                    return super.getInstanceColumnRef(sColumn, bIsHist);
3060:                }
3061:            }
3062:
3063:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.