KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > search > Search


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.rm.search;
20
21 import java.sql.*;
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.cache.CacheException;
26 import org.openharmonise.commons.dsi.*;
27 import org.openharmonise.commons.dsi.dml.*;
28 import org.openharmonise.commons.xml.*;
29 import org.openharmonise.rm.*;
30 import org.openharmonise.rm.config.*;
31 import org.openharmonise.rm.dsi.DataStoreObject;
32 import org.openharmonise.rm.factory.*;
33 import org.openharmonise.rm.metadata.*;
34 import org.openharmonise.rm.publishing.*;
35 import org.openharmonise.rm.resources.*;
36 import org.openharmonise.rm.resources.lifecycle.Status;
37 import org.openharmonise.rm.resources.metadata.properties.*;
38 import org.openharmonise.rm.resources.metadata.properties.ranges.Range;
39 import org.openharmonise.rm.resources.publishing.*;
40 import org.openharmonise.rm.security.authorization.*;
41 import org.w3c.dom.*;
42
43
44 /**
45  * <p>Provides an interface to construct and run searches over
46  * resources within the repository, allowing metadata conditions to be
47  * specified using implementations of <code>AbstractPropertyInstance</code>
48  * core data conditions to be specified using <code>ColumnRef</code>.
49  * The class also implements <code>Publishable</code> in order that
50  * a search can be specified in HaRP and the results can be published
51  * as XML.</p>
52  *
53  * @author Michael Bell
54  * @version $Revision: 1.10 $
55  *
56  */

