Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)

125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2)
      125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Raluca Munteanu
2016-04-26 13:03:25 +00:00
parent 9a889c69ea
commit 386a4aca06
327 changed files with 55062 additions and 55062 deletions

View File

@@ -1,75 +1,75 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.Map;
import org.alfresco.repo.solr.AlfrescoModel;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Support for SOLR: Get Alfresco model
*
* @since 4.0
*/
public class AlfrescoModelGet extends AbstractWebScript
{
protected static final Log logger = LogFactory.getLog(AlfrescoModelGet.class);
private NamespaceService namespaceService;
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void execute(WebScriptRequest req, WebScriptResponse res)
{
try
{
handle(req, res);
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
private void handle(WebScriptRequest req, WebScriptResponse res) throws JSONException, IOException
{
// create map of template vars
String modelQName = req.getParameter("modelQName");
if(modelQName == null)
{
throw new WebScriptException(
Status.STATUS_BAD_REQUEST,
"URL parameter 'modelQName' not provided.");
}
ModelDefinition.XMLBindingType bindingType = ModelDefinition.XMLBindingType.DEFAULT;
AlfrescoModel model = solrTrackingComponent.getModel(QName.createQName(modelQName));
res.setHeader("XAlfresco-modelChecksum", String.valueOf(model.getModelDef().getChecksum(bindingType)));
model.getModelDef().toXML(bindingType, res.getOutputStream());
}
}
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.Map;
import org.alfresco.repo.solr.AlfrescoModel;
import org.alfresco.repo.solr.SOLRTrackingComponent;
import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Support for SOLR: Get Alfresco model
*
* @since 4.0
*/
public class AlfrescoModelGet extends AbstractWebScript
{
protected static final Log logger = LogFactory.getLog(AlfrescoModelGet.class);
private NamespaceService namespaceService;
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void execute(WebScriptRequest req, WebScriptResponse res)
{
try
{
handle(req, res);
}
catch(IOException e)
{
throw new WebScriptException("IO exception parsing request", e);
}
catch(JSONException e)
{
throw new WebScriptException("Invalid JSON", e);
}
}
private void handle(WebScriptRequest req, WebScriptResponse res) throws JSONException, IOException
{
// create map of template vars
String modelQName = req.getParameter("modelQName");
if(modelQName == null)
{
throw new WebScriptException(
Status.STATUS_BAD_REQUEST,
"URL parameter 'modelQName' not provided.");
}
ModelDefinition.XMLBindingType bindingType = ModelDefinition.XMLBindingType.DEFAULT;
AlfrescoModel model = solrTrackingComponent.getModel(QName.createQName(modelQName));
res.setHeader("XAlfresco-modelChecksum", String.valueOf(model.getModelDef().getChecksum(bindingType)));
model.getModelDef().toXML(bindingType, res.getOutputStream());
}
}

View File

@@ -1,110 +1,110 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.solr.AlfrescoModelDiff;
import org.alfresco.repo.solr.SOLRTrackingComponent;
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: Track Alfresco model changes
*
* @since 4.0
*/
public class AlfrescoModelsDiff extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(AlfrescoModelsDiff.class);
private static final String MSG_IO_EXCEPTION = "IO exception parsing request ";
private static final String MSG_JSON_EXCEPTION = "Unable to fetch model changes from ";
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Map<String, Object> model = buildModel(req);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch (IOException e)
{
setExceptionResponse(req, status, MSG_IO_EXCEPTION, Status.STATUS_INTERNAL_SERVER_ERROR, e);
return null;
}
catch (JSONException e)
{
setExceptionResponse(req, status, MSG_JSON_EXCEPTION, Status.STATUS_BAD_REQUEST, e);
return null;
}
}
private void setExceptionResponse(WebScriptRequest req, Status responseStatus, String responseMessage, int statusCode, Exception e)
{
String message = responseMessage + req;
if (logger.isDebugEnabled())
{
logger.warn(message, e);
}
else
{
logger.warn(message);
}
responseStatus.setCode(statusCode, message);
responseStatus.setException(e);
}
private Map<String, Object> buildModel(WebScriptRequest req) throws JSONException, IOException
{
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
JSONArray jsonModels = o.getJSONArray("models");
Map<QName, Long> models = new HashMap<QName, Long>(jsonModels.length());
for(int i = 0; i < jsonModels.length(); i++)
{
JSONObject jsonModel = jsonModels.getJSONObject(i);
models.put(QName.createQName(jsonModel.getString("name")), jsonModel.getLong("checksum"));
}
List<AlfrescoModelDiff> diffs = solrTrackingComponent.getModelDiffs(models);
model.put("diffs", diffs);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.solr.AlfrescoModelDiff;
import org.alfresco.repo.solr.SOLRTrackingComponent;
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: Track Alfresco model changes
*
* @since 4.0
*/
public class AlfrescoModelsDiff extends DeclarativeWebScript
{
protected static final Log logger = LogFactory.getLog(AlfrescoModelsDiff.class);
private static final String MSG_IO_EXCEPTION = "IO exception parsing request ";
private static final String MSG_JSON_EXCEPTION = "Unable to fetch model changes from ";
private SOLRTrackingComponent solrTrackingComponent;
public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
{
this.solrTrackingComponent = solrTrackingComponent;
}
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
try
{
Map<String, Object> model = buildModel(req);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
catch (IOException e)
{
setExceptionResponse(req, status, MSG_IO_EXCEPTION, Status.STATUS_INTERNAL_SERVER_ERROR, e);
return null;
}
catch (JSONException e)
{
setExceptionResponse(req, status, MSG_JSON_EXCEPTION, Status.STATUS_BAD_REQUEST, e);
return null;
}
}
private void setExceptionResponse(WebScriptRequest req, Status responseStatus, String responseMessage, int statusCode, Exception e)
{
String message = responseMessage + req;
if (logger.isDebugEnabled())
{
logger.warn(message, e);
}
else
{
logger.warn(message);
}
responseStatus.setCode(statusCode, message);
responseStatus.setException(e);
}
private Map<String, Object> buildModel(WebScriptRequest req) throws JSONException, IOException
{
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
Content content = req.getContent();
if(content == null)
{
throw new WebScriptException("Failed to convert request to String");
}
JSONObject o = new JSONObject(content.getContent());
JSONArray jsonModels = o.getJSONArray("models");
Map<QName, Long> models = new HashMap<QName, Long>(jsonModels.length());
for(int i = 0; i < jsonModels.length(); i++)
{
JSONObject jsonModel = jsonModels.getJSONObject(i);
models.put(QName.createQName(jsonModel.getString("name")), jsonModel.getLong("checksum"));
}
List<AlfrescoModelDiff> diffs = solrTrackingComponent.getModelDiffs(models);
model.put("diffs", diffs);
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -1,123 +1,123 @@
package org.alfresco.repo.web.scripts.solr;
import java.util.List;
import java.util.Set;
import org.alfresco.service.namespace.QName;
/**
* Input parameters for retrieving node details for SOLR.
*
* @since 4.0
*/
public class GetNodesParameters
{
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 Set<QName> includeAspects;
private Set<QName> excludeAspects;
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;
}
}
package org.alfresco.repo.web.scripts.solr;
import java.util.List;
import java.util.Set;
import org.alfresco.service.namespace.QName;
/**
* Input parameters for retrieving node details for SOLR.
*
* @since 4.0
*/
public class GetNodesParameters
{
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 Set<QName> includeAspects;
private Set<QName> excludeAspects;
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;
}
}

View File

@@ -1,90 +1,90 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
/**
* Bean to carry node metadata
*
* @since 4.0
*/
public class NodeMetaData
{
private long id;
private NodeRef nodeRef;
private QName type;
private long aclId;
private Map<QName, Serializable> properties;
private Set<QName> aspects;
private Path paths;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public QName getType()
{
return type;
}
public void setType(QName type)
{
this.type = type;
}
public long getAclId()
{
return aclId;
}
public void setAclId(long aclId)
{
this.aclId = aclId;
}
public Map<QName, Serializable> getProperties()
{
return properties;
}
public void setProperties(Map<QName, Serializable> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public Path getPaths()
{
return paths;
}
public void setPaths(Path paths)
{
this.paths = paths;
}
@Override
public String toString()
{
return "NodeMetaData [id=" + id + ", nodeRef=" + nodeRef + ", type=" + type + ", aclId=" + aclId
+ ", properties=" + properties + ", aspects=" + aspects + ", paths=" + paths + "]";
}
}
package org.alfresco.repo.web.scripts.solr;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
/**
* Bean to carry node metadata
*
* @since 4.0
*/
public class NodeMetaData
{
private long id;
private NodeRef nodeRef;
private QName type;
private long aclId;
private Map<QName, Serializable> properties;
private Set<QName> aspects;
private Path paths;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public QName getType()
{
return type;
}
public void setType(QName type)
{
this.type = type;
}
public long getAclId()
{
return aclId;
}
public void setAclId(long aclId)
{
this.aclId = aclId;
}
public Map<QName, Serializable> getProperties()
{
return properties;
}
public void setProperties(Map<QName, Serializable> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public Path getPaths()
{
return paths;
}
public void setPaths(Path paths)
{
this.paths = paths;
}
@Override
public String toString()
{
return "NodeMetaData [id=" + id + ", nodeRef=" + nodeRef + ", type=" + type + ", aclId=" + aclId
+ ", properties=" + properties + ", aspects=" + aspects + ", paths=" + paths + "]";
}
}

View File

@@ -1,46 +1,46 @@
package org.alfresco.repo.web.scripts.solr;
/**
* Represents a property value to be used by Freemarker
*
* @since 4.0
*/
class PropertyValue
{
// is value actually a string or a JSON object or array
// if true, enclose the value in double quotes (to represent a JSON string)
// when converting to a string.
private boolean isString = true;
private String value;
public PropertyValue(boolean isString, String value)
{
super();
this.isString = isString;
this.value = value;
}
public boolean isString()
{
return isString;
}
public String getValue()
{
return value;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
if(isString)
{
sb.append("\""); // for json strings
}
sb.append(value);
if(isString)
{
sb.append("\""); // for json strings
}
return sb.toString();
}
}
package org.alfresco.repo.web.scripts.solr;
/**
* Represents a property value to be used by Freemarker
*
* @since 4.0
*/
class PropertyValue
{
// is value actually a string or a JSON object or array
// if true, enclose the value in double quotes (to represent a JSON string)
// when converting to a string.
private boolean isString = true;
private String value;
public PropertyValue(boolean isString, String value)
{
super();
this.isString = isString;
this.value = value;
}
public boolean isString()
{
return isString;
}
public String getValue()
{
return value;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
if(isString)
{
sb.append("\""); // for json strings
}
sb.append(value);
if(isString)
{
sb.append("\""); // for json strings
}
return sb.toString();
}
}

View File

@@ -1,260 +1,260 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This filter protects the solr callback urls by verifying MACs on requests and encrypting responses
* and generating MACs on responses, if the secureComms property is set to "md5". If it is set to "https"
* or "none", the filter does nothing to the request and response.
*
* @since 4.0
*
*/
public class SOLRAuthenticationFilter implements DependencyInjectedFilter
{
public static enum SecureCommsType
{
HTTPS, NONE;
public static SecureCommsType getType(String type)
{
if(type.equalsIgnoreCase("https"))
{
return HTTPS;
}
else if(type.equalsIgnoreCase("none"))
{
return NONE;
}
else
{
throw new IllegalArgumentException("Invalid communications type");
}
}
};
// Logger
private static Log logger = LogFactory.getLog(SOLRAuthenticationFilter.class);
private SecureCommsType secureComms = SecureCommsType.HTTPS;
public void setSecureComms(String type)
{
try
{
this.secureComms = SecureCommsType.getType(type);
}
catch(IllegalArgumentException e)
{
throw new AlfrescoRuntimeException("", e);
}
}
public void doFilter(ServletContext context, ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
/* if(secureComms == SecureCommsType.ALFRESCO)
{
// Need to get as a byte array because we need to read the request twice, once for authentication
// and again by the web service.
SOLRHttpServletRequestWrapper requestWrapper = new SOLRHttpServletRequestWrapper(httpRequest, encryptionUtils);
if(logger.isDebugEnabled())
{
logger.debug("Authenticating " + httpRequest.getRequestURI());
}
if(encryptionUtils.authenticate(httpRequest, requestWrapper.getDecryptedBody()))
{
try
{
OutputStream out = response.getOutputStream();
GenericResponseWrapper responseWrapper = new GenericResponseWrapper(httpResponse);
// TODO - do I need to chain to other authenticating filters - probably not?
// Could also remove sending of credentials with http request
chain.doFilter(requestWrapper, responseWrapper);
Pair<byte[], AlgorithmParameters> pair = encryptor.encrypt(KeyProvider.ALIAS_SOLR, null, responseWrapper.getData());
encryptionUtils.setResponseAuthentication(httpRequest, httpResponse, responseWrapper.getData(), pair.getSecond());
httpResponse.setHeader("Content-Length", Long.toString(pair.getFirst().length));
out.write(pair.getFirst());
out.close();
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("", e);
}
}
else
{
httpResponse.setStatus(401);
}
}
else */if(secureComms == SecureCommsType.HTTPS)
{
if(httpRequest.isSecure())
{
// https authentication
chain.doFilter(request, response);
}
else
{
throw new AlfrescoRuntimeException("Expected a https request");
}
}
else
{
chain.doFilter(request, response);
}
}
protected boolean validateTimestamp(String timestampStr)
{
if(timestampStr == null || timestampStr.equals(""))
{
throw new AlfrescoRuntimeException("Missing timestamp on request");
}
long timestamp = -1;
try
{
timestamp = Long.valueOf(timestampStr);
}
catch(NumberFormatException e)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
if(timestamp == -1)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
long currentTime = System.currentTimeMillis();
return((currentTime - timestamp) < 30 * 1000); // 5s
}
/* private static class SOLRHttpServletRequestWrapper extends HttpServletRequestWrapper
{
private byte[] body;
SOLRHttpServletRequestWrapper(HttpServletRequest req, EncryptionUtils encryptionUtils) throws IOException
{
super(req);
this.body = encryptionUtils.decryptBody(req);
}
byte[] getDecryptedBody()
{
return body;
}
public ServletInputStream getInputStream()
{
final InputStream in = (body != null ? new ByteArrayInputStream(body) : null);
return new ServletInputStream()
{
public int read() throws IOException
{
if(in == null)
{
return -1;
}
else
{
int i = in.read();
if(i == -1)
{
in.close();
}
return i;
}
}
};
}
}*/
private static class ByteArrayServletOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayServletOutputStream()
{
}
public byte[] getData()
{
return out.toByteArray();
}
@Override
public void write(int b) throws IOException
{
out.write(b);
}
}
public static class GenericResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayServletOutputStream output;
private int contentLength;
private String contentType;
public GenericResponseWrapper(HttpServletResponse response) {
super(response);
output = new ByteArrayServletOutputStream();
}
public byte[] getData() {
return output.getData();
}
public ServletOutputStream getOutputStream() {
return output;
}
public PrintWriter getWriter() {
return new PrintWriter(getOutputStream(),true);
}
public void setContentLength(int length) {
this.contentLength = length;
super.setContentLength(length);
}
public int getContentLength() {
return contentLength;
}
public void setContentType(String type) {
this.contentType = type;
super.setContentType(type);
}
public String getContentType() {
return contentType;
}
}
}
package org.alfresco.repo.web.scripts.solr;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This filter protects the solr callback urls by verifying MACs on requests and encrypting responses
* and generating MACs on responses, if the secureComms property is set to "md5". If it is set to "https"
* or "none", the filter does nothing to the request and response.
*
* @since 4.0
*
*/
public class SOLRAuthenticationFilter implements DependencyInjectedFilter
{
public static enum SecureCommsType
{
HTTPS, NONE;
public static SecureCommsType getType(String type)
{
if(type.equalsIgnoreCase("https"))
{
return HTTPS;
}
else if(type.equalsIgnoreCase("none"))
{
return NONE;
}
else
{
throw new IllegalArgumentException("Invalid communications type");
}
}
};
// Logger
private static Log logger = LogFactory.getLog(SOLRAuthenticationFilter.class);
private SecureCommsType secureComms = SecureCommsType.HTTPS;
public void setSecureComms(String type)
{
try
{
this.secureComms = SecureCommsType.getType(type);
}
catch(IllegalArgumentException e)
{
throw new AlfrescoRuntimeException("", e);
}
}
public void doFilter(ServletContext context, ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
/* if(secureComms == SecureCommsType.ALFRESCO)
{
// Need to get as a byte array because we need to read the request twice, once for authentication
// and again by the web service.
SOLRHttpServletRequestWrapper requestWrapper = new SOLRHttpServletRequestWrapper(httpRequest, encryptionUtils);
if(logger.isDebugEnabled())
{
logger.debug("Authenticating " + httpRequest.getRequestURI());
}
if(encryptionUtils.authenticate(httpRequest, requestWrapper.getDecryptedBody()))
{
try
{
OutputStream out = response.getOutputStream();
GenericResponseWrapper responseWrapper = new GenericResponseWrapper(httpResponse);
// TODO - do I need to chain to other authenticating filters - probably not?
// Could also remove sending of credentials with http request
chain.doFilter(requestWrapper, responseWrapper);
Pair<byte[], AlgorithmParameters> pair = encryptor.encrypt(KeyProvider.ALIAS_SOLR, null, responseWrapper.getData());
encryptionUtils.setResponseAuthentication(httpRequest, httpResponse, responseWrapper.getData(), pair.getSecond());
httpResponse.setHeader("Content-Length", Long.toString(pair.getFirst().length));
out.write(pair.getFirst());
out.close();
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("", e);
}
}
else
{
httpResponse.setStatus(401);
}
}
else */if(secureComms == SecureCommsType.HTTPS)
{
if(httpRequest.isSecure())
{
// https authentication
chain.doFilter(request, response);
}
else
{
throw new AlfrescoRuntimeException("Expected a https request");
}
}
else
{
chain.doFilter(request, response);
}
}
protected boolean validateTimestamp(String timestampStr)
{
if(timestampStr == null || timestampStr.equals(""))
{
throw new AlfrescoRuntimeException("Missing timestamp on request");
}
long timestamp = -1;
try
{
timestamp = Long.valueOf(timestampStr);
}
catch(NumberFormatException e)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
if(timestamp == -1)
{
throw new AlfrescoRuntimeException("Invalid timestamp on request");
}
long currentTime = System.currentTimeMillis();
return((currentTime - timestamp) < 30 * 1000); // 5s
}
/* private static class SOLRHttpServletRequestWrapper extends HttpServletRequestWrapper
{
private byte[] body;
SOLRHttpServletRequestWrapper(HttpServletRequest req, EncryptionUtils encryptionUtils) throws IOException
{
super(req);
this.body = encryptionUtils.decryptBody(req);
}
byte[] getDecryptedBody()
{
return body;
}
public ServletInputStream getInputStream()
{
final InputStream in = (body != null ? new ByteArrayInputStream(body) : null);
return new ServletInputStream()
{
public int read() throws IOException
{
if(in == null)
{
return -1;
}
else
{
int i = in.read();
if(i == -1)
{
in.close();
}
return i;
}
}
};
}
}*/
private static class ByteArrayServletOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayServletOutputStream()
{
}
public byte[] getData()
{
return out.toByteArray();
}
@Override
public void write(int b) throws IOException
{
out.write(b);
}
}
public static class GenericResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayServletOutputStream output;
private int contentLength;
private String contentType;
public GenericResponseWrapper(HttpServletResponse response) {
super(response);
output = new ByteArrayServletOutputStream();
}
public byte[] getData() {
return output.getData();
}
public ServletOutputStream getOutputStream() {
return output;
}
public PrintWriter getWriter() {
return new PrintWriter(getOutputStream(),true);
}
public void setContentLength(int length) {
this.contentLength = length;
super.setContentLength(length);
}
public int getContentLength() {
return contentLength;
}
public void setContentType(String type) {
this.contentType = type;
super.setContentType(type);
}
public String getContentType() {
return contentType;
}
}
}

