Source Code Cross Referenced for Search.java in  » Content-Management-System » harmonise » org » openharmonise » rm » search » 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.search 
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.search;
0020:
0021:        import java.sql.*;
0022:        import java.util.*;
0023:        import java.util.logging.*;
0024:
0025:        import org.openharmonise.commons.cache.CacheException;
0026:        import org.openharmonise.commons.dsi.*;
0027:        import org.openharmonise.commons.dsi.dml.*;
0028:        import org.openharmonise.commons.xml.*;
0029:        import org.openharmonise.rm.*;
0030:        import org.openharmonise.rm.config.*;
0031:        import org.openharmonise.rm.dsi.DataStoreObject;
0032:        import org.openharmonise.rm.factory.*;
0033:        import org.openharmonise.rm.metadata.*;
0034:        import org.openharmonise.rm.publishing.*;
0035:        import org.openharmonise.rm.resources.*;
0036:        import org.openharmonise.rm.resources.lifecycle.Status;
0037:        import org.openharmonise.rm.resources.metadata.properties.*;
0038:        import org.openharmonise.rm.resources.metadata.properties.ranges.Range;
0039:        import org.openharmonise.rm.resources.publishing.*;
0040:        import org.openharmonise.rm.security.authorization.*;
0041:        import org.w3c.dom.*;
0042:
0043:        /**
0044:         * <p>Provides an interface to construct and run searches over 
0045:         * resources within the repository, allowing metadata conditions to be 
0046:         * specified using implementations of <code>AbstractPropertyInstance</code>
0047:         * core data conditions to be specified using <code>ColumnRef</code>.
0048:         * The class also implements <code>Publishable</code> in order that
0049:         * a search can be specified in HaRP and the results can be published
0050:         * as XML.</p>
0051:         * 
0052:         * @author Michael Bell
0053:         * @version $Revision: 1.10 $
0054:         *
0055:         */
0056:        public class Search implements  Publishable {
0057:
0058:            private boolean m_bCache = true;
0059:
0060:            //XML constants
0061:            public static final String ATTRIB_ORDERBY = "orderBy";
0062:
0063:            public static final String ATTRIB_ORDER_DIRECTION = "orderDirection";
0064:
0065:            public static final String ATTRIB_OBJECT_TYPE = "objectType";
0066:
0067:            public static final String TAG_SEARCH = "Search";
0068:
0069:            public static final String TAG_LIST = "List";
0070:
0071:            public static final String ATTRIB_MAXRESULTS = "maxResults";
0072:
0073:            public static final String TAG_SEARCHTEXT = "SearchText";
0074:
0075:            public static final String TAG_FURTHERLINKS = "FurtherLinks";
0076:
0077:            public static final String TAG_NUMBER = "Number";
0078:
0079:            public static final String TAG_SEARCHCONDITIONS = "SearchConditions";
0080:
0081:            public static final String TAG_SEARCH_OBJECT = "SearchObject";
0082:
0083:            public static final String TAG_CONDITIONS = "Conditions";
0084:
0085:            public static final String TAG_FILTERCONDITIONS = "FilterConditions";
0086:
0087:            public static final String TAG_FILTERSOURCE = "FilterSource";
0088:
0089:            public static final String TAG_SUBMIT = "Submit";
0090:
0091:            public static final String ATTRIB_STRICT_TYPING = "strictTyping";
0092:
0093:            public static final String TAG_COMMENT = "Comment";
0094:
0095:            public static final String TAG_POSITION = "Position";
0096:
0097:            public static final String TAG_DISPLAY = "Display";
0098:
0099:            public static final String TAG_TOTAL = "Total";
0100:
0101:            public static final String ATTRIB_SUB = "sub";
0102:
0103:            public static final String ATTRIB_SELECTED = "selected";
0104:
0105:            public static final String ATTRIB_INCLUSIVE = "inclusive";
0106:
0107:            public static final String TAG_AND = "And";
0108:
0109:            public static final String TAG_OR = "Or";
0110:
0111:            private static String PNAME_RESULTSET_CACHING = "RESULTSET_CACHING";
0112:
0113:            /**
0114:             * Vector of WhereCondition objects, all of the columns that an object
0115:             * manages itself.
0116:             */
0117:            protected List m_ConditionColumns = null;
0118:
0119:            /**
0120:             * Vector of GroupObjects identifying which groups should be in the search
0121:             */
0122:            protected List m_ConditionGroups = null;
0123:
0124:            /**
0125:             * the properties to be used in the search
0126:             */
0127:            protected List m_ConditionProfile = null;
0128:
0129:            /**
0130:             * Vector of ColumnRefs, identifies which columns should be returned
0131:             */
0132:            protected List m_SearchColumns = null;
0133:
0134:            /**
0135:             * Vector of Properties, identifies which Properties should be returned
0136:             */
0137:            protected List m_SearchProfile = null;
0138:
0139:            /**
0140:             * String operator to link the condition profile properties
0141:             */
0142:            protected String m_ConditionOperator = "and";
0143:
0144:            protected Map m_orderByPropMap = new LinkedHashMap();
0145:
0146:            protected Map m_orderByColMap = new LinkedHashMap();
0147:
0148:            protected String m_sOrderDirection = "ASC";
0149:
0150:            protected int m_nLimit = -1;
0151:
0152:            //position in the results the listings should start from
0153:            protected int m_nPosition = 0;
0154:
0155:            protected String m_sSearchType = "";
0156:
0157:            protected String m_sSearchText = "";
0158:
0159:            protected DataStoreObject m_searchObject = null;
0160:
0161:            protected Profile m_searchObjectProfile = null;
0162:
0163:            protected boolean m_bApprovedSearch = true;
0164:
0165:            protected String m_sFilterObjectClassname = null;
0166:
0167:            protected Vector m_filterProps = null;
0168:
0169:            protected AbstractDataStoreInterface m_dsi = null;
0170:
0171:            protected String m_sId = "";
0172:
0173:            protected String m_sName = "";
0174:
0175:            protected int m_nResultTotal = -1;
0176:
0177:            protected boolean m_bStrictType = true;
0178:
0179:            //	set in getIndexSearchQuery if correct columns exist
0180:            protected boolean m_bIndexableSearch = false;
0181:
0182:            protected CachedResultSet m_cached_rs = null;
0183:
0184:            protected boolean m_bFilterCondsNotFound = false;
0185:
0186:            protected boolean m_bFilterCondsInclusive = false;
0187:
0188:            private List m_indexresults = null;
0189:
0190:            private boolean m_bIsCachingRS = false;
0191:
0192:            private String m_sCacheKey = null;
0193:
0194:            /**
0195:             * Logger for this class
0196:             */
0197:            private static final Logger m_logger = Logger
0198:                    .getLogger(Search.class.getName());
0199:
0200:            //initialising block
0201:            {
0202:                m_ConditionColumns = new Vector(16);
0203:                m_ConditionGroups = new Vector(16);
0204:                m_ConditionProfile = new Vector(16);
0205:
0206:                m_SearchColumns = new Vector(16);
0207:                m_SearchProfile = new Vector(16);
0208:            }
0209:
0210:            /**
0211:             * Basic constructor
0212:             *  
0213:             */
0214:            public Search() {
0215:            }
0216:
0217:            /**
0218:             * Standard constructor with interface to the DB.
0219:             * 
0220:             * @param dbinterf
0221:             */
0222:            public Search(AbstractDataStoreInterface dbinterf) {
0223:                m_dsi = dbinterf;
0224:            }
0225:
0226:            /**
0227:             * Returns an object of the type that the search will be conducted on.
0228:             * 
0229:             * @return
0230:             */
0231:            public DataStoreObject getSearchType() {
0232:                return m_searchObject;
0233:            }
0234:
0235:            /**
0236:             * Sets the object type that the search will be conducted on.
0237:             * 
0238:             * @param dobj
0239:             * @throws DataStoreException
0240:             */
0241:            public void setSearchType(DataStoreObject dobj)
0242:                    throws DataStoreException {
0243:
0244:                if (m_searchObject != null) {
0245:                    if (dobj instanceof  AbstractProfiledObject) {
0246:                        AbstractProfiledObject profObj = (AbstractProfiledObject) dobj;
0247:
0248:                        try {
0249:                            m_searchObjectProfile = profObj.getProfile();
0250:                        } catch (DataAccessException e) {
0251:                            m_searchObjectProfile = null;
0252:                        }
0253:
0254:                        if (m_searchObjectProfile == null) {
0255:                            m_searchObjectProfile = new Profile(m_dsi, profObj);
0256:                        }
0257:                        Profile prof = m_searchObjectProfile;
0258:
0259:                        for (int i = 0; i < this .m_ConditionProfile.size(); i++) {
0260:                            AbstractPropertyInstance propInst = (AbstractPropertyInstance) m_ConditionProfile
0261:                                    .get(i);
0262:                            propInst.setProfile(prof);
0263:                        }
0264:
0265:                        for (int i = 0; i < this .m_SearchProfile.size(); i++) {
0266:                            AbstractPropertyInstance propInst = (AbstractPropertyInstance) m_ConditionProfile
0267:                                    .get(i);
0268:                            propInst.setProfile(prof);
0269:                        }
0270:                    }
0271:
0272:                    m_SearchColumns.clear();
0273:                    m_SearchColumns.add(dobj.getInstanceColumnRef(
0274:                            AbstractObject.ATTRIB_ID, ((AbstractObject) dobj)
0275:                                    .isHistorical()));
0276:                    m_ConditionColumns.clear();
0277:                    m_orderByPropMap.clear();
0278:                    m_orderByColMap.clear();
0279:                }
0280:
0281:                m_searchObject = dobj;
0282:                m_sSearchType = dobj.getClass().getName();
0283:
0284:                ColumnRef colrefId = m_searchObject.getInstanceColumnRef(
0285:                        AbstractObject.ATTRIB_ID,
0286:                        ((AbstractObject) m_searchObject).isHistorical());
0287:
0288:                if (colrefId != null) {
0289:                    addSelectColumn(colrefId);
0290:                }
0291:
0292:                if (m_sSearchType.indexOf(".") >= 0) {
0293:                    int index = m_sSearchType.lastIndexOf(".");
0294:                    m_sSearchType = m_sSearchType.substring(index + 1);
0295:                }
0296:            }
0297:
0298:            /**
0299:             * Sets the maximum size of the list of results.
0300:             * 
0301:             * @param nNum
0302:             */
0303:            public void setResultSize(int nNum) {
0304:                this .m_nLimit = nNum;
0305:            }
0306:
0307:            /**
0308:             * Sets the column which will be used for ordering the results as well as
0309:             * the direction of the ordering.
0310:             * 
0311:             * @param colref
0312:             * @param sOrderDirection
0313:             */
0314:            public void setOrderBy(ColumnRef colref, String sOrderDirection) {
0315:                m_orderByColMap.put(colref, sOrderDirection);
0316:            }
0317:
0318:            /**
0319:             * Sets the property instance which should be used to order the search
0320:             * results as well as the direction of the ordering.
0321:             * 
0322:             * @param propInst
0323:             * @param sOrderDirection
0324:             */
0325:            public void setOrderBy(AbstractPropertyInstance propInst,
0326:                    String sOrderDirection) {
0327:                m_orderByPropMap.put(propInst, sOrderDirection);
0328:            }
0329:
0330:            /**
0331:             * Returns a <code>Set</code> of <code>ColumnRef</code>s which 
0332:             * represents the column by which the results will be ordered.
0333:             * 
0334:             * @return a <code>Set</code> of <code>ColumnRef</code>s
0335:             */
0336:            public Set getOrderByColumns() {
0337:                return m_orderByColMap.keySet();
0338:            }
0339:
0340:            /* (non-Javadoc)
0341:             * @see org.openharmonise.rm.publishing.Publishable#getTagName()
0342:             */
0343:            public String getTagName() {
0344:
0345:                return TAG_SEARCH;
0346:            }
0347:
0348:            /**
0349:             * Returns the direction the results will be ordered in
0350:             * for the specified column reference.
0351:             * 
0352:             * @return the direction the results will be ordered in
0353:             * for the specified column reference
0354:             */
0355:            public String getOrderDirection(ColumnRef colref) {
0356:                return (String) m_orderByColMap.get(colref);
0357:            }
0358:
0359:            /**
0360:             * Adds a condition to the search. Defined by column, operator and value.
0361:             * 
0362:             * @param colref
0363:             * @param sOperator
0364:             * @param values
0365:             * @throws DataStoreException
0366:             */
0367:            public void addConditionColumn(ColumnRef colref, String sOperator,
0368:                    Vector values) throws DataStoreException {
0369:                WhereCondition where = new WhereCondition(colref, sOperator,
0370:                        values);
0371:
0372:                m_ConditionColumns.add(where);
0373:            }
0374:
0375:            /**
0376:             * Adds a relationship condition to the search such that results will be
0377:             * children of the given <code>AbstractParentObject</code>.
0378:             * 
0379:             * @param grpObj
0380:             */
0381:            public void addConditionGroup(AbstractParentObject grpObj) {
0382:                if (grpObj != null) {
0383:                    m_ConditionGroups.add(grpObj);
0384:                }
0385:            }
0386:
0387:            /**
0388:             * Adds a condition to this search which is defined by the given
0389:             * <code>AbstractPropertyInstance</code>.
0390:             * 
0391:             * @param propInst
0392:             */
0393:            public void addConditionProperty(AbstractPropertyInstance propInst) {
0394:                m_ConditionProfile.add(propInst);
0395:            }
0396:
0397:            /**
0398:             * Adds conditions to the search defined by the given <code>Profile</code>,
0399:             * i.e. the conditions will be specified by the property instances the
0400:             * profile contains.
0401:             * 
0402:             * @param prof
0403:             * @throws DataAccessException
0404:             */
0405:            public void addConditionProfile(Profile prof)
0406:                    throws DataAccessException {
0407:                m_ConditionProfile.addAll(prof.getPropertyInstances());
0408:            }
0409:
0410:            /**
0411:             * Adds a select column to be returned in the search. Objects which are
0412:             * returned will be populated with this data from the executed search as an
0413:             * optimisation.
0414:             * 
0415:             * Note: the column referenced will be associated to the object's core data
0416:             * rather than profile data
0417:             * 
0418:             * @param colref
0419:             */
0420:            public void addSelectColumn(ColumnRef colref) {
0421:                m_SearchColumns.add(colref);
0422:            }
0423:
0424:            /**
0425:             * Adds a select column to be returned in the search which corresponds to
0426:             * the given property instance. Objects which are returned will be populated
0427:             * with this data from the executed search as an optimisation.
0428:             * 
0429:             * @param propInst
0430:             */
0431:            public void addSelectProperty(AbstractPropertyInstance propInst) {
0432:                m_SearchProfile.add(propInst);
0433:            }
0434:
0435:            /**
0436:             * Executed the search and returns a vector of objects representing the
0437:             * results of the search.
0438:             * 
0439:             * @return @throws
0440:             *         SearchException
0441:             * @throws HarmoniseIndexerException
0442:             * @throws DataAccessException
0443:             * @throws DataStoreException
0444:             */
0445:            public List executeSearch() throws SearchException,
0446:                    HarmoniseIndexerException, DataAccessException,
0447:                    DataStoreException {
0448:                Vector results = null;
0449:
0450:                SelectStatement select = generateSelectStatement();
0451:
0452:                //if no cached results do DB query
0453:                if (m_cached_rs == null) {
0454:                    ResultSet rs = null;
0455:
0456:                    if ((m_bIndexableSearch == false)
0457:                            || (m_indexresults != null && m_indexresults.size() > 0)) {
0458:
0459:                        if (m_logger.isLoggable(Level.FINE)) {
0460:                            m_logger.logp(Level.FINE,
0461:                                    this .getClass().getName(), "executeSearch",
0462:                                    "Executing search - "
0463:                                            + m_dsi.getSelectStatement(select));
0464:                        }
0465:
0466:                        rs = m_dsi.execute(select);
0467:
0468:                        m_cached_rs = new CachedResultSet(rs);
0469:                    }
0470:
0471:                    if (rs != null) {
0472:                        try {
0473:                            rs.close();
0474:                        } catch (SQLException e) {
0475:                            throw new SearchException(
0476:                                    "Error closing result set", e);
0477:                        }
0478:                    }
0479:
0480:                    if ((m_cached_rs != null) && (m_bIsCachingRS == true)) {
0481:                        if (m_logger.isLoggable(Level.FINE)) {
0482:                            m_logger.log(Level.FINE,
0483:                                    "Caching search results for "
0484:                                            + m_dsi.getSelectStatement(select));
0485:                        }
0486:                        try {
0487:                            SearchResultsCache.getInstance().addToCache(
0488:                                    m_sCacheKey, m_cached_rs);
0489:                        } catch (CacheException e) {
0490:                            throw new SearchException("Cache error", e);
0491:                        }
0492:                    } else {
0493:                        if (m_logger.isLoggable(Level.FINE)) {
0494:                            m_logger.log(Level.FINE,
0495:                                    "Not caching search results");
0496:                        }
0497:                    }
0498:                } else {
0499:                    if (m_logger.isLoggable(Level.FINE)) {
0500:                        m_logger.log(Level.FINE, "Got cached search results");
0501:                    }
0502:                }
0503:
0504:                //fill return vector with objects
0505:                List returnVec = new Vector(16);
0506:
0507:                if (m_cached_rs != null) {
0508:                    m_cached_rs.setStartRow(m_nPosition);
0509:
0510:                    //if no limit is set this should be default value of -1
0511:                    returnVec = m_searchObject.processResultSet(m_cached_rs,
0512:                            select, m_nLimit - m_nPosition);
0513:
0514:                    m_nResultTotal = m_cached_rs.getResultTotal();
0515:                }
0516:
0517:                return returnVec;
0518:            }
0519:
0520:            public SelectStatement generateSelectStatement()
0521:                    throws SearchException, HarmoniseIndexerException,
0522:                    DataAccessException, DataStoreException {
0523:                //build query
0524:                SelectStatement select = new SelectStatement();
0525:
0526:                //add the select colomn refs to the select statement
0527:                select.addSelectColumns(m_SearchColumns);
0528:
0529:                if (m_orderByColMap.isEmpty() == false) {
0530:                    select.addOrderBy(m_orderByColMap);
0531:                }
0532:
0533:                HarmoniseIndexer indexer = HarmoniseIndexer.getInstance();
0534:
0535:                //get index query if applicable
0536:                String sIndexQuery = "";
0537:
0538:                if (this .m_bApprovedSearch == true) {
0539:                    sIndexQuery = getIndexSearchQuery();
0540:
0541:                    if (m_logger.isLoggable(Level.FINE)) {
0542:                        m_logger.log(Level.FINE, "Index search:" + sIndexQuery);
0543:                    }
0544:                }
0545:
0546:                //add conditions to select statement
0547:                addWhereConditions(select);
0548:
0549:                m_sCacheKey = sIndexQuery + "|"
0550:                        + this .m_dsi.getSelectStatement(select);
0551:
0552:                //try and get cached results
0553:                m_bIsCachingRS = m_bCache;
0554:
0555:                if (m_bCache == true) {
0556:                    try {
0557:                        m_bIsCachingRS = ConfigSettings.getProperty(
0558:                                PNAME_RESULTSET_CACHING, "ON").equals("ON");
0559:
0560:                        if (m_bIsCachingRS == true) {
0561:                            if (m_logger.isLoggable(Level.FINE)) {
0562:                                m_logger.logp(Level.FINER, this .getClass()
0563:                                        .getName(), "generateSelectStatement",
0564:                                        "Getting cached results for "
0565:                                                + m_sCacheKey);
0566:                            }
0567:                            m_cached_rs = SearchResultsCache.getInstance()
0568:                                    .getResults(m_sCacheKey);
0569:                            if (m_logger.isLoggable(Level.FINE)
0570:                                    && m_cached_rs == null) {
0571:                                m_logger.logp(Level.FINER, this .getClass()
0572:                                        .getName(), "generateSelectStatement",
0573:                                        "No results cached");
0574:                            }
0575:                        }
0576:                    } catch (ConfigException e) {
0577:                        throw new SearchException("Config error", e);
0578:                    } catch (CacheException e) {
0579:                        throw new SearchException("Cache error", e);
0580:                    }
0581:                }
0582:
0583:                if (m_cached_rs == null) {
0584:                    m_indexresults = null;
0585:                    if ((sIndexQuery != null) && (sIndexQuery.length() > 0)) {
0586:                        m_indexresults = indexer.searchContents(sIndexQuery);
0587:
0588:                        if (m_logger.isLoggable(Level.FINE)) {
0589:                            m_logger
0590:                                    .log(Level.FINE, "there was "
0591:                                            + m_indexresults.size()
0592:                                            + " lucene results");
0593:                        }
0594:
0595:                        select.addWhereCondition(this .m_searchObject
0596:                                .getInstanceColumnRef(AbstractObject.ATTRIB_ID,
0597:                                        ((AbstractObject) m_searchObject)
0598:                                                .isHistorical()), "IN",
0599:                                (Vector) m_indexresults);
0600:
0601:                    }
0602:                }
0603:
0604:                return select;
0605:            }
0606:
0607:            /* (non-Javadoc)
0608:             * @see org.openharmonise.rm.publishing.Publishable#publish(org.openharmonise.rm.resources.publishing.Template, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
0609:             */
0610:            public org.w3c.dom.Element publish(Template template,
0611:                    HarmoniseOutput xmlDoc, State state)
0612:                    throws PublishException {
0613:                Element resultEl = null;
0614:
0615:                try {
0616:
0617:                    resultEl = publish(template.getTemplateRootElement(),
0618:                            xmlDoc, state);
0619:                } catch (DataAccessException e) {
0620:                    throw new PublishException(e);
0621:                }
0622:
0623:                return resultEl;
0624:            }
0625:
0626:            /* (non-Javadoc)
0627:             * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
0628:             */
0629:            public org.w3c.dom.Element publish(Element topEl,
0630:                    HarmoniseOutput xmlDoc, State state)
0631:                    throws PublishException {
0632:                Element docEl;
0633:
0634:                String sTagname = topEl.getTagName();
0635:
0636:                if (m_logger.isLoggable(Level.FINE)) {
0637:                    m_logger.log(Level.FINE, "Publishing " + sTagname
0638:                            + " element");
0639:                }
0640:
0641:                if (sTagname.equalsIgnoreCase(TAG_LIST)) {
0642:                    if (m_logger.isLoggable(Level.FINE)) {
0643:                        m_logger.log(Level.FINE, "Publishing as List element");
0644:                    }
0645:                    docEl = list(topEl, xmlDoc, state);
0646:                } else if (sTagname.equalsIgnoreCase(TAG_SEARCH)) {
0647:                    if (m_logger.isLoggable(Level.FINE)) {
0648:                        m_logger
0649:                                .log(Level.FINE, "Publishing as Search element");
0650:                    }
0651:                    docEl = search(topEl, xmlDoc, state);
0652:                } else {
0653:                    if (m_logger.isLoggable(Level.FINE)) {
0654:                        m_logger.log(Level.FINE, "Didn't recognise element");
0655:                    }
0656:                    docEl = (Element) xmlDoc.copyNode(topEl);
0657:                }
0658:
0659:                return docEl;
0660:            }
0661:
0662:            /* (non-Javadoc)
0663:             * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
0664:             */
0665:            public void populate(Element xmlElement, State state)
0666:                    throws PopulateException {
0667:                if ((xmlElement.getTagName().equals(TAG_SEARCH) == false)
0668:                        && (xmlElement.getTagName().equals(TAG_LIST) == false)) {
0669:                    throw new PopulateException("Expected either " + TAG_SEARCH
0670:                            + " or " + TAG_LIST + " got "
0671:                            + xmlElement.getTagName());
0672:                }
0673:
0674:                boolean bIsList = false;
0675:
0676:                if (xmlElement.getTagName().equals(TAG_LIST)) {
0677:                    bIsList = true;
0678:                }
0679:
0680:                if (xmlElement.getAttribute(AbstractObject.ATTRIB_ID)
0681:                        .equals("") == false) {
0682:                    m_sId = xmlElement.getAttribute(AbstractObject.ATTRIB_ID);
0683:                }
0684:
0685:                if (xmlElement.getAttribute(AbstractObject.ATTRIB_NAME).equals(
0686:                        "") == false) {
0687:                    m_sName = xmlElement
0688:                            .getAttribute(AbstractObject.ATTRIB_NAME);
0689:                }
0690:
0691:                if (xmlElement.getAttribute(ATTRIB_MAXRESULTS).equals("") == false) {
0692:                    m_nLimit = Integer.parseInt(xmlElement
0693:                            .getAttribute(ATTRIB_MAXRESULTS));
0694:                }
0695:
0696:                // get the child nodes for the type of search
0697:                // either list of search
0698:                NodeList nodes = xmlElement.getChildNodes();
0699:                Element formEl;
0700:                Text txt;
0701:                String sTagName;
0702:                Profile pro;
0703:
0704:                // go through each one of them
0705:                for (int i = 0; i < nodes.getLength(); i++) {
0706:                    if (nodes.item(i).getNodeType() == Node.TEXT_NODE) {
0707:                        continue;
0708:                    }
0709:                    formEl = (Element) nodes.item(i);
0710:                    sTagName = formEl.getTagName();
0711:
0712:                    if (sTagName.equalsIgnoreCase(TAG_SEARCHTEXT)) {
0713:                        setSearchText(XMLDocument.getChildTextNodeValue(formEl));
0714:                    } else if (sTagName.equalsIgnoreCase(TAG_CONDITIONS)) {
0715:                        if (bIsList) {
0716:                            try {
0717:                                processSearchConditions(formEl, state);
0718:                            } catch (PublishException e) {
0719:                                throw new PopulateException(
0720:                                        "Error occurred processing search conditions: ",
0721:                                        e);
0722:                            }
0723:                        }
0724:                    } else if (sTagName.equalsIgnoreCase(TAG_SUBMIT)) {
0725:                    } else if (sTagName.equalsIgnoreCase(TAG_SEARCH_OBJECT) == true) {
0726:                        String sSearchTypeTag = "";
0727:                        Element elm = null;
0728:
0729:                        NodeList searchObjectNodes = formEl.getChildNodes();
0730:                        // get all the child nodes
0731:
0732:                        for (int j = 0; j < searchObjectNodes.getLength()
0733:                                && sSearchTypeTag.equals(""); j++) {
0734:                            if (searchObjectNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
0735:                                continue;
0736:                            }
0737:
0738:                            elm = (Element) searchObjectNodes.item(j); // get the
0739:                            // element
0740:                            sSearchTypeTag = elm.getTagName(); // get the tag name
0741:                        }
0742:
0743:                        if (sSearchTypeTag.equals("") == true) {
0744:                            throw new PopulateException(
0745:                                    "Template Tag or Tag for Search object (e.g <Document/>) must be provided");
0746:                        } else if (sSearchTypeTag.equals(Template.TAG_TEMPLATE) == true) {
0747:                            try {
0748:
0749:                                Template tmplt = (Template) HarmoniseObjectFactory
0750:                                        .instantiateHarmoniseObject(
0751:                                                m_dsi,
0752:                                                Template.class.getName(),
0753:                                                Integer
0754:                                                        .parseInt(elm
0755:                                                                .getAttribute(AbstractObject.ATTRIB_ID)));
0756:
0757:                                setSearchType(tmplt.getTemplateRootElement());
0758:                            } catch (NumberFormatException e) {
0759:                                throw new PopulateException(
0760:                                        "Number format exception", e);
0761:                            } catch (DataAccessException e) {
0762:                                throw new PopulateException(
0763:                                        "Error occured getting template root element",
0764:                                        e);
0765:                            } catch (SearchException e) {
0766:                                throw new PopulateException("Search error", e);
0767:                            } catch (DataStoreException e) {
0768:                                throw new PopulateException("Data store error",
0769:                                        e);
0770:                            } catch (HarmoniseFactoryException e) {
0771:                                throw new PopulateException(e);
0772:                            }
0773:                        } else {
0774:                            try {
0775:                                setSearchType(elm);
0776:                            } catch (SearchException e) {
0777:                                throw new PopulateException(
0778:                                        "Problem ocurred while attempting to set search type",
0779:                                        e);
0780:                            } catch (PopulateException e) {
0781:                                throw new PopulateException(
0782:                                        "Problem ocurred while attempting to set search type",
0783:                                        e);
0784:                            } catch (DataStoreException e) {
0785:                                throw new PopulateException(
0786:                                        "Problem ocurred while attempting to set search type",
0787:                                        e);
0788:                            }
0789:                        }
0790:                    }
0791:                }
0792:            }
0793:
0794:            /**
0795:             * Adds the sub groups of the given <code>AbstractParentObject</code> as
0796:             * conditions of this search.
0797:             * 
0798:             * @param grpObj
0799:             * @throws DataAccessException
0800:             */
0801:            public void addSubGroupsAsConditions(AbstractParentObject grpObj)
0802:                    throws DataAccessException {
0803:                if (grpObj != null) {
0804:                    List subGrps = grpObj
0805:                            .getChildrenByType(AbstractParentObject.BRANCH_NODES);
0806:
0807:                    for (int i = 0; i < subGrps.size(); i++) {
0808:                        AbstractParentObject sub = (AbstractParentObject) subGrps
0809:                                .get(i);
0810:                        this .addConditionGroup(sub);
0811:                        addSubGroupsAsConditions(sub);
0812:                    }
0813:                }
0814:
0815:            }
0816:
0817:            /*-------------------------------------------------------------------
0818:             Protected methods
0819:             ------------------------------------------------------------------*/
0820:
0821:            /**
0822:             * Publishes the 'List' element. Executes the search defined by the XML and
0823:             * returns XML which will be a list of results published as specified by the
0824:             * 'Template' child element of 'List'.
0825:             * 
0826:             * @param list
0827:             * @param output
0828:             * @param state
0829:             * @return @throws
0830:             *         PublishException
0831:             */
0832:            protected Element list(Element list, HarmoniseOutput output,
0833:                    State state) throws PublishException {
0834:                if (m_logger.isLoggable(Level.FINE)) {
0835:                    m_logger.log(Level.FINE, "Executing list method");
0836:                }
0837:
0838:                boolean bMore = false;
0839:                NodeList nodes;
0840:                int nMorePage = -2;
0841:                int nPageId = state.getPageId();
0842:                Profile usrProf = state.getLoggedInUserProfile();
0843:
0844:                Element newList = output.createElement(TAG_LIST);
0845:
0846:                if ((m_sName == null) || (m_sName.length() == 0)) {
0847:                    m_sName = list.getAttribute(AbstractObject.ATTRIB_NAME);
0848:                }
0849:
0850:                newList.setAttribute(AbstractObject.ATTRIB_NAME, m_sName);
0851:
0852:                if ((m_sId == null) || (m_sId.length() == 0)) {
0853:                    m_sId = list.getAttribute(AbstractObject.ATTRIB_ID);
0854:                }
0855:
0856:                String sStringTyping = list.getAttribute(ATTRIB_STRICT_TYPING);
0857:
0858:                if ((sStringTyping != null) && (sStringTyping.length() > 0)
0859:                        && (sStringTyping.equalsIgnoreCase("false") == true)) {
0860:                    this .m_bStrictType = false;
0861:                }
0862:
0863:                newList.setAttribute(AbstractObject.ATTRIB_ID, m_sId);
0864:
0865:                if (list.getElementsByTagName("*").getLength() == 0) {
0866:                    return newList;
0867:                }
0868:
0869:                Element searchObjectElm = (Element) XMLUtils
0870:                        .getFirstNamedChild(list, TAG_SEARCH_OBJECT);
0871:
0872:                if (searchObjectElm == null) {
0873:                    throw new PublishException("SearchObject Tag is missing.");
0874:                }
0875:
0876:                String sTagName = "";
0877:                Element elm = null;
0878:
0879:                nodes = searchObjectElm.getChildNodes(); // get all the child nodes
0880:
0881:                for (int i = 0; i < nodes.getLength() && sTagName.equals(""); i++) {
0882:                    if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
0883:                        continue;
0884:                    }
0885:
0886:                    elm = (Element) nodes.item(i); // get the element
0887:                    sTagName = elm.getTagName(); // get the tag name
0888:                }
0889:
0890:                Template template = null;
0891:                int nTemplatePageId = -2;
0892:
0893:                if (sTagName.equals("") == true) {
0894:                    throw new PublishException(
0895:                            "Template Tag or Tag for Search object (e.g <Document/>) must be provided");
0896:                } else if (sTagName.equals(Template.TAG_TEMPLATE) == true) {
0897:                    NodeList pageNodes = elm
0898:                            .getElementsByTagName(WebPage.TAG_PAGE);
0899:
0900:                    if (pageNodes.getLength() > 0) {
0901:                        nTemplatePageId = Integer.parseInt(((Element) pageNodes
0902:                                .item(0))
0903:                                .getAttribute(AbstractObject.ATTRIB_ID));
0904:                    }
0905:
0906:                    try {
0907:                        template = (Template) HarmoniseObjectFactory
0908:                                .instantiateHarmoniseObject(
0909:                                        m_dsi,
0910:                                        Template.class.getName(),
0911:                                        Integer
0912:                                                .parseInt(elm
0913:                                                        .getAttribute(AbstractObject.ATTRIB_ID)));
0914:                    } catch (NumberFormatException e) {
0915:                        throw new PublishException(e);
0916:                    } catch (HarmoniseFactoryException e) {
0917:                        throw new PublishException(e);
0918:                    }
0919:
0920:                    if (template != null) {
0921:                        try {
0922:                            Element root = template.getTemplateRootElement();
0923:
0924:                            setSearchType(root);
0925:                        } catch (DataAccessException e) {
0926:                            throw new PublishException(
0927:                                    "Error getting template root", e);
0928:                        } catch (SearchException e) {
0929:                            throw new PublishException("search error", e);
0930:                        } catch (PopulateException e) {
0931:                            throw new PublishException("Populate error", e);
0932:                        } catch (DataStoreException e) {
0933:                            throw new PublishException("Data store error", e);
0934:                        }
0935:                    } else {
0936:                        throw new InvalidXMLElementException(
0937:                                "Template element not found");
0938:                    }
0939:                } else {
0940:                    try {
0941:                        setSearchType(elm);
0942:                    } catch (SearchException e) {
0943:                        throw new PublishException(
0944:                                "Problem ocurred while attempting to set search type",
0945:                                e);
0946:                    } catch (PopulateException e) {
0947:                        throw new PublishException(
0948:                                "Problem ocurred while attempting to set search type",
0949:                                e);
0950:                    } catch (DataStoreException e) {
0951:                        throw new PublishException(
0952:                                "Problem ocurred while attempting to set search type",
0953:                                e);
0954:                    }
0955:                }
0956:
0957:                //sort out searchconditions if necessary
0958:                nodes = list.getElementsByTagName(TAG_CONDITIONS);
0959:
0960:                Element searchCondEl = null;
0961:                Element stateCondEl = null;
0962:
0963:                if (nodes.getLength() > 0) {
0964:                    searchCondEl = (Element) nodes.item(0);
0965:                    stateCondEl = state.findElement(searchCondEl);
0966:
0967:                    //conditions from state override conditions in input xml
0968:                    if (stateCondEl != null) {
0969:                        searchCondEl = stateCondEl;
0970:                    }
0971:
0972:                    //if the conditions has 'conditions'
0973:                    if (searchCondEl.hasChildNodes()) {
0974:                        processSearchConditions(searchCondEl, state);
0975:                    }
0976:                }
0977:
0978:                nodes = list.getElementsByTagName(TAG_FILTERCONDITIONS);
0979:
0980:                for (int i = 0; i < nodes.getLength(); i++) {
0981:                    Element elFilterConds = (Element) nodes.item(i);
0982:
0983:                    if (elFilterConds.getParentNode().getNodeName()
0984:                            .equalsIgnoreCase(TAG_LIST)) {
0985:                        Profile fListCondProf = createFilterConditionsProfile(
0986:                                elFilterConds, state);
0987:
0988:                        try {
0989:                            if (fListCondProf.match(usrProf) == false) {
0990:                                Element elComment = output
0991:                                        .createElement(TAG_COMMENT);
0992:                                Text txt = output
0993:                                        .createTextNode("User failed list match");
0994:                                elComment.appendChild(txt);
0995:
0996:                                return elComment;
0997:                            }
0998:                        } catch (ProfileException e) {
0999:                            throw new PublishException(
1000:                                    "Error occured matching profiles", e);
1001:                        }
1002:                    } else if (elFilterConds.getParentNode().getNodeName()
1003:                            .equalsIgnoreCase(Template.TAG_TEMPLATE)) {
1004:                        //get filter condition for template and add to search
1005:                        // conditions
1006:                        addFilterSourceConditions(elFilterConds, state);
1007:                    }
1008:                }
1009:
1010:                int nNumber = -1;
1011:                int nMaxResults = -1;
1012:                String sTemp = list.getAttribute(ATTRIB_MAXRESULTS);
1013:
1014:                if ((sTemp != null) && (sTemp.length() > 0)) {
1015:                    nMaxResults = Integer.parseInt(sTemp);
1016:                    nNumber = nMaxResults;
1017:
1018:                    m_nLimit = m_nPosition + nNumber;
1019:                }
1020:
1021:                List results = new Vector();
1022:
1023:                if ((m_bFilterCondsInclusive == false)
1024:                        || (m_bFilterCondsNotFound == false)) {
1025:                    try {
1026:                        results = executeSearch();
1027:                    } catch (SearchException e) {
1028:                        throw new PublishException(
1029:                                "Error occured executing search", e);
1030:                    } catch (HarmoniseIndexerException e) {
1031:                        throw new PublishException(
1032:                                "Error occured with indexer", e);
1033:                    } catch (DataAccessException e) {
1034:                        throw new PublishException("data access error", e);
1035:                    } catch (DataStoreException e) {
1036:                        throw new PublishException("data store error", e);
1037:                    }
1038:                }
1039:
1040:                if (nNumber == -1) {
1041:                    nNumber = results.size();
1042:                }
1043:
1044:                nodes = list.getElementsByTagName(TAG_FURTHERLINKS);
1045:
1046:                Element xnFurtherLinks = null;
1047:
1048:                if (nodes.getLength() > 0) {
1049:                    bMore = true;
1050:
1051:                    NodeList xnlPages = ((Element) nodes.item(0))
1052:                            .getElementsByTagName(WebPage.TAG_PAGE);
1053:
1054:                    if (xnlPages.getLength() > 0) {
1055:                        nMorePage = Integer.parseInt(((Element) xnlPages
1056:                                .item(0))
1057:                                .getAttribute(AbstractObject.ATTRIB_ID));
1058:                    }
1059:                }
1060:
1061:                publishResults(newList, output, state, template, results,
1062:                        nTemplatePageId);
1063:
1064:                if (nMorePage == -1) {
1065:                    nMorePage = nPageId;
1066:                }
1067:
1068:                //add more link if appropriate
1069:                if ((m_nResultTotal > m_nPosition + nNumber) && bMore) {
1070:                    if (xnFurtherLinks == null) {
1071:                        xnFurtherLinks = output.createElement(TAG_FURTHERLINKS);
1072:                    }
1073:
1074:                    xnFurtherLinks.appendChild(createFurtherLinkElement(output,
1075:                            "More", m_nPosition + nNumber, nMorePage));
1076:                }
1077:
1078:                //Add prev link if appropriate
1079:                if ((nNumber != 0) && ((m_nPosition + 1) > nNumber)) {
1080:                    if (xnFurtherLinks == null) {
1081:                        xnFurtherLinks = output.createElement(TAG_FURTHERLINKS);
1082:                    }
1083:
1084:                    xnFurtherLinks.appendChild(createFurtherLinkElement(output,
1085:                            "Previous", m_nPosition - nNumber, nMorePage));
1086:                }
1087:
1088:                if (xnFurtherLinks != null) {
1089:                    newList.appendChild(xnFurtherLinks);
1090:                }
1091:
1092:                Element xnState = output.createElement(State.TAG_STATE);
1093:
1094:                Element xnCond = output.createElement(TAG_CONDITIONS);
1095:
1096:                //set Condition name attribute to same as List
1097:                xnCond.setAttribute(AbstractObject.ATTRIB_NAME, m_sName);
1098:                xnState.appendChild(xnCond);
1099:
1100:                //if there are search conditions in the state append these
1101:                if (searchCondEl != null) {
1102:                    NodeList nlSearchCond = searchCondEl.getChildNodes();
1103:
1104:                    for (int i = 0; i < nlSearchCond.getLength(); i++) {
1105:                        Node node = nlSearchCond.item(i);
1106:
1107:                        if (node.getNodeType() != Node.ELEMENT_NODE) {
1108:                            continue;
1109:                        }
1110:
1111:                        xnCond.appendChild(output.importNode(node, true));
1112:                    }
1113:                }
1114:
1115:                if ((searchCondEl == null)
1116:                        || (searchCondEl.getElementsByTagName(TAG_POSITION)
1117:                                .getLength() == 0)) {
1118:                    Element xnPosition = output.createElement(TAG_POSITION);
1119:                    Text txtPos = output.createTextNode(Integer
1120:                            .toString(m_nPosition));
1121:                    xnPosition.appendChild(txtPos);
1122:                    xnCond.appendChild(xnPosition);
1123:                }
1124:
1125:                Element xnTotal = output.createElement(TAG_TOTAL);
1126:                Text txtTotal = output.createTextNode(Integer
1127:                        .toString(m_nResultTotal));
1128:                xnTotal.appendChild(txtTotal);
1129:                xnCond.appendChild(xnTotal);
1130:
1131:                if (nMaxResults > 0) {
1132:                    Element xnDisplay = output.createElement(TAG_DISPLAY);
1133:                    Text txtNumber = output.createTextNode(Integer
1134:                            .toString(nMaxResults));
1135:                    xnDisplay.appendChild(txtNumber);
1136:                    xnCond.appendChild(xnDisplay);
1137:                }
1138:
1139:                newList.appendChild(xnState);
1140:
1141:                NodeList submitEls = list.getElementsByTagName(TAG_SUBMIT);
1142:
1143:                for (int i = 0; i < submitEls.getLength(); i++) {
1144:                    newList.appendChild(output.copyNode(submitEls.item(i)));
1145:                }
1146:
1147:                return newList;
1148:            }
1149:
1150:            /**
1151:             * Publishes the results contained in <code>results</code> using the given
1152:             * <code>Template</code> under the <code>Element</code> <code>list</code>.
1153:             * 
1154:             * @param list
1155:             * @param output
1156:             * @param state
1157:             * @param template
1158:             * @param results
1159:             * @param nPageId
1160:             * @throws PublishException
1161:             */
1162:            protected void publishResults(Element list, HarmoniseOutput output,
1163:                    State state, Template template, List results, int nPageId)
1164:                    throws PublishException {
1165:                boolean bIsViewable = true;
1166:
1167:                try {
1168:                    WebPage page = (WebPage) HarmoniseObjectFactory
1169:                            .instantiateHarmoniseObject(this .m_dsi,
1170:                                    WebPage.class.getName(), nPageId);
1171:
1172:                    if (AuthorizationValidator.isVisible(state
1173:                            .getLoggedInUser(), page) == false) {
1174:                        bIsViewable = false;
1175:                    }
1176:                } catch (HarmoniseFactoryException e) {
1177:                    throw new PublishException(
1178:                            "Error occured getting object from factory", e);
1179:                } catch (AuthorizationException e) {
1180:                    throw new PublishException(
1181:                            "Error checking permissions on object", e);
1182:                }
1183:
1184:                for (Iterator iter = results.iterator(); iter.hasNext();) {
1185:                    Publishable pObj = (Publishable) iter.next();
1186:
1187:                    Element tmpEl = pObj.publish(template, output, state);
1188:
1189:                    NodeList linkNodes = tmpEl
1190:                            .getElementsByTagName(AbstractObject.TAG_LINK);
1191:
1192:                    if (linkNodes.getLength() > 0) {
1193:                        Element linkNode = (Element) linkNodes.item(0);
1194:
1195:                        if (bIsViewable == false) {
1196:                            linkNode.setAttribute(
1197:                                    AuthorizationValidator.ATTRIB_IS_VIEWABLE,
1198:                                    "false");
1199:                        }
1200:
1201:                        NodeList pageNodes = linkNode
1202:                                .getElementsByTagName(WebPage.TAG_PAGE);
1203:
1204:                        if (pageNodes.getLength() == 0) {
1205:                            Node pageNode = output
1206:                                    .createElement(WebPage.TAG_PAGE);
1207:                            ((Element) pageNode).setAttribute(
1208:                                    AbstractObject.ATTRIB_ID, Integer
1209:                                            .toString(nPageId));
1210:
1211:                            linkNode.appendChild(pageNode);
1212:                        }
1213:                    }
1214:
1215:                    list.appendChild(tmpEl);
1216:
1217:                }
1218:            }
1219:
1220:            /**
1221:             * Publishes the 'Search' element, at most fills in available values for
1222:             * property instances.
1223:             * 
1224:             * @param search
1225:             * @param output
1226:             * @param state
1227:             * @return @throws
1228:             *         PublishException
1229:             */
1230:            protected Element search(Element search, HarmoniseOutput output,
1231:                    State state) throws PublishException {
1232:                Element newSearch = output.createElement(TAG_SEARCH);
1233:                String sSearchName = search
1234:                        .getAttribute(AbstractObject.ATTRIB_NAME);
1235:                newSearch.setAttribute(AbstractObject.ATTRIB_NAME, sSearchName);
1236:                newSearch.setAttribute(AbstractObject.ATTRIB_ID, search
1237:                        .getAttribute(AbstractObject.ATTRIB_ID));
1238:
1239:                NodeList children = search.getChildNodes();
1240:
1241:                for (int i = 0; i < children.getLength(); i++) {
1242:                    if (children.item(i).getNodeType() != Node.ELEMENT_NODE) {
1243:                        continue;
1244:                    }
1245:
1246:                    Element elTemp = (Element) children.item(i);
1247:                    String sTagName = elTemp.getTagName();
1248:
1249:                    if (sTagName.equalsIgnoreCase(TAG_SEARCHTEXT)) {
1250:                        Element searchtext = output
1251:                                .createElement(TAG_SEARCHTEXT);
1252:                        m_sSearchText = ((Text) elTemp.getFirstChild())
1253:                                .getNodeValue();
1254:
1255:                        Text txt = output.createTextNode(this .m_sSearchText);
1256:                        searchtext.appendChild(txt);
1257:                        newSearch.appendChild(searchtext);
1258:                    } else if (sTagName.equalsIgnoreCase(TAG_CONDITIONS)) {
1259:                        Element condEl = output.createElement(TAG_CONDITIONS);
1260:                        String sCondName = elTemp
1261:                                .getAttribute(AbstractObject.ATTRIB_NAME);
1262:                        condEl.setAttribute(AbstractObject.ATTRIB_NAME,
1263:                                sCondName);
1264:
1265:                        NodeList nodes = elTemp.getChildNodes();
1266:
1267:                        for (int j = 0; j < nodes.getLength(); j++) {
1268:                            if (nodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
1269:                                continue;
1270:                            }
1271:
1272:                            Element subEl = (Element) nodes.item(j);
1273:
1274:                            if (subEl.getTagName().equalsIgnoreCase(
1275:                                    AbstractChildObject.TAG_GROUP)) {
1276:                                Element groupEl = output
1277:                                        .createElement(AbstractChildObject.TAG_GROUP);
1278:                                groupEl.setAttribute(ATTRIB_SUB, subEl
1279:                                        .getAttribute(ATTRIB_SUB));
1280:
1281:                                NodeList groupNodes = subEl
1282:                                        .getElementsByTagName(Template.TAG_TEMPLATE);
1283:
1284:                                if (groupNodes.getLength() > 0) {
1285:                                    Element templateEl = (Element) groupNodes
1286:                                            .item(0);
1287:                                    Template tmplt = null;
1288:                                    try {
1289:                                        tmplt = (Template) HarmoniseObjectFactory
1290:                                                .instantiateHarmoniseObject(
1291:                                                        m_dsi,
1292:                                                        Template.class
1293:                                                                .getName(),
1294:                                                        Integer
1295:                                                                .parseInt(templateEl
1296:                                                                        .getAttribute(AbstractObject.ATTRIB_ID)));
1297:                                    } catch (NumberFormatException e) {
1298:                                        throw new PublishException(e);
1299:                                    } catch (HarmoniseFactoryException e) {
1300:                                        throw new PublishException(e);
1301:                                    }
1302:                                    Element child = (Element) templateEl
1303:                                            .getElementsByTagName("*").item(0);
1304:                                    try {
1305:                                        AbstractParentObject grpObj = (AbstractParentObject) HarmoniseObjectFactory
1306:                                                .instantiatePublishableObject(
1307:                                                        this .m_dsi, child,
1308:                                                        state);
1309:                                        groupEl.appendChild(grpObj.publish(
1310:                                                tmplt, output, state));
1311:
1312:                                        if (subEl.getAttribute(ATTRIB_SUB)
1313:                                                .equalsIgnoreCase("true")) {
1314:                                            List subGrps = grpObj
1315:                                                    .getChildrenByType(AbstractParentObject.BRANCH_NODES);
1316:
1317:                                            for (int k = 0; k < subGrps.size(); k++) {
1318:                                                AbstractParentObject sub = (AbstractParentObject) subGrps
1319:                                                        .get(k);
1320:                                                groupEl.appendChild(sub
1321:                                                        .publish(tmplt, output,
1322:                                                                state));
1323:                                            }
1324:                                        }
1325:                                    } catch (HarmoniseFactoryException e) {
1326:                                        throw new PublishException(
1327:                                                "Factory exception", e);
1328:                                    } catch (DataAccessException e) {
1329:                                        throw new PublishException(
1330:                                                "Data access exception", e);
1331:                                    }
1332:                                }
1333:
1334:                                condEl.appendChild(groupEl);
1335:                            } else if (subEl.getTagName().equalsIgnoreCase(
1336:                                    Template.TAG_TEMPLATE)) {
1337:                                Element el = (Element) subEl
1338:                                        .getElementsByTagName("*").item(0);
1339:
1340:                                try {
1341:                                    Publishable pobj = HarmoniseObjectFactory
1342:                                            .instantiatePublishableObject(
1343:                                                    this .m_dsi, el, state);
1344:
1345:                                    Template tmplt = (Template) HarmoniseObjectFactory
1346:                                            .instantiateHarmoniseObject(
1347:                                                    m_dsi,
1348:                                                    Template.class.getName(),
1349:                                                    Integer
1350:                                                            .parseInt(subEl
1351:                                                                    .getAttribute(AbstractObject.ATTRIB_ID)));
1352:
1353:                                    condEl.appendChild(pobj.publish(tmplt,
1354:                                            output, state));
1355:                                } catch (HarmoniseFactoryException e) {
1356:                                    // do nothing - just doesn't figure in conditions
1357:                                    m_logger.log(Level.WARNING, e
1358:                                            .getLocalizedMessage(), e);
1359:                                } catch (NumberFormatException e) {
1360:                                    throw new PublishException(e);
1361:                                }
1362:                            } else if (subEl
1363:                                    .getTagName()
1364:                                    .equalsIgnoreCase(
1365:                                            AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1366:
1367:                                AbstractPropertyInstance pobj = null;
1368:
1369:                                try {
1370:                                    pobj = PropertyInstanceFactory
1371:                                            .getPropertyInstance(m_dsi, subEl);
1372:                                } catch (DataAccessException e) {
1373:                                    throw new PublishException(
1374:                                            "Error occurred while populating property instance:",
1375:                                            e);
1376:                                } catch (HarmoniseFactoryException e) {
1377:                                    throw new PublishException(
1378:                                            "Error occurred while getting property instance from factory:",
1379:                                            e);
1380:                                }
1381:
1382:                                try {
1383:                                    pobj.populate(subEl, state);
1384:                                } catch (PopulateException e) {
1385:                                    throw new PublishException(
1386:                                            "Populate exception", e);
1387:                                }
1388:                                condEl.appendChild(pobj.publish(subEl, output,
1389:                                        state));
1390:                            } else {
1391:                                condEl.appendChild(output.copyNode(subEl));
1392:                            }
1393:                        }
1394:
1395:                        try {
1396:                            populateConditionsFromState(condEl, output, state);
1397:                        } catch (PopulateException e) {
1398:                            throw new PublishException("Populate exception", e);
1399:                        }
1400:                        newSearch.appendChild(condEl);
1401:                    } else if (sTagName.equalsIgnoreCase(TAG_SUBMIT)) {
1402:                        newSearch.appendChild(output.copyNode(elTemp));
1403:                    }
1404:                }
1405:
1406:                return newSearch;
1407:            }
1408:
1409:            /**
1410:             * Populates the search with filter conditions found in
1411:             * <code>xmlElement</code>.
1412:             * 
1413:             * @param xmlElement
1414:             * @throws PublishException
1415:             */
1416:            protected void processFilterConditions(Element xmlElement)
1417:                    throws PublishException {
1418:                if (xmlElement.getTagName().equals(TAG_FILTERCONDITIONS) == false) {
1419:                    throw new InvalidXMLElementException("Expecting "
1420:                            + TAG_FILTERCONDITIONS + " got "
1421:                            + xmlElement.getTagName());
1422:                }
1423:
1424:                NodeList propertyEls = xmlElement
1425:                        .getElementsByTagName(Property.TAG_PROPERTY);
1426:
1427:                if (propertyEls.getLength() > 0) {
1428:                    m_filterProps = new Vector(16);
1429:                }
1430:
1431:                for (int i = 0; i < propertyEls.getLength(); i++) {
1432:                    Element propertyElement = (Element) propertyEls.item(0);
1433:                    NodeList pathNL = propertyElement
1434:                            .getElementsByTagName(AbstractChildObject.TAG_PATH);
1435:
1436:                    if (pathNL.getLength() > 0) {
1437:
1438:                        try {
1439:                            Property prop = (Property) HarmoniseObjectFactory
1440:                                    .instantiateHarmoniseObject(
1441:                                            m_dsi,
1442:                                            Property.class.getName(),
1443:                                            XMLDocument
1444:                                                    .getChildTextNodeValue((Element) pathNL
1445:                                                            .item(0)));
1446:                            m_filterProps.add(prop);
1447:                        } catch (HarmoniseFactoryException e) {
1448:                            throw new PublishException("Factory exception", e);
1449:                        }
1450:
1451:                    }
1452:
1453:                }
1454:
1455:                NodeList filterSourceEls = xmlElement
1456:                        .getElementsByTagName(TAG_FILTERSOURCE);
1457:
1458:                if (filterSourceEls.getLength() > 0) {
1459:                    Element elFilterSource = (Element) filterSourceEls.item(0)
1460:                            .getFirstChild();
1461:                    m_sFilterObjectClassname = elFilterSource.getTagName();
1462:                }
1463:            }
1464:
1465:            /**
1466:             * Adds conditions to the search based on the filter source found in the
1467:             * <code>State</code>. Given a set of property instances specified in
1468:             * <code>xmlElement</code>, the filter source object is located and
1469:             * values for the conditions are taken for the conditions.
1470:             * 
1471:             * @param xmlElement
1472:             * @param state
1473:             * @throws PublishException
1474:             */
1475:            protected void addFilterSourceConditions(Element xmlElement,
1476:                    State state) throws PublishException {
1477:                Profile filterProfile = createFilterConditionsProfile(
1478:                        xmlElement, state);
1479:
1480:                try {
1481:                    List props = filterProfile.getPropertyInstances();
1482:
1483:                    if (props.size() > 0) {
1484:                        for (int i = 0; i < props.size(); i++) {
1485:                            addConditionProperty((AbstractPropertyInstance) props
1486:                                    .get(i));
1487:                        }
1488:                    } else {
1489:                        m_bFilterCondsNotFound = true;
1490:                    }
1491:                } catch (DataAccessException e) {
1492:                    throw new PublishException(
1493:                            "Error occured getting properties from profile", e);
1494:                }
1495:            }
1496:
1497:            /**
1498:             * Processes a 'Conditions' element to extract the conditions to be used in
1499:             * the search.
1500:             * 
1501:             * @param xmlElement
1502:             * @param state
1503:             * @throws PublishException
1504:             */
1505:            protected void processSearchConditions(Element xmlElement,
1506:                    State state) throws PublishException {
1507:                if (xmlElement.getTagName().equals(TAG_CONDITIONS) == false) {
1508:                    throw new InvalidXMLElementException("Expected "
1509:                            + TAG_CONDITIONS + " got "
1510:                            + xmlElement.getTagName());
1511:                }
1512:
1513:                NodeList nodes = xmlElement.getChildNodes();
1514:
1515:                for (int i = 0; i < nodes.getLength(); i++) {
1516:                    if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
1517:                        continue;
1518:                    }
1519:
1520:                    Element condEl = (Element) nodes.item(i);
1521:                    String sTagName = condEl.getTagName();
1522:
1523:                    try {
1524:
1525:                        if (sTagName
1526:                                .equalsIgnoreCase(AbstractChildObject.TAG_GROUP)) {
1527:                            Element groupEl = (Element) condEl
1528:                                    .getElementsByTagName("*").item(0);
1529:                            AbstractParentObject grpObj = (AbstractParentObject) HarmoniseObjectFactory
1530:                                    .instantiatePublishableObject(this .m_dsi,
1531:                                            groupEl, state);
1532:
1533:                            if (grpObj != null) {
1534:                                addConditionGroup(grpObj);
1535:
1536:                                if (condEl.getAttribute(ATTRIB_SUB)
1537:                                        .equalsIgnoreCase("true")) {
1538:                                    addSubGroupsAsConditions(grpObj);
1539:                                }
1540:                            } else if (m_logger.isLoggable(Level.INFO)) {
1541:                                m_logger.logp(Level.INFO, this .getClass()
1542:                                        .getName(), "processSearchConditions",
1543:                                        "Group for group condition not found");
1544:                            }
1545:
1546:                        } else if (sTagName.equalsIgnoreCase(TAG_POSITION)) {
1547:                            m_nPosition = Integer.parseInt(XMLDocument
1548:                                    .getChildTextNodeValue(condEl));
1549:                        } else if (sTagName
1550:                                .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1551:                            AbstractPropertyInstance propInst = PropertyInstanceFactory
1552:                                    .getPropertyInstance(m_dsi, condEl);
1553:
1554:                            propInst.populate(condEl, state);
1555:
1556:                            addConditionProperty(propInst);
1557:
1558:                        } else if (sTagName
1559:                                .equalsIgnoreCase(AbstractEditableObject.TAG_STATUS)) {
1560:                            String txt = XMLDocument
1561:                                    .getChildTextNodeValue(condEl);
1562:
1563:                            if (txt.equals(Status.APPROVED.getStringValue())) {
1564:                                this .m_bApprovedSearch = true;
1565:                            } else if (txt.equals(Status.UNAPPROVED
1566:                                    .getStringValue())) {
1567:                                this .m_bApprovedSearch = false;
1568:                            } else {
1569:                                //if txt is a integer then it may well be a valid
1570:                                // status code
1571:                                try {
1572:                                    int nStatus = Integer.parseInt(txt);
1573:
1574:                                    if (nStatus == 0) {
1575:                                        this .m_bApprovedSearch = true;
1576:                                    }
1577:
1578:                                    if (nStatus == 1) {
1579:                                        this .m_bApprovedSearch = false;
1580:                                    }
1581:                                } catch (NumberFormatException numexp) {
1582:                                    m_logger.log(Level.WARNING, numexp
1583:                                            .getLocalizedMessage(), numexp);
1584:                                }
1585:                            }
1586:                        } else {
1587:                            addWhereConditionsFromXML(condEl, state);
1588:                        }
1589:                    } catch (NumberFormatException e) {
1590:                        throw new PublishException("Number format error", e);
1591:                    } catch (HarmoniseFactoryException e) {
1592:                        throw new PublishException("Factory error", e);
1593:                    } catch (DataAccessException e) {
1594:                        throw new PublishException("data access error", e);
1595:                    } catch (PopulateException e) {
1596:                        throw new PublishException("populate error", e);
1597:                    } catch (DataStoreException e) {
1598:                        throw new PublishException("data store error", e);
1599:                    }
1600:                }
1601:            }
1602:
1603:            /**
1604:             * Sets the text associated with this search.
1605:             * 
1606:             * @param sSearchText
1607:             */
1608:            protected void setSearchText(String sSearchText) {
1609:                m_sSearchText = sSearchText;
1610:            }
1611:
1612:            /**
1613:             * Returns the text associated with this search
1614:             * 
1615:             * @return
1616:             */
1617:            protected String getSearchText() {
1618:                return m_sSearchText;
1619:            }
1620:
1621:            /*-------------------------------------------------------------------
1622:             Private methods
1623:             ------------------------------------------------------------------*/
1624:
1625:            /**
1626:             * Sets the object type that the search will be conducted on, based on the
1627:             * object type associated with the given <code>Element</code>.
1628:             * 
1629:             * @param sSearchObjEl
1630:             * @throws SearchException
1631:             * @throws DataStoreException
1632:             * @throws PopulateException
1633:             */
1634:            private void setSearchType(Element sSearchObjEl)
1635:                    throws SearchException, DataStoreException,
1636:                    PopulateException {
1637:                try {
1638:                    m_searchObject = (DataStoreObject) HarmoniseObjectFactory
1639:                            .instantiatePublishableObject(this .m_dsi,
1640:                                    sSearchObjEl, null);
1641:                } catch (HarmoniseFactoryException e) {
1642:                    throw new SearchException("Factory error", e);
1643:                }
1644:
1645:                m_sSearchType = sSearchObjEl.getTagName();
1646:
1647:                ColumnRef colrefId = m_searchObject.getInstanceColumnRef(
1648:                        AbstractObject.ATTRIB_ID,
1649:                        ((AbstractObject) m_searchObject).isHistorical());
1650:
1651:                if (colrefId != null) {
1652:                    addSelectColumn(colrefId);
1653:                }
1654:
1655:                NamedNodeMap nnm = sSearchObjEl.getAttributes();
1656:
1657:                //handle attributes
1658:                for (int i = 0; i < nnm.getLength(); i++) {
1659:                    Attr attribute = (Attr) nnm.item(i);
1660:
1661:                    String sName = attribute.getName();
1662:                    String sValue = attribute.getValue();
1663:
1664:                    if ((sValue != null) && (sValue.length() > 0)) {
1665:                        Vector vec = new Vector();
1666:                        vec.add(sValue);
1667:
1668:                        try {
1669:                            this .addConditionColumn(m_searchObject
1670:                                    .getInstanceColumnRef(sName,
1671:                                            ((AbstractObject) m_searchObject)
1672:                                                    .isHistorical()), "=", vec);
1673:                        } catch (InvalidColumnReferenceException e) {
1674:                            m_logger.log(Level.INFO, e.getLocalizedMessage());
1675:                        }
1676:                    }
1677:                }
1678:
1679:                //add select columns from elements
1680:                NodeList nodes = sSearchObjEl.getChildNodes();
1681:
1682:                for (int i = 0; i < nodes.getLength(); i++) {
1683:                    if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
1684:                        continue;
1685:                    }
1686:
1687:                    Element el = (Element) nodes.item(i);
1688:                    String sTagName = el.getNodeName();
1689:
1690:                    if (sTagName.equals(Profile.TAG_PROFILE) == true) {
1691:                        NodeList propInstNodes = el
1692:                                .getElementsByTagName(AbstractPropertyInstance.TAG_PROPERTYINSTANCE);
1693:
1694:                        for (int j = 0; j < propInstNodes.getLength(); j++) {
1695:                            Element propInstEl = (Element) propInstNodes
1696:                                    .item(j);
1697:                            NodeList propNodes = propInstEl
1698:                                    .getElementsByTagName(Property.TAG_PROPERTY);
1699:                            AbstractPropertyInstance propInst = null;
1700:                            Element propEl = null;
1701:                            for (int k = 0; k < propNodes.getLength(); k++) {
1702:                                propEl = (Element) propNodes.item(k);
1703:                                if (propEl.hasAttribute(ATTRIB_ORDER_DIRECTION)
1704:                                        && propEl.getAttribute(
1705:                                                ATTRIB_ORDER_DIRECTION)
1706:                                                .length() > 0) {
1707:                                    Element nameEl = XMLUtils
1708:                                            .getFirstNamedChild(propEl,
1709:                                                    Property.TAG_NAME);
1710:                                    try {
1711:                                        if (nameEl != null) {
1712:                                            String sPropName = XMLUtils
1713:                                                    .getChildTextValue(nameEl);
1714:                                            Property prop = PropertyFactory
1715:                                                    .getPropertyFromName(m_dsi,
1716:                                                            sPropName);
1717:                                            propInst = PropertyInstanceFactory
1718:                                                    .getPropertyInstance(m_dsi,
1719:                                                            prop);
1720:                                            propInst.populate(propEl, null);
1721:
1722:                                            addSelectProperty(propInst);
1723:
1724:                                            String sOrderDirection = propEl
1725:                                                    .getAttribute(ATTRIB_ORDER_DIRECTION);
1726:
1727:                                            setOrderBy(propInst,
1728:                                                    sOrderDirection);
1729:                                            break;
1730:                                        }
1731:                                    } catch (DataAccessException e) {
1732:                                        throw new PopulateException(
1733:                                                "Error populating property instance: ",
1734:                                                e);
1735:                                    } catch (HarmoniseFactoryException e) {
1736:                                        throw new PopulateException(
1737:                                                "Error getting property instance from factory: ",
1738:                                                e);
1739:                                    }
1740:                                }
1741:                            }
1742:                        }
1743:                    } else if (sTagName
1744:                            .equals(AbstractParentObject.TAG_CHILDREN)
1745:                            || sTagName
1746:                                    .equals(AbstractParentObject.TAG_SUBGROUPS)
1747:                            || sTagName.equals(AbstractParentObject.TAG_GROUP)) {
1748:                        /**
1749:                         * @todo these tags are not handled in the contruction of the
1750:                         *       Sql
1751:                         */
1752:                    } else {
1753:                        String sLoopTagName = sTagName;
1754:                        Element loopEl = el;
1755:                        ColumnRef colref = null;
1756:
1757:                        while ((sLoopTagName != null) && (colref == null)) {
1758:                            try {
1759:                                colref = m_searchObject.getInstanceColumnRef(
1760:                                        sLoopTagName,
1761:                                        ((AbstractObject) m_searchObject)
1762:                                                .isHistorical());
1763:                                if (loopEl.hasAttribute(ATTRIB_ORDER_DIRECTION)) {
1764:                                    String sOrderDirection = loopEl
1765:                                            .getAttribute(ATTRIB_ORDER_DIRECTION);
1766:
1767:                                    if (sOrderDirection.length() > 0) {
1768:                                        setOrderBy(colref, sOrderDirection);
1769:                                    }
1770:                                }
1771:                            } catch (InvalidColumnReferenceException e) {
1772:                                NodeList loopNodes = loopEl
1773:                                        .getElementsByTagName("*");
1774:
1775:                                if (loopNodes.getLength() > 0) {
1776:                                    loopEl = (Element) loopNodes.item(0);
1777:                                    sLoopTagName = loopEl.getTagName();
1778:
1779:                                } else {
1780:                                    sLoopTagName = null;
1781:                                }
1782:                            }
1783:                        }
1784:
1785:                        if (colref != null) {
1786:                            this .addSelectColumn(colref);
1787:                        }
1788:                    }
1789:                }
1790:            }
1791:
1792:            /**
1793:             * Returns a <code>String</code> containing a query for the search to be
1794:             * run against the indexer.
1795:             * 
1796:             * @return
1797:             * @throws HarmoniseIndexerException
1798:             * @throws DataStoreException
1799:             */
1800:            private String getIndexSearchQuery()
1801:                    throws HarmoniseIndexerException, DataStoreException {
1802:                Vector groupIds = new Vector(16);
1803:                HarmoniseIndexer indexer = HarmoniseIndexer.getInstance();
1804:                String sName = null;
1805:                String sDisplayName = null;
1806:                String sSummary = null;
1807:                String sContents = null;
1808:                String sIndexerQuery = "";
1809:
1810:                for (int i = 0; i < this .m_ConditionGroups.size(); i++) {
1811:                    int groupId = ((AbstractParentObject) m_ConditionGroups
1812:                            .get(i)).getId();
1813:                    groupIds.addElement(String.valueOf(groupId));
1814:                }
1815:
1816:                Vector conditions2remove = new Vector();
1817:
1818:                for (int i = 0; i < this .m_ConditionColumns.size(); i++) {
1819:                    WhereCondition where = (WhereCondition) m_ConditionColumns
1820:                            .get(i);
1821:
1822:                    String columnref = where.getFullColumnRef();
1823:                    Object oText = ((Vector) where.getValues()).firstElement();
1824:
1825:                    if (columnref.equalsIgnoreCase(this .m_searchObject
1826:                            .getInstanceColumnRef(
1827:                                    AbstractObject.TAG_NAME,
1828:                                    ((AbstractObject) m_searchObject)
1829:                                            .isHistorical()).getFullRef())) {
1830:                        sName = (String) oText;
1831:                        conditions2remove.addElement(where);
1832:                        m_bIndexableSearch = true;
1833:                    } else if (columnref.equalsIgnoreCase(this .m_searchObject
1834:                            .getInstanceColumnRef(
1835:                                    AbstractEditableObject.TAG_DISPLAY_NAME,
1836:                                    ((AbstractObject) m_searchObject)
1837:                                            .isHistorical()).getFullRef())) {
1838:                        sDisplayName = (String) oText;
1839:                        conditions2remove.addElement(where);
1840:                        m_bIndexableSearch = true;
1841:                    } else if (columnref.equalsIgnoreCase(this .m_searchObject
1842:                            .getInstanceColumnRef(
1843:                                    AbstractObject.TAG_SUMMARY,
1844:                                    ((AbstractObject) m_searchObject)
1845:                                            .isHistorical()).getFullRef())) {
1846:                        sSummary = (String) oText;
1847:                        conditions2remove.addElement(where);
1848:                        m_bIndexableSearch = true;
1849:                    } else if (this .m_searchObject instanceof  org.openharmonise.rm.resources.content.Document
1850:                            && columnref
1851:                                    .equalsIgnoreCase(this .m_searchObject
1852:                                            .getInstanceColumnRef(
1853:                                                    org.openharmonise.rm.resources.content.Document.TAG_CONTENT,
1854:                                                    ((AbstractObject) m_searchObject)
1855:                                                            .isHistorical())
1856:                                            .getFullRef())) {
1857:                        sContents = (String) oText;
1858:                        conditions2remove.addElement(where);
1859:                        m_bIndexableSearch = true;
1860:                    }
1861:                }
1862:
1863:                if (m_bIndexableSearch == true) {
1864:                    //remove appropriate conditions
1865:                    this .m_ConditionGroups.clear();
1866:
1867:                    for (int i = 0; i < conditions2remove.size(); i++) {
1868:                        this .m_ConditionColumns.remove(conditions2remove
1869:                                .elementAt(i));
1870:                    }
1871:
1872:                    //only fill query string if all of the fields are present but not
1873:                    // empty
1874:                    if ((sName != null && sName.length() > 0)
1875:                            || (sSummary != null && sSummary.length() > 0)
1876:                            || (sContents != null && sContents.length() > 0)
1877:                            || (sDisplayName != null && sDisplayName.length() > 0)) {
1878:                        sIndexerQuery = indexer.getQuery(m_searchObject
1879:                                .getClass(), groupIds, sName, sDisplayName,
1880:                                sSummary, sContents);
1881:                    }
1882:                }
1883:
1884:                return sIndexerQuery;
1885:            }
1886:
1887:            /**
1888:             * Populates conditions by processing the XML contained in the given
1889:             * <code>State</code>.
1890:             * 
1891:             * @param search
1892:             * @param output
1893:             * @param state
1894:             * @throws PublishException
1895:             * @throws PopulateException
1896:             */
1897:            private void populateConditionsFromState(Element search,
1898:                    HarmoniseOutput output, State state)
1899:                    throws PublishException, PopulateException {
1900:                Element stateSearch = state.findElement(search);
1901:                Vector nodes2Remove = new Vector(16);
1902:
1903:                if (stateSearch != null) {
1904:                    NodeList nodes = search.getChildNodes();
1905:
1906:                    //take value here before we start adding nodes
1907:                    int nIter = nodes.getLength();
1908:
1909:                    for (int i = 0; i < nIter; i++) {
1910:                        Element tempEl = (Element) nodes.item(i);
1911:                        String sTagName = tempEl.getTagName();
1912:
1913:                        if (tempEl.getNodeType() != Node.ELEMENT_NODE) {
1914:                            continue;
1915:                        }
1916:
1917:                        if (sTagName
1918:                                .equalsIgnoreCase(AbstractChildObject.TAG_GROUP)) {
1919:                            NodeList stateGroups = state.getDocumentElement()
1920:                                    .getElementsByTagName(
1921:                                            AbstractChildObject.TAG_GROUP);
1922:
1923:                            if (stateGroups.getLength() > 0) {
1924:                                Element stateGroupEl = (Element) stateGroups
1925:                                        .item(0);
1926:                                tempEl.setAttribute(ATTRIB_SUB, stateGroupEl
1927:                                        .getAttribute(ATTRIB_SUB));
1928:
1929:                                NodeList groupNodes = stateGroupEl
1930:                                        .getChildNodes();
1931:
1932:                                for (int j = 0; j < groupNodes.getLength(); j++) {
1933:                                    Element groupEl = (Element) groupNodes
1934:                                            .item(j);
1935:                                    Element foundEl = XMLDocument.findElement(
1936:                                            tempEl, groupEl);
1937:
1938:                                    if (foundEl != null) {
1939:                                        foundEl.setAttribute(ATTRIB_SELECTED,
1940:                                                "selected");
1941:                                    }
1942:                                }
1943:                            }
1944:                        } else {
1945:                            Element foundEl = XMLDocument.findElement(
1946:                                    stateSearch, tempEl);
1947:
1948:                            //if element is in state then we can use data to
1949:                            // instantiate object then publish as new
1950:                            //element to replace current element in searchconditions
1951:                            if ((foundEl != null)
1952:                                    && ((Element) foundEl.getParentNode())
1953:                                            .getTagName().equalsIgnoreCase(
1954:                                                    TAG_CONDITIONS)) {
1955:                                if (sTagName
1956:                                        .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1957:                                    //only do anything of propinst has values
1958:                                    // associated to it
1959:                                    if (foundEl.getChildNodes().getLength() > 0) {
1960:                                        try {
1961:                                            Publishable pubObj = HarmoniseObjectFactory
1962:                                                    .instantiatePublishableObject(
1963:                                                            this .m_dsi, tempEl,
1964:                                                            state);
1965:
1966:                                            pubObj.populate(foundEl, state);
1967:
1968:                                            Element newEl = pubObj.publish(
1969:                                                    tempEl, output, state);
1970:
1971:                                            nodes2Remove.add(tempEl);
1972:                                            search.appendChild(newEl);
1973:                                        } catch (HarmoniseFactoryException e) {
1974:                                            throw new PopulateException(
1975:                                                    "Factory error", e);
1976:                                        }
1977:                                    }
1978:                                } else {
1979:                                    nodes2Remove.add(tempEl);
1980:
1981:                                    Element copyEl = (Element) output
1982:                                            .copyNode(foundEl);
1983:                                    output.copyChildren(copyEl, tempEl);
1984:                                    copyEl.setAttribute(ATTRIB_SELECTED,
1985:                                            ATTRIB_SELECTED);
1986:                                    search.appendChild(copyEl);
1987:                                }
1988:                            }
1989:                        }
1990:                    }
1991:
1992:                    for (int i = 0; i < nodes2Remove.size(); i++) {
1993:                        search.removeChild((Element) nodes2Remove.elementAt(i));
1994:                    }
1995:                }
1996:            }
1997:
1998:            /**
1999:             * Processes <code>xmlElement</code> to add 'where' conditions to the
2000:             * search.
2001:             * 
2002:             * @param xmlElement
2003:             * @param state
2004:             * @throws DataStoreException
2005:             * @throws HarmoniseFactoryException
2006:             */
2007:            private void addWhereConditionsFromXML(Element xmlElement,
2008:                    State state) throws DataStoreException,
2009:                    HarmoniseFactoryException {
2010:                String sTagName = xmlElement.getTagName();
2011:                String sOperator = xmlElement
2012:                        .getAttribute(AbstractPropertyInstance.ATTRIB_OPERATOR);
2013:
2014:                if (sOperator == null) {
2015:                    sOperator = "=";
2016:                }
2017:
2018:                //first assume that we're dealing with a some searchobject data
2019:                Vector tempVec = new Vector();
2020:                String txt = XMLDocument.getChildTextNodeValue(xmlElement);
2021:
2022:                ColumnRef colref = null;
2023:
2024:                colref = this .m_searchObject.getInstanceColumnRef(xmlElement
2025:                        .getTagName(), ((AbstractObject) m_searchObject)
2026:                        .isHistorical());
2027:
2028:                if (colref != null) {
2029:                    if ((txt != null) && (txt.length() > 0)) {
2030:                        tempVec.add(txt);
2031:
2032:                        WhereCondition where = new WhereCondition(colref,
2033:                                sOperator, tempVec);
2034:                        m_ConditionColumns.add(where);
2035:                    }
2036:                } else {
2037:                    DataStoreObject dsObj = (DataStoreObject) HarmoniseObjectFactory
2038:                            .instantiatePublishableObject(this .m_dsi,
2039:                                    xmlElement, state);
2040:
2041:                    NodeList children = xmlElement.getChildNodes();
2042:
2043:                    for (int i = 0; i < children.getLength(); i++) {
2044:                        if (children.item(i).getNodeType() != Node.ELEMENT_NODE) {
2045:                            continue;
2046:                        }
2047:
2048:                        Element tempEl = (Element) children.item(i);
2049:
2050:                        if (tempVec == null) {
2051:                            tempVec = new Vector();
2052:                        }
2053:
2054:                        tempVec.clear();
2055:                        tempVec.add(XMLDocument.getChildTextNodeValue(tempEl));
2056:
2057:                        WhereCondition where = new WhereCondition(dsObj
2058:                                .getInstanceColumnRef(tempEl.getTagName(),
2059:                                        ((AbstractObject) m_searchObject)
2060:                                                .isHistorical()), sOperator,
2061:                                tempVec);
2062:                        m_ConditionColumns.add(where);
2063:                    }
2064:
2065:                }
2066:            }
2067:
2068:            /**
2069:             * Returns a 'FurtherLink' element with the given link text, page id, and
2070:             * position with in the results.
2071:             * 
2072:             * @param output
2073:             * @param linktext
2074:             * @param nPosition
2075:             * @param nPageId
2076:             * @return
2077:             */
2078:            private Element createFurtherLinkElement(HarmoniseOutput output,
2079:                    String linktext, int nPosition, int nPageId) {
2080:                Element xnLink = output.createElement(WebPage.TAG_LINK);
2081:
2082:                Element xnLinkPage = output.createElement(WebPage.TAG_PAGE);
2083:
2084:                xnLinkPage.setAttribute(WebPage.ATTRIB_ID, Integer
2085:                        .toString(nPageId));
2086:
2087:                Node xnLinkTxt = output.createElement(WebPage.TAG_LINK_TEXT);
2088:                Text txt = output.createTextNode(linktext);
2089:
2090:                // Profile to carry search through Prev link
2091:                Element xnState = output.createElement(State.TAG_STATE);
2092:
2093:                Element xnCond = output.createElement(TAG_CONDITIONS);
2094:                xnState.appendChild(xnCond);
2095:
2096:                Element xnPosition = output.createElement(TAG_POSITION);
2097:
2098:                Text txtPos = output
2099:                        .createTextNode(Integer.toString(nPosition));
2100:
2101:                xnPosition.appendChild(txtPos);
2102:                xnCond.appendChild(xnPosition);
2103:                xnLink.appendChild(xnState);
2104:
2105:                xnLink.appendChild(xnLinkPage);
2106:
2107:                xnLinkTxt.appendChild(txt);
2108:                xnLink.appendChild(xnLinkTxt);
2109:
2110:                return xnLink;
2111:            }
2112:
2113:            /**
2114:             * Returns a <code>Profile</code> which represents the
2115:             * <code>xmlElement</code> 'FilterCondition' element.
2116:             * 
2117:             * @param xmlElement
2118:             * @param state
2119:             * @return @throws
2120:             *         PublishException
2121:             */
2122:            private Profile createFilterConditionsProfile(Element xmlElement,
2123:                    State state) throws PublishException {
2124:                if (xmlElement.getTagName().equals(TAG_FILTERCONDITIONS) == false) {
2125:                    throw new InvalidXMLElementException("Expecting "
2126:                            + TAG_FILTERCONDITIONS + " got "
2127:                            + xmlElement.getTagName());
2128:                }
2129:
2130:                String sInclusive = xmlElement.getAttribute(ATTRIB_INCLUSIVE);
2131:
2132:                if ((sInclusive != null) && sInclusive.equalsIgnoreCase("true")) {
2133:                    m_bFilterCondsInclusive = true;
2134:                }
2135:
2136:                Profile returnProf = null;
2137:                Profile filterObjectProfile = null;
2138:                AbstractProfiledObject filterObject = null;
2139:
2140:                NodeList childNodes = xmlElement.getChildNodes();
2141:
2142:                for (int i = 0; i < childNodes.getLength(); i++) {
2143:                    if (childNodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
2144:                        continue;
2145:                    }
2146:
2147:                    Element childEl = (Element) childNodes.item(i);
2148:                    String sTagName = childEl.getTagName();
2149:
2150:                    try {
2151:
2152:                        if (sTagName.equalsIgnoreCase(TAG_FILTERSOURCE)) {
2153:                            NodeList sourceNodes = childEl.getChildNodes();
2154:
2155:                            for (int j = 0; j < sourceNodes.getLength(); j++) {
2156:                                if (sourceNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
2157:                                    continue;
2158:                                }
2159:
2160:                                Element elFilterSource = (Element) sourceNodes
2161:                                        .item(j);
2162:                                String sFilterObjectClassname = elFilterSource
2163:                                        .getTagName();
2164:
2165:                                filterObject = (AbstractProfiledObject) HarmoniseObjectFactory
2166:                                        .instantiateHarmoniseObject(m_dsi,
2167:                                                elFilterSource, state);
2168:                                filterObjectProfile = filterObject.getProfile();
2169:                            }
2170:                        } else if (sTagName.equalsIgnoreCase(TAG_OR)) {
2171:                            m_ConditionOperator = "OR";
2172:                        } else if (sTagName
2173:                                .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)
2174:                                || sTagName
2175:                                        .equalsIgnoreCase(Property.TAG_PROPERTY)) {
2176:                            AbstractPropertyInstance tmpPropInst = PropertyInstanceFactory
2177:                                    .getPropertyInstance(m_dsi, childEl/*
2178:                                     * , returnProf
2179:                                     */);
2180:
2181:                            tmpPropInst.populate(childEl, state);
2182:
2183:                            //if property tag doesn't have values then take property
2184:                            // condition from filter source
2185:                            if (tmpPropInst.hasValues() == false) {
2186:                                if (filterObjectProfile != null) {
2187:                                    AbstractPropertyInstance fltrSrcPropInst = filterObjectProfile
2188:                                            .getPropertyInstance(tmpPropInst
2189:                                                    .getProperty());
2190:
2191:                                    if (fltrSrcPropInst != null) {
2192:                                        if (returnProf == null) {
2193:                                            returnProf = new Profile(m_dsi,
2194:                                                    filterObject);
2195:                                        }
2196:
2197:                                        returnProf
2198:                                                .addPropertyInstance(fltrSrcPropInst);
2199:                                    }
2200:
2201:                                    //TODO need to handle situation where filter object profile does
2202:                                    //not contain the property, currently errors - might lose operator for property
2203:                                    //need to review this - need to think
2204:                                    //about exclusivity wrt to this issue
2205:
2206:                                }
2207:                            } else {
2208:                                returnProf.addPropertyInstance(tmpPropInst);
2209:                            }
2210:                        }
2211:                    } catch (ProfileException e) {
2212:                        throw new PublishException("Profile error", e);
2213:                    } catch (DataAccessException e) {
2214:                        throw new PublishException("Data access error", e);
2215:                    } catch (HarmoniseFactoryException e) {
2216:                        throw new PublishException("Factory error", e);
2217:                    } catch (PopulateException e) {
2218:                        throw new PublishException("Population error", e);
2219:                    }
2220:                }
2221:
2222:                return returnProf;
2223:            }
2224:
2225:            /**
2226:             * Adds 'where' conditions to the select statement from the condition data
2227:             * contained in this object.
2228:             * 
2229:             * @param select
2230:             * @throws DataAccessException
2231:             * @throws DataStoreException
2232:             */
2233:            private void addWhereConditions(SelectStatement select)
2234:                    throws DataAccessException, DataStoreException {
2235:
2236:                SelectStatement subselect = null;
2237:
2238:                if ((m_ConditionProfile.size() > 0)
2239:                        || (m_ConditionGroups.size() > 0)) {
2240:                    subselect = new SelectStatement();
2241:
2242:                    subselect.setDistinct(true);
2243:                    subselect.addSelectColumn(m_searchObject
2244:                            .getInstanceColumnRef(AbstractObject.ATTRIB_ID,
2245:                                    ((AbstractObject) m_searchObject)
2246:                                            .isHistorical()));
2247:                }
2248:
2249:                //are we going to do a strict search by type or just return all
2250:                //matching objects from the same table, e.g. if class B was a 
2251:                //subclass of class A are doing a search on all objects of 
2252:                //class A or specifically class B, if so add the appropriate 
2253:                //condition
2254:                if (m_bStrictType == true) {
2255:                    if (subselect != null) {
2256:                        subselect
2257:                                .addWhereCondition(
2258:                                        ((AbstractObject) this .m_searchObject)
2259:                                                .getInstanceColumnRef(
2260:                                                        Search.ATTRIB_OBJECT_TYPE,
2261:                                                        ((AbstractObject) this .m_searchObject)
2262:                                                                .isHistorical()),
2263:                                        "=",
2264:                                        ((AbstractObject) this .m_searchObject)
2265:                                                .getType());
2266:                    } else {
2267:                        select
2268:                                .addWhereCondition(
2269:                                        ((AbstractObject) this .m_searchObject)
2270:                                                .getInstanceColumnRef(
2271:                                                        Search.ATTRIB_OBJECT_TYPE,
2272:                                                        ((AbstractObject) this .m_searchObject)
2273:                                                                .isHistorical()),
2274:                                        "=",
2275:                                        ((AbstractObject) this .m_searchObject)
2276:                                                .getType());
2277:                    }
2278:                }
2279:
2280:                if (m_searchObject instanceof  AbstractProfiledObject) {
2281:                    AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2282:
2283:                    //add conditions needed for those property instances to be returned
2284:                    //in select statement
2285:                    addSelectPropertyInstanceConditions(select);
2286:
2287:                    if (m_searchObject instanceof  AbstractChildObject) {
2288:                        //add relationship conditions
2289:                        addGroupConditions(subselect);
2290:                    }
2291:
2292:                    //add property instance conditions
2293:                    addPropertyInstanceConditions(subselect);
2294:                }
2295:
2296:                //if this search is on live objects only
2297:                if (m_bApprovedSearch == true) {
2298:                    Vector tempVec = new Vector();
2299:                    tempVec.add(new Integer(Status.APPROVED.getIntValue()));
2300:
2301:                    WhereCondition where = new WhereCondition(m_searchObject
2302:                            .getInstanceColumnRef(
2303:                                    AbstractEditableObject.TAG_STATUS,
2304:                                    ((AbstractObject) this .m_searchObject)
2305:                                            .isHistorical()), "=", tempVec);
2306:                    m_ConditionColumns.add(where);
2307:                }
2308:
2309:                //add core data conditions
2310:                if (subselect != null) {
2311:                    addCoreDataConditions(subselect);
2312:                } else {
2313:                    addCoreDataConditions(select);
2314:                }
2315:
2316:                //add nested select statement
2317:                if (subselect != null) {
2318:                    WhereCondition whereSubselect = new WhereCondition(
2319:                            m_searchObject.getInstanceColumnRef(
2320:                                    AbstractObject.ATTRIB_ID,
2321:                                    ((AbstractObject) this .m_searchObject)
2322:                                            .isHistorical()), "IN", subselect);
2323:                    select.addWhereCondition(whereSubselect);
2324:                }
2325:            }
2326:
2327:            /**
2328:             * Adds relationship conditions to the select statement based on conditions
2329:             * held with in this search object.
2330:             * 
2331:             * @param subselect
2332:             * @throws DataStoreException
2333:             */
2334:            private void addGroupConditions(SelectStatement subselect)
2335:                    throws DataStoreException {
2336:                if (m_ConditionGroups.size() > 0) {
2337:
2338:                    if (m_searchObject instanceof  AbstractChildObject
2339:                            && ((AbstractChildObject) m_searchObject)
2340:                                    .isHistorical() == true) {
2341:                        WhereConditionGroup wheres = new WhereConditionGroup();
2342:                        wheres.setStringingOperator("or");
2343:
2344:                        for (int i = 0; i < m_ConditionGroups.size(); i++) {
2345:                            AbstractParentObject grpObj = (AbstractParentObject) m_ConditionGroups
2346:                                    .get(i);
2347:
2348:                            try {
2349:                                wheres.addCondition(m_searchObject
2350:                                        .getInstanceColumnRef(
2351:                                                AbstractChildObject.TAG_PATH,
2352:                                                true), "STARTS_WITH", grpObj
2353:                                        .getPath());
2354:                            } catch (DataAccessException e) {
2355:                                throw new DataStoreException(e);
2356:                            }
2357:                        }
2358:
2359:                        subselect.addWhereCondition(wheres);
2360:                    } else if (this .m_searchObject instanceof  AbstractParentObject) {
2361:                        WhereConditionGroup wheres = new WhereConditionGroup();
2362:                        String sGroupAlias = "grp";
2363:                        String sGroupTableName = "";
2364:                        wheres.setStringingOperator("or");
2365:
2366:                        DataStoreObject dsObj = null;
2367:                        ColumnRef colId = m_searchObject.getInstanceColumnRef(
2368:                                AbstractObject.ATTRIB_ID, false);
2369:                        sGroupTableName = colId.getTable();
2370:                        colId.setTable(sGroupAlias);
2371:
2372:                        for (int i = 0; i < m_ConditionGroups.size(); i++) {
2373:                            dsObj = (DataStoreObject) m_ConditionGroups.get(i);
2374:
2375:                            wheres.addCondition(colId, "=", dsObj.getId());
2376:                        }
2377:
2378:                        subselect.addWhereCondition(wheres);
2379:
2380:                        ColumnRef subJoinKey = m_searchObject
2381:                                .getInstanceColumnRef(
2382:                                        AbstractParentObject.TAG_SUBGROUPS,
2383:                                        false);
2384:                        ColumnRef subKey = m_searchObject.getInstanceColumnRef(
2385:                                AbstractObject.ATTRIB_KEY, false);
2386:                        ColumnRef parentJoinKey = m_searchObject
2387:                                .getInstanceColumnRef(
2388:                                        AbstractParentObject.TAG_GROUP, false);
2389:                        ColumnRef parentKey = m_searchObject
2390:                                .getInstanceColumnRef(
2391:                                        AbstractObject.ATTRIB_KEY, false);
2392:                        parentKey.setTable(sGroupAlias);
2393:
2394:                        subselect.addJoinCondition(parentJoinKey, parentKey);
2395:                        subselect.addJoinCondition(subJoinKey, subKey);
2396:
2397:                        subselect.addTableAlias(sGroupTableName, sGroupAlias);
2398:                    } else {
2399:                        WhereConditionGroup wheres = new WhereConditionGroup();
2400:                        wheres.setStringingOperator("or");
2401:
2402:                        DataStoreObject dsObj = null;
2403:
2404:                        for (int i = 0; i < m_ConditionGroups.size(); i++) {
2405:                            dsObj = (DataStoreObject) m_ConditionGroups.get(i);
2406:                            wheres.addCondition(dsObj.getInstanceColumnRef(
2407:                                    AbstractObject.ATTRIB_ID, false), "=",
2408:                                    dsObj.getId());
2409:                        }
2410:
2411:                        subselect.addWhereCondition(wheres);
2412:                        subselect.addJoinConditions(dsObj
2413:                                .getInstanceJoinConditions(this .m_sSearchType,
2414:                                        false));
2415:                    }
2416:                }
2417:            }
2418:
2419:            /**
2420:             * Adds 'join' conditions to the select statement necessary to support the
2421:             * return of property instance values in the result set.
2422:             * 
2423:             * @param select
2424:             * @throws DataAccessException
2425:             * @throws DataStoreException
2426:             */
2427:            private void addSelectPropertyInstanceConditions(
2428:                    SelectStatement select) throws DataAccessException,
2429:                    DataStoreException {
2430:                AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2431:
2432:                if (m_searchObjectProfile == null) {
2433:                    m_searchObjectProfile = new Profile(m_dsi, profObj);
2434:                }
2435:                Profile prof = m_searchObjectProfile;
2436:
2437:                for (int i = 0; i < this .m_SearchProfile.size(); i++) {
2438:                    //get necessary object for getting the column refs
2439:
2440:                    AbstractPropertyInstance condPropInst = (AbstractPropertyInstance) m_SearchProfile
2441:                            .get(i);
2442:                    condPropInst.setProfile(prof);
2443:
2444:                    Property property = condPropInst.getProperty();
2445:
2446:                    String sPropertyAlias = "spty" + i;
2447:                    ColumnRef propertyIdCol = property.getInstanceColumnRef(
2448:                            AbstractObject.ATTRIB_ID, false);
2449:                    select.addTableAlias(propertyIdCol.getTable(),
2450:                            sPropertyAlias);
2451:                    propertyIdCol.setTable(sPropertyAlias);
2452:
2453:                    ColumnRef propertyNameCol = property.getInstanceColumnRef(
2454:                            AbstractObject.TAG_NAME, false);
2455:                    propertyNameCol.setTable(sPropertyAlias);
2456:
2457:                    //get column refs and set necessary aliases
2458:                    ColumnRef valColref = condPropInst.getInstanceColumnRef(
2459:                            AbstractPropertyInstance.TAG_VALUE, false);
2460:                    String sPropAlias = "sprop" + i;
2461:                    select.addTableAlias(valColref.getTable(), sPropAlias);
2462:                    valColref.setTable(sPropAlias);
2463:
2464:                    ColumnRef dataProfIdColref = condPropInst
2465:                            .getInstanceColumnRef(Profile.TAG_PROFILE, false);
2466:                    dataProfIdColref.setTable(sPropAlias);
2467:
2468:                    ColumnRef dataPropIdColref = condPropInst
2469:                            .getInstanceColumnRef(Property.TAG_PROPERTY, false);
2470:                    dataPropIdColref.setTable(sPropAlias);
2471:
2472:                    ColumnRef profileIdColref = prof.getInstanceColumnRef(
2473:                            AbstractObject.ATTRIB_ID, prof.isHistorical());
2474:
2475:                    String sProfAlias = "sprof" + i;
2476:
2477:                    select
2478:                            .addTableAlias(profileIdColref.getTable(),
2479:                                    sProfAlias);
2480:                    profileIdColref.setTable(sProfAlias);
2481:
2482:                    ColumnRef profNameColref = prof.getInstanceColumnRef(
2483:                            AbstractObject.TAG_NAME, prof.isHistorical());
2484:                    profNameColref.setTable(sProfAlias);
2485:
2486:                    ColumnRef profObjectKeyColref = prof.getInstanceColumnRef(
2487:                            Profile.ATTRIB_OBJECT_KEY, prof.isHistorical());
2488:                    profObjectKeyColref.setTable(sProfAlias);
2489:
2490:                    ColumnRef objectKeyColref = m_searchObject
2491:                            .getInstanceColumnRef(AbstractObject.ATTRIB_KEY,
2492:                                    ((AbstractObject) m_searchObject)
2493:                                            .isHistorical());
2494:
2495:                    select.addSelectColumn(profNameColref);
2496:                    select.addSelectColumn(valColref);
2497:
2498:                    if ((m_orderByPropMap.isEmpty() == false)
2499:                            && m_orderByPropMap.containsKey(condPropInst)) {
2500:                        select.addOrderBy(valColref, (String) m_orderByPropMap
2501:                                .get(condPropInst));
2502:                    }
2503:
2504:                    select.addSelectColumn(propertyIdCol);
2505:                    select.addSelectColumn(profileIdColref);
2506:                    select.addSelectColumn(propertyNameCol);
2507:
2508:                    select.addOuterJoinCondition(dataProfIdColref,
2509:                            profileIdColref);
2510:
2511:                    select.addJoinCondition(profObjectKeyColref,
2512:                            objectKeyColref);
2513:
2514:                    select.addOuterJoinCondition(dataPropIdColref,
2515:                            propertyIdCol);
2516:                    select.addWhereCondition(propertyNameCol, "=", condPropInst
2517:                            .getName());
2518:                }
2519:            }
2520:
2521:            /**
2522:             * Adds the 'where' conditions to the given <code>SelectStatement</code>
2523:             * based on the property instance conditions held with in this search object.
2524:             * 
2525:             * @param subselect
2526:             * @throws DataStoreException
2527:             * @throws DataAccessException
2528:             */
2529:            private void addPropertyInstanceConditions(SelectStatement subselect)
2530:                    throws DataStoreException, DataAccessException {
2531:                AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2532:                Profile profObjProf = profObj.getProfile();
2533:
2534:                if (m_ConditionProfile.size() > 0) {
2535:                    //WhereConditions object to hold all the propertyinstance conditions
2536:                    WhereConditionGroup outerWheres = new WhereConditionGroup();
2537:
2538:                    for (int i = 0; i < m_ConditionProfile.size(); i++) {
2539:                        //get necessary object for getting the column refs
2540:
2541:                        if (m_searchObjectProfile == null) {
2542:                            m_searchObjectProfile = new Profile(m_dsi, profObj);
2543:                        }
2544:                        Profile prof = m_searchObjectProfile;
2545:
2546:                        AbstractPropertyInstance condPropInst = (AbstractPropertyInstance) m_ConditionProfile
2547:                                .get(i);
2548:
2549:                        String sCondOp = condPropInst.getOperator();
2550:
2551:                        condPropInst.setProfile(prof);
2552:
2553:                        //if there are no values don't go any further
2554:                        if (condPropInst.hasValues() == false) {
2555:                            continue;
2556:                        }
2557:
2558:                        if (sCondOp.equals("<>") == false
2559:                                && sCondOp.equals("!=") == false) {
2560:
2561:                            addPropertyInstanceWhereCondition(subselect,
2562:                                    outerWheres, i, prof, condPropInst, sCondOp);
2563:                        } else {
2564:                            //need to compose a different sort of query for 
2565:                            //the non-existance of a property instance value
2566:                            //that takes account for profiles which may have
2567:                            //more than one value for the property instance
2568:                            //or more than one profile
2569:                            //or even no profile
2570:
2571:                            addNonExistentPropertyInstanceCondition(profObj,
2572:                                    outerWheres, prof, condPropInst);
2573:                        }
2574:
2575:                    } //end for
2576:
2577:                    outerWheres.setStringingOperator(m_ConditionOperator);
2578:                    subselect.addWhereCondition(outerWheres);
2579:                }
2580:            }
2581:
2582:            /**
2583:             * Adds a property instance where condition to <code>outerWheres</code>, 
2584:             * updating <code>subselect</code> with the necessary table aliases.
2585:             * 
2586:             * @param subselect
2587:             * @param outerWheres
2588:             * @param index
2589:             * @param prof
2590:             * @param condPropInst
2591:             * @param sCondOp
2592:             * @throws DataStoreException
2593:             * @throws DataAccessException
2594:             */
2595:            private void addPropertyInstanceWhereCondition(
2596:                    SelectStatement subselect, WhereConditionGroup outerWheres,
2597:                    int index, Profile prof,
2598:                    AbstractPropertyInstance condPropInst, String sCondOp)
2599:                    throws DataStoreException, DataAccessException {
2600:                //set prop inst table alias
2601:                String propInstAlias = "prop" + index;
2602:
2603:                subselect.addTableAlias(condPropInst.getDBTableName(),
2604:                        propInstAlias);
2605:
2606:                //prof id column in prop inst table
2607:                ColumnRef dataProfIdColref = condPropInst.getInstanceColumnRef(
2608:                        Profile.TAG_PROFILE, false);
2609:                dataProfIdColref.setTable(propInstAlias);
2610:
2611:                //prop id column in prop inst table
2612:                ColumnRef dataPropIdColref = condPropInst.getInstanceColumnRef(
2613:                        Property.TAG_PROPERTY, false);
2614:                dataPropIdColref.setTable(propInstAlias);
2615:
2616:                subselect.addWhereCondition(dataPropIdColref, "=", condPropInst
2617:                        .getProperty().getId());
2618:
2619:                //prof id column in profile table
2620:                ColumnRef profileIdColref = prof.getInstanceColumnRef(
2621:                        AbstractObject.ATTRIB_ID, prof.isHistorical());
2622:
2623:                //set alias for profile table
2624:                String profAlias = "prof" + index;
2625:
2626:                subselect.addTableAlias(profileIdColref.getTable(), profAlias);
2627:
2628:                profileIdColref.setTable(profAlias);
2629:
2630:                //join prop inst table to profile table
2631:                subselect.addJoinCondition(dataProfIdColref, profileIdColref);
2632:
2633:                ColumnRef profObjectKeyColref = prof.getInstanceColumnRef(
2634:                        Profile.ATTRIB_OBJECT_KEY, prof.isHistorical());
2635:                profObjectKeyColref.setTable(profAlias);
2636:
2637:                ColumnRef objectKeyColref = m_searchObject
2638:                        .getInstanceColumnRef(AbstractObject.ATTRIB_KEY,
2639:                                ((AbstractObject) m_searchObject)
2640:                                        .isHistorical());
2641:
2642:                //join object table to profile table
2643:                subselect
2644:                        .addJoinCondition(profObjectKeyColref, objectKeyColref);
2645:
2646:                WhereConditionGroup innerWheres = getPropertyInstanceValueConditions(
2647:                        condPropInst, sCondOp, propInstAlias);
2648:
2649:                if (innerWheres.size() > 1) {
2650:                    outerWheres.addCondition(innerWheres);
2651:                } else {
2652:                    //no sense in adding a WhereConditions
2653:                    //when we can just pick up the only condition
2654:                    //and add it
2655:                    Object cond = innerWheres.getCondition(0);
2656:                    if (cond instanceof  WhereCondition) {
2657:                        outerWheres.addCondition((WhereCondition) cond);
2658:                    } else if (cond instanceof  WhereConditionGroup) {
2659:                        outerWheres.addCondition((WhereConditionGroup) cond);
2660:                    }
2661:                }
2662:            }
2663:
2664:            /**
2665:             * Adds the required condition to <code>outerWheres</code> which tests for the non-existence
2666:             * of a property instance value on the search object.
2667:             * 
2668:             * @param profObj
2669:             * @param outerWheres
2670:             * @param prof
2671:             * @param condPropInst
2672:             * @throws DataStoreException
2673:             * @throws DataAccessException
2674:             */
2675:            private void addNonExistentPropertyInstanceCondition(
2676:                    AbstractProfiledObject profObj,
2677:                    WhereConditionGroup outerWheres, Profile prof,
2678:                    AbstractPropertyInstance condPropInst)
2679:                    throws DataStoreException, DataAccessException {
2680:                ColumnRef profObjectKeyColRef = m_searchObjectProfile
2681:                        .getInstanceColumnRef(Profile.ATTRIB_OBJECT_KEY,
2682:                                profObj.isHistorical());
2683:                ColumnRef objObjectKeyColRef = profObj.getInstanceColumnRef(
2684:                        AbstractObject.ATTRIB_KEY, profObj.isHistorical());
2685:
2686:                SelectStatement nestedSelect = new SelectStatement();
2687:
2688:                nestedSelect.addSelectColumn(profObjectKeyColRef);
2689:
2690:                //prof id column in prop inst table
2691:                ColumnRef dataProfIdColref = condPropInst.getInstanceColumnRef(
2692:                        Profile.TAG_PROFILE, false);
2693:
2694:                //prof id column in profile table
2695:                ColumnRef profileIdColref = prof.getInstanceColumnRef(
2696:                        AbstractObject.ATTRIB_ID, prof.isHistorical());
2697:
2698:                //join prop inst table to profile table
2699:                nestedSelect
2700:                        .addJoinCondition(dataProfIdColref, profileIdColref);
2701:
2702:                //prop id column in prop inst table
2703:                ColumnRef dataPropIdColref = condPropInst.getInstanceColumnRef(
2704:                        Property.TAG_PROPERTY, false);
2705:
2706:                nestedSelect.addWhereCondition(dataPropIdColref, "=",
2707:                        condPropInst.getProperty().getId());
2708:
2709:                //only add the following conditions if the property instance 
2710:                //has values
2711:                if (condPropInst.getValues().size() > 0) {
2712:                    WhereConditionGroup innerWheres = getPropertyInstanceValueConditions(
2713:                            condPropInst, "=", null);
2714:
2715:                    if (innerWheres.size() > 1) {
2716:                        nestedSelect.addWhereCondition(innerWheres);
2717:                    } else {
2718:                        //no sense in adding a WhereConditions
2719:                        //when we can just pick up the only condition
2720:                        //and add it
2721:                        Object cond = innerWheres.getCondition(0);
2722:                        if (cond instanceof  WhereCondition) {
2723:                            nestedSelect
2724:                                    .addWhereCondition((WhereCondition) cond);
2725:                        } else if (cond instanceof  WhereConditionGroup) {
2726:                            nestedSelect
2727:                                    .addWhereCondition((WhereConditionGroup) cond);
2728:                        }
2729:                    }
2730:                }
2731:
2732:                outerWheres.addCondition(objObjectKeyColRef, "NOT IN",
2733:                        nestedSelect);
2734:            }
2735:
2736:            /**
2737:             * Sets the logical stringing operator to use between conditions.
2738:             * 
2739:             * @param sOp
2740:             */
2741:            public void setStringingOperator(String sOp) {
2742:                if (sOp.equalsIgnoreCase("and") || sOp.equalsIgnoreCase("or")) {
2743:                    m_ConditionOperator = sOp;
2744:                }
2745:
2746:            }
2747:
2748:            /**
2749:             * Switch caching of results on or off. Default is on.
2750:             * 
2751:             * @param bCache
2752:             */
2753:            public void cacheResults(boolean bCache) {
2754:                m_bCache = bCache;
2755:            }
2756:
2757:            /**
2758:             * Adds core data condition to the given <code>SelectStatement</code>.
2759:             * 
2760:             * @param select
2761:             * @throws DataStoreException
2762:             */
2763:            private void addCoreDataConditions(SelectStatement select)
2764:                    throws DataStoreException {
2765:                for (int i = 0; i < m_ConditionColumns.size(); i++) {
2766:                    select
2767:                            .setWhereConditionStringingOperator(m_ConditionOperator);
2768:                    select
2769:                            .addWhereCondition((WhereCondition) m_ConditionColumns
2770:                                    .get(i));
2771:
2772:                }
2773:            }
2774:
2775:            /**
2776:             * Returns a <code>WhereConditions</code> set of conditions to match on
2777:             * the values specified by the given general property instance, using the
2778:             * alias given for the property instance table.
2779:             * 
2780:             * @param condPropInst
2781:             * @param propInstAlias
2782:             * @return @throws
2783:             *         DataStoreException
2784:             * @throws DataAccessException
2785:             */
2786:            private WhereConditionGroup getPropertyInstanceValueConditions(
2787:                    GeneralPropertyInstance condPropInst, String sPropOperator,
2788:                    String propInstAlias) throws DataStoreException,
2789:                    DataAccessException {
2790:
2791:                ColumnRef valColref = condPropInst.getInstanceColumnRef(
2792:                        AbstractPropertyInstance.TAG_VALUE, false);
2793:
2794:                List values = condPropInst.getCalculatedValues();
2795:
2796:                if (propInstAlias != null && propInstAlias.length() > 0) {
2797:                    valColref.setTable(propInstAlias);
2798:                }
2799:
2800:                // If there are multiple values split into where conditions
2801:                // and separate by OR operator. Should be handled by WhereCondition?
2802:                WhereConditionGroup valuesWheres = new WhereConditionGroup();
2803:
2804:                WhereCondition where = null;
2805:
2806:                if (sPropOperator.equals("<>") == true
2807:                        || sPropOperator.equals("!=")) {
2808:                    valuesWheres.setStringingOperator("AND");
2809:                    sPropOperator = "!=";
2810:                } else {
2811:                    valuesWheres.setStringingOperator("OR");
2812:                }
2813:
2814:                Iterator iter = values.iterator();
2815:
2816:                while (iter.hasNext()) {
2817:
2818:                    where = new WhereCondition(valColref, sPropOperator, iter
2819:                            .next());
2820:
2821:                    valuesWheres.addCondition(where);
2822:                }
2823:
2824:                WhereConditionGroup innerWheres = new WhereConditionGroup();
2825:                innerWheres.addCondition(valuesWheres);
2826:
2827:                return innerWheres;
2828:            }
2829:
2830:            /**
2831:             * Returns a <code>WhereConditions</code> set of conditions to match on
2832:             * the values specified by the given profile property instance, using the
2833:             * alias given for the property instance table.
2834:             * 
2835:             * @param condPropInst
2836:             * @param propInstAlias
2837:             * @return @throws
2838:             *         DataStoreException
2839:             * @throws DataAccessException
2840:             */
2841:            private WhereConditionGroup getPropertyInstanceValueConditions(
2842:                    ProfilePropertyInstance condPropInst, String sPropOperator,
2843:                    String propInstAlias) throws DataStoreException,
2844:                    DataAccessException {
2845:
2846:                List values = condPropInst.getValues();
2847:
2848:                // If there are multiple values split into where conditions
2849:                // and separate by OR operator. Should be handled by WhereCondition?
2850:                WhereConditionGroup valuesWheres = new WhereConditionGroup();
2851:                WhereCondition where = null;
2852:
2853:                if (sPropOperator.equals("<>") == true
2854:                        || sPropOperator.equals("!=")) {
2855:                    valuesWheres.setStringingOperator("AND");
2856:                    sPropOperator = "!=";
2857:                } else {
2858:                    valuesWheres.setStringingOperator("OR");
2859:                }
2860:
2861:                Iterator iter = values.iterator();
2862:
2863:                while (iter.hasNext()) {
2864:                    Profile prof = (Profile) iter.next();
2865:
2866:                    String sName = prof.getName();
2867:
2868:                    ColumnRef nameCol = prof.getInstanceColumnRef(
2869:                            AbstractObject.ATTRIB_NAME, false);
2870:
2871:                    if (propInstAlias != null && propInstAlias.length() > 0) {
2872:                        nameCol.setTable(propInstAlias);
2873:                    }
2874:
2875:                    where = new WhereCondition(nameCol, sPropOperator, sName);
2876:
2877:                    valuesWheres.addCondition(where);
2878:                }
2879:
2880:                WhereConditionGroup innerWheres = new WhereConditionGroup();
2881:                innerWheres.addCondition(valuesWheres);
2882:
2883:                return innerWheres;
2884:
2885:            }
2886:
2887:            /**
2888:             * Returns a <code>WhereConditions</code> set of conditions to match on
2889:             * the values specified by the given child object property instance, using
2890:             * the alias given for the property instance table.
2891:             * 
2892:             * @param condPropInst
2893:             * @param propInstAlias
2894:             * @return @throws
2895:             *         DataStoreException
2896:             * @throws DataAccessException
2897:             */
2898:            private WhereConditionGroup getPropertyInstanceValueConditions(
2899:                    ChildObjectPropertyInstance condPropInst,
2900:                    String sPropOperator, String propInstAlias)
2901:                    throws DataStoreException, DataAccessException {
2902:
2903:                ColumnRef valColref = condPropInst.getInstanceColumnRef(
2904:                        AbstractPropertyInstance.TAG_VALUE, false);
2905:
2906:                List values = condPropInst.getValues();
2907:
2908:                if (propInstAlias != null && propInstAlias.length() > 0) {
2909:                    valColref.setTable(propInstAlias);
2910:                }
2911:
2912:                // If there are multiple values split into where conditions
2913:                // and separate by OR operator. Should be handled by WhereCondition?
2914:                WhereConditionGroup valuesWheres = new WhereConditionGroup();
2915:                WhereCondition where = null;
2916:
2917:                AbstractChildObject child = null;
2918:
2919:                if (sPropOperator.equals("<>") == true) {
2920:                    valuesWheres.setStringingOperator("AND");
2921:                    sPropOperator = "!=";
2922:                } else {
2923:                    valuesWheres.setStringingOperator("OR");
2924:                }
2925:
2926:                for (Iterator iter = values.iterator(); iter.hasNext();) {
2927:                    child = (AbstractChildObject) iter.next();
2928:                    int nChildId = child.getId();
2929:
2930:                    if (nChildId > 0) {
2931:                        //condition is based on object id
2932:                        where = new WhereCondition(valColref, sPropOperator,
2933:                                nChildId);
2934:                    } else {
2935:                        //assume that we're doing a search on name
2936:
2937:                        String sName = child.getName();
2938:
2939:                        if (sName != null) {
2940:                            ColumnRef objIdCol = child.getInstanceColumnRef(
2941:                                    AbstractObject.ATTRIB_ID, child
2942:                                            .isHistorical());
2943:                            ColumnRef objNameCol = child.getInstanceColumnRef(
2944:                                    AbstractObject.TAG_NAME, child
2945:                                            .isHistorical());
2946:
2947:                            String objAlias = condPropInst.getName() + "_"
2948:                                    + child.getDBTableName();
2949:
2950:                            objIdCol.setTableAlias(objAlias);
2951:                            objNameCol.setTableAlias(objAlias);
2952:
2953:                            //condition is based on object id
2954:                            where = new WhereCondition(objNameCol, condPropInst
2955:                                    .getOperator(), sName);
2956:
2957:                            JoinConditions join = new JoinConditions();
2958:
2959:                            join.addCondition(objIdCol, valColref);
2960:
2961:                            where.addAssociatedJoinConditions(join);
2962:                        }
2963:                    }
2964:
2965:                    valuesWheres.addCondition(where);
2966:                }
2967:
2968:                WhereConditionGroup innerWheres = new WhereConditionGroup();
2969:                innerWheres.addCondition(valuesWheres);
2970:
2971:                return innerWheres;
2972:
2973:            }
2974:
2975:            /**
2976:             * Returns a <code>WhereConditions</code> set of conditions to match on
2977:             * the values specified by the given property instance, using the alias
2978:             * given for the property instance table.
2979:             * 
2980:             * @param condPropInst
2981:             * @param condOperator TODO
2982:             * @param propInstAlias
2983:             * @return 
2984:             * @throws DataStoreException
2985:             * @throws DataAccessException
2986:             */
2987:            private WhereConditionGroup getPropertyInstanceValueConditions(
2988:                    AbstractPropertyInstance condPropInst, String condOperator,
2989:                    String propInstAlias) throws DataStoreException,
2990:                    DataAccessException {
2991:                WhereConditionGroup innerWheres = null;
2992:
2993:                if (condPropInst instanceof  GeneralPropertyInstance) {
2994:                    innerWheres = getPropertyInstanceValueConditions(
2995:                            (GeneralPropertyInstance) condPropInst,
2996:                            condOperator, propInstAlias);
2997:                } else if (condPropInst instanceof  ProfilePropertyInstance) {
2998:                    innerWheres = getPropertyInstanceValueConditions(
2999:                            (ProfilePropertyInstance) condPropInst,
3000:                            condOperator, propInstAlias);
3001:                } else if (condPropInst instanceof  ChildObjectPropertyInstance) {
3002:                    innerWheres = getPropertyInstanceValueConditions(
3003:                            (ChildObjectPropertyInstance) condPropInst,
3004:                            condOperator, propInstAlias);
3005:                }
3006:
3007:                return innerWheres;
3008:            }
3009:
3010:            /**
3011:             * @return
3012:             */
3013:            public boolean isApprovedSearch() {
3014:                return m_bApprovedSearch;
3015:            }
3016:
3017:            /**
3018:             * @param b
3019:             */
3020:            public void setApproved(boolean bApproved) {
3021:                m_bApprovedSearch = bApproved;
3022:            }
3023:
3024:            /**
3025:             * @return
3026:             */
3027:            public List getConditionProfile() {
3028:                return m_ConditionProfile;
3029:            }
3030:
3031:            /**
3032:             * @return Returns the m_ConditionGroups.
3033:             */
3034:            public List getConditionGroups() {
3035:                return m_ConditionGroups;
3036:            }
3037:
3038:            /**
3039:             * @return Returns the m_SearchColumns.
3040:             */
3041:            public List getSearchColumns() {
3042:                return m_SearchColumns;
3043:            }
3044:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.