57 public class Search implements Publishable {
58
59     private boolean m_bCache = true;
60
61     //XML constants
62
public static final String JavaDoc ATTRIB_ORDERBY = "orderBy";
63
64     public static final String JavaDoc ATTRIB_ORDER_DIRECTION = "orderDirection";
65
66     public static final String JavaDoc ATTRIB_OBJECT_TYPE = "objectType";
67
68     public static final String JavaDoc TAG_SEARCH = "Search";
69
70     public static final String JavaDoc TAG_LIST = "List";
71
72     public static final String JavaDoc ATTRIB_MAXRESULTS = "maxResults";
73
74     public static final String JavaDoc TAG_SEARCHTEXT = "SearchText";
75
76     public static final String JavaDoc TAG_FURTHERLINKS = "FurtherLinks";
77
78     public static final String JavaDoc TAG_NUMBER = "Number";
79
80     public static final String JavaDoc TAG_SEARCHCONDITIONS = "SearchConditions";
81
82     public static final String JavaDoc TAG_SEARCH_OBJECT = "SearchObject";
83
84     public static final String JavaDoc TAG_CONDITIONS = "Conditions";
85
86     public static final String JavaDoc TAG_FILTERCONDITIONS = "FilterConditions";
87
88     public static final String JavaDoc TAG_FILTERSOURCE = "FilterSource";
89
90     public static final String JavaDoc TAG_SUBMIT = "Submit";
91
92     public static final String JavaDoc ATTRIB_STRICT_TYPING = "strictTyping";
93
94     public static final String JavaDoc TAG_COMMENT = "Comment";
95
96     public static final String JavaDoc TAG_POSITION = "Position";
97
98     public static final String JavaDoc TAG_DISPLAY = "Display";
99
100     public static final String JavaDoc TAG_TOTAL = "Total";
101
102     public static final String JavaDoc ATTRIB_SUB = "sub";
103
104     public static final String JavaDoc ATTRIB_SELECTED = "selected";
105
106     public static final String JavaDoc ATTRIB_INCLUSIVE = "inclusive";
107
108     public static final String JavaDoc TAG_AND = "And";
109
110     public static final String JavaDoc TAG_OR = "Or";
111
112     private static String JavaDoc PNAME_RESULTSET_CACHING = "RESULTSET_CACHING";
113
114     /**
115      * Vector of WhereCondition objects, all of the columns that an object
116      * manages itself.
117      */

118     protected List m_ConditionColumns = null;
119     
120     /**
121      * Vector of GroupObjects identifying which groups should be in the search
122      */

123     protected List m_ConditionGroups = null;
124
125     /**
126      * the properties to be used in the search
127      */

128     protected List m_ConditionProfile = null;
129
130     /**
131      * Vector of ColumnRefs, identifies which columns should be returned
132      */

133     protected List m_SearchColumns = null;
134
135     /**
136      * Vector of Properties, identifies which Properties should be returned
137      */

138     protected List m_SearchProfile = null;
139     
140     /**
141      * String operator to link the condition profile properties
142      */

143     protected String JavaDoc m_ConditionOperator = "and";
144
145     protected Map m_orderByPropMap = new LinkedHashMap();
146
147     protected Map m_orderByColMap = new LinkedHashMap();
148
149     protected String JavaDoc m_sOrderDirection = "ASC";
150
151     protected int m_nLimit = -1;
152
153     //position in the results the listings should start from
154
protected int m_nPosition = 0;
155     
156     protected String JavaDoc m_sSearchType = "";
157
158     protected String JavaDoc m_sSearchText = "";
159
160     protected DataStoreObject m_searchObject = null;
161
162     protected Profile m_searchObjectProfile = null;
163
164     protected boolean m_bApprovedSearch = true;
165
166     protected String JavaDoc m_sFilterObjectClassname = null;
167
168     protected Vector m_filterProps = null;
169
170     protected AbstractDataStoreInterface m_dsi = null;
171
172     protected String JavaDoc m_sId = "";
173
174     protected String JavaDoc m_sName = "";
175
176     protected int m_nResultTotal = -1;
177
178     protected boolean m_bStrictType = true;
179
180     // set in getIndexSearchQuery if correct columns exist
181
protected boolean m_bIndexableSearch = false;
182
183     
184     protected CachedResultSet m_cached_rs = null;
185
186     protected boolean m_bFilterCondsNotFound = false;
187
188     protected boolean m_bFilterCondsInclusive = false;
189
190     private List m_indexresults = null;
191
192     private boolean m_bIsCachingRS = false;
193
194     private String JavaDoc m_sCacheKey = null;
195     
196     /**
197      * Logger for this class
198      */

199     private static final Logger m_logger = Logger.getLogger(Search.class.getName());
200
201     //initialising block
202
{
203         m_ConditionColumns = new Vector(16);
204         m_ConditionGroups = new Vector(16);
205         m_ConditionProfile = new Vector(16);
206
207         m_SearchColumns = new Vector(16);
208         m_SearchProfile = new Vector(16);
209     }
210
211     /**
212      * Basic constructor
213      *
214      */

215     public Search() {
216     }
217
218     /**
219      * Standard constructor with interface to the DB.
220      *
221      * @param dbinterf
222      */

223     public Search(AbstractDataStoreInterface dbinterf) {
224         m_dsi = dbinterf;
225     }
226
227     /**
228      * Returns an object of the type that the search will be conducted on.
229      *
230      * @return
231      */

232     public DataStoreObject getSearchType() {
233         return m_searchObject;
234     }
235
236     /**
237      * Sets the object type that the search will be conducted on.
238      *
239      * @param dobj
240      * @throws DataStoreException
241      */

242     public void setSearchType(DataStoreObject dobj) throws DataStoreException {
243
244         if (m_searchObject != null) {
245             if (dobj instanceof AbstractProfiledObject) {
246                 AbstractProfiledObject profObj = (AbstractProfiledObject) dobj;
247
248                 try {
249                     m_searchObjectProfile = profObj.getProfile();
250                 } catch (DataAccessException e) {
251                     m_searchObjectProfile = null;
252                 }
253
254                 if (m_searchObjectProfile == null) {
255                     m_searchObjectProfile = new Profile(m_dsi, profObj);
256                 }
257                 Profile prof = m_searchObjectProfile;
258
259                 for (int i = 0; i < this.m_ConditionProfile.size(); i++) {
260                     AbstractPropertyInstance propInst = (AbstractPropertyInstance) m_ConditionProfile
261                             .get(i);
262                     propInst.setProfile(prof);
263                 }
264
265                 for (int i = 0; i < this.m_SearchProfile.size(); i++) {
266                     AbstractPropertyInstance propInst = (AbstractPropertyInstance) m_ConditionProfile
267                             .get(i);
268                     propInst.setProfile(prof);
269                 }
270             }
271
272             m_SearchColumns.clear();
273             m_SearchColumns.add(dobj.getInstanceColumnRef(
274                     AbstractObject.ATTRIB_ID, ((AbstractObject) dobj)
275                             .isHistorical()));
276             m_ConditionColumns.clear();
277             m_orderByPropMap.clear();
278             m_orderByColMap.clear();
279         }
280
281         m_searchObject = dobj;
282         m_sSearchType = dobj.getClass().getName();
283     
284         ColumnRef colrefId = m_searchObject.getInstanceColumnRef(
285             AbstractObject.ATTRIB_ID, ((AbstractObject) m_searchObject)
286                 .isHistorical());
287     
288         if (colrefId != null) {
289           addSelectColumn(colrefId);
290         }
291     
292         if (m_sSearchType.indexOf(".") >= 0) {
293             int index = m_sSearchType.lastIndexOf(".");
294             m_sSearchType = m_sSearchType.substring(index + 1);
295         }
296     }
297
298     /**
299      * Sets the maximum size of the list of results.
300      *
301      * @param nNum
302      */

303     public void setResultSize(int nNum) {
304         this.m_nLimit = nNum;
305     }
306
307     /**
308      * Sets the column which will be used for ordering the results as well as
309      * the direction of the ordering.
310      *
311      * @param colref
312      * @param sOrderDirection
313      */

314     public void setOrderBy(ColumnRef colref, String JavaDoc sOrderDirection) {
315         m_orderByColMap.put(colref, sOrderDirection);
316     }
317
318     /**
319      * Sets the property instance which should be used to order the search
320      * results as well as the direction of the ordering.
321      *
322      * @param propInst
323      * @param sOrderDirection
324      */

325     public void setOrderBy(AbstractPropertyInstance propInst,
326             String JavaDoc sOrderDirection) {
327         m_orderByPropMap.put(propInst, sOrderDirection);
328     }
329
330     /**
331      * Returns a <code>Set</code> of <code>ColumnRef</code>s which
332      * represents the column by which the results will be ordered.
333      *
334      * @return a <code>Set</code> of <code>ColumnRef</code>s
335      */

336     public Set getOrderByColumns() {
337         return m_orderByColMap.keySet();
338     }
339
340     /* (non-Javadoc)
341      * @see org.openharmonise.rm.publishing.Publishable#getTagName()
342      */

343     public String JavaDoc getTagName() {
344
345         return TAG_SEARCH;
346     }
347
348     /**
349      * Returns the direction the results will be ordered in
350      * for the specified column reference.
351      *
352      * @return the direction the results will be ordered in
353      * for the specified column reference
354      */

355     public String JavaDoc getOrderDirection(ColumnRef colref) {
356         return (String JavaDoc)m_orderByColMap.get(colref);
357     }
358
359     /**
360      * Adds a condition to the search. Defined by column, operator and value.
361      *
362      * @param colref
363      * @param sOperator
364      * @param values
365      * @throws DataStoreException
366      */

367     public void addConditionColumn(ColumnRef colref, String JavaDoc sOperator,
368             Vector values) throws DataStoreException {
369         WhereCondition where = new WhereCondition(colref, sOperator, values);
370
371         m_ConditionColumns.add(where);
372     }
373
374     /**
375      * Adds a relationship condition to the search such that results will be
376      * children of the given <code>AbstractParentObject</code>.
377      *
378      * @param grpObj
379      */

380     public void addConditionGroup(AbstractParentObject grpObj) {
381         if (grpObj != null) {
382             m_ConditionGroups.add(grpObj);
383         }
384     }
385
386     /**
387      * Adds a condition to this search which is defined by the given
388      * <code>AbstractPropertyInstance</code>.
389      *
390      * @param propInst
391      */

392     public void addConditionProperty(AbstractPropertyInstance propInst) {
393         m_ConditionProfile.add(propInst);
394     }
395
396     /**
397      * Adds conditions to the search defined by the given <code>Profile</code>,
398      * i.e. the conditions will be specified by the property instances the
399      * profile contains.
400      *
401      * @param prof
402      * @throws DataAccessException
403      */

404     public void addConditionProfile(Profile prof) throws DataAccessException {
405         m_ConditionProfile.addAll(prof.getPropertyInstances());
406     }
407
408     /**
409      * Adds a select column to be returned in the search. Objects which are
410      * returned will be populated with this data from the executed search as an
411      * optimisation.
412      *
413      * Note: the column referenced will be associated to the object's core data
414      * rather than profile data
415      *
416      * @param colref
417      */

418     public void addSelectColumn(ColumnRef colref) {
419         m_SearchColumns.add(colref);
420     }
421
422     /**
423      * Adds a select column to be returned in the search which corresponds to
424      * the given property instance. Objects which are returned will be populated
425      * with this data from the executed search as an optimisation.
426      *
427      * @param propInst
428      */

429     public void addSelectProperty(AbstractPropertyInstance propInst) {
430         m_SearchProfile.add(propInst);
431     }
432
433     /**
434      * Executed the search and returns a vector of objects representing the
435      * results of the search.
436      *
437      * @return @throws
438      * SearchException
439      * @throws HarmoniseIndexerException
440      * @throws DataAccessException
441      * @throws DataStoreException
442      */

443     public List executeSearch() throws SearchException, HarmoniseIndexerException,
444             DataAccessException, DataStoreException {
445         Vector results = null;
446
447         SelectStatement select = generateSelectStatement();
448
449         //if no cached results do DB query
450
if (m_cached_rs == null) {
451             ResultSet rs = null;
452
453             if ((m_bIndexableSearch == false)
454                     || (m_indexresults != null && m_indexresults.size() > 0)) {
455                 
456                 if(m_logger.isLoggable(Level.FINE)) {
457                     m_logger.logp(Level.FINE, this.getClass().getName(), "executeSearch", "Executing search - " + m_dsi.getSelectStatement(select));
458                 }
459                 
460                 rs = m_dsi.execute(select);
461
462                 m_cached_rs = new CachedResultSet(rs);
463             }
464
465             if (rs != null) {
466                 try {
467                     rs.close();
468                 } catch (SQLException e) {
469                     throw new SearchException("Error closing result set", e);
470                 }
471             }
472
473             if ((m_cached_rs != null) && (m_bIsCachingRS == true)) {
474                 if (m_logger.isLoggable(Level.FINE)) {
475                     m_logger.log(Level.FINE,"Caching search results for " + m_dsi.getSelectStatement(select));
476                 }
477                 try {
478                     SearchResultsCache.getInstance().addToCache(m_sCacheKey,
479                             m_cached_rs);
480                 } catch (CacheException e) {
481                     throw new SearchException("Cache error", e);
482                 }
483             } else {
484                 if (m_logger.isLoggable(Level.FINE)) {
485                     m_logger.log(Level.FINE,"Not caching search results");
486                 }
487             }
488         } else {
489             if (m_logger.isLoggable(Level.FINE)) {
490                 m_logger.log(Level.FINE,"Got cached search results");
491             }
492         }
493
494         //fill return vector with objects
495
List returnVec = new Vector(16);
496
497         if (m_cached_rs != null) {
498             m_cached_rs.setStartRow(m_nPosition);
499
500             //if no limit is set this should be default value of -1
501
returnVec = m_searchObject.processResultSet(m_cached_rs, select,
502                     m_nLimit - m_nPosition);
503
504             m_nResultTotal = m_cached_rs.getResultTotal();
505         }
506
507         return returnVec;
508     }
509
510     public SelectStatement generateSelectStatement() throws SearchException,
511             HarmoniseIndexerException, DataAccessException, DataStoreException {
512         //build query
513
SelectStatement select = new SelectStatement();
514
515         //add the select colomn refs to the select statement
516
select.addSelectColumns(m_SearchColumns);
517
518         if (m_orderByColMap.isEmpty() == false) {
519             select.addOrderBy(m_orderByColMap);
520         }
521
522         HarmoniseIndexer indexer = HarmoniseIndexer.getInstance();
523
524         //get index query if applicable
525
String JavaDoc sIndexQuery = "";
526
527         if (this.m_bApprovedSearch == true) {
528             sIndexQuery = getIndexSearchQuery();
529
530             if (m_logger.isLoggable(Level.FINE)) {
531                 m_logger.log(Level.FINE,"Index search:" + sIndexQuery);
532             }
533         }
534
535         //add conditions to select statement
536
addWhereConditions(select);
537
538         m_sCacheKey = sIndexQuery + "|" + this.m_dsi.getSelectStatement(select);
539
540         //try and get cached results
541
m_bIsCachingRS = m_bCache;
542
543         if (m_bCache == true) {
544             try {
545                 m_bIsCachingRS = ConfigSettings.getProperty(
546                         PNAME_RESULTSET_CACHING, "ON").equals("ON");
547
548                 if (m_bIsCachingRS == true) {
549                     if(m_logger.isLoggable(Level.FINE)) {
550                         m_logger.logp(Level.FINER, this.getClass().getName(), "generateSelectStatement", "Getting cached results for " + m_sCacheKey);
551                     }
552                     m_cached_rs = SearchResultsCache.getInstance().getResults(
553                             m_sCacheKey);
554                     if(m_logger.isLoggable(Level.FINE) && m_cached_rs == null) {
555                         m_logger.logp(Level.FINER, this.getClass().getName(), "generateSelectStatement", "No results cached");
556                     }
557                 }
558             } catch (ConfigException e) {
559                 throw new SearchException("Config error", e);
560             } catch (CacheException e) {
561                 throw new SearchException("Cache error", e);
562             }
563         }
564
565         if (m_cached_rs == null) {
566             m_indexresults = null;
567             if ((sIndexQuery != null) && (sIndexQuery.length() > 0)) {
568                 m_indexresults = indexer.searchContents(sIndexQuery);
569
570                 if (m_logger.isLoggable(Level.FINE)) {
571                     m_logger.log(Level.FINE,"there was " + m_indexresults.size()
572                             + " lucene results");
573                 }
574
575                 select.addWhereCondition(this.m_searchObject
576                         .getInstanceColumnRef(AbstractObject.ATTRIB_ID,
577                                 ((AbstractObject) m_searchObject)
578                                         .isHistorical()), "IN",
579                         (Vector) m_indexresults);
580
581             }
582         }
583
584         return select;
585     }
586
587     /* (non-Javadoc)
588      * @see org.openharmonise.rm.publishing.Publishable#publish(org.openharmonise.rm.resources.publishing.Template, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
589      */

590     public org.w3c.dom.Element JavaDoc publish(Template template, HarmoniseOutput xmlDoc,
591             State state) throws PublishException {
592         Element resultEl = null;
593
594         try {
595
596             resultEl = publish(template.getTemplateRootElement(), xmlDoc, state);
597         } catch (DataAccessException e) {
598             throw new PublishException(e);
599         }
600
601         return resultEl;
602     }
603
604     /* (non-Javadoc)
605      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
606      */

607     public org.w3c.dom.Element JavaDoc publish(Element topEl, HarmoniseOutput xmlDoc,
608             State state) throws PublishException {
609         Element docEl;
610
611         String JavaDoc sTagname = topEl.getTagName();
612
613         if (m_logger.isLoggable(Level.FINE)) {
614             m_logger.log(Level.FINE,"Publishing " + sTagname + " element");
615         }
616
617         if (sTagname.equalsIgnoreCase(TAG_LIST)) {
618             if (m_logger.isLoggable(Level.FINE)) {
619                 m_logger.log(Level.FINE,"Publishing as List element");
620             }
621             docEl = list(topEl, xmlDoc, state);
622         } else if (sTagname.equalsIgnoreCase(TAG_SEARCH)) {
623             if (m_logger.isLoggable(Level.FINE)) {
624                 m_logger.log(Level.FINE,"Publishing as Search element");
625             }
626             docEl = search(topEl, xmlDoc, state);
627         } else {
628             if (m_logger.isLoggable(Level.FINE)) {
629                 m_logger.log(Level.FINE,"Didn't recognise element");
630             }
631             docEl = (Element) xmlDoc.copyNode(topEl);
632         }
633
634         return docEl;
635     }
636
637     /* (non-Javadoc)
638      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
639      */

640     public void populate(Element xmlElement, State state)
641             throws PopulateException {
642         if ((xmlElement.getTagName().equals(TAG_SEARCH) == false)
643                 && (xmlElement.getTagName().equals(TAG_LIST) == false)) {
644             throw new PopulateException("Expected either " + TAG_SEARCH
645                     + " or " + TAG_LIST + " got " + xmlElement.getTagName());
646         }
647
648         boolean bIsList = false;
649
650         if (xmlElement.getTagName().equals(TAG_LIST)) {
651             bIsList = true;
652         }
653
654         if (xmlElement.getAttribute(AbstractObject.ATTRIB_ID).equals("") == false) {
655             m_sId = xmlElement.getAttribute(AbstractObject.ATTRIB_ID);
656         }
657
658         if (xmlElement.getAttribute(AbstractObject.ATTRIB_NAME).equals("") == false) {
659             m_sName = xmlElement.getAttribute(AbstractObject.ATTRIB_NAME);
660         }
661
662         if (xmlElement.getAttribute(ATTRIB_MAXRESULTS).equals("") == false) {
663             m_nLimit = Integer.parseInt(xmlElement
664                     .getAttribute(ATTRIB_MAXRESULTS));
665         }
666
667         // get the child nodes for the type of search
668
// either list of search
669
NodeList nodes = xmlElement.getChildNodes();
670         Element formEl;
671         Text txt;
672         String JavaDoc sTagName;
673         Profile pro;
674
675         // go through each one of them
676
for (int i = 0; i < nodes.getLength(); i++) {
677             if (nodes.item(i).getNodeType() == Node.TEXT_NODE) {
678                 continue;
679             }
680             formEl = (Element) nodes.item(i);
681             sTagName = formEl.getTagName();
682
683             if (sTagName.equalsIgnoreCase(TAG_SEARCHTEXT)) {
684                 setSearchText(XMLDocument.getChildTextNodeValue(formEl));
685             } else if (sTagName.equalsIgnoreCase(TAG_CONDITIONS)) {
686                 if (bIsList) {
687                     try {
688                         processSearchConditions(formEl, state);
689                     } catch (PublishException e) {
690                         throw new PopulateException(
691                                 "Error occurred processing search conditions: ",
692                                 e);
693                     }
694                 }
695             } else if (sTagName.equalsIgnoreCase(TAG_SUBMIT)) {
696             } else if (sTagName.equalsIgnoreCase(TAG_SEARCH_OBJECT) == true) {
697                 String JavaDoc sSearchTypeTag = "";
698                 Element elm = null;
699
700                 NodeList searchObjectNodes = formEl.getChildNodes();
701                 // get all the child nodes
702

703                 for (int j = 0; j < searchObjectNodes.getLength()
704                         && sSearchTypeTag.equals(""); j++) {
705                     if (searchObjectNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
706                         continue;
707                     }
708
709                     elm = (Element) searchObjectNodes.item(j); // get the
710
// element
711
sSearchTypeTag = elm.getTagName(); // get the tag name
712
}
713
714                 if (sSearchTypeTag.equals("") == true) {
715                     throw new PopulateException(
716                             "Template Tag or Tag for Search object (e.g <Document/>) must be provided");
717                 } else if (sSearchTypeTag.equals(Template.TAG_TEMPLATE) == true) {
718                     try {
719
720                         Template tmplt = (Template) HarmoniseObjectFactory
721                                 .instantiateHarmoniseObject(
722                                         m_dsi,
723                                         Template.class.getName(),
724                                         Integer
725                                                 .parseInt(elm
726                                                         .getAttribute(AbstractObject.ATTRIB_ID)));
727
728                         setSearchType(tmplt.getTemplateRootElement());
729                     } catch (NumberFormatException JavaDoc e) {
730                         throw new PopulateException("Number format exception",
731                                 e);
732                     } catch (DataAccessException e) {
733                         throw new PopulateException(
734                                 "Error occured getting template root element",
735                                 e);
736                     } catch (SearchException e) {
737                         throw new PopulateException("Search error", e);
738                     } catch (DataStoreException e) {
739                         throw new PopulateException("Data store error", e);
740                     } catch (HarmoniseFactoryException e) {
741                         throw new PopulateException(e);
742                     }
743                 } else {
744                     try {
745                         setSearchType(elm);
746                     } catch (SearchException e) {
747                         throw new PopulateException(
748                                 "Problem ocurred while attempting to set search type",
749                                 e);
750                     } catch (PopulateException e) {
751                         throw new PopulateException(
752                                 "Problem ocurred while attempting to set search type",
753                                 e);
754                     } catch (DataStoreException e) {
755                         throw new PopulateException(
756                                 "Problem ocurred while attempting to set search type",
757                                 e);
758                     }
759                 }
760             }
761         }
762     }
763
764     /**
765      * Adds the sub groups of the given <code>AbstractParentObject</code> as
766      * conditions of this search.
767      *
768      * @param grpObj
769      * @throws DataAccessException
770      */

771     public void addSubGroupsAsConditions(AbstractParentObject grpObj)
772             throws DataAccessException {
773         if(grpObj != null) {
774             List subGrps = grpObj
775             .getChildrenByType(AbstractParentObject.BRANCH_NODES);
776
777             for (int i = 0; i < subGrps.size(); i++) {
778                 AbstractParentObject sub = (AbstractParentObject) subGrps.get(i);
779                 this.addConditionGroup(sub);
780                 addSubGroupsAsConditions(sub);
781             }
782         }
783         
784     }
785
786     /*-------------------------------------------------------------------
787      Protected methods
788      ------------------------------------------------------------------*/

789
790     /**
791      * Publishes the 'List' element. Executes the search defined by the XML and
792      * returns XML which will be a list of results published as specified by the
793      * 'Template' child element of 'List'.
794      *
795      * @param list
796      * @param output
797      * @param state
798      * @return @throws
799      * PublishException
800      */

801     protected Element list(Element list, HarmoniseOutput output, State state)
802             throws PublishException {
803         if (m_logger.isLoggable(Level.FINE)) {
804             m_logger.log(Level.FINE,"Executing list method");
805         }
806
807         boolean bMore = false;
808         NodeList nodes;
809         int nMorePage = -2;
810         int nPageId = state.getPageId();
811         Profile usrProf = state.getLoggedInUserProfile();
812
813         Element newList = output.createElement(TAG_LIST);
814
815         if ((m_sName == null) || (m_sName.length() == 0)) {
816             m_sName = list.getAttribute(AbstractObject.ATTRIB_NAME);
817         }
818
819         newList.setAttribute(AbstractObject.ATTRIB_NAME, m_sName);
820
821         if ((m_sId == null) || (m_sId.length() == 0)) {
822             m_sId = list.getAttribute(AbstractObject.ATTRIB_ID);
823         }
824
825         String JavaDoc sStringTyping = list.getAttribute(ATTRIB_STRICT_TYPING);
826
827         if ((sStringTyping != null) && (sStringTyping.length() > 0)
828                 && (sStringTyping.equalsIgnoreCase("false") == true)) {
829             this.m_bStrictType = false;
830         }
831
832         newList.setAttribute(AbstractObject.ATTRIB_ID, m_sId);
833
834         if (list.getElementsByTagName("*").getLength() == 0) {
835             return newList;
836         }
837
838         Element searchObjectElm = (Element) XMLUtils.getFirstNamedChild(list,
839                 TAG_SEARCH_OBJECT);
840
841         if (searchObjectElm == null) {
842             throw new PublishException("SearchObject Tag is missing.");
843         }
844
845         String JavaDoc sTagName = "";
846         Element elm = null;
847
848         nodes = searchObjectElm.getChildNodes(); // get all the child nodes
849

850         for (int i = 0; i < nodes.getLength() && sTagName.equals(""); i++) {
851             if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
852                 continue;
853             }
854
855             elm = (Element) nodes.item(i); // get the element
856
sTagName = elm.getTagName(); // get the tag name
857
}
858
859         Template template = null;
860         int nTemplatePageId = -2;
861
862         if (sTagName.equals("") == true) {
863             throw new PublishException(
864                     "Template Tag or Tag for Search object (e.g <Document/>) must be provided");
865         } else if (sTagName.equals(Template.TAG_TEMPLATE) == true) {
866             NodeList pageNodes = elm.getElementsByTagName(WebPage.TAG_PAGE);
867
868             if (pageNodes.getLength() > 0) {
869                 nTemplatePageId = Integer
870                         .parseInt(((Element) pageNodes.item(0))
871                                 .getAttribute(AbstractObject.ATTRIB_ID));
872             }
873
874             try {
875                 template = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(
876                         m_dsi, Template.class.getName(), Integer.parseInt(elm
877                                 .getAttribute(AbstractObject.ATTRIB_ID)));
878             } catch (NumberFormatException JavaDoc e) {
879                 throw new PublishException(e);
880             } catch (HarmoniseFactoryException e) {
881                 throw new PublishException(e);
882             }
883
884             if (template != null) {
885                 try {
886                     Element root = template.getTemplateRootElement();
887
888                     setSearchType(root);
889                 } catch (DataAccessException e) {
890                     throw new PublishException("Error getting template root", e);
891                 } catch (SearchException e) {
892                     throw new PublishException("search error", e);
893                 } catch (PopulateException e) {
894                     throw new PublishException("Populate error", e);
895                 } catch (DataStoreException e) {
896                     throw new PublishException("Data store error", e);
897                 }
898             } else {
899                 throw new InvalidXMLElementException(
900                         "Template element not found");
901             }
902         } else {
903             try {
904                 setSearchType(elm);
905             } catch (SearchException e) {
906                 throw new PublishException(
907                         "Problem ocurred while attempting to set search type",
908                         e);
909             } catch (PopulateException e) {
910                 throw new PublishException(
911                         "Problem ocurred while attempting to set search type",
912                         e);
913             } catch (DataStoreException e) {
914                 throw new PublishException(
915                         "Problem ocurred while attempting to set search type",
916                         e);
917             }
918         }
919
920         //sort out searchconditions if necessary
921
nodes = list.getElementsByTagName(TAG_CONDITIONS);
922
923         Element searchCondEl = null;
924         Element stateCondEl = null;
925
926         if (nodes.getLength() > 0) {
927             searchCondEl = (Element) nodes.item(0);
928             stateCondEl = state.findElement(searchCondEl);
929
930             //conditions from state override conditions in input xml
931
if (stateCondEl != null) {
932                 searchCondEl = stateCondEl;
933             }
934
935             //if the conditions has 'conditions'
936
if (searchCondEl.hasChildNodes()) {
937                 processSearchConditions(searchCondEl, state);
938             }
939         }
940
941         nodes = list.getElementsByTagName(TAG_FILTERCONDITIONS);
942
943         for (int i = 0; i < nodes.getLength(); i++) {
944             Element elFilterConds = (Element) nodes.item(i);
945
946             if (elFilterConds.getParentNode().getNodeName().equalsIgnoreCase(
947                     TAG_LIST)) {
948                 Profile fListCondProf = createFilterConditionsProfile(
949                         elFilterConds, state);
950
951                 try {
952                     if (fListCondProf.match(usrProf) == false) {
953                         Element elComment = output.createElement(TAG_COMMENT);
954                         Text txt = output
955                                 .createTextNode("User failed list match");
956                         elComment.appendChild(txt);
957
958                         return elComment;
959                     }
960                 } catch (ProfileException e) {
961                     throw new PublishException(
962                             "Error occured matching profiles", e);
963                 }
964             } else if (elFilterConds.getParentNode().getNodeName()
965                     .equalsIgnoreCase(Template.TAG_TEMPLATE)) {
966                 //get filter condition for template and add to search
967
// conditions
968
addFilterSourceConditions(elFilterConds, state);
969             }
970         }
971
972         int nNumber = -1;
973         int nMaxResults = -1;
974         String JavaDoc sTemp = list.getAttribute(ATTRIB_MAXRESULTS);
975
976         if ((sTemp != null) && (sTemp.length() > 0)) {
977             nMaxResults = Integer.parseInt(sTemp);
978             nNumber = nMaxResults;
979
980             m_nLimit = m_nPosition + nNumber;
981         }
982
983         List results = new Vector();
984
985         if ((m_bFilterCondsInclusive == false)
986                 || (m_bFilterCondsNotFound == false)) {
987             try {
988                 results = executeSearch();
989             } catch (SearchException e) {
990                 throw new PublishException("Error occured executing search", e);
991             } catch (HarmoniseIndexerException e) {
992                 throw new PublishException("Error occured with indexer", e);
993             } catch (DataAccessException e) {
994                 throw new PublishException("data access error", e);
995             } catch (DataStoreException e) {
996                 throw new PublishException("data store error", e);
997             }
998         }
999
1000        if (nNumber == -1) {
1001            nNumber = results.size();
1002        }
1003
1004        nodes = list.getElementsByTagName(TAG_FURTHERLINKS);
1005
1006        Element xnFurtherLinks = null;
1007
1008        if (nodes.getLength() > 0) {
1009            bMore = true;
1010
1011            NodeList xnlPages = ((Element) nodes.item(0))
1012                    .getElementsByTagName(WebPage.TAG_PAGE);
1013
1014            if (xnlPages.getLength() > 0) {
1015                nMorePage = Integer.parseInt(((Element) xnlPages.item(0))
1016                        .getAttribute(AbstractObject.ATTRIB_ID));
1017            }
1018        }
1019
1020        publishResults(newList, output, state, template, results,
1021                nTemplatePageId);
1022
1023        if (nMorePage == -1) {
1024            nMorePage = nPageId;
1025        }
1026
1027        //add more link if appropriate
1028
if ((m_nResultTotal > m_nPosition + nNumber) && bMore) {
1029            if (xnFurtherLinks == null) {
1030                xnFurtherLinks = output.createElement(TAG_FURTHERLINKS);
1031            }
1032
1033            xnFurtherLinks.appendChild(createFurtherLinkElement(output, "More",
1034                    m_nPosition + nNumber, nMorePage));
1035        }
1036
1037        //Add prev link if appropriate
1038
if ((nNumber != 0) && ((m_nPosition + 1) > nNumber)) {
1039            if (xnFurtherLinks == null) {
1040                xnFurtherLinks = output.createElement(TAG_FURTHERLINKS);
1041            }
1042
1043            xnFurtherLinks.appendChild(createFurtherLinkElement(output,
1044                    "Previous", m_nPosition - nNumber, nMorePage));
1045        }
1046
1047        if (xnFurtherLinks != null) {
1048            newList.appendChild(xnFurtherLinks);
1049        }
1050
1051        Element xnState = output.createElement(State.TAG_STATE);
1052
1053        Element xnCond = output.createElement(TAG_CONDITIONS);
1054
1055        //set Condition name attribute to same as List
1056
xnCond.setAttribute(AbstractObject.ATTRIB_NAME, m_sName);
1057        xnState.appendChild(xnCond);
1058
1059        //if there are search conditions in the state append these
1060
if (searchCondEl != null) {
1061            NodeList nlSearchCond = searchCondEl.getChildNodes();
1062
1063            for (int i = 0; i < nlSearchCond.getLength(); i++) {
1064                Node node = nlSearchCond.item(i);
1065
1066                if (node.getNodeType() != Node.ELEMENT_NODE) {
1067                    continue;
1068                }
1069
1070                xnCond.appendChild(output.importNode(node, true));
1071            }
1072        }
1073
1074        if ((searchCondEl == null)
1075                || (searchCondEl.getElementsByTagName(TAG_POSITION).getLength() == 0)) {
1076            Element xnPosition = output.createElement(TAG_POSITION);
1077            Text txtPos = output.createTextNode(Integer.toString(m_nPosition));
1078            xnPosition.appendChild(txtPos);
1079            xnCond.appendChild(xnPosition);
1080        }
1081
1082        Element xnTotal = output.createElement(TAG_TOTAL);
1083        Text txtTotal = output.createTextNode(Integer.toString(m_nResultTotal));
1084        xnTotal.appendChild(txtTotal);
1085        xnCond.appendChild(xnTotal);
1086
1087        if (nMaxResults > 0) {
1088            Element xnDisplay = output.createElement(TAG_DISPLAY);
1089            Text txtNumber = output.createTextNode(Integer
1090                    .toString(nMaxResults));
1091            xnDisplay.appendChild(txtNumber);
1092            xnCond.appendChild(xnDisplay);
1093        }
1094
1095        newList.appendChild(xnState);
1096
1097        NodeList submitEls = list.getElementsByTagName(TAG_SUBMIT);
1098
1099        for (int i = 0; i < submitEls.getLength(); i++) {
1100            newList.appendChild(output.copyNode(submitEls.item(i)));
1101        }
1102
1103        return newList;
1104    }
1105
1106    /**
1107     * Publishes the results contained in <code>results</code> using the given
1108     * <code>Template</code> under the <code>Element</code> <code>list</code>.
1109     *
1110     * @param list
1111     * @param output
1112     * @param state
1113     * @param template
1114     * @param results
1115     * @param nPageId
1116     * @throws PublishException
1117     */

