Merged SWIFT to HEAD

25250: SWIFT branch moved to 4.0.0 schema 5000
   25435: Initial checkin for ALF-7069
   25450: ALF-7069:
          - add maxResults to SOLR DAO
          - refactoring
   25480: ALF-7069: further enhancements + unit tests
          - include/exclude aspects, store protocol + identifier

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@27999 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-05-24 01:02:38 +00:00
parent 05d1778a5d
commit 0488757523
13 changed files with 904 additions and 6 deletions

View File

@@ -253,4 +253,9 @@
<property name="controlDAO" ref="controlDAO"/> <property name="controlDAO" ref="controlDAO"/>
</bean> </bean>
<bean id="solrDAO" class="org.alfresco.repo.domain.solr.ibatis.SOLRDAOImpl" init-method="init">
<property name="sqlMapClientTemplate" ref="solrSqlMapClientTemplate"/>
<property name="qNameDAO" ref="qnameDAO"/>
</bean>
</beans> </beans>

View File

@@ -41,6 +41,7 @@
<sqlMap resource="alfresco/ibatis/#resource.dialect#/permissions-insert-SqlMap.xml"/> <sqlMap resource="alfresco/ibatis/#resource.dialect#/permissions-insert-SqlMap.xml"/>
<sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-common-SqlMap.xml"/> <sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-common-SqlMap.xml"/>
<sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-insert-SqlMap.xml"/> <sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-insert-SqlMap.xml"/>
<sqlMap resource="alfresco/ibatis/#resource.dialect#/solr-common-SqlMap.xml"/>
<!-- Canned queries --> <!-- Canned queries -->
<sqlMap resource="alfresco/ibatis/#resource.dialect#/query-test-common-SqlMap.xml"/> <sqlMap resource="alfresco/ibatis/#resource.dialect#/query-test-common-SqlMap.xml"/>

View File

