mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Checkin for RSOLR 031: "Remote API to get and compare models"
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28472 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -371,7 +371,6 @@ public class NodePropertyHelper
|
||||
}
|
||||
}
|
||||
|
||||
// TODO decrypt TEXT and MLTEXT properties where necessary
|
||||
public Map<QName, Serializable> convertToPublicProperties(Map<NodePropertyKey, NodePropertyValue> propertyValues)
|
||||
{
|
||||
Map<QName, Serializable> propertyMap = new HashMap<QName, Serializable>(propertyValues.size(), 1.0F);
|
||||
|
55
source/java/org/alfresco/repo/solr/AlfrescoModel.java
Normal file
55
source/java/org/alfresco/repo/solr/AlfrescoModel.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package org.alfresco.repo.solr;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
|
||||
/**
|
||||
* Represents an alfresco model and checksum.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class AlfrescoModel
|
||||
{
|
||||
private ModelDefinition modelDef;
|
||||
private long checksum;
|
||||
|
||||
protected AlfrescoModel(ModelDefinition modelDef)
|
||||
{
|
||||
this.modelDef = modelDef;
|
||||
this.checksum = modelDef.getChecksum(ModelDefinition.XMLBindingType.SOLR);
|
||||
}
|
||||
|
||||
public ModelDefinition getModelDef()
|
||||
{
|
||||
return modelDef;
|
||||
}
|
||||
|
||||
public long getChecksum()
|
||||
{
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (this == other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!(other instanceof AlfrescoModel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AlfrescoModel model = (AlfrescoModel)other;
|
||||
return (modelDef.getName().equals(model.getModelDef().getName()) &&
|
||||
checksum == model.getChecksum());
|
||||
}
|
||||
|
||||
public int hashcode()
|
||||
{
|
||||
int result = 17;
|
||||
result = 31 * result + modelDef.hashCode();
|
||||
result = 31 * result + Long.valueOf(checksum).hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
52
source/java/org/alfresco/repo/solr/AlfrescoModelDiff.java
Normal file
52
source/java/org/alfresco/repo/solr/AlfrescoModelDiff.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package org.alfresco.repo.solr;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Represents a diff between the set of current repository Alfresco models and the set maintained in SOLR.
|
||||
* The diff can represent a new, changed or removed Alfresco model. For a new model the newChecksum is
|
||||
* populated; for a changed model both checksums are populated; for a removed model neither checksum is populated.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class AlfrescoModelDiff
|
||||
{
|
||||
public static enum TYPE
|
||||
{
|
||||
NEW, CHANGED, REMOVED;
|
||||
};
|
||||
|
||||
private QName modelName;
|
||||
private TYPE type;
|
||||
private Long oldChecksum;
|
||||
private Long newChecksum;
|
||||
|
||||
public AlfrescoModelDiff(QName modelName, TYPE type, Long oldChecksum, Long newChecksum)
|
||||
{
|
||||
super();
|
||||
this.modelName = modelName;
|
||||
this.type = type;
|
||||
this.oldChecksum = oldChecksum;
|
||||
this.newChecksum = newChecksum;
|
||||
}
|
||||
|
||||
public QName getModelName()
|
||||
{
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public TYPE getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public Long getOldChecksum()
|
||||
{
|
||||
return oldChecksum;
|
||||
}
|
||||
|
||||
public Long getNewChecksum()
|
||||
{
|
||||
return newChecksum;
|
||||
}
|
||||
}
|
@@ -19,8 +19,11 @@
|
||||
package org.alfresco.repo.solr;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Interface for component to provide tracking data for SOLR.
|
||||
@@ -84,7 +87,24 @@ public interface SOLRTrackingComponent
|
||||
* @param callback a callback to receive the results
|
||||
*/
|
||||
public void getNodesMetadata(NodeMetaDataParameters nodeMetaDataParameters, MetaDataResultsFilter resultFilter, NodeMetaDataQueryCallback callback);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the Alfresco model given by the name modelName
|
||||
*
|
||||
* @param modelName the name of the model
|
||||
* @return the model plus a checksum
|
||||
*/
|
||||
public AlfrescoModel getModel(QName modelName);
|
||||
|
||||
/**
|
||||
* Returns a list of diffs representing differences between the current Repository models
|
||||
* and those passed in the models parameter.
|
||||
*
|
||||
* @param models a set of mappings of model names to checksums
|
||||
* @return a list of diffs between those in the repository and those passed in the models parameter
|
||||
*/
|
||||
public List<AlfrescoModelDiff> getModelDiffs(Map<QName, Long> models);
|
||||
|
||||
/**
|
||||
* The interface that will be used to give query results to the calling code.
|
||||
*/
|
||||
|
@@ -28,6 +28,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.node.NodeDAO.ChildAssocRefQueryCallback;
|
||||
@@ -37,6 +38,7 @@ import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
@@ -59,6 +61,7 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
|
||||
private NodeDAO nodeDAO;
|
||||
private QNameDAO qnameDAO;
|
||||
private SOLRDAO solrDAO;
|
||||
private DictionaryDAO dictionaryDAO;
|
||||
private PermissionService permissionService;
|
||||
private OwnableService ownableService;
|
||||
private TenantService tenantService;
|
||||
@@ -524,6 +527,62 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
|
||||
rowHandler.processResult(nodeMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public AlfrescoModel getModel(QName modelName)
|
||||
{
|
||||
ModelDefinition modelDef = dictionaryService.getModel(modelName);
|
||||
return (modelDef != null ? new AlfrescoModel(modelDef) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public List<AlfrescoModelDiff> getModelDiffs(Map<QName, Long> models)
|
||||
{
|
||||
List<AlfrescoModelDiff> diffs = new ArrayList<AlfrescoModelDiff>();
|
||||
|
||||
// get all models the repository knows about and add each to a list with its checksum
|
||||
Collection<QName> allModels = dictionaryService.getAllModels();
|
||||
|
||||
// look for changed and removed models
|
||||
for(QName modelName : models.keySet())
|
||||
{
|
||||
if(allModels.contains(modelName))
|
||||
{
|
||||
Long checksum = models.get(modelName);
|
||||
AlfrescoModel serverModel = getModel(modelName);
|
||||
if(serverModel.getChecksum() != checksum.longValue())
|
||||
{
|
||||
// model has changed, add the changed server model
|
||||
diffs.add(new AlfrescoModelDiff(modelName,
|
||||
AlfrescoModelDiff.TYPE.CHANGED, checksum, serverModel.getChecksum()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// model no longer exists, just add it's name
|
||||
diffs.add(new AlfrescoModelDiff(modelName,
|
||||
AlfrescoModelDiff.TYPE.REMOVED, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
// look for new models
|
||||
for(QName modelName : allModels)
|
||||
{
|
||||
if(!models.containsKey(modelName))
|
||||
{
|
||||
// new model, add the model xml and checksum
|
||||
AlfrescoModel model = getModel(modelName);
|
||||
diffs.add(new AlfrescoModelDiff(modelName,
|
||||
AlfrescoModelDiff.TYPE.NEW, null, model.getChecksum()));
|
||||
}
|
||||
}
|
||||
|
||||
return diffs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that passes results from a result entity into the client callback
|
||||
|
@@ -18,8 +18,10 @@
|
||||
*/
|
||||
package org.alfresco.repo.solr;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +30,10 @@ import java.util.Set;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||
import org.alfresco.repo.dictionary.M2Model;
|
||||
import org.alfresco.repo.dictionary.M2Property;
|
||||
import org.alfresco.repo.dictionary.M2Type;
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
@@ -36,11 +42,13 @@ import org.alfresco.repo.solr.SOLRTrackingComponent.NodeQueryCallback;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
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.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
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.ApplicationContextHelper;
|
||||
@@ -66,10 +74,13 @@ public class SOLRTrackingComponentTest extends TestCase
|
||||
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private TransactionService transactionService;
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private RetryingTransactionHelper txnHelper;
|
||||
private NodeService nodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
private NodeDAO nodeDAO;
|
||||
private DictionaryDAO dictionaryDAO;
|
||||
private SOLRTrackingComponent solrTrackingComponent;
|
||||
|
||||
private StoreRef storeRef;
|
||||
@@ -84,8 +95,11 @@ public class SOLRTrackingComponentTest extends TestCase
|
||||
|
||||
solrTrackingComponent = (SOLRTrackingComponent) ctx.getBean("solrTrackingComponent");
|
||||
nodeDAO = (NodeDAO)ctx.getBean("nodeDAO");
|
||||
dictionaryDAO = (DictionaryDAO)ctx.getBean("dictionaryDAO");
|
||||
nodeService = (NodeService)ctx.getBean("NodeService");
|
||||
fileFolderService = (FileFolderService)ctx.getBean("FileFolderService");
|
||||
dictionaryService = serviceRegistry.getDictionaryService();
|
||||
namespaceService = serviceRegistry.getNamespaceService();
|
||||
authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
|
||||
|
||||
authenticationComponent.setSystemUserAsCurrentUser();
|
||||
@@ -302,7 +316,138 @@ public class SOLRTrackingComponentTest extends TestCase
|
||||
nodeMetaDataParams.setNodeIds(st.getNodeIds());
|
||||
getNodeMetaData(nodeMetaDataParams, null, st);
|
||||
}
|
||||
|
||||
public void testModelDiffs()
|
||||
{
|
||||
Collection<QName> allModels = dictionaryService.getAllModels();
|
||||
|
||||
ModelDiffsTracker tracker = new ModelDiffsTracker();
|
||||
ModelDiffResults diffResults = tracker.diff();
|
||||
|
||||
// number of diffs should equal the number of models in the repository
|
||||
assertEquals("Unexpected number of new models", allModels.size(), diffResults.getNewModels().size());
|
||||
assertEquals("Expected no removed models", 0, diffResults.getRemovedModels().size());
|
||||
assertEquals("Expected no changed models", 0, diffResults.getChangedModels().size());
|
||||
|
||||
// create a new model
|
||||
InputStream modelStream = getClass().getClassLoader().getResourceAsStream("org/alfresco/repo/solr/testModel.xml");
|
||||
M2Model testModel = M2Model.createModel(modelStream);
|
||||
dictionaryDAO.putModel(testModel);
|
||||
|
||||
// call model diffs - should detect new model
|
||||
ModelDiffResults diffResults1 = tracker.diff();
|
||||
assertEquals("Expected 1 new model", 1, diffResults1.getNewModels().size());
|
||||
assertEquals("Unexpected number of changed models", 0, diffResults1.getChangedModels().size());
|
||||
assertEquals("Unexpected number of removed models", 0, diffResults1.getRemovedModels().size());
|
||||
AlfrescoModelDiff diff = diffResults1.getNewModels().get(0);
|
||||
assertEquals("Unexpected model name change", QName.createQName(testModel.getName(), namespaceService), diff.getModelName());
|
||||
|
||||
// get current checksum for the test model
|
||||
Long testModelChecksum = tracker.getChecksum(QName.createQName(testModel.getName(), namespaceService));
|
||||
assertNotNull("", testModelChecksum);
|
||||
|
||||
// create a new type and add it to the new test model
|
||||
M2Type anotherType = testModel.createType("anothertype");
|
||||
M2Property prop1 = anotherType.createProperty("prop1");
|
||||
prop1.setType("d:text");
|
||||
|
||||
// call model diffs - should detect test model changes
|
||||
ModelDiffResults diffResults2 = tracker.diff();
|
||||
List<AlfrescoModelDiff> changedModels = diffResults2.getChangedModels();
|
||||
assertEquals("Expected no new models", 0, diffResults2.getNewModels().size());
|
||||
assertEquals("Expected no removed models", 0, diffResults2.getRemovedModels().size());
|
||||
assertEquals("Expected detection of changed testmodel", 1, changedModels.size());
|
||||
|
||||
AlfrescoModelDiff changedModel = changedModels.get(0);
|
||||
assertEquals("Unexpected changed model name", QName.createQName(testModel.getName(), namespaceService),
|
||||
changedModel.getModelName());
|
||||
assertNotNull("", changedModel.getOldChecksum().longValue());
|
||||
assertEquals("Old checksum value is incorrect", testModelChecksum.longValue(), changedModel.getOldChecksum().longValue());
|
||||
assertNotSame("Expected checksums to be different", changedModel.getOldChecksum(), changedModel.getNewChecksum());
|
||||
|
||||
// remove the model
|
||||
dictionaryDAO.removeModel(QName.createQName(testModel.getName(), namespaceService));
|
||||
|
||||
// call model diffs - check that the model has been removed
|
||||
ModelDiffResults diffResults3 = tracker.diff();
|
||||
List<AlfrescoModelDiff> removedModels = diffResults3.getRemovedModels();
|
||||
assertEquals("Expected 1 removed model", 1, removedModels.size());
|
||||
QName removedModelName = removedModels.get(0).getModelName();
|
||||
String removedModelNamespace = removedModelName.getNamespaceURI();
|
||||
String removedModelLocalName = removedModelName.getLocalName();
|
||||
assertEquals("Removed model namespace is incorrect", "http://www.alfresco.org/model/solrtest/1.0", removedModelNamespace);
|
||||
assertEquals("Removed model name is incorrect", "contentmodel", removedModelLocalName);
|
||||
assertEquals("Expected no new models", 0, diffResults3.getNewModels().size());
|
||||
assertEquals("Expected no changed modeks", 0, diffResults3.getChangedModels().size());
|
||||
}
|
||||
|
||||
private static class ModelDiffResults
|
||||
{
|
||||
private List<AlfrescoModelDiff> newModels;
|
||||
private List<AlfrescoModelDiff> changedModels;
|
||||
private List<AlfrescoModelDiff> removedModels;
|
||||
|
||||
public ModelDiffResults(List<AlfrescoModelDiff> newModels, List<AlfrescoModelDiff> changedModels, List<AlfrescoModelDiff> removedModels)
|
||||
{
|
||||
super();
|
||||
this.newModels = newModels;
|
||||
this.changedModels = changedModels;
|
||||
this.removedModels = removedModels;
|
||||
}
|
||||
|
||||
public List<AlfrescoModelDiff> getNewModels()
|
||||
{
|
||||
return newModels;
|
||||
}
|
||||
|
||||
public List<AlfrescoModelDiff> getChangedModels()
|
||||
{
|
||||
return changedModels;
|
||||
}
|
||||
|
||||
public List<AlfrescoModelDiff> getRemovedModels()
|
||||
{
|
||||
return removedModels;
|
||||
}
|
||||
}
|
||||
|
||||
private class ModelDiffsTracker
|
||||
{
|
||||
private Map<QName, Long> trackedModels = new HashMap<QName, Long>();
|
||||
|
||||
public ModelDiffResults diff()
|
||||
{
|
||||
List<AlfrescoModelDiff> modelDiffs = solrTrackingComponent.getModelDiffs(trackedModels);
|
||||
List<AlfrescoModelDiff> newModels = new ArrayList<AlfrescoModelDiff>();
|
||||
List<AlfrescoModelDiff> changedModels = new ArrayList<AlfrescoModelDiff>();
|
||||
List<AlfrescoModelDiff> removedModels = new ArrayList<AlfrescoModelDiff>();
|
||||
|
||||
for(AlfrescoModelDiff diff : modelDiffs)
|
||||
{
|
||||
if(diff.getType().equals(AlfrescoModelDiff.TYPE.NEW))
|
||||
{
|
||||
newModels.add(diff);
|
||||
trackedModels.put(diff.getModelName(), diff.getNewChecksum());
|
||||
}
|
||||
else if(diff.getType().equals(AlfrescoModelDiff.TYPE.CHANGED))
|
||||
{
|
||||
changedModels.add(diff);
|
||||
}
|
||||
else if(diff.getType().equals(AlfrescoModelDiff.TYPE.REMOVED))
|
||||
{
|
||||
removedModels.add(diff);
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelDiffResults(newModels, changedModels, removedModels);
|
||||
}
|
||||
|
||||
public Long getChecksum(QName modelName)
|
||||
{
|
||||
return trackedModels.get(modelName);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NodeAssertions
|
||||
{
|
||||
private Set<QName> aspects;
|
||||
|
129
source/java/org/alfresco/repo/solr/testModel.xml
Normal file
129
source/java/org/alfresco/repo/solr/testModel.xml
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- xsi:schemaLocation="http://www.alfresco.org/model/dictionary/1.0 modelSchema.xsd" -->
|
||||
<model name="testcm:contentmodel"
|
||||
xmlns="http://www.alfresco.org/model/dictionary/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<description>Alfresco Content Domain Model</description>
|
||||
<author>Alfresco</author>
|
||||
<published>2009-06-04</published>
|
||||
<version>1.1</version>
|
||||
|
||||
<imports>
|
||||
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
|
||||
</imports>
|
||||
|
||||
<namespaces>
|
||||
<namespace uri="http://www.alfresco.org/model/solrtest/1.0" prefix="testcm"/>
|
||||
</namespaces>
|
||||
|
||||
<constraints>
|
||||
<constraint name="testcm:filename" type="REGEX">
|
||||
<parameter name="expression"><value><![CDATA[(.*[\"\*\\\>\<\?\/\:\|]+.*)|(.*[\.]?.*[\.]+$)|(.*[ ]+$)]]></value></parameter>
|
||||
<parameter name="requiresMatch"><value>false</value></parameter>
|
||||
</constraint>
|
||||
<constraint name="testcm:userNameConstraint" type="org.alfresco.repo.dictionary.constraint.UserNameConstraint" />
|
||||
<constraint name="testcm:authorityNameConstraint" type="org.alfresco.repo.dictionary.constraint.AuthorityNameConstraint" />
|
||||
<constraint name="testcm:storeSelectorConstraint" type="REGISTERED">
|
||||
<parameter name="registeredName"><value>defaultStoreSelector</value></parameter>
|
||||
</constraint>
|
||||
</constraints>
|
||||
|
||||
<types>
|
||||
|
||||
<type name="testcm:testobject">
|
||||
<title>Object</title>
|
||||
<parent>sys:base</parent>
|
||||
<properties>
|
||||
<property name="testcm:name">
|
||||
<title>Name</title>
|
||||
<type>d:text</type>
|
||||
<mandatory enforced="true">true</mandatory>
|
||||
<index enabled="true">
|
||||
<atomic>true</atomic>
|
||||
<stored>false</stored>
|
||||
<tokenised>both</tokenised>
|
||||
</index>
|
||||
<constraints>
|
||||
<constraint ref="testcm:filename" />
|
||||
</constraints>
|
||||
</property>
|
||||
</properties>
|
||||
<mandatory-aspects>
|
||||
<aspect>testcm:testaspect</aspect>
|
||||
</mandatory-aspects>
|
||||
</type>
|
||||
|
||||
<type name="testcm:folder">
|
||||
<title>Folder</title>
|
||||
<parent>testcm:testobject</parent>
|
||||
<archive>true</archive>
|
||||
<associations>
|
||||
<child-association name="testcm:contains">
|
||||
<source>
|
||||
<mandatory>false</mandatory>
|
||||
<many>true</many>
|
||||
</source>
|
||||
<target>
|
||||
<class>sys:base</class>
|
||||
<mandatory>false</mandatory>
|
||||
<many>true</many>
|
||||
</target>
|
||||
<duplicate>false</duplicate>
|
||||
<propagateTimestamps>true</propagateTimestamps>
|
||||
</child-association>
|
||||
</associations>
|
||||
</type>
|
||||
|
||||
<type name="testcm:content">
|
||||
<title>Content</title>
|
||||
<parent>testcm:testobject</parent>
|
||||
<archive>true</archive>
|
||||
<properties>
|
||||
<property name="testcm:content">
|
||||
<type>d:content</type>
|
||||
<mandatory>false</mandatory>
|
||||
<!-- Although content is marked as indexed atomically it may end up asynchronous -->
|
||||
<!-- if the content conversion will take too long. Content that does not require conversion -->
|
||||
<!-- to UTF8 test/plain will always be indexed atomically -->
|
||||
<index enabled="true">
|
||||
<atomic>true</atomic>
|
||||
<stored>false</stored>
|
||||
<tokenised>true</tokenised>
|
||||
</index>
|
||||
</property>
|
||||
</properties>
|
||||
</type>
|
||||
|
||||
</types>
|
||||
|
||||
<aspects>
|
||||
|
||||
<aspect name="testcm:testaspect">
|
||||
<title>Titled</title>
|
||||
<properties>
|
||||
<property name="testcm:title">
|
||||
<title>Title</title>
|
||||
<type>d:mltext</type>
|
||||
<index enabled="true">
|
||||
<atomic>true</atomic>
|
||||
<stored>false</stored>
|
||||
<tokenised>both</tokenised>
|
||||
</index>
|
||||
</property>
|
||||
<property name="testcm:description">
|
||||
<title>Description</title>
|
||||
<type>d:mltext</type>
|
||||
<index enabled="true">
|
||||
<atomic>true</atomic>
|
||||
<stored>false</stored>
|
||||
<tokenised>both</tokenised>
|
||||
</index>
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
|
||||
</aspects>
|
||||
|
||||
</model>
|
Reference in New Issue
Block a user