1118    protected void publishResults(Element list, HarmoniseOutput output, State state,
1119            Template template, List results, int nPageId)
1120            throws PublishException {
1121        boolean bIsViewable = true;
1122
1123        try {
1124            WebPage page = (WebPage) HarmoniseObjectFactory.instantiateHarmoniseObject(
1125                    this.m_dsi, WebPage.class.getName(), nPageId);
1126
1127            if (AuthorizationValidator.isVisible(state.getLoggedInUser(), page) == false) {
1128                bIsViewable = false;
1129            }
1130        } catch (HarmoniseFactoryException e) {
1131            throw new PublishException(
1132                    "Error occured getting object from factory", e);
1133        } catch (AuthorizationException e) {
1134            throw new PublishException("Error checking permissions on object",
1135                    e);
1136        }
1137
1138        for (Iterator iter = results.iterator(); iter.hasNext();) {
1139            Publishable pObj = (Publishable) iter.next();
1140
1141            Element tmpEl = pObj.publish(template, output, state);
1142
1143            NodeList linkNodes = tmpEl
1144                    .getElementsByTagName(AbstractObject.TAG_LINK);
1145
1146            if (linkNodes.getLength() > 0) {
1147                Element linkNode = (Element) linkNodes.item(0);
1148
1149                if (bIsViewable == false) {
1150                    linkNode.setAttribute(AuthorizationValidator.ATTRIB_IS_VIEWABLE,
1151                            "false");
1152                }
1153
1154                NodeList pageNodes = linkNode
1155                        .getElementsByTagName(WebPage.TAG_PAGE);
1156
1157                if (pageNodes.getLength() == 0) {
1158                    Node pageNode = output.createElement(WebPage.TAG_PAGE);
1159                    ((Element) pageNode).setAttribute(AbstractObject.ATTRIB_ID,
1160                            Integer.toString(nPageId));
1161
1162                    linkNode.appendChild(pageNode);
1163                }
1164            }
1165
1166            list.appendChild(tmpEl);
1167
1168        }
1169    }
1170
1171    /**
1172     * Publishes the 'Search' element, at most fills in available values for
1173     * property instances.
1174     *
1175     * @param search
1176     * @param output
1177     * @param state
1178     * @return @throws
1179     * PublishException
1180     */