@@ -78,5 +78,7 @@
<bean id="avmSqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <bean id="avmSqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="alfrescoSqlMapClient"/> <property name="sqlMapClient" ref="alfrescoSqlMapClient"/>
</bean> </bean>
<bean id="solrSqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="alfrescoSqlMapClient"/>
</bean>
</beans> </beans>

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="alfresco.solr">
<typeAlias alias="SOLRTransaction" type="org.alfresco.repo.domain.solr.TransactionEntity"/>
<typeAlias alias="Node" type="org.alfresco.repo.domain.node.NodeEntity"/>
<typeAlias alias="SOLRTransactionParameters" type="org.alfresco.repo.domain.solr.SOLRTransactionParameters"/>
<typeAlias alias="NodeParameters" type="org.alfresco.repo.domain.solr.NodeParameters"/>
<resultMap id="result_Node" class="Node">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="deleted" column="node_deleted" jdbcType="BIT" javaType="java.lang.Boolean" />
<result property="transaction.id" column="txn_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<resultMap id="result_Transaction" class="SOLRTransaction">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="commitTimeMs" column="commit_time_ms" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="updates" column="updates" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="deletes" column="deletes" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<select id="select_Txns" parameterClass="SOLRTransactionParameters" resultMap="result_Transaction">
select
txn.id as id,
txn.commit_time_ms as commit_time_ms,
(select
count(node.id)
from
alf_node node
where
txn.id = node.transaction_id and
node.node_deleted = 0
) as updates,
(select
count(node.id)
from
alf_node node
where
txn.id = node.transaction_id and
node.node_deleted = 1
) as deletes
from
alf_transaction txn
<dynamic prepend="where">
<isNotNull property="txnFromCommitTime" prepend="and">
<![CDATA[txn.commit_time_ms >= #txnFromCommitTime#]]>
</isNotNull>
<isNotNull property="minTxnId" prepend="and">
<![CDATA[txn.id >= #minTxnId#]]>
</isNotNull>
</dynamic>
order by txn.commit_time_ms ASC, txn.id ASC
</select>
<select id="select_Txn_Nodes" parameterClass="NodeParameters" resultMap="result_Node">
select
node.id as id,
node.node_deleted as node_deleted,
node.transaction_id as txn_id
from
alf_transaction txn
join alf_node node on (txn.id = node.transaction_id)
<dynamic>
<isEqual property="storeFilter" compareValue="true">
join alf_store store on (store.id = node.store_id)
</isEqual>
</dynamic>
<dynamic prepend="where">
<isNotNull property="transactionIds" prepend="and">
txn.id in <iterate property="transactionIds" open="(" close=")" conjunction=", ">#transactionIds[]#</iterate>
</isNotNull>
<isNotNull property="fromNodeId" prepend="and">
<![CDATA[node.id >= #fromNodeId#]]>
</isNotNull>
<isNotNull property="toNodeId" prepend="and">
<![CDATA[node.id <= #toNodeId#]]>
</isNotNull>
<isNotNull property="storeProtocol" prepend="and">
store.protocol = #storeProtocol#
</isNotNull>
<isNotNull property="storeIdentifier" prepend="and">
store.identifier = #storeIdentifier#
</isNotNull>
<isNotNull property="includeTypeIds" prepend="and">
node.type_qname_id in <iterate property="includeTypeIds" open="(" close=")" conjunction=", ">#includeTypeIds[]#</iterate>
</isNotNull>
<isNotNull property="excludeTypeIds" prepend="and">
node.type_qname_id not in <iterate property="excludeTypeIds" open="(" close=")" conjunction=", ">#excludeTypeIds[]#</iterate>
</isNotNull>
<isNotNull property="includeAspectIds" prepend="and">
exists (
select *
from alf_node_aspects aspects
where
aspects.node_id = node.id
and aspects.qname_id in <iterate property="includeAspectIds" open="(" close=")" conjunction=", ">#includeAspectIds[]#</iterate>
)
</isNotNull>
<isNotNull property="excludeAspectIds" prepend="and">
not exists (
select *
from alf_node_aspects aspects
where
aspects.node_id = node.id
and aspects.qname_id in <iterate property="excludeAspectIds" open="(" close=")" conjunction=", ">#excludeAspectIds[]#</iterate>
)
</isNotNull>
</dynamic>
order by node.id ASC
</select>
</sqlMap>

View File

@@ -4,10 +4,10 @@
# Version label # Version label
version.major=3 version.major=4
version.minor=5 version.minor=0
version.revision=0 version.revision=0
version.label=a version.label=
# Edition label # Edition label
@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=4306 version.schema=5000

View File

@@ -0,0 +1,167 @@
package org.alfresco.repo.domain.solr;
import java.util.List;
import java.util.Set;
import org.alfresco.service.namespace.QName;
/**
* Stores node parameters for use in SOLR DAO queries
*
* @since 4.0
*/
public class NodeParameters
{
private List<Long> transactionIds;
private Long fromNodeId;
private Long toNodeId;
private String storeProtocol;
private String storeIdentifier;
private Set<QName> includeNodeTypes;
private Set<QName> excludeNodeTypes;
private List<Long> includeTypeIds;
private List<Long> excludeTypeIds;
private Set<QName> includeAspects;
private Set<QName> excludeAspects;
private List<Long> includeAspectIds;
private List<Long> excludeAspectIds;
public boolean getStoreFilter()
{
return (storeProtocol != null || storeIdentifier != null);
}
public void setStoreProtocol(String storeProtocol)
{
this.storeProtocol = storeProtocol;
}
public String getStoreProtocol()
{
return storeProtocol;
}
public void setStoreIdentifier(String storeIdentifier)
{
this.storeIdentifier = storeIdentifier;
}
public String getStoreIdentifier()
{
return storeIdentifier;
}
public void setTransactionIds(List<Long> txnIds)
{
this.transactionIds = txnIds;
}
public List<Long> getTransactionIds()
{
return transactionIds;
}
public Long getFromNodeId()
{
return fromNodeId;
}
public void setFromNodeId(Long fromNodeId)
{
this.fromNodeId = fromNodeId;
}
public Long getToNodeId()
{
return toNodeId;
}
public void setToNodeId(Long toNodeId)
{
this.toNodeId = toNodeId;
}
public Set<QName> getIncludeNodeTypes()
{
return includeNodeTypes;
}
public Set<QName> getExcludeNodeTypes()
{
return excludeNodeTypes;
}
public Set<QName> getIncludeAspects()
{
return includeAspects;
}
public Set<QName> getExcludeAspects()
{
return excludeAspects;
}
public void setIncludeNodeTypes(Set<QName> includeNodeTypes)
{
this.includeNodeTypes = includeNodeTypes;
}
public void setExcludeNodeTypes(Set<QName> excludeNodeTypes)
{
this.excludeNodeTypes = excludeNodeTypes;
}
public void setIncludeAspects(Set<QName> includeAspects)
{
this.includeAspects = includeAspects;
}
public void setExcludeAspects(Set<QName> excludeAspects)
{
this.excludeAspects = excludeAspects;
}
public List<Long> getIncludeAspectIds()
{
return includeAspectIds;
}
public void setIncludeAspectIds(List<Long> includeAspectIds)
{
this.includeAspectIds = includeAspectIds;
}
public List<Long> getExcludeAspectIds()
{
return excludeAspectIds;
}
public void setExcludeAspectIds(List<Long> excludeAspectIds)
{
this.excludeAspectIds = excludeAspectIds;
}
public List<Long> getIncludeTypeIds()
{
return includeTypeIds;
}
public void setIncludeTypeIds(List<Long> includeTypeIds)
{
this.includeTypeIds = includeTypeIds;
}
public List<Long> getExcludeTypeIds()
{
return excludeTypeIds;
}
public void setExcludeTypeIds(List<Long> excludeTypeIds)
{
this.excludeTypeIds = excludeTypeIds;
}
}

View File

@@ -0,0 +1,31 @@
package org.alfresco.repo.domain.solr;
import java.util.List;
import org.alfresco.repo.domain.node.Node;
/**
* DAO support for SOLR web scripts.
*
* @since 4.0
*/
// TODO - permit shortened form of QNames for e.g. aspects i.e. cm:content vs {http://www.alfresco.org/model/content/1.0}content?
public interface SOLRDAO
{
public List<Transaction> getTransactions(Long minTxnId, Long fromCommitTime, int maxResults);
public void getNodes(NodeParameters nodeParameters, int maxResults, NodeQueryCallback callback);
/**
* The interface that will be used to give query results to the calling code.
*/
public static interface NodeQueryCallback
{
/**
* Handle a node.
*
* @param node the node
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
*/
boolean handleNode(Node node);
}
}

View File

@@ -0,0 +1,250 @@
package org.alfresco.repo.domain.solr;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.solr.SOLRDAO.NodeQueryCallback;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.PropertyMap;
import org.springframework.context.ConfigurableApplicationContext;
public class SOLRDAOTest extends TestCase
{
private ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) ApplicationContextHelper.getApplicationContext();
private AuthenticationComponent authenticationComponent;
private TransactionService transactionService;
private RetryingTransactionHelper txnHelper;
private NodeService nodeService;
private FileFolderService fileFolderService;
private SOLRDAO solrDAO;
private StoreRef storeRef;
private NodeRef rootNodeRef;
private NodeRef container1;
private NodeRef content1;
private NodeRef content2;
@Override
public void setUp() throws Exception
{
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
transactionService = serviceRegistry.getTransactionService();
txnHelper = transactionService.getRetryingTransactionHelper();
solrDAO = (SOLRDAO)ctx.getBean("solrDAO");
nodeService = (NodeService)ctx.getBean("NodeService");
fileFolderService = (FileFolderService)ctx.getBean("FileFolderService");
authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
}
private void buildTransactions1()
{
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
PropertyMap props = new PropertyMap();
props.put(ContentModel.PROP_NAME, "Container1");
container1 = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_FOLDER,
props).getChildRef();
System.out.println("container1 = " + container1);
FileInfo content1Info = fileFolderService.create(container1, "Content1", ContentModel.TYPE_CONTENT);
content1 = content1Info.getNodeRef();
System.out.println("content1 = " + content1);
return null;
}
});
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
FileInfo content2Info = fileFolderService.create(container1, "Content2", ContentModel.TYPE_CONTENT);
content2 = content2Info.getNodeRef();
System.out.println("content2 = " + content2);
fileFolderService.delete(content1);
return null;
}
});
}
private void buildTransactions2()
{
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
PropertyMap props = new PropertyMap();
props.put(ContentModel.PROP_NAME, "Container1");
container1 = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_FOLDER,
props).getChildRef();
System.out.println("container1 = " + container1);
FileInfo content1Info = fileFolderService.create(container1, "Content1", ContentModel.TYPE_CONTENT);
content1 = content1Info.getNodeRef();
System.out.println("content1 = " + content1);
return null;
}
});
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
FileInfo content2Info = fileFolderService.create(container1, "Content2", ContentModel.TYPE_CONTENT);
content2 = content2Info.getNodeRef();
System.out.println("content2 = " + content2);
fileFolderService.delete(content1);
return null;
}
});
}
public void testQueryTransactions1()
{
long startTime = System.currentTimeMillis();
buildTransactions1();
List<Transaction> txns = solrDAO.getTransactions(null, startTime, 0);
assertEquals("Number of transactions is incorrect", 2, txns.size());
int[] updates = new int[] {1, 1};
int[] deletes = new int[] {0, 1};
List<Long> txnIds = new ArrayList<Long>(txns.size());
int i = 0;
for(Transaction txn : txns)
{
assertEquals("Number of deletes is incorrect", deletes[i], txn.getDeletes());
assertEquals("Number of updates is incorrect", updates[i], txn.getUpdates());
i++;
txnIds.add(txn.getId());
}
TestNodeQueryCallback nodeQueryCallback = new TestNodeQueryCallback(container1, content1, content2);
NodeParameters nodeParameters = new NodeParameters();
nodeParameters.setTransactionIds(txnIds);
solrDAO.getNodes(nodeParameters, 0, nodeQueryCallback);
assertEquals("Unxpected nodes", 3, nodeQueryCallback.getSuccessCount());
}
public void testQueryTransactions2()
{
long startTime = System.currentTimeMillis();
buildTransactions2();
List<Transaction> txns = solrDAO.getTransactions(null, startTime, 0);
assertEquals("Number of transactions is incorrect", 2, txns.size());
int[] updates = new int[] {1, 1};
int[] deletes = new int[] {0, 1};
List<Long> txnIds = new ArrayList<Long>(txns.size());
int i = 0;
for(Transaction txn : txns)
{
assertEquals("Number of deletes is incorrect", deletes[i], txn.getDeletes());
assertEquals("Number of updates is incorrect", updates[i], txn.getUpdates());
i++;
txnIds.add(txn.getId());
}
TestNodeQueryCallback nodeQueryCallback = new TestNodeQueryCallback(container1, content1, content2);
NodeParameters nodeParameters = new NodeParameters();
nodeParameters.setTransactionIds(txnIds);
solrDAO.getNodes(nodeParameters, 0, nodeQueryCallback);
assertEquals("Unxpected nodes", 3, nodeQueryCallback.getSuccessCount());
}
private static class TestNodeQueryCallback implements NodeQueryCallback
{
private int successCount = 0;
private NodeRef container1;
private NodeRef content1;
private NodeRef content2;
public TestNodeQueryCallback(NodeRef container1,
NodeRef content1, NodeRef content2) {
super();
this.container1 = container1;
this.content1 = content1;
this.content2 = content2;
}
@Override
public boolean handleNode(Node node) {
NodeRef nodeRef = node.getNodeRef();
Boolean isDeleted = node.getDeleted();
System.out.println("Node: " + node.toString());
if(nodeRef.equals(container1) && !isDeleted)
{
successCount++;
}
if(nodeRef.equals(content1) && isDeleted)
{
successCount++;
}
if(nodeRef.equals(content2) && !isDeleted)
{
successCount++;
}
return true;
}
public int getSuccessCount()
{
return successCount;
}
}
}

