Merged DEV/SWIFT to HEAD

25834: ALF-7070: more tweaks to node properties serialization
          ALF-7071: initial checkin
          SOLR API client library: node metadata, node text content
   25869: ALF-6862 - When performing XML Metadata Extraction on a file with a DTD,
                     if the DTD cannot be found then re-try the extraction with a parser that ignores DTDs.
          Includes unit tests for a file with and without a DTD, showing we now correctly process both.
   25892: OpenCMIS
          - add multi-filing support to CMIS getObjectParents()
          - update OpenCMIS libraries
   25905: Push the DataList model namespace definition into a constant in NameSpaceService in the usual pattern,
          rather than being hard coded in a util class
   25922: (RECORD ONLY) Fix version number

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28115 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-05-30 16:15:56 +00:00
parent cdcb97aecf
commit 426b213db7
9 changed files with 1170 additions and 794 deletions

View File

@@ -0,0 +1,204 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
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.cmr.repository.TransformationOptions;
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 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;
}
/**
* @see org.alfresco.web.scripts.WebScript#execute(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
*/
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
ContentReader textReader = null;
Exception transformException = null;
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String nodeIDString = templateVars.get("nodeId");
if(nodeIDString == null)
{
throw new WebScriptException("nodeID parameter is required for GetNodeContent");
}
long nodeId = Long.valueOf(nodeIDString).longValue();
String propertyQName = templateVars.get("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.isInfoEnabled())
{
logger.info("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;
}
// optimisation - already text so just return the content directly
// TODO - better way of doing this?
if(reader.getMimetype().startsWith("text/"))
{
textReader = reader;
}
else
{
ContentWriter writer = contentService.getTempWriter();
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8");
TransformationOptions options = new TransformationOptions();
ContentTransformer transformer = contentService.getTransformer(reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN);
if(transformer == null)
{
res.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
try
{
// TODO how to ensure UTF-8?
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("XAlfresco-transformException", transformException.getMessage());
res.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
else
{
streamContentImpl(req, res, textReader, false, modified, String.valueOf(modified.getTime()), null);
}
/* writer.addListener(new ContentStreamListener()
{
@Override
public void contentStreamClosed() throws ContentIOException
{
// TODO Auto-generated method stub
}
});*/
}
}

View File

@@ -8,7 +8,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.domain.node.ContentDataWithId;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.domain.solr.MetaDataResultsFilter;
import org.alfresco.repo.domain.solr.NodeMetaData;
import org.alfresco.repo.domain.solr.NodeMetaDataParameters;
@@ -18,7 +18,6 @@ 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.SOLRSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -160,8 +159,15 @@ public class GetNodesMetaData extends DeclarativeWebScript
{
// need to perform data structure conversions that are compatible with Freemarker
// e.g. Serializable -> String, QName -> String (because map keys must be string, number)
FreemarkerNodeMetaData fNodeMetaData = new FreemarkerNodeMetaData(solrSerializer, nodeMetaData);
nodesMetaData.add(fNodeMetaData);
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)
{
@@ -194,47 +200,54 @@ public class GetNodesMetaData extends DeclarativeWebScript
}
}
/*
* Bean to store node meta data for use by FreeMarker templates
*/
public static class FreemarkerNodeMetaData
{
private Long nodeId;
private NodeRef nodeRef;
private QName nodeType;
private Long aclId;
private Map<String, Object> properties;
private Map<String, String> properties;
private Set<QName> aspects;
private List<Path> paths;
private List<String> paths;
private List<ChildAssociationRef> childAssocs;
public FreemarkerNodeMetaData(SOLRSerializer solrSerializer, NodeMetaData nodeMetaData)
@SuppressWarnings("unchecked")
public FreemarkerNodeMetaData(SOLRSerializer solrSerializer, NodeMetaData nodeMetaData) throws IOException, JSONException
{
setNodeId(nodeMetaData.getNodeId());
setAclId(nodeMetaData.getAclId());
setNodeRef(nodeMetaData.getNodeRef());
setNodeType(nodeMetaData.getNodeType());
// TODO need to use SOLRTypeConverter to serialize Path
// convert Paths to Strings
List<String> paths = new ArrayList<String>();
for(Path path : nodeMetaData.getPaths())
{
paths.add(solrSerializer.serializeValue(String.class, path));
}
setPaths(nodeMetaData.getPaths());
setPaths(paths);
setChildAssocs(nodeMetaData.getChildAssocs());
setAspects(nodeMetaData.getAspects());
Map<QName, Serializable> props = nodeMetaData.getProperties();
Map<String, Object> properties = (props != null ? new HashMap<String, Object>(props.size()) : null);
Map<String, String> properties = (props != null ? new HashMap<String, String>(props.size()) : null);
for(QName propName : props.keySet())
{
Serializable value = props.get(propName);
if(value instanceof ContentDataWithId)
{
// special case - ContentDataWithId
properties.put(propName.toString(), ((ContentDataWithId)value).getId());
}
else
{
properties.put(propName.toString(), solrSerializer.serialize(propName, value));
}
// deal with mutli value here
// if(value instanceof ContentDataWithId)
// {
// // special case - ContentDataWithId
// properties.put(propName, String.valueOf(((ContentDataWithId)value).getId()));
// }
// else
// {
properties.put(solrSerializer.serializeValue(String.class, propName),
solrSerializer.serialize(propName, value));
// }
}
setProperties(properties);
}
@@ -247,11 +260,11 @@ public class GetNodesMetaData extends DeclarativeWebScript
{
this.nodeRef = nodeRef;
}
public List<Path> getPaths()
public List<String> getPaths()
{
return paths;
}
public void setPaths(List<Path> paths)
public void setPaths(List<String> paths)
{
this.paths = paths;
}
@@ -279,11 +292,11 @@ public class GetNodesMetaData extends DeclarativeWebScript
{
this.aclId = aclId;
}
public Map<String, Object> getProperties()
public Map<String, String> getProperties()
{
return properties;
}
public void setProperties(Map<String, Object> properties)
public void setProperties(Map<String, String> properties)
{
this.properties = properties;
}

View File

@@ -73,4 +73,13 @@ public class NodeMetaData
{
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

@@ -0,0 +1,397 @@
package org.alfresco.repo.web.scripts.solr;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.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.JSONException;
import org.springframework.extensions.webscripts.json.JSONWriter;
public class SOLRSerializer
{
protected static final Log logger = LogFactory.getLog(SOLRSerializer.class);
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 <T> T serializeValue(Class<T> targetClass, Object value) throws JSONException
{
return typeConverter.INSTANCE.convert(targetClass, value);
}
public String serializeToString(Serializable value)
{
return typeConverter.INSTANCE.convert(String.class, value);
}
public String serialize(QName propName, Serializable value) throws IOException
{
if(value == null)
{
return null;
}
PropertyDefinition propertyDef = dictionaryService.getProperty(propName);
if(propertyDef == null)
{
throw new IllegalArgumentException("Could not find property definition for property " + propName);
}
boolean isMulti = propertyDef.isMultiValued();
if(isMulti)
{
if(!(value instanceof Collection))
{
throw new IllegalArgumentException("Multi value: expected a collection, got " + value.getClass().getName());
}
@SuppressWarnings("unchecked")
Collection<Serializable> c = (Collection<Serializable>)value;
StringWriter body = new StringWriter();
JSONWriter jsonOut = new JSONWriter(body);
jsonOut.startObject();
{
jsonOut.startArray();
for(Serializable o : c)
{
jsonOut.writeValue(serializeToString(o));
}
jsonOut.endArray();
}
jsonOut.endObject();
return body.toString();
}
else
{
return serializeToString(value);
}
}
@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);
}
}
// QName
INSTANCE.addConverter(QName.class, String.class, new TypeConverter.Converter<QName, String>()
{
public String convert(QName source)
{
return source.toPrefixString(SOLRTypeConverter.this.namespaceService);
}
});
// content
INSTANCE.addConverter(ContentDataWithId.class, String.class, new TypeConverter.Converter<ContentDataWithId, String>()
{
public String convert(ContentDataWithId source)
{
return String.valueOf(source.getId());
}
});
// 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();
}
});
// TODO should be list of Strings, need to double-check
// INSTANCE.addConverter(List.class, Path.class, new TypeConverter.Converter<List, Path>()
// {
// public Path convert(List source)
// {
//// try
//// {
// Path path = new Path();
// for(Object pathElementObj : source)
// {
// String pathElementStr = (String)pathElementObj;
// Path.Element pathElement = null;
// int idx = pathElementStr.indexOf("|");
// if(idx == -1)
// {
// throw new IllegalArgumentException("Unable to deserialize to Path Element, invalid string " + pathElementStr);
// }
//
// String prefix = pathElementStr.substring(0, idx+1);
// String suffix = pathElementStr.substring(idx+1);
// if(prefix.equals("a|"))
// {
// pathElement = INSTANCE.convert(Path.AttributeElement.class, suffix);
// }
// else if(prefix.equals("p|"))
// {
// pathElement = INSTANCE.convert(Path.ParentElement.class, suffix);
// }
// else if(prefix.equals("c|"))
// {
// pathElement = INSTANCE.convert(Path.ChildAssocElement.class, suffix);
// }
// else if(prefix.equals("s|"))
// {
// pathElement = INSTANCE.convert(Path.SelfElement.class, suffix);
// }
// else if(prefix.equals("ds|"))
// {
// pathElement = new Path.DescendentOrSelfElement();
// }
//// else if(prefix.equals("se|"))
//// {
//// pathElement = new JCRPath.SimpleElement(QName.createQName(suffix));
//// }
// else
// {
// throw new IllegalArgumentException("Unable to deserialize to Path, invalid path element string " + pathElementStr);
// }
//
// path.append(pathElement);
// }
// return path;
//// }
//// catch(JSONException e)
//// {
//// throw new IllegalArgumentException(e);
//// }
// }
// });
// 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();
}
});
}
}
}