1181    protected Element search(Element search, HarmoniseOutput output, State state)
1182            throws PublishException {
1183        Element newSearch = output.createElement(TAG_SEARCH);
1184        String JavaDoc sSearchName = search.getAttribute(AbstractObject.ATTRIB_NAME);
1185        newSearch.setAttribute(AbstractObject.ATTRIB_NAME, sSearchName);
1186        newSearch.setAttribute(AbstractObject.ATTRIB_ID, search
1187                .getAttribute(AbstractObject.ATTRIB_ID));
1188
1189        NodeList children = search.getChildNodes();
1190
1191        for (int i = 0; i < children.getLength(); i++) {
1192            if (children.item(i).getNodeType() != Node.ELEMENT_NODE) {
1193                continue;
1194            }
1195
1196            Element elTemp = (Element) children.item(i);
1197            String JavaDoc sTagName = elTemp.getTagName();
1198
1199            if (sTagName.equalsIgnoreCase(TAG_SEARCHTEXT)) {
1200                Element searchtext = output.createElement(TAG_SEARCHTEXT);
1201                m_sSearchText = ((Text) elTemp.getFirstChild()).getNodeValue();
1202
1203                Text txt = output.createTextNode(this.m_sSearchText);
1204                searchtext.appendChild(txt);
1205                newSearch.appendChild(searchtext);
1206            } else if (sTagName.equalsIgnoreCase(TAG_CONDITIONS)) {
1207                Element condEl = output.createElement(TAG_CONDITIONS);
1208                String JavaDoc sCondName = elTemp
1209                        .getAttribute(AbstractObject.ATTRIB_NAME);
1210                condEl.setAttribute(AbstractObject.ATTRIB_NAME, sCondName);
1211
1212                NodeList nodes = elTemp.getChildNodes();
1213
1214                for (int j = 0; j < nodes.getLength(); j++) {
1215                    if (nodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
1216                        continue;
1217                    }
1218
1219                    Element subEl = (Element) nodes.item(j);
1220
1221                    if (subEl.getTagName().equalsIgnoreCase(
1222                            AbstractChildObject.TAG_GROUP)) {
1223                        Element groupEl = output
1224                                .createElement(AbstractChildObject.TAG_GROUP);
1225                        groupEl.setAttribute(ATTRIB_SUB, subEl
1226                                .getAttribute(ATTRIB_SUB));
1227
1228                        NodeList groupNodes = subEl
1229                                .getElementsByTagName(Template.TAG_TEMPLATE);
1230
1231                        if (groupNodes.getLength() > 0) {
1232                            Element templateEl = (Element) groupNodes.item(0);
1233                            Template tmplt = null;
1234                            try {
1235                                tmplt = (Template) HarmoniseObjectFactory
1236                                        .instantiateHarmoniseObject(
1237                                                m_dsi,
1238                                                Template.class.getName(),
1239                                                Integer
1240                                                        .parseInt(templateEl
1241                                                                .getAttribute(AbstractObject.ATTRIB_ID)));
1242                            } catch (NumberFormatException JavaDoc e) {
1243                                throw new PublishException(e);
1244                            } catch (HarmoniseFactoryException e) {
1245                                throw new PublishException(e);
1246                            }
1247                            Element child = (Element) templateEl
1248                                    .getElementsByTagName("*").item(0);
1249                            try {
1250                                AbstractParentObject grpObj = (AbstractParentObject) HarmoniseObjectFactory
1251                                        .instantiatePublishableObject(
1252                                                this.m_dsi, child, state);
1253                                groupEl.appendChild(grpObj.publish(tmplt,
1254                                        output, state));
1255
1256                                if (subEl.getAttribute(ATTRIB_SUB)
1257                                        .equalsIgnoreCase("true")) {
1258                                    List subGrps = grpObj
1259                                            .getChildrenByType(AbstractParentObject.BRANCH_NODES);
1260
1261                                    for (int k = 0; k < subGrps.size(); k++) {
1262                                        AbstractParentObject sub = (AbstractParentObject) subGrps
1263                                                .get(k);
1264                                        groupEl.appendChild(sub.publish(tmplt,
1265                                                output, state));
1266                                    }
1267                                }
1268                            } catch (HarmoniseFactoryException e) {
1269                                throw new PublishException("Factory exception",
1270                                        e);
1271                            } catch (DataAccessException e) {
1272                                throw new PublishException(
1273                                        "Data access exception", e);
1274                            }
1275                        }
1276
1277                        condEl.appendChild(groupEl);
1278                    } else if (subEl.getTagName().equalsIgnoreCase(
1279                            Template.TAG_TEMPLATE)) {
1280                        Element el = (Element) subEl.getElementsByTagName("*")
1281                                .item(0);
1282
1283                        try {
1284                            Publishable pobj = HarmoniseObjectFactory
1285                                    .instantiatePublishableObject(this.m_dsi,
1286                                            el, state);
1287
1288                            Template tmplt = (Template) HarmoniseObjectFactory
1289                                    .instantiateHarmoniseObject(
1290                                            m_dsi,
1291                                            Template.class.getName(),
1292                                            Integer
1293                                                    .parseInt(subEl
1294                                                            .getAttribute(AbstractObject.ATTRIB_ID)));
1295
1296                            condEl.appendChild(pobj.publish(tmplt, output,
1297                                    state));
1298                        } catch (HarmoniseFactoryException e) {
1299                            // do nothing - just doesn't figure in conditions
1300
m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1301                        } catch (NumberFormatException JavaDoc e) {
1302                            throw new PublishException(e);
1303                        }
1304                    } else if (subEl.getTagName().equalsIgnoreCase(
1305                            AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1306
1307                        AbstractPropertyInstance pobj = null;
1308
1309                        try {
1310                            pobj = PropertyInstanceFactory.getPropertyInstance(
1311                                    m_dsi, subEl);
1312                        } catch (DataAccessException e) {
1313                            throw new PublishException(
1314                                    "Error occurred while populating property instance:",
1315                                    e);
1316                        } catch (HarmoniseFactoryException e) {
1317                            throw new PublishException(
1318                                    "Error occurred while getting property instance from factory:",
1319                                    e);
1320                        }
1321
1322                        try {
1323                            pobj.populate(subEl, state);
1324                        } catch (PopulateException e) {
1325                            throw new PublishException("Populate exception", e);
1326                        }
1327                        condEl.appendChild(pobj.publish(subEl, output, state));
1328                    } else {
1329                        condEl.appendChild(output.copyNode(subEl));
1330                    }
1331                }
1332
1333                try {
1334                    populateConditionsFromState(condEl, output, state);
1335                } catch (PopulateException e) {
1336                    throw new PublishException("Populate exception", e);
1337                }
1338                newSearch.appendChild(condEl);
1339            } else if (sTagName.equalsIgnoreCase(TAG_SUBMIT)) {
1340                newSearch.appendChild(output.copyNode(elTemp));
1341            }
1342        }
1343
1344        return newSearch;
1345    }
1346
1347    /**
1348     * Populates the search with filter conditions found in
1349     * <code>xmlElement</code>.
1350     *
1351     * @param xmlElement
1352     * @throws PublishException
1353     */

1354    protected void processFilterConditions(Element xmlElement)
1355            throws PublishException {
1356        if (xmlElement.getTagName().equals(TAG_FILTERCONDITIONS) == false) {
1357            throw new InvalidXMLElementException("Expecting "
1358                    + TAG_FILTERCONDITIONS + " got " + xmlElement.getTagName());
1359        }
1360
1361        NodeList propertyEls = xmlElement
1362                .getElementsByTagName(Property.TAG_PROPERTY);
1363
1364        if (propertyEls.getLength() > 0) {
1365            m_filterProps = new Vector(16);
1366        }
1367
1368        for (int i = 0; i < propertyEls.getLength(); i++) {
1369            Element propertyElement = (Element) propertyEls.item(0);
1370            NodeList pathNL = propertyElement
1371                    .getElementsByTagName(AbstractChildObject.TAG_PATH);
1372
1373            if (pathNL.getLength() > 0) {
1374
1375                try {
1376                    Property prop = (Property) HarmoniseObjectFactory
1377                            .instantiateHarmoniseObject(m_dsi, Property.class
1378                                    .getName(), XMLDocument
1379                                    .getChildTextNodeValue((Element) pathNL
1380                                            .item(0)));
1381                    m_filterProps.add(prop);
1382                } catch (HarmoniseFactoryException e) {
1383                    throw new PublishException("Factory exception", e);
1384                }
1385
1386            }
1387
1388        }
1389
1390        NodeList filterSourceEls = xmlElement
1391                .getElementsByTagName(TAG_FILTERSOURCE);
1392
1393        if (filterSourceEls.getLength() > 0) {
1394            Element elFilterSource = (Element) filterSourceEls.item(0)
1395                    .getFirstChild();
1396            m_sFilterObjectClassname = elFilterSource.getTagName();
1397        }
1398    }
1399
1400    /**
1401     * Adds conditions to the search based on the filter source found in the
1402     * <code>State</code>. Given a set of property instances specified in
1403     * <code>xmlElement</code>, the filter source object is located and
1404     * values for the conditions are taken for the conditions.
1405     *
1406     * @param xmlElement
1407     * @param state
1408     * @throws PublishException
1409     */

1410    protected void addFilterSourceConditions(Element xmlElement, State state)
1411            throws PublishException {
1412        Profile filterProfile = createFilterConditionsProfile(xmlElement, state);
1413
1414        try {
1415            List props = filterProfile.getPropertyInstances();
1416
1417            if (props.size() > 0) {
1418                for (int i = 0; i < props.size(); i++) {
1419                    addConditionProperty((AbstractPropertyInstance) props
1420                            .get(i));
1421                }
1422            } else {
1423                m_bFilterCondsNotFound = true;
1424            }
1425        } catch (DataAccessException e) {
1426            throw new PublishException(
1427                    "Error occured getting properties from profile", e);
1428        }
1429    }
1430
1431    /**
1432     * Processes a 'Conditions' element to extract the conditions to be used in
1433     * the search.
1434     *
1435     * @param xmlElement
1436     * @param state
1437     * @throws PublishException
1438     */

1439    protected void processSearchConditions(Element xmlElement, State state)
1440            throws PublishException {
1441        if (xmlElement.getTagName().equals(TAG_CONDITIONS) == false) {
1442            throw new InvalidXMLElementException("Expected " + TAG_CONDITIONS
1443                    + " got " + xmlElement.getTagName());
1444        }
1445
1446        NodeList nodes = xmlElement.getChildNodes();
1447
1448        for (int i = 0; i < nodes.getLength(); i++) {
1449            if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
1450                continue;
1451            }
1452
1453            Element condEl = (Element) nodes.item(i);
1454            String JavaDoc sTagName = condEl.getTagName();
1455
1456            try {
1457
1458                if (sTagName.equalsIgnoreCase(AbstractChildObject.TAG_GROUP)) {
1459                    Element groupEl = (Element) condEl
1460                            .getElementsByTagName("*").item(0);
1461                    AbstractParentObject grpObj = (AbstractParentObject) HarmoniseObjectFactory
1462                            .instantiatePublishableObject(this.m_dsi, groupEl,
1463                                    state);
1464
1465                    if(grpObj != null) {
1466                        addConditionGroup(grpObj);
1467                        
1468                        if (condEl.getAttribute(ATTRIB_SUB)
1469                                .equalsIgnoreCase("true")) {
1470                            addSubGroupsAsConditions(grpObj);
1471                        }
1472                    } else if(m_logger.isLoggable(Level.INFO)) {
1473                        m_logger.logp(Level.INFO, this.getClass().getName(), "processSearchConditions", "Group for group condition not found");
1474                    }
1475                    
1476
1477                    
1478                } else if (sTagName.equalsIgnoreCase(TAG_POSITION)) {
1479                    m_nPosition = Integer.parseInt(XMLDocument
1480                            .getChildTextNodeValue(condEl));
1481                } else if (sTagName
1482                        .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1483                    AbstractPropertyInstance propInst = PropertyInstanceFactory
1484                            .getPropertyInstance(m_dsi, condEl);
1485
1486                    propInst.populate(condEl, state);
1487
1488                    addConditionProperty(propInst);
1489
1490                } else if (sTagName
1491                        .equalsIgnoreCase(AbstractEditableObject.TAG_STATUS)) {
1492                    String JavaDoc txt = XMLDocument.getChildTextNodeValue(condEl);
1493
1494                    if (txt.equals(Status.APPROVED.getStringValue())) {
1495                        this.m_bApprovedSearch = true;
1496                    } else if (txt.equals(Status.UNAPPROVED.getStringValue())) {
1497                        this.m_bApprovedSearch = false;
1498                    } else {
1499                        //if txt is a integer then it may well be a valid
1500
// status code
1501
try {
1502                            int nStatus = Integer.parseInt(txt);
1503
1504                            if (nStatus == 0) {
1505                                this.m_bApprovedSearch = true;
1506                            }
1507
1508                            if (nStatus == 1) {
1509                                this.m_bApprovedSearch = false;
1510                            }
1511                        } catch (NumberFormatException JavaDoc numexp) {
1512                            m_logger.log(Level.WARNING, numexp.getLocalizedMessage(), numexp);
1513                        }
1514                    }
1515                } else {
1516                    addWhereConditionsFromXML(condEl, state);
1517                }
1518            } catch (NumberFormatException JavaDoc e) {
1519                throw new PublishException("Number format error", e);
1520            } catch (HarmoniseFactoryException e) {
1521                throw new PublishException("Factory error", e);
1522            } catch (DataAccessException e) {
1523                throw new PublishException("data access error", e);
1524            } catch (PopulateException e) {
1525                throw new PublishException("populate error", e);
1526            } catch (DataStoreException e) {
1527                throw new PublishException("data store error", e);
1528            }
1529        }
1530    }
1531
1532    /**
1533     * Sets the text associated with this search.
1534     *
1535     * @param sSearchText
1536     */

