try
{
Logging.connectors.debug("Entering documentSpecificationSearch");
int currentSearchTerm = 1;
DMDataSet dsSearchCriteria = new DMDataSet();
/*====================================================================
* Exclude things marked for delete
*===================================================================*/
PROPERTY_TERMS drDeleteSearch = new PROPERTY_TERMS();
drDeleteSearch.setId(currentSearchTerm++);
drDeleteSearch.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDeleteSearch.setPropertyName("PROP_markedForDelete");
drDeleteSearch.setCategoryId(4); //Global Standard/Fixed Property
drDeleteSearch.setNum_relation(new Short("0").shortValue()); //dmNumRelation.EQUAL
drDeleteSearch.setNum_value(0);
drDeleteSearch.setParentId(1);
drDeleteSearch.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDeleteSearch);
/*====================================================================
* Restrict based on start & end date/time, if necessssary
*===================================================================*/
if (startTime > 0L)
{
Logging.connectors.debug("Start Date/time is <" + new Date(startTime) + "> in ms <" + startTime + ">" +
" End Date/time is <" + new Date(endTime) + "> in ms <" + endTime + ">");
PROPERTY_TERMS drDateStart = new PROPERTY_TERMS();
drDateStart.setId(currentSearchTerm++);
drDateStart.setTermType(new Short("2").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDateStart.setPropertyName("PROP_lastModifiedDate");
drDateStart.setCategoryId(4); //Global Standard/Fixed Property
drDateStart.setDate_relation(new Short("11").shortValue()); //dtONORAFTER
drDateStart.setDate_value(new Date(startTime));
drDateStart.setParentId(1);
drDateStart.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDateStart);
PROPERTY_TERMS drDateEnd = new PROPERTY_TERMS();
drDateEnd.setId(currentSearchTerm++);
drDateEnd.setTermType(new Short("2").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDateEnd.setPropertyName("PROP_lastModifiedDate");
drDateEnd.setCategoryId(4); //Global Standard/Fixed Property
drDateEnd.setDate_relation(new Short("8").shortValue()); //dtBEFORE
drDateEnd.setDate_value(new Date(endTime));
drDateEnd.setParentId(1);
drDateEnd.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDateEnd);
}
/*====================================================================
* Just add a dummy term to make the conditional logic easier; i.e.
* always add an "AND" - the dummy term is required in case there are
* no other search criteria - i.e. we could be searching the whole
* Meridio repository
*
* Search for document id's which are > 0 - this will always be true
*===================================================================*/
PROPERTY_TERMS drDocIdSearch = new PROPERTY_TERMS();
drDocIdSearch.setId(currentSearchTerm++);
drDocIdSearch.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocIdSearch.setPropertyName("PROP_documentId");
drDocIdSearch.setCategoryId(4); //Global Standard/Fixed Property
drDocIdSearch.setNum_relation(new Short("3").shortValue()); //dmNumRelation.GREATER
drDocIdSearch.setNum_value(0);
drDocIdSearch.setParentId(1);
drDocIdSearch.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocIdSearch);
if (restrictDocumentId != null && restrictDocumentId.length == 1)
{
/*====================================================================
* Restrict the search query to just the 1 document ID passed in
*===================================================================*/
PROPERTY_TERMS drDocIdSearchRestricted = new PROPERTY_TERMS();
drDocIdSearchRestricted.setId(currentSearchTerm++);
drDocIdSearchRestricted.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocIdSearchRestricted.setPropertyName("PROP_documentId");
drDocIdSearchRestricted.setCategoryId(4); //Global Standard/Fixed Property
drDocIdSearchRestricted.setNum_relation(new Short("0").shortValue()); //dmNumRelation.EQUAL
drDocIdSearchRestricted.setNum_value(restrictDocumentId[0]); //Search for the specific doc ID
drDocIdSearchRestricted.setParentId(1);
drDocIdSearchRestricted.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocIdSearchRestricted);
}
else if (restrictDocumentId != null && restrictDocumentId.length > 1)
{
/*====================================================================
* Multiple document id's have been passed in, so we need to "or"
* them together
*===================================================================*/
for (int i = 0; i < restrictDocumentId.length; i++)
{
PROPERTY_TERMS drDocIdSearchRestricted = new PROPERTY_TERMS();
drDocIdSearchRestricted.setId(currentSearchTerm++);
drDocIdSearchRestricted.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocIdSearchRestricted.setPropertyName("PROP_documentId");
drDocIdSearchRestricted.setCategoryId(4); //Global Standard/Fixed Property
drDocIdSearchRestricted.setNum_relation(new Short("0").shortValue()); //dmNumRelation.EQUAL
drDocIdSearchRestricted.setNum_value(restrictDocumentId[i]); //Search for the specific doc ID
drDocIdSearchRestricted.setParentId(4);
drDocIdSearchRestricted.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocIdSearchRestricted);
}
PROPERTY_OPS drMIMETypeOps = new PROPERTY_OPS();
drMIMETypeOps.setId(4);
drMIMETypeOps.setParentId(1);
drMIMETypeOps.setOperator(new Short("1").shortValue()); // OR
dsSearchCriteria.addPROPERTY_OPS(drMIMETypeOps);
}
PROPERTY_OPS drPropertyOps = new PROPERTY_OPS();
drPropertyOps.setId(1);
drPropertyOps.setOperator(new Short("0").shortValue()); //AND
dsSearchCriteria.addPROPERTY_OPS(drPropertyOps);
/*====================================================================
* Filter on documents, records, or documents and records
*
* The "SearchDocuments" method returns both documents and records; to
* return just documents, get things where the recordType is not
* 0, 4 or 19 (refer to Meridio Documentation)
*===================================================================*/
String searchOn = null;
for (int i = 0; i < docSpec.getChildCount(); i++)
{
SpecificationNode sn = docSpec.getChild(i);
if (sn.getType().equals("SearchOn"))
{
searchOn = sn.getAttributeValue("value");
}
}
if (searchOn != null && searchOn.equals("DOCUMENTS_ONLY"))
{
PROPERTY_TERMS drDocsOrRecsSearch = new PROPERTY_TERMS();
drDocsOrRecsSearch.setId(currentSearchTerm++);
drDocsOrRecsSearch.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocsOrRecsSearch.setPropertyName("PROP_recordType");
drDocsOrRecsSearch.setCategoryId(4); //Global Standard/Fixed Property
drDocsOrRecsSearch.setNum_relation(new Short("1").shortValue()); //dmNumberRelation.NOTEQUAL=1
drDocsOrRecsSearch.setNum_value(0);
drDocsOrRecsSearch.setParentId(1);
drDocsOrRecsSearch.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocsOrRecsSearch);
PROPERTY_TERMS drDocsOrRecsSearch2 = new PROPERTY_TERMS();
drDocsOrRecsSearch2.setId(currentSearchTerm++);
drDocsOrRecsSearch2.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocsOrRecsSearch2.setPropertyName("PROP_recordType");
drDocsOrRecsSearch2.setCategoryId(4); //Global Standard/Fixed Property
drDocsOrRecsSearch2.setNum_relation(new Short("1").shortValue()); //dmNumberRelation.NOTEQUAL=1
drDocsOrRecsSearch2.setNum_value(4);
drDocsOrRecsSearch2.setParentId(1);
drDocsOrRecsSearch2.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocsOrRecsSearch2);
PROPERTY_TERMS drDocsOrRecsSearch3 = new PROPERTY_TERMS();
drDocsOrRecsSearch3.setId(currentSearchTerm++);
drDocsOrRecsSearch3.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocsOrRecsSearch3.setPropertyName("PROP_recordType");
drDocsOrRecsSearch3.setCategoryId(4); //Global Standard/Fixed Property
drDocsOrRecsSearch3.setNum_relation(new Short("1").shortValue()); //dmNumberRelation.NOTEQUAL=1
drDocsOrRecsSearch3.setNum_value(19);
drDocsOrRecsSearch3.setParentId(1);
drDocsOrRecsSearch3.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocsOrRecsSearch3);
}
/*====================================================================
* Filter on documents, records, or documents and records
*
* The "SearchDocuments" method returns both documents and records; to
* return just records, get things where the recordType is 4 or greater
*===================================================================*/
if (searchOn != null && searchOn.equals("RECORDS_ONLY"))
{
PROPERTY_TERMS drDocsOrRecsSearch = new PROPERTY_TERMS();
drDocsOrRecsSearch.setId(currentSearchTerm++);
drDocsOrRecsSearch.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocsOrRecsSearch.setPropertyName("PROP_recordType");
drDocsOrRecsSearch.setCategoryId(4); //Global Standard/Fixed Property
drDocsOrRecsSearch.setNum_relation(new Short("5").shortValue()); //dmNumberRelation.GREATEROREQUAL=5
drDocsOrRecsSearch.setNum_value(4);
drDocsOrRecsSearch.setParentId(1);
drDocsOrRecsSearch.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocsOrRecsSearch);
}
/*====================================================================
* Filter on class or folder (if any)
*===================================================================*/
for (int i = 0; i < docSpec.getChildCount(); i++)
{
SpecificationNode sn = docSpec.getChild(i);
if (sn.getType().equals("SearchPath"))
{
String searchPath = sn.getAttributeValue("path");
int searchContainer = meridio_.findClassOrFolder(searchPath);
if (searchContainer > 0)
{
SEARCH_CONTAINERS drSearchContainers = new SEARCH_CONTAINERS();
drSearchContainers.setContainerId(searchContainer);
dsSearchCriteria.addSEARCH_CONTAINERS(drSearchContainers);
Logging.connectors.debug("Found path [" + searchPath + "] id: [" +
searchContainer + "]");
}
else if (searchContainer == 0)
{
Logging.connectors.debug("Meridio: Found FilePlan root, so not including in search criteria!");
}
else
{
/*====================================================================
* We can't find the path, so ignore it.
*
* This is potentially opening up the search scope, i.e. if there was
* one path which was being searched and then the Meridio FilePlan is
* re-organised and the path no longer exists (but the original content
* has just been moved in the tree) then this could cause all the
* Meridio content to be returned
*===================================================================*/
Logging.connectors.warn("Meridio: Did not find FilePlan path [" + searchPath + "]. " +
"The path is therefore *not* being used to restrict the search scope");
}
}
}
/*====================================================================
* Filter on category (if any)
*===================================================================*/
CATEGORIES [] meridioCategories = meridio_.getCategories().getCATEGORIES();
// Create a map from title to category ID
HashMap categoryMap = new HashMap();
int i = 0;
while (i < meridioCategories.length)
{
String title = meridioCategories[i].getPROP_title();
long categoryID = meridioCategories[i].getPROP_categoryId();
categoryMap.put(title,new Long(categoryID));
i++;
}
ArrayList categoriesToAdd = new ArrayList ();
for (i = 0; i < docSpec.getChildCount(); i++)
{
SpecificationNode sn = docSpec.getChild(i);
if (sn.getType().equals("SearchCategory"))
{
String searchCategory = sn.getAttributeValue("category");
Long categoryIDObject = (Long)categoryMap.get(searchCategory);
if (categoryIDObject != null)
{
if (Logging.connectors.isDebugEnabled())
Logging.connectors.debug("Meridio: Category [" + searchCategory + "] match, ID=[" + categoryIDObject + "]");
categoriesToAdd.add(categoryIDObject);
}
else
{
if (Logging.connectors.isDebugEnabled())
Logging.connectors.debug("Meridio: No match found for Category [" + searchCategory + "]");
}
}
}
for (i = 0; i < categoriesToAdd.size(); i++)
{
PROPERTY_TERMS drDocsOrRecsSearch = new PROPERTY_TERMS();
drDocsOrRecsSearch.setId(currentSearchTerm++);
drDocsOrRecsSearch.setTermType(new Short("1").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drDocsOrRecsSearch.setPropertyName("PROP_categoryId");
drDocsOrRecsSearch.setCategoryId(4); //Global Standard/Fixed Property
drDocsOrRecsSearch.setNum_relation(new Short("0").shortValue()); //dmNumberRelation.GREATEROREQUAL=5
drDocsOrRecsSearch.setNum_value(((Long) categoriesToAdd.get(i)).longValue());
if (categoriesToAdd.size() == 1) // If there is one term, we can use the AND clause
{
drDocsOrRecsSearch.setParentId(1);
}
else // Otherwise, need to have an OR subclause
{
drDocsOrRecsSearch.setParentId(2);
}
drDocsOrRecsSearch.setIsVersionProperty(false);
dsSearchCriteria.addPROPERTY_TERMS(drDocsOrRecsSearch);
}
/*====================================================================
* Filter on MIME Type (if any are in the Document Specification)
*===================================================================*/
String [] mimeTypes = getMIMETypes(docSpec);
for (i = 0; i < mimeTypes.length; i++)
{
PROPERTY_TERMS drMIMETypesSearch = new PROPERTY_TERMS();
drMIMETypesSearch.setId(currentSearchTerm++);
drMIMETypesSearch.setTermType(new Short("0").shortValue()); //0=STRING, 1=NUMBER, 2=DATE
drMIMETypesSearch.setPropertyName("PROP_W_mimeType");
drMIMETypesSearch.setCategoryId(4); //Global Standard/Fixed Property
drMIMETypesSearch.setStr_relation(new Short("0").shortValue()); //dmNumberRelation.GREATEROREQUAL=5
drMIMETypesSearch.setStr_value(mimeTypes[i]);
if (mimeTypes.length == 1) // If there is one term, we can use the AND clause
{
drMIMETypesSearch.setParentId(1);
}
else // Otherwise, need to have an OR subclause
{
drMIMETypesSearch.setParentId(3);
}
drMIMETypesSearch.setIsVersionProperty(true);
dsSearchCriteria.addPROPERTY_TERMS(drMIMETypesSearch);
}
if (categoriesToAdd.size() > 1)
{
PROPERTY_OPS drCategoryOps = new PROPERTY_OPS();
drCategoryOps.setId(2);
drCategoryOps.setParentId(1);
drCategoryOps.setOperator(new Short("1").shortValue()); // OR
dsSearchCriteria.addPROPERTY_OPS(drCategoryOps);
}
if (mimeTypes.length > 1)
{
PROPERTY_OPS drMIMETypeOps = new PROPERTY_OPS();
drMIMETypeOps.setId(3);
drMIMETypeOps.setParentId(1);
drMIMETypeOps.setOperator(new Short("1").shortValue()); // OR
dsSearchCriteria.addPROPERTY_OPS(drMIMETypeOps);
}
/*====================================================================
* Define what is being returned: include the properties that are
* present within the document specification
*===================================================================*/
int returnResultsAdded = 0;
if (returnMetadata != null && returnMetadata.length > 0)
{
PROPERTYDEFS [] propertyDefs = meridio_.getStaticData().getPROPERTYDEFS();
// Build a hash table containing standard and custom properties
HashMap propertyMap = new HashMap();
HashMap customMap = new HashMap();
i = 0;
while (i < propertyDefs.length)
{
PROPERTYDEFS def = propertyDefs[i++];
if (def.getTableName().equals("DOCUMENTS"))
{
propertyMap.put(def.getDisplayName(),def.getColumnName());
}
else if (def.getTableName().equals("DOCUMENT_CUSTOMPROPS"))
{
Long categoryID = new Long(def.getCategoryId());
HashMap dataMap = (HashMap)customMap.get(categoryID);
if (dataMap == null)
{
dataMap = new HashMap();
customMap.put(categoryID,dataMap);
}
dataMap.put(def.getDisplayName(),def.getColumnName());
}
}
for (i = 0; i < returnMetadata.length; i++)
{
long categoryMatch = 0;
boolean isCategoryMatch = false;
RESULTDEFS drResultDefs = new RESULTDEFS();
drResultDefs.setIsVersionProperty(false);
if (returnMetadata[i].getCategoryName() == null ||
returnMetadata[i].getCategoryName().length() == 0)
{
isCategoryMatch = true;
categoryMatch = 4;
}
else
{
Long categoryIDObject = (Long)categoryMap.get(returnMetadata[i].getCategoryName());
if (categoryIDObject != null)
{
isCategoryMatch = true;
categoryMatch = categoryIDObject.longValue();
}
}
if (!isCategoryMatch)
{
if (Logging.connectors.isDebugEnabled())
Logging.connectors.debug("Meridio: Category '" + returnMetadata[i].getCategoryName() + "' no match found for search results criteria!");
continue;
}
else
{
/*====================================================================
* Find the matching property name for the display name (as it is the
* property column name that is required by the search)
*===================================================================*/
String columnName = (String)propertyMap.get(returnMetadata[i].getPropertyName());
if (columnName == null)
{
HashMap categoryMatchMap = (HashMap)customMap.get(new Long(categoryMatch));
if (categoryMatchMap != null)
{
columnName = (String)categoryMatchMap.get(returnMetadata[i].getPropertyName());
}
}
if (columnName != null)
drResultDefs.setPropertyName(columnName);
else
{
if (Logging.connectors.isDebugEnabled())
Logging.connectors.debug("Meridio: No property match found for '" + returnMetadata[i].getPropertyName() + "'");
continue;
}
drResultDefs.setCategoryId(categoryMatch);
dsSearchCriteria.addRESULTDEFS(drResultDefs);
returnResultsAdded++;
}
}
}
/*====================================================================
* We always need to return something in the search results, so add
* the last modified date if nothing else was provided
*===================================================================*/
if (returnResultsAdded == 0)
{
RESULTDEFS drResultDefs = new RESULTDEFS();
drResultDefs.setPropertyName("PROP_lastModifiedDate");
drResultDefs.setIsVersionProperty(false);
drResultDefs.setCategoryId(4);
dsSearchCriteria.addRESULTDEFS(drResultDefs);
}
/*====================================================================
* Call the search method
*===================================================================*/