Merged DEV/SWIFT to HEAD

27168: Added generics for cannedQueryRegistry
   27169: Fixed formatting
   27170: SOLR queries
          - ALF-7072 RSOLR 013: Remote API to get ACLs and readers
            - Queries for ACL ChangeSets and ACLs
            - WebScripts for AclChangeSetsGet
          - ALF-7071 and ALF-7072: Fix naming conventions
   27171: Fixed MySQL create script (ALF-8336: RSOLR 013: DB upgrade scripts for ACL changes)
   27337: Initial draft of the publishing API
   27516: Get the basic WCM ML tests working, covering the simpler use cases
   27517: More on the WCM-QS multi lingual support, further on the aspect and the unit tests for it
   27518: Begin the WCM-QS webscript to return the translation details on a node
   27519: Push some WCM-QS ML search logic into SiteHelper, and add a unit test for it
   27542: - Initial skeleton of the channel API.
          - Initial draft of the publishing content model.
   27546: ALF-7481: RSOLR 018: Execute query against SOLR
          - pass authority filter in json body to avoid possible issue over-running the max URL length
   27559: Created a Web Site Generator tool which randomly generates WCM QS websites.
   27561: Created ChannelServiceImpl and implemented the ChannelType registry.
   27577: Start to pull across the WCM-QS ML custom action
   27579: More pulling across the WCM-QS ML custom action
   27580: More WCM-QS ML ui porting
   27588: ALF-8421: RSOLR 037: Encapsulate the CMIS Query Parser
   27589: Created a PublishingModel to hold Web Publishing constants.
   27610: ALF-7874 Add iWorks mimetype entries
   27624: Restructure index tracking
   27630: ALF-8182: SVC 03: Object Picker needs to use new NodeLocatorService to resolve startLocation parameter
          The picker now uses the NodeLocatorService to look up some start locations and most importantly allows
		  custom 'locators' to be used. All the current start location tokens are still supported
		  i.e. {companyhome}, {userhome}, {siteshome}, {doclib}, {self} and {parent}. A new one has been added called {ancestor},
		  this will allow an ancestor node to be located, the node can be selected by type or aspect, see example below.
          Some node locators can take parameters, a "startLocationParams" has therefore been added to allow these to be specified.

		  The example below shows how to configure a picker to start in the root folder of the site the node being edited is located within.

		  <field id="fdk:contentMultiple">
             <control>
                <control-param name="startLocation">{ancestor}</control-param>
                <control-param name="startLocationParams">type=st:site</control-param>
             </control>
          </field>
   27631: ALF-8182: SVC 03: Object Picker needs to use new NodeLocatorService to resolve startLocation parameter
          Centralised node locator classes to repo.nodelocator package
		  (moved out of repo.node package as that area is reserved for low level node processing)
		  and made all naming consistent i.e. nodelocator rather than nodelocation.
   27633: Fixed cmis:objectTypeId property definition (required = true, see CMIS 1.0 errata 1)
   27635: CMIS compliance fixes
   27638: - Initial operational publishing context with model bootstrapped.
          - First implementation of ChannelService.getChannels and ChannelService.createChannel. Test cases to follow imminently...

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28301 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-06-09 12:08:12 +00:00
parent c47ecc4208
commit 2af7da2c23
23 changed files with 1033 additions and 981 deletions

View File