1537    protected void setSearchText(String JavaDoc sSearchText) {
1538        m_sSearchText = sSearchText;
1539    }
1540
1541    /**
1542     * Returns the text associated with this search
1543     *
1544     * @return
1545     */

1546    protected String JavaDoc getSearchText() {
1547        return m_sSearchText;
1548    }
1549
1550    /*-------------------------------------------------------------------
1551     Private methods
1552     ------------------------------------------------------------------*/

1553
1554    /**
1555     * Sets the object type that the search will be conducted on, based on the
1556     * object type associated with the given <code>Element</code>.
1557     *
1558     * @param sSearchObjEl
1559     * @throws SearchException
1560     * @throws DataStoreException
1561     * @throws PopulateException
1562     */

1563    private void setSearchType(Element sSearchObjEl) throws SearchException,
1564            DataStoreException, PopulateException {
1565        try {
1566            m_searchObject = (DataStoreObject) HarmoniseObjectFactory
1567                    .instantiatePublishableObject(this.m_dsi, sSearchObjEl,
1568                            null);
1569        } catch (HarmoniseFactoryException e) {
1570            throw new SearchException("Factory error", e);
1571        }
1572
1573        m_sSearchType = sSearchObjEl.getTagName();
1574
1575        ColumnRef colrefId = m_searchObject.getInstanceColumnRef(
1576                AbstractObject.ATTRIB_ID, ((AbstractObject) m_searchObject)
1577                        .isHistorical());
1578
1579        if (colrefId != null) {
1580            addSelectColumn(colrefId);
1581        }
1582
1583        NamedNodeMap nnm = sSearchObjEl.getAttributes();
1584
1585        //handle attributes
1586
for (int i = 0; i < nnm.getLength(); i++) {
1587            Attr attribute = (Attr) nnm.item(i);
1588
1589            String JavaDoc sName = attribute.getName();
1590            String JavaDoc sValue = attribute.getValue();
1591
1592            if ((sValue != null) && (sValue.length() > 0)) {
1593                Vector vec = new Vector();
1594                vec.add(sValue);
1595
1596                try {
1597                    this.addConditionColumn(m_searchObject
1598                            .getInstanceColumnRef(sName,
1599                                    ((AbstractObject) m_searchObject)
1600                                            .isHistorical()), "=", vec);
1601                } catch (InvalidColumnReferenceException e) {
1602                    m_logger.log(Level.INFO, e.getLocalizedMessage());
1603                }
1604            }
1605        }
1606
1607        //add select columns from elements
1608
NodeList nodes = sSearchObjEl.getChildNodes();
1609
1610        for (int i = 0; i < nodes.getLength(); i++) {
1611            if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
1612                continue;
1613            }
1614
1615            Element el = (Element) nodes.item(i);
1616            String JavaDoc sTagName = el.getNodeName();
1617
1618            if (sTagName.equals(Profile.TAG_PROFILE) == true) {
1619                NodeList propInstNodes = el
1620                        .getElementsByTagName(AbstractPropertyInstance.TAG_PROPERTYINSTANCE);
1621
1622                for (int j = 0; j < propInstNodes.getLength(); j++) {
1623                    Element propInstEl = (Element) propInstNodes.item(j);
1624                    NodeList propNodes = propInstEl
1625                            .getElementsByTagName(Property.TAG_PROPERTY);
1626                    AbstractPropertyInstance propInst = null;
1627                    Element propEl = null;
1628                    for (int k = 0; k < propNodes.getLength(); k++) {
1629                        propEl = (Element) propNodes.item(k);
1630                        if (propEl.hasAttribute(ATTRIB_ORDER_DIRECTION)
1631                                && propEl.getAttribute(ATTRIB_ORDER_DIRECTION)
1632                                        .length() > 0) {
1633                            Element nameEl = XMLUtils.getFirstNamedChild(propEl, Property.TAG_NAME);
1634                            try {
1635                                if(nameEl != null) {
1636                                    String JavaDoc sPropName = XMLUtils.getChildTextValue(nameEl);
1637                                    Property prop = PropertyFactory.getPropertyFromName(m_dsi, sPropName);
1638                                    propInst = PropertyInstanceFactory
1639                                            .getPropertyInstance(m_dsi, prop);
1640                                    propInst.populate(propEl, null);
1641
1642                                    addSelectProperty(propInst);
1643
1644                                    String JavaDoc sOrderDirection = propEl
1645                                            .getAttribute(ATTRIB_ORDER_DIRECTION);
1646
1647                                    setOrderBy(propInst, sOrderDirection);
1648                                    break;
1649                                }
1650                            } catch (DataAccessException e) {
1651                                throw new PopulateException(
1652                                        "Error populating property instance: ",
1653                                        e);
1654                            } catch (HarmoniseFactoryException e) {
1655                                throw new PopulateException(
1656                                        "Error getting property instance from factory: ",
1657                                        e);
1658                            }
1659                        }
1660                    }
1661                }
1662            } else if (sTagName.equals(AbstractParentObject.TAG_CHILDREN)
1663                    || sTagName.equals(AbstractParentObject.TAG_SUBGROUPS)
1664                    || sTagName.equals(AbstractParentObject.TAG_GROUP)) {
1665                /**
1666                 * @todo these tags are not handled in the contruction of the
1667                 * Sql
1668                 */

1669            } else {
1670                String JavaDoc sLoopTagName = sTagName;
1671                Element loopEl = el;
1672                ColumnRef colref = null;
1673
1674                while ((sLoopTagName != null) && (colref == null)) {
1675                    try {
1676                        colref = m_searchObject.getInstanceColumnRef(
1677                                sLoopTagName, ((AbstractObject) m_searchObject)
1678                                        .isHistorical());
1679                        if (loopEl.hasAttribute(ATTRIB_ORDER_DIRECTION)) {
1680                            String JavaDoc sOrderDirection = loopEl
1681                                    .getAttribute(ATTRIB_ORDER_DIRECTION);
1682
1683                            if (sOrderDirection.length() > 0) {
1684                                setOrderBy(colref, sOrderDirection);
1685                            }
1686                        }
1687                    } catch (InvalidColumnReferenceException e) {
1688                        NodeList loopNodes = loopEl.getElementsByTagName("*");
1689
1690                        if (loopNodes.getLength() > 0) {
1691                            loopEl = (Element) loopNodes.item(0);
1692                            sLoopTagName = loopEl.getTagName();
1693
1694                        } else {
1695                            sLoopTagName = null;
1696                        }
1697                    }
1698                }
1699
1700                if (colref != null) {
1701                    this.addSelectColumn(colref);
1702                }
1703            }
1704        }
1705    }
1706
1707    /**
1708     * Returns a <code>String</code> containing a query for the search to be
1709     * run against the indexer.
1710     *
1711     * @return
1712     * @throws HarmoniseIndexerException
1713     * @throws DataStoreException
1714     */

1715    private String JavaDoc getIndexSearchQuery() throws HarmoniseIndexerException,
1716            DataStoreException {
1717        Vector groupIds = new Vector(16);
1718        HarmoniseIndexer indexer = HarmoniseIndexer.getInstance();
1719        String JavaDoc sName = null;
1720        String JavaDoc sDisplayName = null;
1721        String JavaDoc sSummary = null;
1722        String JavaDoc sContents = null;
1723        String JavaDoc sIndexerQuery = "";
1724
1725        for (int i = 0; i < this.m_ConditionGroups.size(); i++) {
1726            int groupId = ((AbstractParentObject) m_ConditionGroups
1727                    .get(i)).getId();
1728            groupIds.addElement(String.valueOf(groupId));
1729        }
1730
1731        Vector conditions2remove = new Vector();
1732
1733        for (int i = 0; i < this.m_ConditionColumns.size(); i++) {
1734            WhereCondition where = (WhereCondition) m_ConditionColumns
1735                    .get(i);
1736
1737            String JavaDoc columnref = where.getFullColumnRef();
1738            Object JavaDoc oText = ((Vector) where.getValues()).firstElement();
1739
1740            if (columnref.equalsIgnoreCase(this.m_searchObject
1741                    .getInstanceColumnRef(AbstractObject.TAG_NAME,
1742                            ((AbstractObject) m_searchObject).isHistorical())
1743                    .getFullRef())) {
1744                sName = (String JavaDoc) oText;
1745                conditions2remove.addElement(where);
1746                m_bIndexableSearch = true;
1747            } else if (columnref.equalsIgnoreCase(this.m_searchObject
1748                    .getInstanceColumnRef(AbstractEditableObject.TAG_DISPLAY_NAME,
1749                            ((AbstractObject) m_searchObject).isHistorical())
1750                    .getFullRef())) {
1751                sDisplayName = (String JavaDoc) oText;
1752                conditions2remove.addElement(where);
1753                m_bIndexableSearch = true;
1754            } else if (columnref.equalsIgnoreCase(this.m_searchObject
1755                    .getInstanceColumnRef(AbstractObject.TAG_SUMMARY,
1756                            ((AbstractObject) m_searchObject).isHistorical())
1757                    .getFullRef())) {
1758                sSummary = (String JavaDoc) oText;
1759                conditions2remove.addElement(where);
1760                m_bIndexableSearch = true;
1761            } else if (this.m_searchObject instanceof org.openharmonise.rm.resources.content.Document
1762                    && columnref
1763                            .equalsIgnoreCase(this.m_searchObject
1764                                    .getInstanceColumnRef(
1765                                            org.openharmonise.rm.resources.content.Document.TAG_CONTENT,
1766                                            ((AbstractObject) m_searchObject)
1767                                                    .isHistorical())
1768                                    .getFullRef())) {
1769                sContents = (String JavaDoc) oText;
1770                conditions2remove.addElement(where);
1771                m_bIndexableSearch = true;
1772            }
1773        }
1774
1775        if (m_bIndexableSearch == true) {
1776            //remove appropriate conditions
1777
this.m_ConditionGroups.clear();
1778
1779            for (int i = 0; i < conditions2remove.size(); i++) {
1780                this.m_ConditionColumns.remove(conditions2remove.elementAt(i));
1781            }
1782
1783            //only fill query string if all of the fields are present but not
1784
// empty
1785
if ((sName != null && sName.length() > 0)
1786                    || (sSummary != null && sSummary.length() > 0)
1787                    || (sContents != null && sContents.length() > 0)
1788                    || (sDisplayName != null && sDisplayName.length() > 0)) {
1789                sIndexerQuery = indexer.getQuery(m_searchObject.getClass(),
1790                        groupIds, sName, sDisplayName, sSummary, sContents);
1791            }
1792        }
1793
1794        return sIndexerQuery;
1795    }
1796
1797    /**
1798     * Populates conditions by processing the XML contained in the given
1799     * <code>State</code>.
1800     *
1801     * @param search
1802     * @param output
1803     * @param state
1804     * @throws PublishException
1805     * @throws PopulateException
1806     */

1807    private void populateConditionsFromState(Element search, HarmoniseOutput output,
1808            State state) throws PublishException, PopulateException {
1809        Element stateSearch = state.findElement(search);
1810        Vector nodes2Remove = new Vector(16);
1811
1812        if (stateSearch != null) {
1813            NodeList nodes = search.getChildNodes();
1814
1815            //take value here before we start adding nodes
1816
int nIter = nodes.getLength();
1817
1818            for (int i = 0; i < nIter; i++) {
1819                Element tempEl = (Element) nodes.item(i);
1820                String JavaDoc sTagName = tempEl.getTagName();
1821
1822                if (tempEl.getNodeType() != Node.ELEMENT_NODE) {
1823                    continue;
1824                }
1825
1826                if (sTagName.equalsIgnoreCase(AbstractChildObject.TAG_GROUP)) {
1827                    NodeList stateGroups = state
1828                            .getDocumentElement()
1829                            .getElementsByTagName(AbstractChildObject.TAG_GROUP);
1830
1831                    if (stateGroups.getLength() > 0) {
1832                        Element stateGroupEl = (Element) stateGroups.item(0);
1833                        tempEl.setAttribute(ATTRIB_SUB, stateGroupEl
1834                                .getAttribute(ATTRIB_SUB));
1835
1836                        NodeList groupNodes = stateGroupEl.getChildNodes();
1837
1838                        for (int j = 0; j < groupNodes.getLength(); j++) {
1839                            Element groupEl = (Element) groupNodes.item(j);
1840                            Element foundEl = XMLDocument.findElement(tempEl,
1841                                    groupEl);
1842
1843                            if (foundEl != null) {
1844                                foundEl.setAttribute(ATTRIB_SELECTED,
1845                                        "selected");
1846                            }
1847                        }
1848                    }
1849                } else {
1850                    Element foundEl = XMLDocument.findElement(stateSearch,
1851                            tempEl);
1852
1853                    //if element is in state then we can use data to
1854
// instantiate object then publish as new
1855
//element to replace current element in searchconditions
1856
if ((foundEl != null)
1857                            && ((Element) foundEl.getParentNode()).getTagName()
1858                                    .equalsIgnoreCase(TAG_CONDITIONS)) {
1859                        if (sTagName
1860                                .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)) {
1861                            //only do anything of propinst has values
1862
// associated to it
1863
if (foundEl.getChildNodes().getLength() > 0) {
1864                                try {
1865                                    Publishable pubObj = HarmoniseObjectFactory
1866                                            .instantiatePublishableObject(
1867                                                    this.m_dsi, tempEl, state);
1868
1869                                    pubObj.populate(foundEl, state);
1870
1871                                    Element newEl = pubObj.publish(tempEl,
1872                                            output, state);
1873
1874                                    nodes2Remove.add(tempEl);
1875                                    search.appendChild(newEl);
1876                                } catch (HarmoniseFactoryException e) {
1877                                    throw new PopulateException(
1878                                            "Factory error", e);
1879                                }
1880                            }
1881                        } else {
1882                            nodes2Remove.add(tempEl);
1883
1884                            Element copyEl = (Element) output.copyNode(foundEl);
1885                            output.copyChildren(copyEl, tempEl);
1886                            copyEl.setAttribute(ATTRIB_SELECTED,
1887                                    ATTRIB_SELECTED);
1888                            search.appendChild(copyEl);
1889                        }
1890                    }
1891                }
1892            }
1893
1894            for (int i = 0; i < nodes2Remove.size(); i++) {
1895                search.removeChild((Element) nodes2Remove.elementAt(i));
1896            }
1897        }
1898    }
1899
1900    /**
1901     * Processes <code>xmlElement</code> to add 'where' conditions to the
1902     * search.
1903     *
1904     * @param xmlElement
1905     * @param state
1906     * @throws DataStoreException
1907     * @throws HarmoniseFactoryException
1908     */