View File

@@ -0,0 +1,14 @@
package org.alfresco.repo.domain.solr;
/**
* Interface for SOLR transaction objects.
*
* @since 4.0
*/
public interface SOLRTransaction
{
public Long getId();
public Long getCommitTimeMs();
public int getUpdates();
public int getDeletes();
}

View File

@@ -0,0 +1,76 @@
package org.alfresco.repo.domain.solr;
import java.util.Date;
import java.util.List;
/**
* Holds parameters for SOLR DAO calls
*
* @since 4.0
*/
public class SOLRTransactionParameters {
private Long minTxnId;
private Long txnFromCommitTime;
private List<Long> transactionIds;
private Long fromNodeId;
private Long toNodeId;
public SOLRTransactionParameters()
{
}
public void setMinTxnId(Long minTxnId)
{
this.minTxnId = minTxnId;
}
public Long getMinTxnId()
{
return minTxnId;
}
public void setTxnFromCommitTime(Long txnFromCommitTime) {
this.txnFromCommitTime = txnFromCommitTime;
}
public Long getTxnFromCommitTime() {
return txnFromCommitTime;
}
public void setTransactionIds(List<Long> txnIds) {
this.transactionIds = txnIds;
}
public List<Long> getTransactionIds() {
return transactionIds;
}
public Long getFromNodeId() {
return fromNodeId;
}
public void setFromNodeId(Long fromNodeId) {
this.fromNodeId = fromNodeId;
}
public Long getToNodeId() {
return toNodeId;
}
public void setToNodeId(Long toNodeId) {
this.toNodeId = toNodeId;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(512);
sb.append("SOLRTransactionParameters")
.append(", txnFromCommitTime").append(txnFromCommitTime == null ? null : new Date(txnFromCommitTime))
.append(", fromNodeId").append(fromNodeId == null ? null : fromNodeId)
.append(", toNodeId").append(toNodeId == null ? null : toNodeId)
.append(", txnIds").append(transactionIds == null ? null : transactionIds.size())
.append("]");
return sb.toString();
}
}