@@ -1,74 +1,71 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.domain.solr.SOLRDAO;
import org.alfresco.repo.domain.solr.Transaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Track ACL Change Sets
*
* @since 4.0
*/
public class GetAclChangeSets extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(GetAclChangeSets.class);
private SOLRDAO solrDAO;
/**
* @param solrDAO the SOLDAO to set
*/
public void setSolrDAO(SOLRDAO solrDAO)
{
this.solrDAO = solrDAO;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
String minAclChangeSetIdParam = req.getParameter("minAclChangeSetId");
String fromCommitTimeParam = req.getParameter("fromCommitTime");
String maxResultsParam = req.getParameter("maxResults");
Long minAclChangeSetId = (minAclChangeSetIdParam == null ? null : Long.valueOf(minAclChangeSetIdParam));
Long fromCommitTime = (fromCommitTimeParam == null ? null : Long.valueOf(fromCommitTimeParam));
int maxResults = (maxResultsParam == null ? 0 : Integer.valueOf(maxResultsParam));
List<Transaction> transactions = solrDAO.getTransactions(minAclChangeSetId, fromCommitTime, maxResults);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("transactions", transactions);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.solr.AclChangeSet;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Track ACL Change Sets
*
* @since 4.0
*/
public class AclChangeSetsGet extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(AclChangeSetsGet.class);
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
String fromIdParam = req.getParameter("fromId");
String fromTimeParam = req.getParameter("fromTime");
String maxResultsParam = req.getParameter("maxResults");
Long fromId = (fromIdParam == null ? null : Long.valueOf(fromIdParam));
Long fromTime = (fromTimeParam == null ? null : Long.valueOf(fromTimeParam));
int maxResults = (maxResultsParam == null ? 1024 : Integer.valueOf(maxResultsParam));
List<AclChangeSet> changesets = solrTrackingComponent.getAclChangeSets(fromId, fromTime, maxResults);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("aclChangeSets", changesets);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -1,201 +1,201 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.web.scripts.content.StreamContent;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* A web service to return the text content (transformed if required) of a node's
* content property.
*
* @since 4.0
*/
public class GetNodeContent extends StreamContent
{
private static final String TRANSFORM_STATUS_HEADER = "X-Alfresco-transformStatus";
private static final String TRANSFORM_EXCEPTION_HEADER = "X-Alfresco-transformException";
private static final Log logger = LogFactory.getLog(GetNodeContent.class);
/**
* format definied by RFC 822, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
*/
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
private NodeDAO nodeDAO;
private NodeService nodeService;
private ContentService contentService;
public void setNodeDAO(NodeDAO nodeDAO)
{
this.nodeDAO = nodeDAO;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @in
*/
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
ContentReader textReader = null;
Exception transformException = null;
String nodeIDString = req.getParameter("nodeId");
if(nodeIDString == null)
{
throw new WebScriptException("nodeID parameter is required for GetNodeContent");
}
long nodeId = Long.valueOf(nodeIDString).longValue();
String propertyQName = req.getParameter("propertyQName");
QName propertyName = null;
if(propertyQName == null)
{
propertyName = ContentModel.PROP_CONTENT;
}
else
{
propertyName = QName.createQName(propertyQName);
}
Pair<Long, NodeRef> pair = nodeDAO.getNodePair(nodeId);
if(pair == null)
{
throw new WebScriptException("Node id does not exist");
}
NodeRef nodeRef = pair.getSecond();
// check If-Modified-Since header and set Last-Modified header as appropriate
Date modified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
long modifiedSince = -1;
String modifiedSinceStr = req.getHeader("If-Modified-Since");
if(modifiedSinceStr != null)
{
try
{
modifiedSince = dateFormat.parse(modifiedSinceStr).getTime();
}
catch (Throwable e)
{
if (logger.isWarnEnabled())
{
logger.warn("Browser sent badly-formatted If-Modified-Since header: " + modifiedSinceStr);
}
}
if (modifiedSince > 0L)
{
// round the date to the ignore millisecond value which is not supplied by header
long modDate = (modified.getTime() / 1000L) * 1000L;
if (modDate <= modifiedSince)
{
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}
}
ContentReader reader = contentService.getReader(nodeRef, propertyName);
if(reader == null)
{
res.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
// Perform transformation catering for mimetype AND encoding
ContentWriter writer = contentService.getTempWriter();
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8"); // Expect transformers to produce UTF-8
ContentTransformer transformer = contentService.getTransformer(reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN);
if(transformer == null)
{
res.setHeader(TRANSFORM_STATUS_HEADER, "noTransform");
res.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
try
{
transformer.transform(reader, writer);
}
catch (ContentIOException e)
{
transformException = e;
}
if(transformException == null)
{
// point the reader to the new-written content
textReader = writer.getReader();
// Check that the reader is a view onto something concrete
if (textReader == null || !textReader.exists())
{
transformException = new ContentIOException(
"The transformation did not write any content, yet: \n"
+ " transformer: " + transformer + "\n" + " temp writer: " + writer);
}
}
if(transformException != null)
{
res.setHeader(TRANSFORM_STATUS_HEADER, "transformFailed");
res.setHeader(TRANSFORM_EXCEPTION_HEADER, transformException.getMessage());
res.setStatus(HttpStatus.SC_NO_CONTENT);
}
else
{
res.setStatus(HttpStatus.SC_OK);
streamContentImpl(req, res, textReader, false, modified, String.valueOf(modified.getTime()), null);
}
}
}
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.web.scripts.content.StreamContent;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* A web service to return the text content (transformed if required) of a node's
* content property.
*
* @since 4.0
*/
public class NodeContentGet extends StreamContent
{
private static final String TRANSFORM_STATUS_HEADER = "X-Alfresco-transformStatus";
private static final String TRANSFORM_EXCEPTION_HEADER = "X-Alfresco-transformException";
private static final Log logger = LogFactory.getLog(NodeContentGet.class);
/**
* format definied by RFC 822, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
*/
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
private NodeDAO nodeDAO;
private NodeService nodeService;
private ContentService contentService;
public void setNodeDAO(NodeDAO nodeDAO)
{
this.nodeDAO = nodeDAO;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @in
*/
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
ContentReader textReader = null;
Exception transformException = null;
String nodeIDString = req.getParameter("nodeId");
if(nodeIDString == null)
{
throw new WebScriptException("nodeID parameter is required for GetNodeContent");
}
long nodeId = Long.valueOf(nodeIDString).longValue();
String propertyQName = req.getParameter("propertyQName");
QName propertyName = null;
if(propertyQName == null)
{
propertyName = ContentModel.PROP_CONTENT;
}
else
{
propertyName = QName.createQName(propertyQName);
}
Pair<Long, NodeRef> pair = nodeDAO.getNodePair(nodeId);
if(pair == null)
{
throw new WebScriptException("Node id does not exist");
}
NodeRef nodeRef = pair.getSecond();
// check If-Modified-Since header and set Last-Modified header as appropriate
Date modified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
long modifiedSince = -1;
String modifiedSinceStr = req.getHeader("If-Modified-Since");
if(modifiedSinceStr != null)
{
try
{
modifiedSince = dateFormat.parse(modifiedSinceStr).getTime();
}
catch (Throwable e)
{
if (logger.isWarnEnabled())
{
logger.warn("Browser sent badly-formatted If-Modified-Since header: " + modifiedSinceStr);
}
}
if (modifiedSince > 0L)
{
// round the date to the ignore millisecond value which is not supplied by header
long modDate = (modified.getTime() / 1000L) * 1000L;
if (modDate <= modifiedSince)
{
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}
}
ContentReader reader = contentService.getReader(nodeRef, propertyName);
if(reader == null)
{
res.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
// Perform transformation catering for mimetype AND encoding
ContentWriter writer = contentService.getTempWriter();
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8"); // Expect transformers to produce UTF-8
ContentTransformer transformer = contentService.getTransformer(reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN);
if(transformer == null)
{
res.setHeader(TRANSFORM_STATUS_HEADER, "noTransform");
res.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
try
{
transformer.transform(reader, writer);
}
catch (ContentIOException e)
{
transformException = e;
}
if(transformException == null)
{
// point the reader to the new-written content
textReader = writer.getReader();
// Check that the reader is a view onto something concrete
if (textReader == null || !textReader.exists())
{
transformException = new ContentIOException(
"The transformation did not write any content, yet: \n"
+ " transformer: " + transformer + "\n" + " temp writer: " + writer);
}
}
if(transformException != null)
{
res.setHeader(TRANSFORM_STATUS_HEADER, "transformFailed");
res.setHeader(TRANSFORM_EXCEPTION_HEADER, transformException.getMessage());
res.setStatus(HttpStatus.SC_NO_CONTENT);
}
else
{
res.setStatus(HttpStatus.SC_OK);
streamContentImpl(req, res, textReader, false, modified, String.valueOf(modified.getTime()), null);
}
}
}

View File

@@ -1,208 +1,208 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.solr.NodeParameters;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.repo.solr.SOLRTrackingComponent.NodeQueryCallback;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Get a list of nodes in the given transactions.
* <p/>
* Supports fromNodeId, toNodeId, count (all optional) to control the number of nodes returned<br/>
* e.g. (null, null, 1000) will return at most 1000 nodes starting from the first node in the first transaction.<br/>
* e.g. (1234, null, 1000) will return at most 1000 nodes starting from the node id 1234.<br/>
*
* @since 4.0
*/
public class GetNodes extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(GetNodes.class);
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
JSONArray aTxnIds = o.has("txnIds") ? o.getJSONArray("txnIds") : null;
Long fromTxnId = o.has("fromTxnId") ? o.getLong("fromTxnId") : null;
Long toTxnId = o.has("toTxnId") ? o.getLong("toTxnId") : null;
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
Set<QName> excludeAspects = null;
if(o.has("excludeAspects"))
{
JSONArray aExcludeAspects = o.getJSONArray("excludeAspects");
excludeAspects = new HashSet<QName>(aExcludeAspects.length());
for(int i = 0; i < aExcludeAspects.length(); i++)
{
excludeAspects.add(QName.createQName(aExcludeAspects.getString(i).trim()));
}
}
Set<QName> includeAspects = null;
if(o.has("includeAspects"))
{
JSONArray aIncludeAspects = o.getJSONArray("includeAspects");
includeAspects = new HashSet<QName>(aIncludeAspects.length());
for(int i = 0; i < aIncludeAspects.length(); i++)
{
includeAspects.add(QName.createQName(aIncludeAspects.getString(i).trim()));
}
}
Set<QName> excludeNodeTypes = null;
if(o.has("excludeNodeTypes"))
{
JSONArray aExcludeNodeTypes = o.getJSONArray("excludeNodeTypes");
excludeNodeTypes = new HashSet<QName>(aExcludeNodeTypes.length());
for(int i = 0; i < aExcludeNodeTypes.length(); i++)
{
excludeNodeTypes.add(QName.createQName(aExcludeNodeTypes.getString(i).trim()));
}
}
Set<QName> includeNodeTypes = null;
if(o.has("includeNodeTypes"))
{
JSONArray aIncludeNodeTypes = o.getJSONArray("includeNodeTypes");
includeNodeTypes = new HashSet<QName>(aIncludeNodeTypes.length());
for(int i = 0; i < aIncludeNodeTypes.length(); i++)
{
includeNodeTypes.add(QName.createQName(aIncludeNodeTypes.getString(i).trim()));
}
}
// 0 or Integer.MAX_VALUE => ignore
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
String storeProtocol = o.has("storeProtocol") ? o.getString("storeProtocol") : null;
String storeIdentifier = o.has("storeIdentifier") ? o.getString("storeIdentifier") : null;
List<Long> txnIds = null;
if(aTxnIds != null)
{
txnIds = new ArrayList<Long>(aTxnIds.length());
for(int i = 0; i < aTxnIds.length(); i++)
{
txnIds.add(aTxnIds.getLong(i));
}
}
WebNodeQueryCallback nodeQueryCallback = new WebNodeQueryCallback(maxResults);
NodeParameters nodeParameters = new NodeParameters();
nodeParameters.setTransactionIds(txnIds);
nodeParameters.setFromTxnId(fromTxnId);
nodeParameters.setToTxnId(toTxnId);
nodeParameters.setFromNodeId(fromNodeId);
nodeParameters.setToNodeId(toNodeId);
nodeParameters.setExcludeAspects(excludeAspects);
nodeParameters.setIncludeAspects(includeAspects);
nodeParameters.setExcludeNodeTypes(excludeNodeTypes);
nodeParameters.setIncludeNodeTypes(includeNodeTypes);
nodeParameters.setStoreProtocol(storeProtocol);
nodeParameters.setStoreIdentifier(storeIdentifier);
nodeParameters.setMaxResults(maxResults);
solrTrackingComponent.getNodes(nodeParameters, nodeQueryCallback);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
List<Node> nodes = nodeQueryCallback.getNodes();
model.put("nodes", nodes);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
/**
* Callback for DAO get nodes query
*
*/
private static class WebNodeQueryCallback implements NodeQueryCallback
{
private ArrayList<Node> nodes;
public WebNodeQueryCallback(int count) {
super();
nodes = new ArrayList<Node>(count == 0 || count == Integer.MAX_VALUE ? 100 : count);
}
@Override
public boolean handleNode(Node node) {
nodes.add(node);
// continue - get next node
return true;
}
public List<Node> getNodes()
{
return nodes;
}
}
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.solr.NodeParameters;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.repo.solr.SOLRTrackingComponent.NodeQueryCallback;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Get a list of nodes in the given transactions.
* <p/>
* Supports fromNodeId, toNodeId, count (all optional) to control the number of nodes returned<br/>
* e.g. (null, null, 1000) will return at most 1000 nodes starting from the first node in the first transaction.<br/>
* e.g. (1234, null, 1000) will return at most 1000 nodes starting from the node id 1234.<br/>
*
* @since 4.0
*/
public class NodesGet extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(NodesGet.class);
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
JSONArray aTxnIds = o.has("txnIds") ? o.getJSONArray("txnIds") : null;
Long fromTxnId = o.has("fromTxnId") ? o.getLong("fromTxnId") : null;
Long toTxnId = o.has("toTxnId") ? o.getLong("toTxnId") : null;
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
Set<QName> excludeAspects = null;
if(o.has("excludeAspects"))
{
JSONArray aExcludeAspects = o.getJSONArray("excludeAspects");
excludeAspects = new HashSet<QName>(aExcludeAspects.length());
for(int i = 0; i < aExcludeAspects.length(); i++)
{
excludeAspects.add(QName.createQName(aExcludeAspects.getString(i).trim()));
}
}
Set<QName> includeAspects = null;
if(o.has("includeAspects"))
{
JSONArray aIncludeAspects = o.getJSONArray("includeAspects");
includeAspects = new HashSet<QName>(aIncludeAspects.length());
for(int i = 0; i < aIncludeAspects.length(); i++)
{
includeAspects.add(QName.createQName(aIncludeAspects.getString(i).trim()));
}
}
Set<QName> excludeNodeTypes = null;
if(o.has("excludeNodeTypes"))
{
JSONArray aExcludeNodeTypes = o.getJSONArray("excludeNodeTypes");
excludeNodeTypes = new HashSet<QName>(aExcludeNodeTypes.length());
for(int i = 0; i < aExcludeNodeTypes.length(); i++)
{
excludeNodeTypes.add(QName.createQName(aExcludeNodeTypes.getString(i).trim()));
}
}
Set<QName> includeNodeTypes = null;
if(o.has("includeNodeTypes"))
{
JSONArray aIncludeNodeTypes = o.getJSONArray("includeNodeTypes");
includeNodeTypes = new HashSet<QName>(aIncludeNodeTypes.length());
for(int i = 0; i < aIncludeNodeTypes.length(); i++)
{
includeNodeTypes.add(QName.createQName(aIncludeNodeTypes.getString(i).trim()));
}
}
// 0 or Integer.MAX_VALUE => ignore
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
String storeProtocol = o.has("storeProtocol") ? o.getString("storeProtocol") : null;
String storeIdentifier = o.has("storeIdentifier") ? o.getString("storeIdentifier") : null;
List<Long> txnIds = null;
if(aTxnIds != null)
{
txnIds = new ArrayList<Long>(aTxnIds.length());
for(int i = 0; i < aTxnIds.length(); i++)
{
txnIds.add(aTxnIds.getLong(i));
}
}
WebNodeQueryCallback nodeQueryCallback = new WebNodeQueryCallback(maxResults);
NodeParameters nodeParameters = new NodeParameters();
nodeParameters.setTransactionIds(txnIds);
nodeParameters.setFromTxnId(fromTxnId);
nodeParameters.setToTxnId(toTxnId);
nodeParameters.setFromNodeId(fromNodeId);
nodeParameters.setToNodeId(toNodeId);
nodeParameters.setExcludeAspects(excludeAspects);
nodeParameters.setIncludeAspects(includeAspects);
nodeParameters.setExcludeNodeTypes(excludeNodeTypes);
nodeParameters.setIncludeNodeTypes(includeNodeTypes);
nodeParameters.setStoreProtocol(storeProtocol);
nodeParameters.setStoreIdentifier(storeIdentifier);
nodeParameters.setMaxResults(maxResults);
solrTrackingComponent.getNodes(nodeParameters, nodeQueryCallback);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
List<Node> nodes = nodeQueryCallback.getNodes();
model.put("nodes", nodes);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
/**
* Callback for DAO get nodes query
*
*/
private static class WebNodeQueryCallback implements NodeQueryCallback
{
private ArrayList<Node> nodes;
public WebNodeQueryCallback(int count) {
super();
nodes = new ArrayList<Node>(count == 0 || count == Integer.MAX_VALUE ? 100 : count);
}
@Override
public boolean handleNode(Node node) {
nodes.add(node);
// continue - get next node
return true;
}
public List<Node> getNodes()
{
return nodes;
}
}
}

View File

@@ -1,334 +1,334 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.solr.MetaDataResultsFilter;
import org.alfresco.repo.solr.NodeMetaData;
import org.alfresco.repo.solr.NodeMetaDataParameters;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.repo.solr.SOLRTrackingComponent.NodeMetaDataQueryCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
// todo url parameter to remove whitespace in results - make it the default?
/**
* Support for SOLR: Get metadata for nodes given IDs, ranges of IDs, etc.
* <p/>
*
* @since 4.0
*/
public class GetNodesMetaData extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(GetNodesMetaData.class);
private static final int INITIAL_DEFAULT_SIZE = 100;
private static final int BATCH_SIZE = 50;
private SOLRTrackingComponent solrTrackingComponent;
private SOLRSerializer solrSerializer;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
public void setSolrSerializer(SOLRSerializer solrSerializer)
{
this.solrSerializer = solrSerializer;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
List<Long> nodeIds = null;
if(o.has("nodeIds"))
{
JSONArray jsonNodeIds = o.getJSONArray("nodeIds");
nodeIds = new ArrayList<Long>(jsonNodeIds.length());
for(int i = 0; i < jsonNodeIds.length(); i++)
{
Long nodeId = jsonNodeIds.getLong(i);
nodeIds.add(nodeId);
}
}
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
// 0 or Integer.MAX_VALUE => ignore
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
int size = 0;
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
{
size = maxResults;
}
else if(nodeIds != null)
{
size = nodeIds.size();
}
else if(fromNodeId != null && toNodeId != null)
{
if((toNodeId.longValue() - fromNodeId.longValue()) > Integer.MAX_VALUE)
{
throw new WebScriptException("Too many nodes expected, try changing the criteria");
}
size = (int)(toNodeId - fromNodeId);
}
final boolean noSizeCalculated = (size == 0);
// filters, defaults are 'true'
MetaDataResultsFilter filter = new MetaDataResultsFilter();
if(o.has("includeAclId"))
{
filter.setIncludeAclId(o.getBoolean("includeAclId"));
}
if(o.has("includeAspects"))
{
filter.setIncludeAspects(o.getBoolean("includeAspects"));
}
if(o.has("includeNodeRef"))
{
filter.setIncludeNodeRef(o.getBoolean("includeNodeRef"));
}
if(o.has("includeOwner"))
{
filter.setIncludeOwner(o.getBoolean("includeOwner"));
}
if(o.has("includeProperties"))
{
filter.setIncludeProperties(o.getBoolean("includeProperties"));
}
if(o.has("includePaths"))
{
filter.setIncludePaths(o.getBoolean("includePaths"));
}
if(o.has("includeType"))
{
filter.setIncludeType(o.getBoolean("includeType"));
}
if(o.has("includeAssociations"))
{
filter.setIncludeAssociations(o.getBoolean("includeAssociations"));
}
final ArrayList<FreemarkerNodeMetaData> nodesMetaData =
new ArrayList<FreemarkerNodeMetaData>(size > 0 ? size : INITIAL_DEFAULT_SIZE);
NodeMetaDataParameters params = new NodeMetaDataParameters();
params.setNodeIds(nodeIds);
params.setFromNodeId(fromNodeId);
params.setToNodeId(toNodeId);
params.setMaxResults(maxResults);
solrTrackingComponent.getNodesMetadata(params, filter, new NodeMetaDataQueryCallback()
{
private int counter = BATCH_SIZE;
private int numBatches = 0;
@Override
public boolean handleNodeMetaData(NodeMetaData nodeMetaData)
{
// need to perform data structure conversions that are compatible with Freemarker
// e.g. Serializable -> String, QName -> String (because map keys must be string, number)
try
{
FreemarkerNodeMetaData fNodeMetaData = new FreemarkerNodeMetaData(solrSerializer, nodeMetaData);
nodesMetaData.add(fNodeMetaData);
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("Problem converting to Freemarker", e);
}
if(noSizeCalculated && --counter == 0)
{
counter = BATCH_SIZE;
nodesMetaData.ensureCapacity(++numBatches*BATCH_SIZE);
}
return true;
}
});
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("nodes", nodesMetaData);
model.put("filter", filter);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
/**
* Bean to store node meta data for use by FreeMarker templates
*
* @since 4.0
*/
public static class FreemarkerNodeMetaData
{
private Long nodeId;
private NodeRef nodeRef;
private QName nodeType;
private Long aclId;
private Map<String, PropertyValue> properties;
private Set<QName> aspects;
private List<String> paths;
private List<ChildAssociationRef> childAssocs;
public FreemarkerNodeMetaData(SOLRSerializer solrSerializer, NodeMetaData nodeMetaData) throws IOException, JSONException
{
setNodeId(nodeMetaData.getNodeId());
setAclId(nodeMetaData.getAclId());
setNodeRef(nodeMetaData.getNodeRef());
setNodeType(nodeMetaData.getNodeType());
// convert Paths to Strings
List<String> paths = new ArrayList<String>();
for(Pair<Path, QName> pair : nodeMetaData.getPaths())
{
JSONObject o = new JSONObject();
o.put("path", solrSerializer.serializeValue(String.class, pair.getFirst()));
o.put("qname", solrSerializer.serializeValue(String.class, pair.getSecond()));
paths.add(o.toString(3));
}
setPaths(paths);
setChildAssocs(nodeMetaData.getChildAssocs());
setAspects(nodeMetaData.getAspects());
Map<QName, Serializable> props = nodeMetaData.getProperties();
Map<String, PropertyValue> properties = (props != null ? new HashMap<String, PropertyValue>(props.size()) : null);
for(QName propName : props.keySet())
{
Serializable value = props.get(propName);
properties.put(solrSerializer.serializeValue(String.class, propName),
solrSerializer.serialize(propName, value));
}
setProperties(properties);
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public List<String> getPaths()
{
return paths;
}
public void setPaths(List<String> paths)
{
this.paths = paths;
}
public QName getNodeType()
{
return nodeType;
}
public void setNodeType(QName nodeType)
{
this.nodeType = nodeType;
}
public Long getNodeId()
{
return nodeId;
}
public void setNodeId(Long nodeId)
{
this.nodeId = nodeId;
}
public Long getAclId()
{
return aclId;
}
public void setAclId(Long aclId)
{
this.aclId = aclId;
}
public Map<String, PropertyValue> getProperties()
{
return properties;
}
public void setProperties(Map<String, PropertyValue> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public List<ChildAssociationRef> getChildAssocs()
{
return childAssocs;
}
public void setChildAssocs(List<ChildAssociationRef> childAssocs)
{
this.childAssocs = childAssocs;
}
}
}
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.solr.MetaDataResultsFilter;
import org.alfresco.repo.solr.NodeMetaData;
import org.alfresco.repo.solr.NodeMetaDataParameters;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.repo.solr.SOLRTrackingComponent.NodeMetaDataQueryCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
// todo url parameter to remove whitespace in results - make it the default?
/**
* Support for SOLR: Get metadata for nodes given IDs, ranges of IDs, etc.
* <p/>
*
* @since 4.0
*/
public class NodesMetaDataGet extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(NodesMetaDataGet.class);
private static final int INITIAL_DEFAULT_SIZE = 100;
private static final int BATCH_SIZE = 50;
private SOLRTrackingComponent solrTrackingComponent;
private SOLRSerializer solrSerializer;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
public void setSolrSerializer(SOLRSerializer solrSerializer)
{
this.solrSerializer = solrSerializer;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
List<Long> nodeIds = null;
if(o.has("nodeIds"))
{
JSONArray jsonNodeIds = o.getJSONArray("nodeIds");
nodeIds = new ArrayList<Long>(jsonNodeIds.length());
for(int i = 0; i < jsonNodeIds.length(); i++)
{
Long nodeId = jsonNodeIds.getLong(i);
nodeIds.add(nodeId);
}
}
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
// 0 or Integer.MAX_VALUE => ignore
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
int size = 0;
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
{
size = maxResults;
}
else if(nodeIds != null)
{
size = nodeIds.size();
}
else if(fromNodeId != null && toNodeId != null)
{
if((toNodeId.longValue() - fromNodeId.longValue()) > Integer.MAX_VALUE)
{
throw new WebScriptException("Too many nodes expected, try changing the criteria");
}
size = (int)(toNodeId - fromNodeId);
}
final boolean noSizeCalculated = (size == 0);
// filters, defaults are 'true'
MetaDataResultsFilter filter = new MetaDataResultsFilter();
if(o.has("includeAclId"))
{
filter.setIncludeAclId(o.getBoolean("includeAclId"));
}
if(o.has("includeAspects"))
{
filter.setIncludeAspects(o.getBoolean("includeAspects"));
}
if(o.has("includeNodeRef"))
{
filter.setIncludeNodeRef(o.getBoolean("includeNodeRef"));
}
if(o.has("includeOwner"))
{
filter.setIncludeOwner(o.getBoolean("includeOwner"));
}
if(o.has("includeProperties"))
{
filter.setIncludeProperties(o.getBoolean("includeProperties"));
}
if(o.has("includePaths"))
{
filter.setIncludePaths(o.getBoolean("includePaths"));
}
if(o.has("includeType"))
{
filter.setIncludeType(o.getBoolean("includeType"));
}
if(o.has("includeAssociations"))
{
filter.setIncludeAssociations(o.getBoolean("includeAssociations"));
}
final ArrayList<FreemarkerNodeMetaData> nodesMetaData =
new ArrayList<FreemarkerNodeMetaData>(size > 0 ? size : INITIAL_DEFAULT_SIZE);
NodeMetaDataParameters params = new NodeMetaDataParameters();
params.setNodeIds(nodeIds);
params.setFromNodeId(fromNodeId);
params.setToNodeId(toNodeId);
params.setMaxResults(maxResults);
solrTrackingComponent.getNodesMetadata(params, filter, new NodeMetaDataQueryCallback()
{
private int counter = BATCH_SIZE;
private int numBatches = 0;
@Override
public boolean handleNodeMetaData(NodeMetaData nodeMetaData)
{
// need to perform data structure conversions that are compatible with Freemarker
// e.g. Serializable -> String, QName -> String (because map keys must be string, number)
try
{
FreemarkerNodeMetaData fNodeMetaData = new FreemarkerNodeMetaData(solrSerializer, nodeMetaData);
nodesMetaData.add(fNodeMetaData);
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("Problem converting to Freemarker", e);
}
if(noSizeCalculated && --counter == 0)
{
counter = BATCH_SIZE;
nodesMetaData.ensureCapacity(++numBatches*BATCH_SIZE);
}
return true;
}
});
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("nodes", nodesMetaData);
model.put("filter", filter);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
/**
* Bean to store node meta data for use by FreeMarker templates
*
* @since 4.0
*/
public static class FreemarkerNodeMetaData
{
private Long nodeId;
private NodeRef nodeRef;
private QName nodeType;
private Long aclId;
private Map<String, PropertyValue> properties;
private Set<QName> aspects;
private List<String> paths;
private List<ChildAssociationRef> childAssocs;
public FreemarkerNodeMetaData(SOLRSerializer solrSerializer, NodeMetaData nodeMetaData) throws IOException, JSONException
{
setNodeId(nodeMetaData.getNodeId());
setAclId(nodeMetaData.getAclId());
setNodeRef(nodeMetaData.getNodeRef());
setNodeType(nodeMetaData.getNodeType());
// convert Paths to Strings
List<String> paths = new ArrayList<String>();
for(Pair<Path, QName> pair : nodeMetaData.getPaths())
{
JSONObject o = new JSONObject();
o.put("path", solrSerializer.serializeValue(String.class, pair.getFirst()));
o.put("qname", solrSerializer.serializeValue(String.class, pair.getSecond()));
paths.add(o.toString(3));
}
setPaths(paths);
setChildAssocs(nodeMetaData.getChildAssocs());
setAspects(nodeMetaData.getAspects());
Map<QName, Serializable> props = nodeMetaData.getProperties();
Map<String, PropertyValue> properties = (props != null ? new HashMap<String, PropertyValue>(props.size()) : null);
for(QName propName : props.keySet())
{
Serializable value = props.get(propName);
properties.put(solrSerializer.serializeValue(String.class, propName),
solrSerializer.serialize(propName, value));
}
setProperties(properties);
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public List<String> getPaths()
{
return paths;
}
public void setPaths(List<String> paths)
{
this.paths = paths;
}
public QName getNodeType()
{
return nodeType;
}
public void setNodeType(QName nodeType)
{
this.nodeType = nodeType;
}
public Long getNodeId()
{
return nodeId;
}
public void setNodeId(Long nodeId)
{
this.nodeId = nodeId;
}
public Long getAclId()
{
return aclId;
}
public void setAclId(Long aclId)
{
this.aclId = aclId;
}
public Map<String, PropertyValue> getProperties()
{
return properties;
}
public void setProperties(Map<String, PropertyValue> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public List<ChildAssociationRef> getChildAssocs()
{
return childAssocs;
}
public void setChildAssocs(List<ChildAssociationRef> childAssocs)
{
this.childAssocs = childAssocs;
}
}
}

View File

@@ -23,11 +23,9 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.node.NodeDAO;
@@ -167,6 +165,25 @@ public class SOLRWebScriptTest extends BaseWebScriptTest
return transactions;
}
public void testAclChangeSetsGet() throws Exception
{
String url = "/api/solr/aclchangesets?fromTime=" + 0L + "&fromId=" + 0L;
TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url);
long startTime = System.currentTimeMillis();
Response response = sendRequest(req, Status.STATUS_OK, admin);
long endTime = System.currentTimeMillis();
if(logger.isDebugEnabled())
{
logger.debug(response.getContentAsString());
}
JSONObject json = new JSONObject(response.getContentAsString());
JSONArray aclChangeSets = json.getJSONArray("aclChangeSets");
System.out.println("Got " + aclChangeSets.length() + " txns in " + (endTime - startTime) + " ms");
}
private JSONArray getNodes(GetNodesParameters parameters, int maxResults, int expectedNumNodes) throws Exception
{
StringBuilder url = new StringBuilder("/api/solr/nodes");

View File

@@ -1,73 +1,72 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.domain.solr.SOLRDAO;
import org.alfresco.repo.domain.solr.Transaction;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Get a list of transactions with a commit time greater than or equal to the given parameter.
*
* @since 4.0
*/
public class GetTransactions extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(GetTransactions.class);
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
String minTxnIdParam = req.getParameter("minTxnId");
String fromCommitTimeParam = req.getParameter("fromCommitTime");
String maxResultsParam = req.getParameter("maxResults");
Long minTxnId = (minTxnIdParam == null ? null : Long.valueOf(minTxnIdParam));
Long fromCommitTime = (fromCommitTimeParam == null ? null : Long.valueOf(fromCommitTimeParam));
int maxResults = (maxResultsParam == null ? 0 : Integer.valueOf(maxResultsParam));
List<Transaction> transactions = solrTrackingComponent.getTransactions(minTxnId, fromCommitTime, maxResults);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("transactions", transactions);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.solr;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.repo.solr.Transaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Support for SOLR: Get a list of transactions with a commit time greater than or equal to the given parameter.
*
* @since 4.0
*/
public class TransactionsGet extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(TransactionsGet.class);
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
String minTxnIdParam = req.getParameter("minTxnId");
String fromCommitTimeParam = req.getParameter("fromCommitTime");
String maxResultsParam = req.getParameter("maxResults");
Long minTxnId = (minTxnIdParam == null ? null : Long.valueOf(minTxnIdParam));
Long fromCommitTime = (fromCommitTimeParam == null ? null : Long.valueOf(fromCommitTimeParam));
int maxResults = (maxResultsParam == null ? 1024 : Integer.valueOf(maxResultsParam));
List<Transaction> transactions = solrTrackingComponent.getTransactions(minTxnId, fromCommitTime, maxResults);
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
model.put("transactions", transactions);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}