1909    private void addWhereConditionsFromXML(Element xmlElement, State state)
1910            throws DataStoreException, HarmoniseFactoryException {
1911        String JavaDoc sTagName = xmlElement.getTagName();
1912        String JavaDoc sOperator = xmlElement.getAttribute(AbstractPropertyInstance.ATTRIB_OPERATOR);
1913
1914        if(sOperator == null) {
1915            sOperator = "=";
1916        }
1917
1918        //first assume that we're dealing with a some searchobject data
1919
Vector tempVec = new Vector();
1920        String JavaDoc txt = XMLDocument.getChildTextNodeValue(xmlElement);
1921
1922        ColumnRef colref = null;
1923
1924        colref = this.m_searchObject
1925                .getInstanceColumnRef(xmlElement.getTagName(),
1926                        ((AbstractObject) m_searchObject).isHistorical());
1927
1928        if (colref != null) {
1929            if ((txt != null) && (txt.length() > 0)) {
1930                tempVec.add(txt);
1931
1932                WhereCondition where = new WhereCondition(colref, sOperator,
1933                        tempVec);
1934                m_ConditionColumns.add(where);
1935            }
1936        } else {
1937            DataStoreObject dsObj = (DataStoreObject) HarmoniseObjectFactory
1938                    .instantiatePublishableObject(this.m_dsi, xmlElement, state);
1939
1940            NodeList children = xmlElement.getChildNodes();
1941
1942            for (int i = 0; i < children.getLength(); i++) {
1943                if (children.item(i).getNodeType() != Node.ELEMENT_NODE) {
1944                    continue;
1945                }
1946
1947                Element tempEl = (Element) children.item(i);
1948
1949                if (tempVec == null) {
1950                    tempVec = new Vector();
1951                }
1952
1953                tempVec.clear();
1954                tempVec.add(XMLDocument.getChildTextNodeValue(tempEl));
1955
1956                WhereCondition where = new WhereCondition(dsObj
1957                        .getInstanceColumnRef(tempEl.getTagName(),
1958                                ((AbstractObject) m_searchObject)
1959                                        .isHistorical()), sOperator, tempVec);
1960                m_ConditionColumns.add(where);
1961            }
1962
1963        }
1964    }
1965
1966    /**
1967     * Returns a 'FurtherLink' element with the given link text, page id, and
1968     * position with in the results.
1969     *
1970     * @param output
1971     * @param linktext
1972     * @param nPosition
1973     * @param nPageId
1974     * @return
1975     */

1976    private Element createFurtherLinkElement(HarmoniseOutput output, String JavaDoc linktext,
1977            int nPosition, int nPageId) {
1978        Element xnLink = output.createElement(WebPage.TAG_LINK);
1979
1980        Element xnLinkPage = output.createElement(WebPage.TAG_PAGE);
1981
1982        xnLinkPage.setAttribute(WebPage.ATTRIB_ID, Integer.toString(nPageId));
1983
1984        Node xnLinkTxt = output.createElement(WebPage.TAG_LINK_TEXT);
1985        Text txt = output.createTextNode(linktext);
1986
1987        // Profile to carry search through Prev link
1988
Element xnState = output.createElement(State.TAG_STATE);
1989
1990        Element xnCond = output.createElement(TAG_CONDITIONS);
1991        xnState.appendChild(xnCond);
1992
1993        Element xnPosition = output.createElement(TAG_POSITION);
1994
1995        Text txtPos = output.createTextNode(Integer.toString(nPosition));
1996
1997        xnPosition.appendChild(txtPos);
1998        xnCond.appendChild(xnPosition);
1999        xnLink.appendChild(xnState);
2000
2001        xnLink.appendChild(xnLinkPage);
2002
2003        xnLinkTxt.appendChild(txt);
2004        xnLink.appendChild(xnLinkTxt);
2005
2006        return xnLink;
2007    }
2008
2009    /**
2010     * Returns a <code>Profile</code> which represents the
2011     * <code>xmlElement</code> 'FilterCondition' element.
2012     *
2013     * @param xmlElement
2014     * @param state
2015     * @return @throws
2016     * PublishException
2017     */

2018    private Profile createFilterConditionsProfile(Element xmlElement,
2019            State state) throws PublishException {
2020        if (xmlElement.getTagName().equals(TAG_FILTERCONDITIONS) == false) {
2021            throw new InvalidXMLElementException("Expecting "
2022                    + TAG_FILTERCONDITIONS + " got " + xmlElement.getTagName());
2023        }
2024
2025        String JavaDoc sInclusive = xmlElement.getAttribute(ATTRIB_INCLUSIVE);
2026
2027        if ((sInclusive != null) && sInclusive.equalsIgnoreCase("true")) {
2028            m_bFilterCondsInclusive = true;
2029        }
2030
2031        Profile returnProf = null;
2032        Profile filterObjectProfile = null;
2033        AbstractProfiledObject filterObject = null;
2034
2035        NodeList childNodes = xmlElement.getChildNodes();
2036
2037        for (int i = 0; i < childNodes.getLength(); i++) {
2038            if (childNodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
2039                continue;
2040            }
2041
2042            Element childEl = (Element) childNodes.item(i);
2043            String JavaDoc sTagName = childEl.getTagName();
2044
2045            try {
2046
2047                if (sTagName.equalsIgnoreCase(TAG_FILTERSOURCE)) {
2048                    NodeList sourceNodes = childEl.getChildNodes();
2049
2050                    for (int j = 0; j < sourceNodes.getLength(); j++) {
2051                        if (sourceNodes.item(j).getNodeType() != Node.ELEMENT_NODE) {
2052                            continue;
2053                        }
2054
2055                        Element elFilterSource = (Element) sourceNodes.item(j);
2056                        String JavaDoc sFilterObjectClassname = elFilterSource
2057                                .getTagName();
2058
2059                        filterObject = (AbstractProfiledObject) HarmoniseObjectFactory
2060                                .instantiateHarmoniseObject(m_dsi, elFilterSource,
2061                                        state);
2062                        filterObjectProfile = filterObject.getProfile();
2063                    }
2064                } else if (sTagName.equalsIgnoreCase(TAG_OR)) {
2065                    m_ConditionOperator = "OR";
2066                } else if (sTagName
2067                        .equalsIgnoreCase(AbstractPropertyInstance.TAG_PROPERTYINSTANCE)
2068                        || sTagName.equalsIgnoreCase(Property.TAG_PROPERTY)) {
2069                    AbstractPropertyInstance tmpPropInst = PropertyInstanceFactory
2070                            .getPropertyInstance(m_dsi, childEl/*
2071                                                                * , returnProf
2072                                                                */
);
2073
2074                    tmpPropInst.populate(childEl, state);
2075
2076                    //if property tag doesn't have values then take property
2077
// condition from filter source
2078
if (tmpPropInst.hasValues() == false) {
2079                        if (filterObjectProfile != null) {
2080                            AbstractPropertyInstance fltrSrcPropInst = filterObjectProfile
2081                                    .getPropertyInstance(tmpPropInst
2082                                            .getProperty());
2083
2084                            if (fltrSrcPropInst != null) {
2085                                if (returnProf == null) {
2086                                    returnProf = new Profile(m_dsi,
2087                                            filterObject);
2088                                }
2089
2090                                returnProf.addPropertyInstance(fltrSrcPropInst);
2091                            }
2092
2093                            //TODO need to handle situation where filter object profile does
2094
//not contain the property, currently errors - might lose operator for property
2095
//need to review this - need to think
2096
//about exclusivity wrt to this issue
2097

2098                        }
2099                    } else {
2100                        returnProf.addPropertyInstance(tmpPropInst);
2101                    }
2102                }
2103            } catch (ProfileException e) {
2104                throw new PublishException("Profile error", e);
2105            } catch (DataAccessException e) {
2106                throw new PublishException("Data access error", e);
2107            } catch (HarmoniseFactoryException e) {
2108                throw new PublishException("Factory error", e);
2109            } catch (PopulateException e) {
2110                throw new PublishException("Population error", e);
2111            }
2112        }
2113
2114        return returnProf;
2115    }
2116
2117    /**
2118     * Adds 'where' conditions to the select statement from the condition data
2119     * contained in this object.
2120     *
2121     * @param select
2122     * @throws DataAccessException
2123     * @throws DataStoreException
2124     */

2125    private void addWhereConditions(SelectStatement select)
2126            throws DataAccessException, DataStoreException {
2127
2128        SelectStatement subselect = null;
2129
2130        if ((m_ConditionProfile.size() > 0) || (m_ConditionGroups.size() > 0)) {
2131            subselect = new SelectStatement();
2132
2133            subselect.setDistinct(true);
2134            subselect.addSelectColumn(m_searchObject.getInstanceColumnRef(
2135                    AbstractObject.ATTRIB_ID, ((AbstractObject) m_searchObject)
2136                            .isHistorical()));
2137        }
2138
2139        //are we going to do a strict search by type or just return all
2140
//matching objects from the same table, e.g. if class B was a
2141
//subclass of class A are doing a search on all objects of
2142
//class A or specifically class B, if so add the appropriate
2143
//condition
2144
if (m_bStrictType == true) {
2145            if (subselect != null) {
2146                subselect.addWhereCondition(
2147                        ((AbstractObject) this.m_searchObject)
2148                                .getInstanceColumnRef(
2149                                        Search.ATTRIB_OBJECT_TYPE,
2150                                        ((AbstractObject) this.m_searchObject)
2151                                                .isHistorical()), "=",
2152                        ((AbstractObject) this.m_searchObject).getType());
2153            } else {
2154                select.addWhereCondition(((AbstractObject) this.m_searchObject)
2155                        .getInstanceColumnRef(Search.ATTRIB_OBJECT_TYPE,
2156                                ((AbstractObject) this.m_searchObject)
2157                                        .isHistorical()), "=",
2158                        ((AbstractObject) this.m_searchObject).getType());
2159            }
2160        }
2161
2162        if (m_searchObject instanceof AbstractProfiledObject) {
2163            AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2164
2165            //add conditions needed for those property instances to be returned
2166
//in select statement
2167
addSelectPropertyInstanceConditions(select);
2168
2169            if (m_searchObject instanceof AbstractChildObject) {
2170                //add relationship conditions
2171
addGroupConditions(subselect);
2172            }
2173
2174            //add property instance conditions
2175
addPropertyInstanceConditions(subselect);
2176        }
2177
2178        //if this search is on live objects only
2179
if (m_bApprovedSearch == true) {
2180            Vector tempVec = new Vector();
2181            tempVec.add(new Integer JavaDoc(Status.APPROVED.getIntValue()));
2182
2183            WhereCondition where = new WhereCondition(m_searchObject
2184                    .getInstanceColumnRef(AbstractEditableObject.TAG_STATUS,
2185                            ((AbstractObject) this.m_searchObject)
2186                                    .isHistorical()), "=", tempVec);
2187            m_ConditionColumns.add(where);
2188        }
2189
2190        //add core data conditions
2191
if (subselect != null) {
2192            addCoreDataConditions(subselect);
2193        } else {
2194            addCoreDataConditions(select);
2195        }
2196
2197        //add nested select statement
2198
if (subselect != null) {
2199            WhereCondition whereSubselect = new WhereCondition(m_searchObject
2200                    .getInstanceColumnRef(AbstractObject.ATTRIB_ID,
2201                            ((AbstractObject) this.m_searchObject)
2202                                    .isHistorical()), "IN", subselect);
2203            select.addWhereCondition(whereSubselect);
2204        }
2205    }
2206
2207    /**
2208     * Adds relationship conditions to the select statement based on conditions
2209     * held with in this search object.
2210     *
2211     * @param subselect
2212     * @throws DataStoreException
2213     */