View File

@@ -1,257 +0,0 @@
package org.alfresco.repo.web.scripts.solr.test;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.node.ContentDataWithId;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Period;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.PropertyMap;
import org.alfresco.util.SOLRDeserializer;
import org.alfresco.util.SOLRSerializer;
public class SOLRSerializerTests extends BaseWebScriptTest
{
static final String SOLR_TEST_MODEL_1_0_URI = "http://www.alfresco.org/model/solrtest/1.0";
static final QName TYPE_TEST_OBJECT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "testobject");
static final QName PROP_MLTEXT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "mlTextProp");
static final QName PROP_BOOL = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "boolProp");
static final QName PROP_LONG = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "longProp");
static final QName PROP_FLOAT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "floatProp");
static final QName PROP_DOUBLE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "doubleProp");
static final QName PROP_DATE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "dateProp");
static final QName PROP_DATETIME = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "dateTimeProp");
static final QName PROP_QNAME = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "qnameProp");
static final QName PROP_NODEREF = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "nodeRefProp");
static final QName PROP_CHILDASSOC = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "childAssocProp");
static final QName PROP_ASSOC = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "assocProp");
static final QName PROP_PATH = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "pathProp");
static final QName PROP_CATEGORY = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "categoryProp");
static final QName PROP_LOCALE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "localeProp");
static final QName PROP_PERIOD = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "periodProp");
static final QName PROP_ANY = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "anyProp");
private AuthenticationComponent authenticationComponent;
private TransactionService transactionService;
private RetryingTransactionHelper txnHelper;
private NodeService nodeService;
private FileFolderService fileFolderService;
private ContentService contentService;
private DictionaryService dictionaryService;
private RepoAdminService repoAdminService;
private SOLRSerializer solrSerializer;
private SOLRDeserializer solrDeserializer;
private StoreRef storeRef;
private NodeRef rootNodeRef;
@Override
public void setUp() throws Exception
{
ServiceRegistry serviceRegistry = (ServiceRegistry) getServer().getApplicationContext().getBean(ServiceRegistry.SERVICE_REGISTRY);
transactionService = serviceRegistry.getTransactionService();
txnHelper = transactionService.getRetryingTransactionHelper();
fileFolderService = serviceRegistry.getFileFolderService();
contentService = serviceRegistry.getContentService();
nodeService = serviceRegistry.getNodeService();
dictionaryService = serviceRegistry.getDictionaryService();
authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent");
repoAdminService = (RepoAdminService)getServer().getApplicationContext().getBean("repoAdminService");
solrSerializer = (SOLRSerializer)getServer().getApplicationContext().getBean("solrSerializer");
solrDeserializer = new SOLRDeserializer(dictionaryService);
authenticationComponent.setSystemUserAsCurrentUser();
InputStream modelStream = getClass().getClassLoader().getResourceAsStream("solr/solr-test-model.xml");
repoAdminService.deployModel(modelStream, "solr-test-model");
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
}
private NodeRef solrNode;
private Date date;
private MLText mlText;
private ChildAssociationRef childAssoc;
private AssociationRef assoc;
private List<NodeRef> multiCategory;
private NodeRef category;
private static String[] mlOrderable_en = new String[] { "AAAA BBBB", "EEEE FFFF", "II", "KK", "MM", "OO", "QQ", "SS", "UU", "AA", "CC" };
private static String[] mlOrderable_fr = new String[] { "CCCC DDDD", "GGGG HHHH", "JJ", "LL", "NN", "PP", "RR", "TT", "VV", "BB", "DD" };
private MLText makeMLText()
{
return makeMLText(0);
}
private MLText makeMLText(int position)
{
MLText ml = new MLText();
ml.addValue(Locale.ENGLISH, mlOrderable_en[position]);
ml.addValue(Locale.FRENCH, mlOrderable_fr[position]);
return ml;
}
private void buildTransaction()
{
PropertyMap props = new PropertyMap();
props.put(ContentModel.PROP_NAME, "Container1");
NodeRef container = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_FOLDER,
props).getChildRef();
FileInfo contentInfo = fileFolderService.create(container, "SolrNode", TYPE_TEST_OBJECT);
solrNode = contentInfo.getNodeRef();
ContentWriter writer = contentService.getWriter(solrNode, ContentModel.PROP_CONTENT, true);
writer.putContent("Some Content");
date = new Date();
mlText = makeMLText();
childAssoc = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN,
new NodeRef("testProtocol", "testID", "abcde"),
QName.createQName("testProtocol", "testID"),
new NodeRef("testProtocol", "testID", "xyz"));
assoc = new AssociationRef(
new NodeRef("testProtocol", "testID", "abcde"),
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "parts"),
new NodeRef("testProtocol", "testID", "xyz"));
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(PROP_BOOL, Boolean.TRUE);
properties.put(PROP_LONG, Long.valueOf(42));
properties.put(PROP_FLOAT, Float.valueOf(42.0f));
properties.put(PROP_DOUBLE, Double.valueOf(42.0));
properties.put(PROP_DATE, date);
properties.put(PROP_DATETIME, date);
properties.put(PROP_NODEREF, container);
properties.put(PROP_LOCALE, Locale.ITALY);
properties.put(PROP_QNAME, PROP_QNAME);
//properties.put(PROP_VERSION, new VersionNumber("1.0"));
properties.put(PROP_PERIOD, new Period("period|12"));
Path path = new Path();
Path.Element element0 = new Path.ChildAssocElement(new ChildAssociationRef(null, null, null, new NodeRef("testProtocol", "testID", "abcde")));
path.prepend(element0);
properties.put(PROP_PATH, path);
properties.put(PROP_ASSOC, assoc);
category = new NodeRef("testProtocol", "testID", "cat1");
properties.put(PROP_CATEGORY, (Serializable)category);
properties.put(PROP_CHILDASSOC, childAssoc);
properties.put(PROP_MLTEXT, mlText);
nodeService.setProperties(solrNode, properties);
}
public void testAll()
{
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
buildTransaction();
Serializable value = nodeService.getProperty(solrNode, ContentModel.PROP_NAME);
Object serialized = solrSerializer.serialize(ContentModel.PROP_NAME, value);
Serializable deserialized = solrDeserializer.deserialize(ContentModel.PROP_NAME, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_MLTEXT);
serialized = solrSerializer.serialize(PROP_MLTEXT, value);
deserialized = solrDeserializer.deserialize(PROP_MLTEXT, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, ContentModel.PROP_CONTENT);
assertTrue("Expected ContentDataId, got " + value.getClass().getName(), value instanceof ContentDataWithId);
serialized = solrSerializer.serialize(ContentModel.PROP_CONTENT, value);
deserialized = solrDeserializer.deserialize(ContentModel.PROP_CONTENT, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_BOOL);
serialized = solrSerializer.serialize(PROP_BOOL, value);
deserialized = solrDeserializer.deserialize(PROP_BOOL, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_DATE);
assertTrue("Expected Date object, got " + value.getClass().getName(), value instanceof Date);
serialized = solrSerializer.serialize(PROP_DATE, value);
deserialized = solrDeserializer.deserialize(PROP_DATE, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_DATETIME);
assertTrue("Expected Date object, got " + value.getClass().getName(), value instanceof Date);
serialized = solrSerializer.serialize(PROP_DATETIME, value);
deserialized = solrDeserializer.deserialize(PROP_DATETIME, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_DOUBLE);
assertTrue("Expected Double object, got " + value.getClass().getName(), value instanceof Double);
serialized = solrSerializer.serialize(PROP_DATETIME, value);
deserialized = solrDeserializer.deserialize(PROP_DATETIME, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_FLOAT);
assertTrue("Expected Float object, got " + value.getClass().getName(), value instanceof Float);
serialized = solrSerializer.serialize(PROP_FLOAT, value);
deserialized = solrDeserializer.deserialize(PROP_FLOAT, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_LONG);
assertTrue("Expected Long object, got " + value.getClass().getName(), value instanceof Long);
serialized = solrSerializer.serialize(PROP_LONG, value);
deserialized = solrDeserializer.deserialize(PROP_LONG, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_CHILDASSOC);
serialized = solrSerializer.serialize(PROP_CHILDASSOC, value);
deserialized = solrDeserializer.deserialize(PROP_CHILDASSOC, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_ASSOC);
serialized = solrSerializer.serialize(PROP_ASSOC, value);
deserialized = solrDeserializer.deserialize(PROP_ASSOC, serialized);
assertEquals(value, deserialized);
value = nodeService.getProperty(solrNode, PROP_CATEGORY);
serialized = solrSerializer.serialize(PROP_ASSOC, value);
deserialized = solrDeserializer.deserialize(PROP_ASSOC, serialized);
assertEquals(value, deserialized);
return null;
}
});
}
}