View File

@@ -0,0 +1,14 @@
package org.alfresco.repo.domain.solr;
/**
* Interface for SOLR transaction objects.
*
* @since 4.0
*/
public interface Transaction
{
public Long getId();
public Long getCommitTimeMs();
public int getUpdates();
public int getDeletes();
}

View File

@@ -0,0 +1,75 @@
package org.alfresco.repo.domain.solr;
/**
* Bean to represent SOLR transaction data.
*
* @since 4.0
*/
public class TransactionEntity implements Transaction
{
private Long id;
private Long commitTimeMs;
private int updates;
private int deletes;
/**
* Required default constructor
*/
public TransactionEntity()
{
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(512);
sb.append("TransactionEntity")
.append("[ ID=").append(id)
.append(", updates=").append(updates)
.append(", deletes=").append(deletes)
.append(", commitTimeMs=").append(commitTimeMs)
.append("]");
return sb.toString();
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public int getUpdates()
{
return updates;
}
public void setUpdates(int updates)
{
this.updates = updates;
}
public int getDeletes()
{
return deletes;
}
public void setDeletes(int deletes)
{
this.deletes = deletes;
}
public Long getCommitTimeMs()
{
return commitTimeMs;
}
public void setCommitTimeMs(Long commitTimeMs)
{
this.commitTimeMs = commitTimeMs;
}
}

View File

@@ -0,0 +1,147 @@
package org.alfresco.repo.domain.solr.ibatis;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeEntity;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.domain.solr.NodeParameters;
import org.alfresco.repo.domain.solr.SOLRDAO;
import org.alfresco.repo.domain.solr.SOLRTransactionParameters;
import org.alfresco.repo.domain.solr.Transaction;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
/**
* DAO support for SOLR web scripts.
*
* @since 4.0
*/
public class SOLRDAOImpl implements SOLRDAO
{
private static final String SELECT_TRANSACTIONS = "alfresco.solr.select_Txns";
private static final String SELECT_NODES = "alfresco.solr.select_Txn_Nodes";
private QNameDAO qnameDAO;
private SqlMapClientTemplate template;
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate)
{
this.template = sqlMapClientTemplate;
}
public SqlMapClientTemplate getSqlMapClientTemplate()
{
return this.template;
}
public void setQNameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
/*
* Initialize
*/
public void init()
{
}
@SuppressWarnings("unchecked")
public List<Transaction> getTransactions(Long minTxnId, Long fromCommitTime, int maxResults)
{
if(minTxnId == null && fromCommitTime == null && (maxResults == 0 || maxResults == Integer.MAX_VALUE))
{
throw new IllegalArgumentException("Must specify at least one parameter");
}
List<Transaction> txns = null;
SOLRTransactionParameters params = new SOLRTransactionParameters();
params.setMinTxnId(minTxnId);
params.setTxnFromCommitTime(fromCommitTime);
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
{
txns = (List<Transaction>)template.queryForList(SELECT_TRANSACTIONS, params, 0, maxResults);
}
else
{
txns = (List<Transaction>)template.queryForList(SELECT_TRANSACTIONS, params);
}
return txns;
}
@SuppressWarnings("unchecked")
// TODO should create qnames if don't exist?
public void getNodes(NodeParameters nodeParameters, int maxResults, NodeQueryCallback callback)
{
List<NodeEntity> nodes = null;
NodeQueryRowHandler rowHandler = new NodeQueryRowHandler(callback);
if(nodeParameters.getIncludeTypeIds() == null && nodeParameters.getIncludeNodeTypes() != null)
{
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getIncludeNodeTypes(), false);
nodeParameters.setIncludeTypeIds(new ArrayList<Long>(qnamesIds));
}
if(nodeParameters.getExcludeTypeIds() == null && nodeParameters.getExcludeNodeTypes() != null)
{
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getExcludeNodeTypes(), false);
nodeParameters.setExcludeTypeIds(new ArrayList<Long>(qnamesIds));
}
if(nodeParameters.getExcludeAspectIds() == null && nodeParameters.getExcludeAspects() != null)
{
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getExcludeAspects(), false);
nodeParameters.setExcludeAspectIds(new ArrayList<Long>(qnamesIds));
}
if(nodeParameters.getIncludeAspectIds() == null && nodeParameters.getIncludeAspects() != null)
{
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getIncludeAspects(), false);
nodeParameters.setIncludeAspectIds(new ArrayList<Long>(qnamesIds));
}
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
{
nodes = (List<NodeEntity>)template.queryForList(SELECT_NODES, nodeParameters, 0, maxResults);
}
else
{
nodes = (List<NodeEntity>)template.queryForList(SELECT_NODES, nodeParameters);
}
for(NodeEntity node : nodes)
{
rowHandler.processResult(node);
}
}
/**
* Class that passes results from a result entity into the client callback
*/
protected class NodeQueryRowHandler
{
private final NodeQueryCallback callback;
private boolean more;
private NodeQueryRowHandler(NodeQueryCallback callback)
{
this.callback = callback;
this.more = true;
}
public void processResult(Node row)
{
if (!more)
{
// No more results required
return;
}
more = callback.handleNode(row);
}
}
}