2214    private void addGroupConditions(SelectStatement subselect)
2215            throws DataStoreException {
2216        if (m_ConditionGroups.size() > 0) {
2217
2218            if (m_searchObject instanceof AbstractChildObject
2219                    && ((AbstractChildObject) m_searchObject).isHistorical() == true) {
2220                WhereConditionGroup wheres = new WhereConditionGroup();
2221                wheres.setStringingOperator("or");
2222
2223                for (int i = 0; i < m_ConditionGroups.size(); i++) {
2224                    AbstractParentObject grpObj = (AbstractParentObject) m_ConditionGroups
2225                            .get(i);
2226
2227                    try {
2228                        wheres.addCondition(m_searchObject
2229                                .getInstanceColumnRef(
2230                                        AbstractChildObject.TAG_PATH, true),
2231                                "STARTS_WITH", grpObj.getPath());
2232                    } catch (DataAccessException e) {
2233                        throw new DataStoreException(e);
2234                    }
2235                }
2236
2237                subselect.addWhereCondition(wheres);
2238            } else if (this.m_searchObject instanceof AbstractParentObject) {
2239                WhereConditionGroup wheres = new WhereConditionGroup();
2240                String JavaDoc sGroupAlias = "grp";
2241                String JavaDoc sGroupTableName = "";
2242                wheres.setStringingOperator("or");
2243
2244                DataStoreObject dsObj = null;
2245                ColumnRef colId = m_searchObject.getInstanceColumnRef(
2246                        AbstractObject.ATTRIB_ID, false);
2247                sGroupTableName = colId.getTable();
2248                colId.setTable(sGroupAlias);
2249
2250                for (int i = 0; i < m_ConditionGroups.size(); i++) {
2251                    dsObj = (DataStoreObject) m_ConditionGroups.get(i);
2252
2253                    wheres.addCondition(colId, "=", dsObj.getId());
2254                }
2255
2256                subselect.addWhereCondition(wheres);
2257
2258                ColumnRef subJoinKey = m_searchObject.getInstanceColumnRef(
2259                        AbstractParentObject.TAG_SUBGROUPS, false);
2260                ColumnRef subKey = m_searchObject.getInstanceColumnRef(
2261                        AbstractObject.ATTRIB_KEY, false);
2262                ColumnRef parentJoinKey = m_searchObject.getInstanceColumnRef(
2263                        AbstractParentObject.TAG_GROUP, false);
2264                ColumnRef parentKey = m_searchObject.getInstanceColumnRef(
2265                        AbstractObject.ATTRIB_KEY, false);
2266                parentKey.setTable(sGroupAlias);
2267
2268                subselect.addJoinCondition(parentJoinKey, parentKey);
2269                subselect.addJoinCondition(subJoinKey, subKey);
2270
2271                subselect.addTableAlias(sGroupTableName, sGroupAlias);
2272            } else {
2273                WhereConditionGroup wheres = new WhereConditionGroup();
2274                wheres.setStringingOperator("or");
2275
2276                DataStoreObject dsObj = null;
2277
2278                for (int i = 0; i < m_ConditionGroups.size(); i++) {
2279                    dsObj = (DataStoreObject) m_ConditionGroups.get(i);
2280                    wheres.addCondition(dsObj.getInstanceColumnRef(
2281                            AbstractObject.ATTRIB_ID, false), "=", dsObj
2282                            .getId());
2283                }
2284
2285                subselect.addWhereCondition(wheres);
2286                subselect.addJoinConditions(dsObj.getInstanceJoinConditions(
2287                        this.m_sSearchType, false));
2288            }
2289        }
2290    }
2291
2292    /**
2293     * Adds 'join' conditions to the select statement necessary to support the
2294     * return of property instance values in the result set.
2295     *
2296     * @param select
2297     * @throws DataAccessException
2298     * @throws DataStoreException
2299     */

2300    private void addSelectPropertyInstanceConditions(SelectStatement select)
2301            throws DataAccessException, DataStoreException {
2302        AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2303
2304        if (m_searchObjectProfile == null) {
2305            m_searchObjectProfile = new Profile(m_dsi, profObj);
2306        }
2307        Profile prof = m_searchObjectProfile;
2308
2309        for (int i = 0; i < this.m_SearchProfile.size(); i++) {
2310            //get necessary object for getting the column refs
2311

2312            AbstractPropertyInstance condPropInst = (AbstractPropertyInstance) m_SearchProfile
2313                    .get(i);
2314            condPropInst.setProfile(prof);
2315
2316            Property property = condPropInst.getProperty();
2317
2318            String JavaDoc sPropertyAlias = "spty" + i;
2319            ColumnRef propertyIdCol = property.getInstanceColumnRef(
2320                    AbstractObject.ATTRIB_ID, false);
2321            select.addTableAlias(propertyIdCol.getTable(), sPropertyAlias);
2322            propertyIdCol.setTable(sPropertyAlias);
2323
2324            ColumnRef propertyNameCol = property.getInstanceColumnRef(
2325                    AbstractObject.TAG_NAME, false);
2326            propertyNameCol.setTable(sPropertyAlias);
2327
2328            //get column refs and set necessary aliases
2329
ColumnRef valColref = condPropInst.getInstanceColumnRef(
2330                    AbstractPropertyInstance.TAG_VALUE, false);
2331            String JavaDoc sPropAlias = "sprop" + i;
2332            select.addTableAlias(valColref.getTable(), sPropAlias);
2333            valColref.setTable(sPropAlias);
2334
2335            ColumnRef dataProfIdColref = condPropInst.getInstanceColumnRef(
2336                    Profile.TAG_PROFILE, false);
2337            dataProfIdColref.setTable(sPropAlias);
2338
2339            ColumnRef dataPropIdColref = condPropInst.getInstanceColumnRef(
2340                    Property.TAG_PROPERTY, false);
2341            dataPropIdColref.setTable(sPropAlias);
2342
2343            ColumnRef profileIdColref = prof.getInstanceColumnRef(
2344                    AbstractObject.ATTRIB_ID, prof.isHistorical());
2345
2346            String JavaDoc sProfAlias = "sprof" + i;
2347
2348            select.addTableAlias(profileIdColref.getTable(), sProfAlias);
2349            profileIdColref.setTable(sProfAlias);
2350
2351            ColumnRef profNameColref = prof.getInstanceColumnRef(
2352                    AbstractObject.TAG_NAME, prof.isHistorical());
2353            profNameColref.setTable(sProfAlias);
2354
2355            ColumnRef profObjectKeyColref = prof.getInstanceColumnRef(
2356                    Profile.ATTRIB_OBJECT_KEY, prof.isHistorical());
2357            profObjectKeyColref.setTable(sProfAlias);
2358
2359            ColumnRef objectKeyColref = m_searchObject.getInstanceColumnRef(
2360                    AbstractObject.ATTRIB_KEY,
2361                    ((AbstractObject) m_searchObject).isHistorical());
2362
2363            select.addSelectColumn(profNameColref);
2364            select.addSelectColumn(valColref);
2365
2366            if ((m_orderByPropMap.isEmpty() == false) && m_orderByPropMap.containsKey(condPropInst)) {
2367                select.addOrderBy(valColref, (String JavaDoc) m_orderByPropMap.get(condPropInst));
2368            }
2369
2370            select.addSelectColumn(propertyIdCol);
2371            select.addSelectColumn(profileIdColref);
2372            select.addSelectColumn(propertyNameCol);
2373
2374            select.addOuterJoinCondition(dataProfIdColref, profileIdColref);
2375
2376            select.addJoinCondition(profObjectKeyColref, objectKeyColref);
2377
2378            select.addOuterJoinCondition(dataPropIdColref, propertyIdCol);
2379            select.addWhereCondition(propertyNameCol, "=", condPropInst
2380                    .getName());
2381        }
2382    }
2383
2384    /**
2385     * Adds the 'where' conditions to the given <code>SelectStatement</code>
2386     * based on the property instance conditions held with in this search object.
2387     *
2388     * @param subselect
2389     * @throws DataStoreException
2390     * @throws DataAccessException
2391     */

2392    private void addPropertyInstanceConditions(SelectStatement subselect)
2393            throws DataStoreException, DataAccessException {
2394        AbstractProfiledObject profObj = (AbstractProfiledObject) m_searchObject;
2395        Profile profObjProf = profObj.getProfile();
2396        
2397        if (m_ConditionProfile.size() > 0) {
2398            //WhereConditions object to hold all the propertyinstance conditions
2399
WhereConditionGroup outerWheres = new WhereConditionGroup();
2400            
2401            for (int i = 0; i < m_ConditionProfile.size(); i++) {
2402                //get necessary object for getting the column refs
2403

2404                if (m_searchObjectProfile == null) {
2405                    m_searchObjectProfile = new Profile(m_dsi, profObj);
2406                }
2407                Profile prof = m_searchObjectProfile;
2408
2409                AbstractPropertyInstance condPropInst = (AbstractPropertyInstance) m_ConditionProfile
2410                        .get(i);
2411                
2412                String JavaDoc sCondOp = condPropInst.getOperator();
2413
2414                condPropInst.setProfile(prof);
2415
2416                //if there are no values don't go any further
2417
if (condPropInst.hasValues() == false) {
2418                    continue;
2419                }
2420                
2421                if(sCondOp.equals("<>") == false
2422                        && sCondOp.equals("!=") == false) {
2423    
2424                    addPropertyInstanceWhereCondition(subselect, outerWheres, i, prof, condPropInst, sCondOp);
2425                } else {
2426                    //need to compose a different sort of query for
2427
//the non-existance of a property instance value
2428
//that takes account for profiles which may have
2429
//more than one value for the property instance
2430
//or more than one profile
2431
//or even no profile
2432

2433                    addNonExistentPropertyInstanceCondition(profObj, outerWheres, prof, condPropInst);
2434                }
2435
2436            } //end for
2437

2438            outerWheres.setStringingOperator(m_ConditionOperator);
2439            subselect.addWhereCondition(outerWheres);
2440        }
2441    }
2442
2443    /**
2444     * Adds a property instance where condition to <code>outerWheres</code>,
2445     * updating <code>subselect</code> with the necessary table aliases.
2446     *
2447     * @param subselect
2448     * @param outerWheres
2449     * @param index
2450     * @param prof
2451     * @param condPropInst
2452     * @param sCondOp
2453     * @throws DataStoreException
2454     * @throws DataAccessException
2455     */

2456    private void addPropertyInstanceWhereCondition(SelectStatement subselect, WhereConditionGroup outerWheres, int index, Profile prof, AbstractPropertyInstance condPropInst, String JavaDoc sCondOp) throws DataStoreException, DataAccessException {
2457        //set prop inst table alias
2458
String JavaDoc propInstAlias = "prop" + index;
2459
2460        subselect.addTableAlias(condPropInst.getDBTableName(),
2461                propInstAlias);
2462
2463        //prof id column in prop inst table
2464
ColumnRef dataProfIdColref = condPropInst.getInstanceColumnRef(
2465                Profile.TAG_PROFILE, false);
2466        dataProfIdColref.setTable(propInstAlias);
2467
2468        //prop id column in prop inst table
2469
ColumnRef dataPropIdColref = condPropInst.getInstanceColumnRef(
2470                Property.TAG_PROPERTY, false);
2471        dataPropIdColref.setTable(propInstAlias);
2472
2473        subselect.addWhereCondition(dataPropIdColref, "=", condPropInst
2474                .getProperty().getId());
2475
2476        //prof id column in profile table
2477
ColumnRef profileIdColref = prof.getInstanceColumnRef(
2478                AbstractObject.ATTRIB_ID, prof.isHistorical());
2479
2480        //set alias for profile table
2481
String JavaDoc profAlias = "prof" + index;
2482
2483        subselect.addTableAlias(profileIdColref.getTable(), profAlias);
2484
2485        profileIdColref.setTable(profAlias);
2486
2487        //join prop inst table to profile table
2488
subselect.addJoinCondition(dataProfIdColref, profileIdColref);
2489
2490        ColumnRef profObjectKeyColref = prof.getInstanceColumnRef(
2491                Profile.ATTRIB_OBJECT_KEY, prof.isHistorical());
2492        profObjectKeyColref.setTable(profAlias);
2493
2494        ColumnRef objectKeyColref = m_searchObject
2495                .getInstanceColumnRef(AbstractObject.ATTRIB_KEY,
2496                        ((AbstractObject) m_searchObject)
2497                                .isHistorical());
2498
2499        //join object table to profile table
2500
subselect
2501                .addJoinCondition(profObjectKeyColref, objectKeyColref);
2502
2503        WhereConditionGroup innerWheres = getPropertyInstanceValueConditions(
2504                condPropInst, sCondOp, propInstAlias);
2505
2506        if(innerWheres.size() > 1) {
2507            outerWheres.addCondition(innerWheres);
2508        } else {
2509            //no sense in adding a WhereConditions
2510
//when we can just pick up the only condition
2511
//and add it
2512
Object JavaDoc cond = innerWheres.getCondition(0);
2513            if(cond instanceof WhereCondition) {
2514                outerWheres.addCondition((WhereCondition)cond);
2515            } else if(cond instanceof WhereConditionGroup) {
2516                outerWheres.addCondition((WhereConditionGroup)cond);
2517            }
2518        }
2519    }
2520
2521    /**
2522     * Adds the required condition to <code>outerWheres</code> which tests for the non-existence
2523     * of a property instance value on the search object.
2524     *
2525     * @param profObj
2526     * @param outerWheres
2527     * @param prof
2528     * @param condPropInst
2529     * @throws DataStoreException
2530     * @throws DataAccessException
2531     */