View File

@@ -1,456 +1,456 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.domain.node.ContentDataWithId;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Path.AttributeElement;
import org.alfresco.service.cmr.repository.Path.ChildAssocElement;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConverter.Converter;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck;
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.webscripts.json.JSONUtils;
/**
* SOLR conversions of values to JSON-compatible <tt>String</tt>.
*
* @since 4.0
*/
/* package */ class SOLRSerializer
{
protected static final Log logger = LogFactory.getLog(SOLRSerializer.class);
private JSONUtils jsonUtils = new JSONUtils();
private Set<QName> NUMBER_TYPES;
private DictionaryService dictionaryService;
private NamespaceService namespaceService;
private SOLRTypeConverter typeConverter;
public void init()
{
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
NUMBER_TYPES = new HashSet<QName>(4);
NUMBER_TYPES.add(DataTypeDefinition.DOUBLE);
NUMBER_TYPES.add(DataTypeDefinition.FLOAT);
NUMBER_TYPES.add(DataTypeDefinition.INT);
NUMBER_TYPES.add(DataTypeDefinition.LONG);
typeConverter = new SOLRTypeConverter(namespaceService);
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public String serializeToJSONString(Serializable value)
{
if (value != null && typeConverter.INSTANCE.getConverter(value.getClass(), String.class) == null)
{
// There is no converter
return value.toString();
}
else
{
return typeConverter.INSTANCE.convert(String.class, value);
}
}
public <T> T serializeValue(Class<T> targetClass, Object value) throws JSONException
{
return typeConverter.INSTANCE.convert(targetClass, value);
}
@SuppressWarnings("unchecked")
public PropertyValue serialize(QName propName, Serializable value) throws IOException, JSONException
{
if(value == null)
{
return new PropertyValue(false, "null");
}
PropertyDefinition propertyDef = dictionaryService.getProperty(propName);
if (propertyDef == null)
{
// Treat it as text
return new PropertyValue(true, serializeToJSONString(value));
}
DataTypeDefinition dataType = propertyDef.getDataType();
QName dataTypeName = dataType.getName();
if (propertyDef.isMultiValued())
{
if(!(value instanceof Collection))
{
throw new IllegalArgumentException("Multi value: expected a collection, got " + value.getClass().getName());
}
Collection<Serializable> c = (Collection<Serializable>)value;
JSONArray body = new JSONArray();
for(Serializable o : c)
{
if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
{
MLText source = (MLText)o;
JSONArray array = new JSONArray();
for(Locale locale : source.getLocales())
{
JSONObject json = new JSONObject();
json.put("locale", DefaultTypeConverter.INSTANCE.convert(String.class, locale));
json.put("value", source.getValue(locale));
array.put(json);
}
body.put(array);
}
else if(dataTypeName.equals(DataTypeDefinition.CONTENT))
{
throw new RuntimeException("Multi-valued content properties are not supported");
}
else
{
body.put(serializeToJSONString(o));
}
}
return new PropertyValue(false, body.toString());
}
else
{
boolean encodeString = true;
if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
{
encodeString = false;
}
else if(dataTypeName.equals(DataTypeDefinition.CONTENT))
{
encodeString = false;
}
else
{
encodeString = true;
}
String sValue = null;
if (value instanceof String && encodeString) {
sValue = (String)jsonUtils.encodeJSONString(value);
} else {
sValue = serializeToJSONString(value);
}
return new PropertyValue(encodeString, sValue);
}
}
@SuppressWarnings("rawtypes")
private class SOLRTypeConverter
{
private NamespaceService namespaceService;
TypeConverter INSTANCE = new TypeConverter();
@SuppressWarnings("unchecked")
SOLRTypeConverter(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
// add all default converters to this converter
// TODO find a better way of doing this
Map<Class<?>, Map<Class<?>, Converter<?, ?>>> converters = DefaultTypeConverter.INSTANCE.getConverters();
for(Class<?> source : converters.keySet())
{
Map<Class<?>, Converter<?, ?>> converters1 = converters.get(source);
for(Class dest : converters1.keySet())
{
Converter converter = converters1.get(dest);
INSTANCE.addConverter(source, dest, converter);
}
}
// MLText
INSTANCE.addConverter(MLText.class, String.class, new TypeConverter.Converter<MLText, String>()
{
public String convert(MLText source)
{
try
{
JSONArray array = new JSONArray();
for(Locale locale : source.getLocales())
{
JSONObject json = new JSONObject();
json.put("locale", DefaultTypeConverter.INSTANCE.convert(String.class, locale));
json.put("value", source.getValue(locale));
array.put(json);
}
return array.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
// QName
INSTANCE.addConverter(QName.class, String.class, new TypeConverter.Converter<QName, String>()
{
public String convert(QName source)
{
return source.toString();
}
});
// content
INSTANCE.addConverter(ContentDataWithId.class, String.class, new TypeConverter.Converter<ContentDataWithId, String>()
{
public String convert(ContentDataWithId source)
{
JSONObject json = new JSONObject();
try
{
json.put("contentId", String.valueOf(source.getId()));
String locale = INSTANCE.convert(String.class, source.getLocale());
json.put("locale", locale == null ? JSONObject.NULL : locale);
String encoding = source.getEncoding();
json.put("encoding", encoding == null ? JSONObject.NULL : encoding);
String mimetype = source.getMimetype();
json.put("mimetype", mimetype == null ? JSONObject.NULL : mimetype);
json.put("size", String.valueOf(source.getSize()));
return json.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
INSTANCE.addConverter(ContentData.class, String.class, new TypeConverter.Converter<ContentData, String>()
{
public String convert(ContentData source)
{
JSONObject json = new JSONObject();
try
{
String locale = INSTANCE.convert(String.class, source.getLocale());
json.put("locale", locale == null ? JSONObject.NULL : locale);
String encoding = source.getEncoding();
json.put("encoding", encoding == null ? JSONObject.NULL : encoding);
String mimetype = source.getMimetype();
json.put("mimetype", mimetype == null ? JSONObject.NULL : mimetype);
json.put("size", String.valueOf(source.getSize()));
return json.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
// node refs
INSTANCE.addConverter(NodeRef.class, String.class, new TypeConverter.Converter<NodeRef, String>()
{
public String convert(NodeRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, NodeRef.class, new TypeConverter.Converter<String, NodeRef>()
{
public NodeRef convert(String source)
{
return new NodeRef(source);
}
});
// paths
INSTANCE.addConverter(AttributeElement.class, String.class, new TypeConverter.Converter<AttributeElement, String>()
{
public String convert(AttributeElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(ChildAssocElement.class, String.class, new TypeConverter.Converter<ChildAssocElement, String>()
{
public String convert(ChildAssocElement source)
{
return source.getRef().toString();
}
});
INSTANCE.addConverter(Path.DescendentOrSelfElement.class, String.class, new TypeConverter.Converter<Path.DescendentOrSelfElement, String>()
{
public String convert(Path.DescendentOrSelfElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(Path.ParentElement.class, String.class, new TypeConverter.Converter<Path.ParentElement, String>()
{
public String convert(Path.ParentElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(Path.SelfElement.class, String.class, new TypeConverter.Converter<Path.SelfElement, String>()
{
public String convert(Path.SelfElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, AttributeElement.class, new TypeConverter.Converter<String, AttributeElement>()
{
public AttributeElement convert(String source)
{
return new Path.AttributeElement(source);
}
});
INSTANCE.addConverter(String.class, ChildAssocElement.class, new TypeConverter.Converter<String, ChildAssocElement>()
{
public ChildAssocElement convert(String source)
{
return new Path.ChildAssocElement(INSTANCE.convert(ChildAssociationRef.class, source));
}
});
INSTANCE.addConverter(String.class, Path.DescendentOrSelfElement.class, new TypeConverter.Converter<String, Path.DescendentOrSelfElement>()
{
public Path.DescendentOrSelfElement convert(String source)
{
return new Path.DescendentOrSelfElement();
}
});
INSTANCE.addConverter(String.class, Path.ParentElement.class, new TypeConverter.Converter<String, Path.ParentElement>()
{
public Path.ParentElement convert(String source)
{
return new Path.ParentElement();
}
});
INSTANCE.addConverter(String.class, Path.SelfElement.class, new TypeConverter.Converter<String, Path.SelfElement>()
{
public Path.SelfElement convert(String source)
{
return new Path.SelfElement();
}
});
INSTANCE.addConverter(Path.class, List.class, new TypeConverter.Converter<Path, List>()
{
public List convert(Path source)
{
List<String> pathArray = new ArrayList<String>(source.size());
for(Path.Element element : source)
{
pathArray.add(INSTANCE.convert(String.class, element));
}
return pathArray;
}
});
INSTANCE.addConverter(Path.class, String.class, new TypeConverter.Converter<Path, String>()
{
public String convert(Path source)
{
return source.toString();
}
});
// associations
INSTANCE.addConverter(ChildAssociationRef.class, String.class, new TypeConverter.Converter<ChildAssociationRef, String>()
{
public String convert(ChildAssociationRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, ChildAssociationRef.class, new TypeConverter.Converter<String, ChildAssociationRef>()
{
public ChildAssociationRef convert(String source)
{
return new ChildAssociationRef(source);
}
});
INSTANCE.addConverter(AssociationRef.class, String.class, new TypeConverter.Converter<AssociationRef, String>()
{
public String convert(AssociationRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, AssociationRef.class, new TypeConverter.Converter<String, AssociationRef>()
{
public AssociationRef convert(String source)
{
return new AssociationRef(source);
}
});
INSTANCE.addConverter(Number.class, String.class, new TypeConverter.Converter<Number, String>()
{
public String convert(Number source)
{
return source.toString();
}
});
INSTANCE.addConverter(Boolean.class, String.class, new TypeConverter.Converter<Boolean, String>()
{
public String convert(Boolean source)
{
return source.toString();
}
});
}
}
}
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.domain.node.ContentDataWithId;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Path.AttributeElement;
import org.alfresco.service.cmr.repository.Path.ChildAssocElement;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConverter.Converter;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck;
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.webscripts.json.JSONUtils;
/**
* SOLR conversions of values to JSON-compatible <tt>String</tt>.
*
* @since 4.0
*/
/* package */ class SOLRSerializer
{
protected static final Log logger = LogFactory.getLog(SOLRSerializer.class);
private JSONUtils jsonUtils = new JSONUtils();
private Set<QName> NUMBER_TYPES;
private DictionaryService dictionaryService;
private NamespaceService namespaceService;
private SOLRTypeConverter typeConverter;
public void init()
{
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
NUMBER_TYPES = new HashSet<QName>(4);
NUMBER_TYPES.add(DataTypeDefinition.DOUBLE);
NUMBER_TYPES.add(DataTypeDefinition.FLOAT);
NUMBER_TYPES.add(DataTypeDefinition.INT);
NUMBER_TYPES.add(DataTypeDefinition.LONG);
typeConverter = new SOLRTypeConverter(namespaceService);
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public String serializeToJSONString(Serializable value)
{
if (value != null && typeConverter.INSTANCE.getConverter(value.getClass(), String.class) == null)
{
// There is no converter
return value.toString();
}
else
{
return typeConverter.INSTANCE.convert(String.class, value);
}
}
public <T> T serializeValue(Class<T> targetClass, Object value) throws JSONException
{
return typeConverter.INSTANCE.convert(targetClass, value);
}
@SuppressWarnings("unchecked")
public PropertyValue serialize(QName propName, Serializable value) throws IOException, JSONException
{
if(value == null)
{
return new PropertyValue(false, "null");
}
PropertyDefinition propertyDef = dictionaryService.getProperty(propName);
if (propertyDef == null)
{
// Treat it as text
return new PropertyValue(true, serializeToJSONString(value));
}
DataTypeDefinition dataType = propertyDef.getDataType();
QName dataTypeName = dataType.getName();
if (propertyDef.isMultiValued())
{
if(!(value instanceof Collection))
{
throw new IllegalArgumentException("Multi value: expected a collection, got " + value.getClass().getName());
}
Collection<Serializable> c = (Collection<Serializable>)value;
JSONArray body = new JSONArray();
for(Serializable o : c)
{
if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
{
MLText source = (MLText)o;
JSONArray array = new JSONArray();
for(Locale locale : source.getLocales())
{
JSONObject json = new JSONObject();
json.put("locale", DefaultTypeConverter.INSTANCE.convert(String.class, locale));
json.put("value", source.getValue(locale));
array.put(json);
}
body.put(array);
}
else if(dataTypeName.equals(DataTypeDefinition.CONTENT))
{
throw new RuntimeException("Multi-valued content properties are not supported");
}
else
{
body.put(serializeToJSONString(o));
}
}
return new PropertyValue(false, body.toString());
}
else
{
boolean encodeString = true;
if(dataTypeName.equals(DataTypeDefinition.MLTEXT))
{
encodeString = false;
}
else if(dataTypeName.equals(DataTypeDefinition.CONTENT))
{
encodeString = false;
}
else
{
encodeString = true;
}
String sValue = null;
if (value instanceof String && encodeString) {
sValue = (String)jsonUtils.encodeJSONString(value);
} else {
sValue = serializeToJSONString(value);
}
return new PropertyValue(encodeString, sValue);
}
}
@SuppressWarnings("rawtypes")
private class SOLRTypeConverter
{
private NamespaceService namespaceService;
TypeConverter INSTANCE = new TypeConverter();
@SuppressWarnings("unchecked")
SOLRTypeConverter(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
// add all default converters to this converter
// TODO find a better way of doing this
Map<Class<?>, Map<Class<?>, Converter<?, ?>>> converters = DefaultTypeConverter.INSTANCE.getConverters();
for(Class<?> source : converters.keySet())
{
Map<Class<?>, Converter<?, ?>> converters1 = converters.get(source);
for(Class dest : converters1.keySet())
{
Converter converter = converters1.get(dest);
INSTANCE.addConverter(source, dest, converter);
}
}
// MLText
INSTANCE.addConverter(MLText.class, String.class, new TypeConverter.Converter<MLText, String>()
{
public String convert(MLText source)
{
try
{
JSONArray array = new JSONArray();
for(Locale locale : source.getLocales())
{
JSONObject json = new JSONObject();
json.put("locale", DefaultTypeConverter.INSTANCE.convert(String.class, locale));
json.put("value", source.getValue(locale));
array.put(json);
}
return array.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
// QName
INSTANCE.addConverter(QName.class, String.class, new TypeConverter.Converter<QName, String>()
{
public String convert(QName source)
{
return source.toString();
}
});
// content
INSTANCE.addConverter(ContentDataWithId.class, String.class, new TypeConverter.Converter<ContentDataWithId, String>()
{
public String convert(ContentDataWithId source)
{
JSONObject json = new JSONObject();
try
{
json.put("contentId", String.valueOf(source.getId()));
String locale = INSTANCE.convert(String.class, source.getLocale());
json.put("locale", locale == null ? JSONObject.NULL : locale);
String encoding = source.getEncoding();
json.put("encoding", encoding == null ? JSONObject.NULL : encoding);
String mimetype = source.getMimetype();
json.put("mimetype", mimetype == null ? JSONObject.NULL : mimetype);
json.put("size", String.valueOf(source.getSize()));
return json.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
INSTANCE.addConverter(ContentData.class, String.class, new TypeConverter.Converter<ContentData, String>()
{
public String convert(ContentData source)
{
JSONObject json = new JSONObject();
try
{
String locale = INSTANCE.convert(String.class, source.getLocale());
json.put("locale", locale == null ? JSONObject.NULL : locale);
String encoding = source.getEncoding();
json.put("encoding", encoding == null ? JSONObject.NULL : encoding);
String mimetype = source.getMimetype();
json.put("mimetype", mimetype == null ? JSONObject.NULL : mimetype);
json.put("size", String.valueOf(source.getSize()));
return json.toString(3);
}
catch(JSONException e)
{
throw new AlfrescoRuntimeException("Unable to serialize content data to JSON", e);
}
}
});
// node refs
INSTANCE.addConverter(NodeRef.class, String.class, new TypeConverter.Converter<NodeRef, String>()
{
public String convert(NodeRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, NodeRef.class, new TypeConverter.Converter<String, NodeRef>()
{
public NodeRef convert(String source)
{
return new NodeRef(source);
}
});
// paths
INSTANCE.addConverter(AttributeElement.class, String.class, new TypeConverter.Converter<AttributeElement, String>()
{
public String convert(AttributeElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(ChildAssocElement.class, String.class, new TypeConverter.Converter<ChildAssocElement, String>()
{
public String convert(ChildAssocElement source)
{
return source.getRef().toString();
}
});
INSTANCE.addConverter(Path.DescendentOrSelfElement.class, String.class, new TypeConverter.Converter<Path.DescendentOrSelfElement, String>()
{
public String convert(Path.DescendentOrSelfElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(Path.ParentElement.class, String.class, new TypeConverter.Converter<Path.ParentElement, String>()
{
public String convert(Path.ParentElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(Path.SelfElement.class, String.class, new TypeConverter.Converter<Path.SelfElement, String>()
{
public String convert(Path.SelfElement source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, AttributeElement.class, new TypeConverter.Converter<String, AttributeElement>()
{
public AttributeElement convert(String source)
{
return new Path.AttributeElement(source);
}
});
INSTANCE.addConverter(String.class, ChildAssocElement.class, new TypeConverter.Converter<String, ChildAssocElement>()
{
public ChildAssocElement convert(String source)
{
return new Path.ChildAssocElement(INSTANCE.convert(ChildAssociationRef.class, source));
}
});
INSTANCE.addConverter(String.class, Path.DescendentOrSelfElement.class, new TypeConverter.Converter<String, Path.DescendentOrSelfElement>()
{
public Path.DescendentOrSelfElement convert(String source)
{
return new Path.DescendentOrSelfElement();
}
});
INSTANCE.addConverter(String.class, Path.ParentElement.class, new TypeConverter.Converter<String, Path.ParentElement>()
{
public Path.ParentElement convert(String source)
{
return new Path.ParentElement();
}
});
INSTANCE.addConverter(String.class, Path.SelfElement.class, new TypeConverter.Converter<String, Path.SelfElement>()
{
public Path.SelfElement convert(String source)
{
return new Path.SelfElement();
}
});
INSTANCE.addConverter(Path.class, List.class, new TypeConverter.Converter<Path, List>()
{
public List convert(Path source)
{
List<String> pathArray = new ArrayList<String>(source.size());
for(Path.Element element : source)
{
pathArray.add(INSTANCE.convert(String.class, element));
}
return pathArray;
}
});
INSTANCE.addConverter(Path.class, String.class, new TypeConverter.Converter<Path, String>()
{
public String convert(Path source)
{
return source.toString();
}
});
// associations
INSTANCE.addConverter(ChildAssociationRef.class, String.class, new TypeConverter.Converter<ChildAssociationRef, String>()
{
public String convert(ChildAssociationRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, ChildAssociationRef.class, new TypeConverter.Converter<String, ChildAssociationRef>()
{
public ChildAssociationRef convert(String source)
{
return new ChildAssociationRef(source);
}
});
INSTANCE.addConverter(AssociationRef.class, String.class, new TypeConverter.Converter<AssociationRef, String>()
{
public String convert(AssociationRef source)
{
return source.toString();
}
});
INSTANCE.addConverter(String.class, AssociationRef.class, new TypeConverter.Converter<String, AssociationRef>()
{
public AssociationRef convert(String source)
{
return new AssociationRef(source);
}
});
INSTANCE.addConverter(Number.class, String.class, new TypeConverter.Converter<Number, String>()
{
public String convert(Number source)
{
return source.toString();
}
});
INSTANCE.addConverter(Boolean.class, String.class, new TypeConverter.Converter<Boolean, String>()
{
public String convert(Boolean source)
{
return source.toString();
}
});
}
}
}