Author: jonesde
Date: Fri Dec 15 02:29:34 2006 New Revision: 487512 URL: http://svn.apache.org/viewvc?view=rev&rev=487512 Log: Implemented initial WorkEffortSearch class with a few different constraints, etc; also add some entities for storing data about work effort searches and their results Added: incubator/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortSearch.java (with props) Modified: incubator/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.properties incubator/ofbiz/trunk/applications/workeffort/entitydef/entitygroup.xml incubator/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml Modified: incubator/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.properties URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.properties?view=diff&rev=487512&r1=487511&r2=487512 ============================================================================== --- incubator/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.properties (original) +++ incubator/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.properties Fri Dec 15 02:29:34 2006 @@ -157,8 +157,9 @@ WorkEffortApplicationEventsTasksWorkflowActivities=This application is meant for those who maintain and use calendar events tasks and workflow activities WorkEffortAssignedTasks=Assigned Tasks WorkEffortAssociatedFromParentToChild=(associated from parent to child) -WorkEffortAttender=Attender WorkEffortAssociatedFromParentToChild=(associated from parent to child) +WorkEffortAssoc=WorkEffort Association +WorkEffortAttender=Attender WorkEffortBannerAddWorkEffortAndAssoc1=Enter an existing workEffortId below, WorkEffortBannerAddWorkEffortAndAssoc2=OR enter the WorkEffort Details below WorkEffortBanner3=Enter existing CommunicationEvent Id below @@ -211,8 +212,15 @@ WorkEffortIdMissing=Work Effort ID is missing. WorkEffortInterestingSure=For something interesting make sure, you are logged in try : Username;Admin;Password Ofbiz WorkEffortGeneral=General +WorkEffortIncludeAllSubWorkEfforts=Include all Sub-WorkEfforts WorkEffortInformation=Information WorkEffortItem=Item +WorkEffortKeyword=Keyword +WorkEffortKeywordAllWordsMatch=all words match +WorkEffortKeywordAnyWordMatches=any word matches +WorkEffortKeywordRelevency=Keyword Relevency +WorkEffortKeywords=Keywords +WorkEffortKeywordWhere=where WorkEffortLastModified=Last Modified WorkEffortLocation=Location WorkEffortLookup=Lookup Modified: incubator/ofbiz/trunk/applications/workeffort/entitydef/entitygroup.xml URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/workeffort/entitydef/entitygroup.xml?view=diff&rev=487512&r1=487511&r2=487512 ============================================================================== --- incubator/ofbiz/trunk/applications/workeffort/entitydef/entitygroup.xml (original) +++ incubator/ofbiz/trunk/applications/workeffort/entitydef/entitygroup.xml Fri Dec 15 02:29:34 2006 @@ -67,6 +67,8 @@ <entity-group group="org.ofbiz" entity="WorkEffortPartyAssignment" /> <entity-group group="org.ofbiz" entity="WorkEffortPurposeType" /> <entity-group group="org.ofbiz" entity="WorkEffortReview" /> + <entity-group group="org.ofbiz" entity="WorkEffortSearchConstraint" /> + <entity-group group="org.ofbiz" entity="WorkEffortSearchResult" /> <entity-group group="org.ofbiz" entity="WorkEffortSkillStandard" /> <entity-group group="org.ofbiz" entity="WorkEffortStatus" /> <entity-group group="org.ofbiz" entity="WorkEffortTransBox" /> Modified: incubator/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml?view=diff&rev=487512&r1=487511&r2=487512 ============================================================================== --- incubator/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml (original) +++ incubator/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml Fri Dec 15 02:29:34 2006 @@ -727,6 +727,37 @@ <key-map field-name="statusId"/> </relation> </entity> + <entity entity-name="WorkEffortSearchConstraint" package-name="org.ofbiz.workeffort.workeffort" never-cache="true" title="WorkEffort Search Result Constraint Entity"> + <field name="workEffortSearchResultId" type="id-ne"></field> + <field name="constraintSeqId" type="id-ne"></field> + <field name="constraintName" type="long-varchar"></field> + <field name="infoString" type="long-varchar"></field> + <field name="includeSubCategories" type="indicator"></field> + <field name="isAnd" type="indicator"></field> + <field name="anyPrefix" type="indicator"></field> + <field name="anySuffix" type="indicator"></field> + <field name="removeStems" type="indicator"></field> + <field name="lowValue" type="short-varchar"></field> + <field name="highValue" type="short-varchar"></field> + <prim-key field="workEffortSearchResultId"/> + <prim-key field="constraintSeqId"/> + <relation type="one" fk-name="WEFF_SCHRSI_RES" rel-entity-name="WorkEffortSearchResult"> + <key-map field-name="workEffortSearchResultId"/> + </relation> + </entity> + <entity entity-name="WorkEffortSearchResult" package-name="org.ofbiz.workeffort.workeffort" never-cache="true" title="WorkEffort Search Result Entity"> + <field name="workEffortSearchResultId" type="id-ne"></field> + <field name="visitId" type="id"></field> + <field name="orderByName" type="long-varchar"></field> + <field name="isAscending" type="indicator"></field> + <field name="numResults" type="numeric"></field> + <field name="secondsTotal" type="floating-point"></field> + <field name="searchDate" type="date-time"></field> + <prim-key field="workEffortSearchResultId"/> + <relation type="one" fk-name="WEFF_SCHRES_VST" rel-entity-name="Visit"> + <key-map field-name="visitId"/> + </relation> + </entity> <entity entity-name="WorkEffortSkillStandard" package-name="org.ofbiz.workeffort.workeffort" title="Work Effort Skill Standard Entity"> Added: incubator/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortSearch.java URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortSearch.java?view=auto&rev=487512 ============================================================================== --- incubator/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortSearch.java (added) +++ incubator/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortSearch.java Fri Dec 15 02:29:34 2006 @@ -0,0 +1,1098 @@ +/* + * + * Copyright 2001-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.ofbiz.workeffort.workeffort; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javolution.util.FastSet; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilDateTime; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.common.KeywordSearchUtil; +import org.ofbiz.entity.GenericDelegator; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.condition.EntityComparisonOperator; +import org.ofbiz.entity.condition.EntityCondition; +import org.ofbiz.entity.condition.EntityConditionList; +import org.ofbiz.entity.condition.EntityExpr; +import org.ofbiz.entity.condition.EntityOperator; +import org.ofbiz.entity.model.DynamicViewEntity; +import org.ofbiz.entity.model.ModelKeyMap; +import org.ofbiz.entity.model.ModelViewEntity.ComplexAlias; +import org.ofbiz.entity.model.ModelViewEntity.ComplexAliasField; +import org.ofbiz.entity.transaction.GenericTransactionException; +import org.ofbiz.entity.transaction.TransactionUtil; +import org.ofbiz.entity.util.EntityFindOptions; +import org.ofbiz.entity.util.EntityListIterator; +import org.ofbiz.entity.util.EntityUtil; +import org.ofbiz.party.party.PartyHelper; + + +/** + * Utilities for WorkEffort search based on various constraints including assocs, features and keywords. + * + * Search: + * WorkEffort fields: workEffortTypeId,workEffortPurposeTypeId,scopeEnumId, ??others + * WorkEffortKeyword - keyword search + * WorkEffortAssoc.workEffortIdTo,workEffortIdFrom,workEffortAssocTypeId + * Sub-tasks: WorkEffortAssoc.workEffortIdTo,workEffortIdFrom,workEffortAssocTypeId=WORK_EFF_BREAKDOWN for sub-tasks OR: (specific assoc and all sub-tasks) + * Sub-tasks: WorkEffort.workEffortParentId tree + * WorkEffortGoodStandard.productId + * WorkEffortPartyAssignment.partyId,roleTypeId + * Planned for later: + * WorkEffortFixedAssetAssign.fixedAssetId + * WorkEffortContent.contentId,workEffortContentTypeId + * WorkEffortBilling.invoiceId,invoiceItemSeqId + * CommunicationEventWorkEff.communicationEventId + * TimeEntry.partyId,rateTypeId,timesheetId,invoiceId,invoiceItemSeqId + */ +public class WorkEffortSearch { + + public static final String module = WorkEffortSearch.class.getName(); + public static final String resource = "WorkEffortUiLabels"; + + public static ArrayList searchWorkEfforts(List workEffortSearchConstraintList, ResultSortOrder resultSortOrder, GenericDelegator delegator, String visitId) { + WorkEffortSearchContext workEffortSearchContext = new WorkEffortSearchContext(delegator, visitId); + + workEffortSearchContext.addWorkEffortSearchConstraints(workEffortSearchConstraintList); + workEffortSearchContext.setResultSortOrder(resultSortOrder); + + ArrayList workEffortIds = workEffortSearchContext.doSearch(); + return workEffortIds; + } + + public static void getAllSubWorkEffortIds(String workEffortId, Set workEffortIdSet, GenericDelegator delegator, Timestamp nowTimestamp) { + if (nowTimestamp == null) { + nowTimestamp = UtilDateTime.nowTimestamp(); + } + + // first make sure the current id is in the Set + workEffortIdSet.add(workEffortId); + + // now find all sub-categories, filtered by effective dates, and call this routine for them + try { + // Find WorkEffortAssoc, workEffortAssocTypeId=WORK_EFF_BREAKDOWN + List workEffortAssocList = delegator.findByAndCache("WorkEffortAssoc", UtilMisc.toMap("workEffortIdFrom", workEffortId, "workEffortAssocTypeId", "WORK_EFF_BREAKDOWN")); + Iterator workEffortAssocIter = workEffortAssocList.iterator(); + while (workEffortAssocIter.hasNext()) { + GenericValue workEffortAssoc = (GenericValue) workEffortAssocIter.next(); + + String subWorkEffortId = workEffortAssoc.getString("workEffortIdTo"); + if (workEffortIdSet.contains(subWorkEffortId)) { + // if this category has already been traversed, no use doing it again; this will also avoid infinite loops + continue; + } + + // do the date filtering in the loop to avoid looping through the list twice + if (EntityUtil.isValueActive(workEffortAssoc, nowTimestamp)) { + getAllSubWorkEffortIds(subWorkEffortId, workEffortIdSet, delegator, nowTimestamp); + } + } + + // Find WorkEffort where current workEffortId = workEffortParentId; only select minimal fields to keep the size low + List childWorkEffortList = delegator.findByConditionCache("WorkEffort", new EntityExpr("workEffortParentId", EntityComparisonOperator.EQUALS, workEffortId), + UtilMisc.toList("workEffortId", "workEffortParentId"), null); + Iterator childWorkEffortIter = childWorkEffortList.iterator(); + while (childWorkEffortIter.hasNext()) { + GenericValue childWorkEffort = (GenericValue) childWorkEffortIter.next(); + + String subWorkEffortId = childWorkEffort.getString("workEffortId"); + if (workEffortIdSet.contains(subWorkEffortId)) { + // if this category has already been traversed, no use doing it again; this will also avoid infinite loops + continue; + } + + // do the date filtering in the loop to avoid looping through the list twice + getAllSubWorkEffortIds(subWorkEffortId, workEffortIdSet, delegator, nowTimestamp); + } + } catch (GenericEntityException e) { + Debug.logError(e, "Error finding sub-categories for workEffort search", module); + } + } + + public static class WorkEffortSearchContext { + public int index = 1; + public List entityConditionList = new LinkedList(); + public List orderByList = new LinkedList(); + public List fieldsToSelect = UtilMisc.toList("workEffortId"); + public DynamicViewEntity dynamicViewEntity = new DynamicViewEntity(); + public boolean workEffortIdGroupBy = false; + public boolean includedKeywordSearch = false; + public Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); + public List keywordFixedOrSetAndList = new LinkedList(); + public Set orKeywordFixedSet = new HashSet(); + public Set andKeywordFixedSet = new HashSet(); + public List workEffortSearchConstraintList = new LinkedList(); + public ResultSortOrder resultSortOrder = null; + public Integer resultOffset = null; + public Integer maxResults = null; + protected GenericDelegator delegator = null; + protected String visitId = null; + protected Integer totalResults = null; + + public WorkEffortSearchContext(GenericDelegator delegator, String visitId) { + this.delegator = delegator; + this.visitId = visitId; + dynamicViewEntity.addMemberEntity("WEFF", "WorkEffort"); + } + + public GenericDelegator getDelegator() { + return this.delegator; + } + + public void addWorkEffortSearchConstraints(List workEffortSearchConstraintList) { + // Go through the constraints and add them in + Iterator workEffortSearchConstraintIter = workEffortSearchConstraintList.iterator(); + while (workEffortSearchConstraintIter.hasNext()) { + WorkEffortSearchConstraint constraint = (WorkEffortSearchConstraint) workEffortSearchConstraintIter.next(); + constraint.addConstraint(this); + } + } + + public void setResultSortOrder(ResultSortOrder resultSortOrder) { + this.resultSortOrder = resultSortOrder; + } + + public void setResultOffset(Integer resultOffset) { + this.resultOffset = resultOffset; + } + + public void setMaxResults(Integer maxResults) { + this.maxResults = maxResults; + } + + public Integer getTotalResults() { + return this.totalResults; + } + + public ArrayList doSearch() { + long startMillis = System.currentTimeMillis(); + + // do the query + EntityListIterator eli = this.doQuery(delegator); + ArrayList workEffortIds = this.makeWorkEffortIdList(eli); + if (eli != null) { + try { + eli.close(); + } catch (GenericEntityException e) { + Debug.logError(e, "Error closing WorkEffortSearch EntityListIterator"); + } + } + + long endMillis = System.currentTimeMillis(); + double totalSeconds = ((double)endMillis - (double)startMillis)/1000.0; + + // store info about results in the database, attached to the user's visitId, if specified + this.saveSearchResultInfo(new Long(workEffortIds.size()), new Double(totalSeconds)); + + return workEffortIds; + } + + public void finishKeywordConstraints() { + if (orKeywordFixedSet.size() == 0 && andKeywordFixedSet.size() == 0 && keywordFixedOrSetAndList.size() == 0) { + return; + } + + // we know we have a keyword search to do, so keep track of that now... + this.includedKeywordSearch = true; + + // if there is anything in the orKeywordFixedSet add it to the keywordFixedOrSetAndList + if (orKeywordFixedSet.size() > 0) { + // put in keywordFixedOrSetAndList to process with other or lists where at least one is required + keywordFixedOrSetAndList.add(orKeywordFixedSet); + } + + // remove all or sets from the or set and list where the or set is size 1 and put them in the and list + Iterator keywordFixedOrSetAndTestIter = keywordFixedOrSetAndList.iterator(); + while (keywordFixedOrSetAndTestIter.hasNext()) { + Set keywordFixedOrSet = (Set) keywordFixedOrSetAndTestIter.next(); + if (keywordFixedOrSet.size() == 0) { + keywordFixedOrSetAndTestIter.remove(); + } else if (keywordFixedOrSet.size() == 1) { + // treat it as just another and + andKeywordFixedSet.add(keywordFixedOrSet.iterator().next()); + keywordFixedOrSetAndTestIter.remove(); + } + } + + boolean doingBothAndOr = (keywordFixedOrSetAndList.size() > 1) || (keywordFixedOrSetAndList.size() > 0 && andKeywordFixedSet.size() > 0); + + Debug.logInfo("Finished initial setup of keywords, doingBothAndOr=" + doingBothAndOr + ", andKeywordFixedSet=" + andKeywordFixedSet + "\n keywordFixedOrSetAndList=" + keywordFixedOrSetAndList, module); + + ComplexAlias relevancyComplexAlias = new ComplexAlias("+"); + if (andKeywordFixedSet.size() > 0) { + // add up the relevancyWeight fields from all keyword member entities for a total to sort by + + Iterator keywordIter = andKeywordFixedSet.iterator(); + while (keywordIter.hasNext()) { + String keyword = (String) keywordIter.next(); + + // make index based values and increment + String entityAlias = "PK" + index; + String prefix = "pk" + index; + index++; + + dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortKeyword"); + dynamicViewEntity.addAlias(entityAlias, prefix + "Keyword", "keyword", null, null, null, null); + dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortId")); + entityConditionList.add(new EntityExpr(prefix + "Keyword", EntityOperator.LIKE, keyword)); + + //don't add an alias for this, will be part of a complex alias: dynamicViewEntity.addAlias(entityAlias, prefix + "RelevancyWeight", "relevancyWeight", null, null, null, null); + relevancyComplexAlias.addComplexAliasMember(new ComplexAliasField(entityAlias, "relevancyWeight", null, null)); + } + + //TODO: find out why Oracle and other dbs don't like the query resulting from this and fix: workEffortIdGroupBy = true; + + if (!doingBothAndOr) { + dynamicViewEntity.addAlias(null, "totalRelevancy", null, null, null, null, null, relevancyComplexAlias); + } + } + if (keywordFixedOrSetAndList.size() > 0) { + Iterator keywordFixedOrSetAndIter = keywordFixedOrSetAndList.iterator(); + while (keywordFixedOrSetAndIter.hasNext()) { + Set keywordFixedOrSet = (Set) keywordFixedOrSetAndIter.next(); + // make index based values and increment + String entityAlias = "PK" + index; + String prefix = "pk" + index; + index++; + + dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortKeyword"); + dynamicViewEntity.addAlias(entityAlias, prefix + "Keyword", "keyword", null, null, null, null); + dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortId")); + List keywordOrList = new LinkedList(); + Iterator keywordIter = keywordFixedOrSet.iterator(); + while (keywordIter.hasNext()) { + String keyword = (String) keywordIter.next(); + keywordOrList.add(new EntityExpr(prefix + "Keyword", EntityOperator.LIKE, keyword)); + } + entityConditionList.add(new EntityConditionList(keywordOrList, EntityOperator.OR)); + + workEffortIdGroupBy = true; + + if (doingBothAndOr) { + relevancyComplexAlias.addComplexAliasMember(new ComplexAliasField(entityAlias, "relevancyWeight", null, "sum")); + } else { + dynamicViewEntity.addAlias(entityAlias, "totalRelevancy", "relevancyWeight", null, null, null, "sum"); + } + } + } + + if (doingBothAndOr) { + dynamicViewEntity.addAlias(null, "totalRelevancy", null, null, null, null, null, relevancyComplexAlias); + } + } + + public EntityListIterator doQuery(GenericDelegator delegator) { + // handle the now assembled or and and keyword fixed lists + this.finishKeywordConstraints(); + + if (resultSortOrder != null) { + resultSortOrder.setSortOrder(this); + } + + dynamicViewEntity.addAlias("WEFF", "workEffortId", null, null, null, new Boolean(workEffortIdGroupBy), null); + EntityCondition whereCondition = new EntityConditionList(entityConditionList, EntityOperator.AND); + EntityFindOptions efo = new EntityFindOptions(); + efo.setDistinct(true); + efo.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE); + + EntityListIterator eli = null; + try { + eli = delegator.findListIteratorByCondition(dynamicViewEntity, whereCondition, null, fieldsToSelect, orderByList, efo); + } catch (GenericEntityException e) { + Debug.logError(e, "Error in workEffort search", module); + return null; + } + + return eli; + } + + public ArrayList makeWorkEffortIdList(EntityListIterator eli) { + ArrayList workEffortIds = new ArrayList(maxResults == null ? 100 : maxResults.intValue()); + if (eli == null) { + Debug.logWarning("The eli is null, returning zero results", module); + return workEffortIds; + } + + try { + boolean hasResults = false; + Object initialResult = null; + + /* this method has been replaced by the following to address issue with SAP DB and possibly other DBs + if (resultOffset != null) { + Debug.logInfo("Before relative, current index=" + eli.currentIndex(), module); + hasResults = eli.relative(resultOffset.intValue()); + } else { + initialResult = eli.next(); + if (initialResult != null) { + hasResults = true; + } + } + */ + + initialResult = eli.next(); + if (initialResult != null) { + hasResults = true; + } + if (resultOffset != null && resultOffset.intValue() > 1) { + if (Debug.infoOn()) Debug.logInfo("Before relative, current index=" + eli.currentIndex(), module); + hasResults = eli.relative(resultOffset.intValue() - 1); + initialResult = null; + } + + // get the first as the current one + GenericValue searchResult = null; + if (hasResults) { + if (initialResult != null) { + searchResult = (GenericValue) initialResult; + } else { + searchResult = eli.currentGenericValue(); + } + } + + if (searchResult == null) { + // nothing to get... + int failTotal = 0; + if (this.resultOffset != null) { + failTotal = this.resultOffset.intValue() - 1; + } + this.totalResults = new Integer(failTotal); + return workEffortIds; + } + + + // init numRetreived to one since we have already grabbed the initial one + int numRetreived = 1; + int duplicatesFound = 0; + + Set workEffortIdSet = new HashSet(); + + workEffortIds.add(searchResult.getString("workEffortId")); + workEffortIdSet.add(searchResult.getString("workEffortId")); + + while (((searchResult = (GenericValue) eli.next()) != null) && (maxResults == null || numRetreived < maxResults.intValue())) { + String workEffortId = searchResult.getString("workEffortId"); + if (!workEffortIdSet.contains(workEffortId)) { + workEffortIds.add(workEffortId); + workEffortIdSet.add(workEffortId); + numRetreived++; + } else { + duplicatesFound++; + } + + /* + StringBuffer lineMsg = new StringBuffer("Got search result line: "); + Iterator fieldsToSelectIter = fieldsToSelect.iterator(); + while (fieldsToSelectIter.hasNext()) { + String fieldName = (String) fieldsToSelectIter.next(); + lineMsg.append(fieldName); + lineMsg.append("="); + lineMsg.append(searchResult.get(fieldName)); + if (fieldsToSelectIter.hasNext()) { + lineMsg.append(", "); + } + } + Debug.logInfo(lineMsg.toString(), module); + */ + } + + if (searchResult != null) { + // we weren't at the end, so go to the end and get the index + //Debug.logInfo("Getting totalResults from ending index - before last() currentIndex=" + eli.currentIndex(), module); + if (eli.last()) { + this.totalResults = new Integer(eli.currentIndex()); + //Debug.logInfo("Getting totalResults from ending index - after last() currentIndex=" + eli.currentIndex(), module); + } + } + if (this.totalResults == null || this.totalResults.intValue() == 0) { + int total = numRetreived; + if (this.resultOffset != null) { + total += (this.resultOffset.intValue() - 1); + } + this.totalResults = new Integer(total); + } + + Debug.logInfo("Got search values, numRetreived=" + numRetreived + ", totalResults=" + totalResults + ", maxResults=" + maxResults + ", resultOffset=" + resultOffset + ", duplicatesFound(in the current results)=" + duplicatesFound, module); + + } catch (GenericEntityException e) { + Debug.logError(e, "Error getting results from the workEffort search query", module); + } + return workEffortIds; + } + + public void saveSearchResultInfo(Long numResults, Double secondsTotal) { + // uses entities: WorkEffortSearchResult and WorkEffortSearchConstraint + + try { + // make sure this is in a transaction + boolean beganTransaction = TransactionUtil.begin(); + + try { + + GenericValue workEffortSearchResult = delegator.makeValue("WorkEffortSearchResult", null); + String workEffortSearchResultId = delegator.getNextSeqId("WorkEffortSearchResult"); + + workEffortSearchResult.set("workEffortSearchResultId", workEffortSearchResultId); + workEffortSearchResult.set("visitId", this.visitId); + if (this.resultSortOrder != null) { + workEffortSearchResult.set("orderByName", this.resultSortOrder.getOrderName()); + workEffortSearchResult.set("isAscending", this.resultSortOrder.isAscending() ? "Y" : "N"); + } + workEffortSearchResult.set("numResults", numResults); + workEffortSearchResult.set("secondsTotal", secondsTotal); + workEffortSearchResult.set("searchDate", nowTimestamp); + workEffortSearchResult.create(); + + Iterator workEffortSearchConstraintIter = workEffortSearchConstraintList.iterator(); + int seqId = 1; + while (workEffortSearchConstraintIter.hasNext()) { + GenericValue workEffortSearchConstraint = (GenericValue) workEffortSearchConstraintIter.next(); + workEffortSearchConstraint.set("workEffortSearchResultId", workEffortSearchResultId); + workEffortSearchConstraint.set("constraintSeqId", Integer.toString(seqId)); + workEffortSearchConstraint.create(); + seqId++; + } + + TransactionUtil.commit(beganTransaction); + } catch (GenericEntityException e1) { + String errMsg = "Error saving workEffort search result info/stats"; + Debug.logError(e1, errMsg, module); + TransactionUtil.rollback(beganTransaction, errMsg, e1); + } + } catch (GenericTransactionException e) { + Debug.logError(e, "Error saving workEffort search result info/stats", module); + } + } + } + + // ====================================================================== + // Search Constraint Classes + // ====================================================================== + + public static abstract class WorkEffortSearchConstraint implements java.io.Serializable { + public WorkEffortSearchConstraint() { } + + public abstract void addConstraint(WorkEffortSearchContext workEffortSearchContext); + /** pretty print for log messages and even UI stuff */ + public abstract String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale); + } + + + public static class WorkEffortAssocConstraint extends WorkEffortSearchConstraint { + public static final String constraintName = "WorkEffortAssoc"; + protected String workEffortId; + protected String workEffortAssocTypeId; + protected boolean includeSubWorkEfforts; + + public WorkEffortAssocConstraint(String workEffortId, String workEffortAssocTypeId, boolean includeSubWorkEfforts) { + this.workEffortId = workEffortId; + this.workEffortAssocTypeId = workEffortAssocTypeId; + this.includeSubWorkEfforts = includeSubWorkEfforts; + } + + public void addConstraint(WorkEffortSearchContext workEffortSearchContext) { + Set workEffortIdSet = FastSet.newInstance(); + if (includeSubWorkEfforts) { + // find all sub-categories recursively, make a Set of workEffortId + WorkEffortSearch.getAllSubWorkEffortIds(workEffortId, workEffortIdSet, workEffortSearchContext.getDelegator(), workEffortSearchContext.nowTimestamp); + } else { + workEffortIdSet.add(workEffortId); + } + + // allow assoc from or to the current WE and the workEffortId on this constraint + + // make index based values and increment + String entityAlias; + String prefix; + + // do workEffortId = workEffortIdFrom, workEffortIdTo IN workEffortIdSet + entityAlias = "WFA" + workEffortSearchContext.index; + prefix = "wfa" + workEffortSearchContext.index; + workEffortSearchContext.index++; + + workEffortSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortAssoc"); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortIdFrom", "workEffortIdFrom", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortIdTo", "workEffortIdTo", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortAssocTypeId", "workEffortAssocTypeId", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortIdFrom")); + + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "WorkEffortIdTo", EntityOperator.IN, workEffortIdSet)); + if (UtilValidate.isNotEmpty(workEffortAssocTypeId)) { + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "WorkEffortAssocTypeId", EntityOperator.EQUALS, workEffortAssocTypeId)); + } + workEffortSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, workEffortSearchContext.nowTimestamp))); + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, workEffortSearchContext.nowTimestamp)); + + // do workEffortId = workEffortIdTo, workEffortIdFrom IN workEffortIdSet + entityAlias = "WFA" + workEffortSearchContext.index; + prefix = "wfa" + workEffortSearchContext.index; + workEffortSearchContext.index++; + + workEffortSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortAssoc"); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortIdFrom", "workEffortIdFrom", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortIdTo", "workEffortIdTo", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "WorkEffortAssocTypeId", "workEffortAssocTypeId", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortIdTo")); + + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "WorkEffortIdFrom", EntityOperator.IN, workEffortIdSet)); + if (UtilValidate.isNotEmpty(workEffortAssocTypeId)) { + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "WorkEffortAssocTypeId", EntityOperator.EQUALS, workEffortAssocTypeId)); + } + workEffortSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, workEffortSearchContext.nowTimestamp))); + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, workEffortSearchContext.nowTimestamp)); + + // add in workEffortSearchConstraint, don't worry about the workEffortSearchResultId or constraintSeqId, those will be fill in later + workEffortSearchContext.workEffortSearchConstraintList.add(workEffortSearchContext.getDelegator().makeValue("WorkEffortSearchConstraint", UtilMisc.toMap("constraintName", constraintName, "infoString", this.workEffortId + "," + this.workEffortAssocTypeId, "includeSubWorkEfforts", this.includeSubWorkEfforts ? "Y" : "N"))); + } + + /** pretty print for log messages and even UI stuff */ + public String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale) { + GenericValue workEffort = null; + GenericValue workEffortAssocType = null; + try { + workEffort = delegator.findByPrimaryKeyCache("WorkEffort", UtilMisc.toMap("workEffortId", this.workEffortId)); + workEffortAssocType = delegator.findByPrimaryKeyCache("WorkEffortAssocType", UtilMisc.toMap("workEffortAssocTypeId", this.workEffortAssocTypeId)); + } catch (GenericEntityException e) { + Debug.logError(e, "Error looking up WorkEffortAssocConstraint pretty print info: " + e.toString(), module); + } + + StringBuffer ppBuf = new StringBuffer(); + ppBuf.append(UtilProperties.getMessage(resource, "WorkEffortAssoc", locale) + ": "); + if (workEffort != null) { + ppBuf.append(workEffort.getString("workEffortName")); + } + if (workEffort == null || detailed) { + ppBuf.append(" ["); + ppBuf.append(workEffortId); + ppBuf.append("]"); + } + if (UtilValidate.isNotEmpty(this.workEffortAssocTypeId)) { + if (workEffortAssocType != null) { + ppBuf.append(workEffortAssocType.getString("description")); + } + if (workEffortAssocType == null || detailed) { + ppBuf.append(" ["); + ppBuf.append(workEffortAssocTypeId); + ppBuf.append("]"); + } + } + if (this.includeSubWorkEfforts) { + ppBuf.append(" (" + UtilProperties.getMessage(resource, "WorkEffortIncludeAllSubWorkEfforts", locale) + ")"); + } + return ppBuf.toString(); + } + + public boolean equals(Object obj) { + WorkEffortSearchConstraint psc = (WorkEffortSearchConstraint) obj; + if (psc instanceof WorkEffortAssocConstraint) { + WorkEffortAssocConstraint that = (WorkEffortAssocConstraint) psc; + if (this.includeSubWorkEfforts != that.includeSubWorkEfforts) { + return false; + } + if (this.workEffortId == null) { + if (that.workEffortId != null) { + return false; + } + } else { + if (!this.workEffortId.equals(that.workEffortId)) { + return false; + } + } + if (this.workEffortAssocTypeId == null) { + if (that.workEffortAssocTypeId != null) { + return false; + } + } else { + if (!this.workEffortAssocTypeId.equals(that.workEffortAssocTypeId)) { + return false; + } + } + return true; + } else { + return false; + } + } + } + + public static class PartyAssignmentConstraint extends WorkEffortSearchConstraint { + public static final String constraintName = "PartyAssignment"; + protected String partyId; + protected String roleTypeId; + + public PartyAssignmentConstraint(String partyId, String roleTypeId) { + this.partyId = partyId; + this.roleTypeId = roleTypeId; + } + + public void addConstraint(WorkEffortSearchContext workEffortSearchContext) { + // make index based values and increment + String entityAlias = "WEPA" + workEffortSearchContext.index; + String prefix = "wepa" + workEffortSearchContext.index; + workEffortSearchContext.index++; + + workEffortSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortPartyAssignment"); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "PartyId", "partyId", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "RoleTypeId", "roleTypeId", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortId")); + + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "PartyId", EntityOperator.EQUALS, partyId)); + workEffortSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, workEffortSearchContext.nowTimestamp))); + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, workEffortSearchContext.nowTimestamp)); + if (UtilValidate.isNotEmpty(this.roleTypeId)) { + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "RoleTypeId", EntityOperator.EQUALS, roleTypeId)); + } + + // add in workEffortSearchConstraint, don't worry about the workEffortSearchResultId or constraintSeqId, those will be fill in later + workEffortSearchContext.workEffortSearchConstraintList.add(workEffortSearchContext.getDelegator().makeValue("WorkEffortSearchConstraint", UtilMisc.toMap("constraintName", constraintName, "infoString", this.partyId + "," + this.roleTypeId))); + } + + public String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale) { + GenericValue partyNameView = null; + GenericValue roleType = null; + try { + partyNameView = delegator.findByPrimaryKeyCache("PartyNameView", UtilMisc.toMap("partyId", partyId)); + roleType = delegator.findByPrimaryKeyCache("RoleType", UtilMisc.toMap("roleTypeId", roleTypeId)); + } catch (GenericEntityException e) { + Debug.logError(e, "Error finding PartyAssignmentConstraint information for constraint pretty print", module); + } + StringBuffer ppBuf = new StringBuffer(); + ppBuf.append("WorkEffort Assignment: "); + if (partyNameView != null) { + if (UtilValidate.isNotEmpty(partyNameView.getString("firstName"))) { + ppBuf.append(partyNameView.getString("firstName")); + ppBuf.append(" "); + } + if (UtilValidate.isNotEmpty(partyNameView.getString("middleName"))) { + ppBuf.append(partyNameView.getString("middleName")); + ppBuf.append(" "); + } + if (UtilValidate.isNotEmpty(partyNameView.getString("lastName"))) { + ppBuf.append(partyNameView.getString("lastName")); + } + if (UtilValidate.isNotEmpty(partyNameView.getString("groupName"))) { + ppBuf.append(partyNameView.getString("groupName")); + } + } else { + ppBuf.append("["); + ppBuf.append(this.partyId); + ppBuf.append("] "); + } + + if (roleType != null) { + ppBuf.append(roleType.getString("description")); + } else { + if (UtilValidate.isNotEmpty(this.roleTypeId)) { + ppBuf.append("["); + ppBuf.append(this.roleTypeId); + ppBuf.append("]"); + } + } + return ppBuf.toString(); + } + + public boolean equals(Object obj) { + WorkEffortSearchConstraint psc = (WorkEffortSearchConstraint) obj; + if (psc instanceof PartyAssignmentConstraint) { + PartyAssignmentConstraint that = (PartyAssignmentConstraint) psc; + if (this.partyId == null) { + if (that.partyId != null) { + return false; + } + } else { + if (!this.partyId.equals(that.partyId)) { + return false; + } + } + if (this.roleTypeId == null) { + if (that.roleTypeId != null) { + return false; + } + } else { + if (!this.roleTypeId.equals(that.roleTypeId)) { + return false; + } + } + return true; + } else { + return false; + } + } + } + + public static class ProductSetConstraint extends WorkEffortSearchConstraint { + public static final String constraintName = "ProductSet"; + protected Set productIdSet; + + public ProductSetConstraint(Collection productIdSet) { + this.productIdSet = new HashSet(productIdSet); + } + + public void addConstraint(WorkEffortSearchContext workEffortSearchContext) { + // make index based values and increment + String entityAlias = "WEGS" + workEffortSearchContext.index; + String prefix = "wegs" + workEffortSearchContext.index; + workEffortSearchContext.index++; + + workEffortSearchContext.dynamicViewEntity.addMemberEntity(entityAlias, "WorkEffortGoodStandard"); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ProductId", "productId", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "FromDate", "fromDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addAlias(entityAlias, prefix + "ThruDate", "thruDate", null, null, null, null); + workEffortSearchContext.dynamicViewEntity.addViewLink("WEFF", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("workEffortId")); + + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "ProductId", EntityOperator.IN, productIdSet)); + workEffortSearchContext.entityConditionList.add(new EntityExpr(new EntityExpr(prefix + "ThruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr(prefix + "ThruDate", EntityOperator.GREATER_THAN, workEffortSearchContext.nowTimestamp))); + workEffortSearchContext.entityConditionList.add(new EntityExpr(prefix + "FromDate", EntityOperator.LESS_THAN, workEffortSearchContext.nowTimestamp)); + + // add in workEffortSearchConstraint, don't worry about the workEffortSearchResultId or constraintSeqId, those will be fill in later + StringBuffer productIdInfo = new StringBuffer(); + Iterator productIdIter = this.productIdSet.iterator(); + while (productIdIter.hasNext()) { + String productId = (String) productIdIter.next(); + productIdInfo.append(productId); + if (productIdIter.hasNext()) { + productIdInfo.append(","); + } + } + + workEffortSearchContext.workEffortSearchConstraintList.add(workEffortSearchContext.getDelegator().makeValue("WorkEffortSearchConstraint", UtilMisc.toMap("constraintName", constraintName, "infoString", productIdInfo.toString()))); + } + + public String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale) { + StringBuffer infoOut = new StringBuffer(); + try { + Iterator productIdIter = this.productIdSet.iterator(); + while (productIdIter.hasNext()) { + String productId = (String) productIdIter.next(); + GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId)); + if (product == null) { + infoOut.append("["); + infoOut.append(productId); + infoOut.append("]"); + } else { + infoOut.append(product.getString("productName")); + } + + if (productIdIter.hasNext()) { + infoOut.append(", "); + } + } + } catch (GenericEntityException e) { + Debug.logError(e, "Error finding ProductSetConstraint information for constraint pretty print", module); + } + + return infoOut.toString(); + } + + public boolean equals(Object obj) { + WorkEffortSearchConstraint psc = (WorkEffortSearchConstraint) obj; + if (psc instanceof ProductSetConstraint) { + ProductSetConstraint that = (ProductSetConstraint) psc; + if (this.productIdSet == null) { + if (that.productIdSet != null) { + return false; + } + } else { + if (!this.productIdSet.equals(that.productIdSet)) { + return false; + } + } + return true; + } else { + return false; + } + } + } + + public static class KeywordConstraint extends WorkEffortSearchConstraint { + public static final String constraintName = "Keyword"; + protected String keywordsString; + protected boolean anyPrefix; + protected boolean anySuffix; + protected boolean isAnd; + protected boolean removeStems; + + public KeywordConstraint(String keywordsString, boolean anyPrefix, boolean anySuffix, Boolean removeStems, boolean isAnd) { + this.keywordsString = keywordsString; + this.anyPrefix = anyPrefix; + this.anySuffix = anySuffix; + this.isAnd = isAnd; + if (removeStems != null) { + this.removeStems = removeStems.booleanValue(); + } else { + this.removeStems = UtilProperties.propertyValueEquals("prodsearch", "remove.stems", "true"); + } + } + + public Set makeFullKeywordSet(GenericDelegator delegator) { + Set keywordSet = KeywordSearchUtil.makeKeywordSet(this.keywordsString, null, true); + Set fullKeywordSet = new TreeSet(); + + // expand the keyword list according to the thesaurus and create a new set of keywords + Iterator keywordIter = keywordSet.iterator(); + while (keywordIter.hasNext()) { + String keyword = (String) keywordIter.next(); + Set expandedSet = new TreeSet(); + boolean replaceEntered = KeywordSearchUtil.expandKeywordForSearch(keyword, expandedSet, delegator); + fullKeywordSet.addAll(expandedSet); + if (!replaceEntered) { + fullKeywordSet.add(keyword); + } + } + + return fullKeywordSet; + } + + public void addConstraint(WorkEffortSearchContext workEffortSearchContext) { + // just make the fixed keyword lists and put them in the context + if (isAnd) { + // when isAnd is true we need to make a list of keyword sets where each set corresponds to one + //incoming/entered keyword and contains all of the expanded keywords plus the entered keyword if none of + //the expanded keywords are flagged as replacements; now the tricky part: each set should be or'ed together, + //but then the sets should be and'ed to produce the overall expression; create the SQL for this + //needs some work as the current method only support a list of and'ed words and a list of or'ed words, not + //a list of or'ed sets to be and'ed together + Set keywordSet = KeywordSearchUtil.makeKeywordSet(this.keywordsString, null, true); + + // expand the keyword list according to the thesaurus and create a new set of keywords + Iterator keywordIter = keywordSet.iterator(); + while (keywordIter.hasNext()) { + String keyword = (String) keywordIter.next(); + Set expandedSet = new TreeSet(); + boolean replaceEntered = KeywordSearchUtil.expandKeywordForSearch(keyword, expandedSet, workEffortSearchContext.getDelegator()); + if (!replaceEntered) { + expandedSet.add(keyword); + } + Set fixedSet = KeywordSearchUtil.fixKeywordsForSearch(expandedSet, anyPrefix, anySuffix, removeStems, isAnd); + Set fixedKeywordSet = new HashSet(); + fixedKeywordSet.addAll(fixedSet); + workEffortSearchContext.keywordFixedOrSetAndList.add(fixedKeywordSet); + } + } else { + // when isAnd is false, just add all of the new entries to the big list + Set keywordFirstPass = makeFullKeywordSet(workEffortSearchContext.getDelegator()); // includes keyword expansion, etc + Set keywordSet = KeywordSearchUtil.fixKeywordsForSearch(keywordFirstPass, anyPrefix, anySuffix, removeStems, isAnd); + workEffortSearchContext.orKeywordFixedSet.addAll(keywordSet); + } + + // add in workEffortSearchConstraint, don't worry about the workEffortSearchResultId or constraintSeqId, those will be fill in later + Map valueMap = UtilMisc.toMap("constraintName", constraintName, "infoString", this.keywordsString); + valueMap.put("anyPrefix", this.anyPrefix ? "Y" : "N"); + valueMap.put("anySuffix", this.anySuffix ? "Y" : "N"); + valueMap.put("isAnd", this.isAnd ? "Y" : "N"); + valueMap.put("removeStems", this.removeStems ? "Y" : "N"); + workEffortSearchContext.workEffortSearchConstraintList.add(workEffortSearchContext.getDelegator().makeValue("WorkEffortSearchConstraint", valueMap)); + } + + /** pretty print for log messages and even UI stuff */ + public String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale) { + StringBuffer ppBuf = new StringBuffer(); + ppBuf.append(UtilProperties.getMessage(resource, "WorkEffortKeywords", locale) + ": \""); + ppBuf.append(this.keywordsString + "\", " + UtilProperties.getMessage(resource, "WorkEffortKeywordWhere", locale) + " "); + ppBuf.append(isAnd ? UtilProperties.getMessage(resource, "WorkEffortKeywordAllWordsMatch", locale) : UtilProperties.getMessage(resource, "WorkEffortKeywordAnyWordMatches", locale)); + return ppBuf.toString(); + } + + public boolean equals(Object obj) { + WorkEffortSearchConstraint psc = (WorkEffortSearchConstraint) obj; + if (psc instanceof KeywordConstraint) { + KeywordConstraint that = (KeywordConstraint) psc; + if (this.anyPrefix != that.anyPrefix) { + return false; + } + if (this.anySuffix != that.anySuffix) { + return false; + } + if (this.isAnd != that.isAnd) { + return false; + } + if (this.removeStems != that.removeStems) { + return false; + } + if (this.keywordsString == null) { + if (that.keywordsString != null) { + return false; + } + } else { + if (!this.keywordsString.equals(that.keywordsString)) { + return false; + } + } + return true; + } else { + return false; + } + } + } + + public static class LastUpdatedRangeConstraint extends WorkEffortSearchConstraint { + public static final String constraintName = "LastUpdatedRange"; + protected Timestamp fromDate; + protected Timestamp thruDate; + + public LastUpdatedRangeConstraint(Timestamp fromDate, Timestamp thruDate) { + this.fromDate = fromDate; + this.thruDate = thruDate; + } + + public void addConstraint(WorkEffortSearchContext workEffortSearchContext) { + // TODO: implement LastUpdatedRangeConstraint makeEntityCondition + } + + /** pretty print for log messages and even UI stuff */ + public String prettyPrintConstraint(GenericDelegator delegator, boolean detailed, Locale locale) { + // TODO: implement the pretty print for log messages and even UI stuff + return null; + } + + public boolean equals(Object obj) { + WorkEffortSearchConstraint psc = (WorkEffortSearchConstraint) obj; + if (psc instanceof LastUpdatedRangeConstraint) { + LastUpdatedRangeConstraint that = (LastUpdatedRangeConstraint) psc; + if (this.fromDate == null) { + if (that.fromDate != null) { + return false; + } + } else { + if (!this.fromDate.equals(that.fromDate)) { + return false; + } + } + if (this.thruDate == null) { + if (that.thruDate != null) { + return false; + } + } else { + if (!this.thruDate.equals(that.thruDate)) { + return false; + } + } + return true; + } else { + return false; + } + } + } + + // ====================================================================== + // Result Sort Classes + // ====================================================================== + + public static abstract class ResultSortOrder implements java.io.Serializable { + public ResultSortOrder() { + } + + public abstract void setSortOrder(WorkEffortSearchContext workEffortSearchContext); + public abstract String getOrderName(); + public abstract String prettyPrintSortOrder(boolean detailed, Locale locale); + public abstract boolean isAscending(); + } + + public static class SortKeywordRelevancy extends ResultSortOrder { + public SortKeywordRelevancy() { + } + + public void setSortOrder(WorkEffortSearchContext workEffortSearchContext) { + if (workEffortSearchContext.includedKeywordSearch) { + // we have to check this in order to be sure that there is a totalRelevancy to sort by... + workEffortSearchContext.orderByList.add("-totalRelevancy"); + workEffortSearchContext.fieldsToSelect.add("totalRelevancy"); + } + } + + public String getOrderName() { + return "KeywordRelevancy"; + } + + public Strin |
Free forum by Nabble | Edit this page |