2532    private void addNonExistentPropertyInstanceCondition(AbstractProfiledObject profObj, WhereConditionGroup outerWheres, Profile prof, AbstractPropertyInstance condPropInst) throws DataStoreException, DataAccessException {
2533        ColumnRef profObjectKeyColRef = m_searchObjectProfile.getInstanceColumnRef(Profile.ATTRIB_OBJECT_KEY, profObj.isHistorical());
2534        ColumnRef objObjectKeyColRef = profObj.getInstanceColumnRef(AbstractObject.ATTRIB_KEY, profObj.isHistorical());
2535    
2536        SelectStatement nestedSelect = new SelectStatement();
2537        
2538        nestedSelect.addSelectColumn(profObjectKeyColRef);
2539        
2540        //prof id column in prop inst table
2541
ColumnRef dataProfIdColref = condPropInst.getInstanceColumnRef(
2542                Profile.TAG_PROFILE, false);
2543
2544        
2545        //prof id column in profile table
2546
ColumnRef profileIdColref = prof.getInstanceColumnRef(
2547                AbstractObject.ATTRIB_ID, prof.isHistorical());
2548
2549        //join prop inst table to profile table
2550
nestedSelect.addJoinCondition(dataProfIdColref, profileIdColref);
2551
2552        //prop id column in prop inst table
2553
ColumnRef dataPropIdColref = condPropInst.getInstanceColumnRef(
2554                Property.TAG_PROPERTY, false);
2555
2556        nestedSelect.addWhereCondition(dataPropIdColref, "=", condPropInst
2557                .getProperty().getId());
2558        
2559        //only add the following conditions if the property instance
2560
//has values
2561
if(condPropInst.getValues().size() > 0) {
2562            WhereConditionGroup innerWheres = getPropertyInstanceValueConditions(
2563                    condPropInst, "=", null);
2564
2565            if(innerWheres.size() > 1) {
2566                nestedSelect.addWhereCondition(innerWheres);
2567            } else {
2568                //no sense in adding a WhereConditions
2569
//when we can just pick up the only condition
2570
//and add it
2571
Object JavaDoc cond = innerWheres.getCondition(0);
2572                if(cond instanceof WhereCondition) {
2573                    nestedSelect.addWhereCondition((WhereCondition)cond);
2574                } else if(cond instanceof WhereConditionGroup) {
2575                    nestedSelect.addWhereCondition((WhereConditionGroup)cond);
2576                }
2577            }
2578        }
2579        
2580        outerWheres.addCondition(objObjectKeyColRef, "NOT IN", nestedSelect);
2581    }
2582
2583    /**
2584     * Sets the logical stringing operator to use between conditions.
2585     *
2586     * @param sOp
2587     */

2588    public void setStringingOperator(String JavaDoc sOp) {
2589        if (sOp.equalsIgnoreCase("and") || sOp.equalsIgnoreCase("or")) {
2590            m_ConditionOperator = sOp;
2591        }
2592
2593    }
2594
2595    /**
2596     * Switch caching of results on or off. Default is on.
2597     *
2598     * @param bCache
2599     */

2600    public void cacheResults(boolean bCache) {
2601        m_bCache = bCache;
2602    }
2603
2604    /**
2605     * Adds core data condition to the given <code>SelectStatement</code>.
2606     *
2607     * @param select
2608     * @throws DataStoreException
2609     */

2610    private void addCoreDataConditions(SelectStatement select)
2611            throws DataStoreException {
2612        for (int i = 0; i < m_ConditionColumns.size(); i++) {
2613            select.setWhereConditionStringingOperator(m_ConditionOperator);
2614            select.addWhereCondition((WhereCondition) m_ConditionColumns
2615                    .get(i));
2616
2617        }
2618    }
2619
2620    /**
2621     * Returns a <code>WhereConditions</code> set of conditions to match on
2622     * the values specified by the given general property instance, using the
2623     * alias given for the property instance table.
2624     *
2625     * @param condPropInst
2626     * @param propInstAlias
2627     * @return @throws
2628     * DataStoreException
2629     * @throws DataAccessException
2630     */

2631    private WhereConditionGroup getPropertyInstanceValueConditions(
2632            GeneralPropertyInstance condPropInst, String JavaDoc sPropOperator, String JavaDoc propInstAlias)
2633            throws DataStoreException, DataAccessException {
2634    
2635        ColumnRef valColref = condPropInst.getInstanceColumnRef(
2636                AbstractPropertyInstance.TAG_VALUE, false);
2637
2638        List values = condPropInst.getCalculatedValues();
2639
2640        if(propInstAlias != null && propInstAlias.length() > 0) {
2641            valColref.setTable(propInstAlias);
2642        }
2643
2644        // If there are multiple values split into where conditions
2645
// and separate by OR operator. Should be handled by WhereCondition?
2646
WhereConditionGroup valuesWheres = new WhereConditionGroup();
2647    
2648        WhereCondition where = null;
2649        
2650        if (sPropOperator.equals("<>") == true
2651                || sPropOperator.equals("!=")) {
2652          valuesWheres.setStringingOperator("AND");
2653          sPropOperator = "!=";
2654        } else {
2655            valuesWheres.setStringingOperator("OR");
2656        }
2657    
2658        Iterator iter = values.iterator();
2659
2660        while (iter.hasNext()) {
2661
2662            where = new WhereCondition(valColref, sPropOperator,
2663                    iter.next());
2664
2665            valuesWheres.addCondition(where);
2666        }
2667    
2668        WhereConditionGroup innerWheres = new WhereConditionGroup();
2669        innerWheres.addCondition(valuesWheres);
2670
2671        return innerWheres;
2672    }
2673
2674    /**
2675     * Returns a <code>WhereConditions</code> set of conditions to match on
2676     * the values specified by the given profile property instance, using the
2677     * alias given for the property instance table.
2678     *
2679     * @param condPropInst
2680     * @param propInstAlias
2681     * @return @throws
2682     * DataStoreException
2683     * @throws DataAccessException
2684     */

2685    private WhereConditionGroup getPropertyInstanceValueConditions(
2686            ProfilePropertyInstance condPropInst, String JavaDoc sPropOperator, String JavaDoc propInstAlias)
2687            throws DataStoreException, DataAccessException {
2688
2689        List values = condPropInst.getValues();
2690    
2691        // If there are multiple values split into where conditions
2692
// and separate by OR operator. Should be handled by WhereCondition?
2693
WhereConditionGroup valuesWheres = new WhereConditionGroup();
2694        WhereCondition where = null;
2695        
2696        if (sPropOperator.equals("<>") == true
2697                || sPropOperator.equals("!=")) {
2698          valuesWheres.setStringingOperator("AND");
2699          sPropOperator = "!=";
2700        } else {
2701          valuesWheres.setStringingOperator("OR");
2702        }
2703    
2704        Iterator iter = values.iterator();
2705
2706        while (iter.hasNext()) {
2707            Profile prof = (Profile) iter.next();
2708
2709            String JavaDoc sName = prof.getName();
2710
2711            ColumnRef nameCol = prof.getInstanceColumnRef(
2712                    AbstractObject.ATTRIB_NAME, false);
2713            
2714            if(propInstAlias != null && propInstAlias.length() > 0) {
2715                nameCol.setTable(propInstAlias);
2716            }
2717
2718            where = new WhereCondition(nameCol, sPropOperator,
2719                    sName);
2720
2721            valuesWheres.addCondition(where);
2722        }
2723
2724        WhereConditionGroup innerWheres = new WhereConditionGroup();
2725        innerWheres.addCondition(valuesWheres);
2726
2727
2728        return innerWheres;
2729
2730    }
2731
2732    /**
2733     * Returns a <code>WhereConditions</code> set of conditions to match on
2734     * the values specified by the given child object property instance, using
2735     * the alias given for the property instance table.
2736     *
2737     * @param condPropInst
2738     * @param propInstAlias
2739     * @return @throws
2740     * DataStoreException
2741     * @throws DataAccessException
2742     */

2743    private WhereConditionGroup getPropertyInstanceValueConditions(
2744            ChildObjectPropertyInstance condPropInst, String JavaDoc sPropOperator, String JavaDoc propInstAlias)
2745            throws DataStoreException, DataAccessException {
2746
2747        ColumnRef valColref = condPropInst.getInstanceColumnRef(
2748                AbstractPropertyInstance.TAG_VALUE, false);
2749    
2750        List values = condPropInst.getValues();
2751
2752        if(propInstAlias != null && propInstAlias.length() > 0) {
2753            valColref.setTable(propInstAlias);
2754        }
2755
2756        // If there are multiple values split into where conditions
2757
// and separate by OR operator. Should be handled by WhereCondition?
2758
WhereConditionGroup valuesWheres = new WhereConditionGroup();
2759        WhereCondition where = null;
2760        
2761        AbstractChildObject child = null;
2762        
2763        if (sPropOperator.equals("<>") == true) {
2764          valuesWheres.setStringingOperator("AND");
2765          sPropOperator = "!=";
2766        } else {
2767          valuesWheres.setStringingOperator("OR");
2768        }
2769    
2770        for (Iterator iter = values.iterator(); iter.hasNext();) {
2771            child = (AbstractChildObject) iter.next();
2772            int nChildId = child.getId();
2773
2774            if (nChildId > 0) {
2775                //condition is based on object id
2776
where = new WhereCondition(valColref, sPropOperator, nChildId);
2777            } else {
2778                //assume that we're doing a search on name
2779

2780                String JavaDoc sName = child.getName();
2781
2782                if (sName != null) {
2783                    ColumnRef objIdCol = child.getInstanceColumnRef(
2784                            AbstractObject.ATTRIB_ID, child.isHistorical());
2785                    ColumnRef objNameCol = child.getInstanceColumnRef(
2786                            AbstractObject.TAG_NAME, child.isHistorical());
2787
2788                    String JavaDoc objAlias = condPropInst.getName() + "_"
2789                            + child.getDBTableName();
2790
2791                    objIdCol.setTableAlias(objAlias);
2792                    objNameCol.setTableAlias(objAlias);
2793
2794                    //condition is based on object id
2795
where = new WhereCondition(objNameCol, condPropInst
2796                            .getOperator(), sName);
2797
2798                    JoinConditions join = new JoinConditions();
2799
2800                    join.addCondition(objIdCol, valColref);
2801
2802                    where.addAssociatedJoinConditions(join);
2803                }
2804            }
2805
2806            valuesWheres.addCondition(where);
2807        }
2808    
2809        WhereConditionGroup innerWheres = new WhereConditionGroup();
2810        innerWheres.addCondition(valuesWheres);
2811
2812
2813        return innerWheres;
2814
2815    }
2816
2817    /**
2818     * Returns a <code>WhereConditions</code> set of conditions to match on
2819     * the values specified by the given property instance, using the alias
2820     * given for the property instance table.
2821     *
2822     * @param condPropInst
2823     * @param condOperator TODO
2824     * @param propInstAlias
2825     * @return
2826     * @throws DataStoreException
2827     * @throws DataAccessException
2828     */

2829    private WhereConditionGroup getPropertyInstanceValueConditions(
2830            AbstractPropertyInstance condPropInst, String JavaDoc condOperator, String JavaDoc propInstAlias)
2831            throws DataStoreException, DataAccessException {
2832        WhereConditionGroup innerWheres = null;
2833
2834        if (condPropInst instanceof GeneralPropertyInstance) {
2835            innerWheres = getPropertyInstanceValueConditions(
2836                    (GeneralPropertyInstance) condPropInst, condOperator, propInstAlias);
2837        } else if (condPropInst instanceof ProfilePropertyInstance) {
2838            innerWheres = getPropertyInstanceValueConditions(
2839                    (ProfilePropertyInstance) condPropInst, condOperator, propInstAlias);
2840        } else if (condPropInst instanceof ChildObjectPropertyInstance) {
2841            innerWheres = getPropertyInstanceValueConditions(
2842                    (ChildObjectPropertyInstance) condPropInst, condOperator, propInstAlias);
2843        }
2844
2845        return innerWheres;
2846    }
2847
2848    /**
2849     * @return
2850     */

2851    public boolean isApprovedSearch() {
2852        return m_bApprovedSearch;
2853    }
2854
2855    /**
2856     * @param b
2857     */

2858    public void setApproved(boolean bApproved) {
2859        m_bApprovedSearch = bApproved;
2860    }
2861
2862    /**
2863     * @return
2864     */

2865    public List getConditionProfile() {
2866        return m_ConditionProfile;
2867    }
2868
2869    /**
2870     * @return Returns the m_ConditionGroups.
2871     */

2872    public List getConditionGroups() {
2873        return m_ConditionGroups;
2874    }
2875
2876    /**
2877     * @return Returns the m_SearchColumns.
2878     */

2879    public List getSearchColumns() {
2880        return m_SearchColumns;
2881    }
2882}
Popular Tags