mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
- Action web service implementation
- Simple Ruby web service examples - Outstanding work around persiatancy of models in the repository git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2094 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -79,4 +79,12 @@ public interface DictionaryDAO extends ModelQuery
|
||||
*/
|
||||
public void putModel(M2Model model);
|
||||
|
||||
/**
|
||||
* Removes a model from the dictionary. The types and aspect in the model will no longer be
|
||||
* available.
|
||||
*
|
||||
* @param model the qname of the model to remove
|
||||
*/
|
||||
public void removeModel(QName model);
|
||||
|
||||
}
|
||||
|
@@ -100,6 +100,28 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
||||
compiledModels.put(modelName, compiledModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.dictionary.DictionaryDAO#removeModel(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public void removeModel(QName modelName)
|
||||
{
|
||||
CompiledModel compiledModel = this.compiledModels.get(modelName);
|
||||
if (compiledModel != null)
|
||||
{
|
||||
// Remove the namespaces from the namespace service
|
||||
M2Model model = compiledModel.getM2Model();
|
||||
for (M2Namespace namespace : model.getNamespaces())
|
||||
{
|
||||
namespaceDAO.removePrefix(namespace.getPrefix());
|
||||
namespaceDAO.removeURI(namespace.getUri());
|
||||
namespaceToModel.remove(namespace.getUri());
|
||||
}
|
||||
|
||||
// Remove the model from the list
|
||||
this.compiledModels.remove(modelName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param uri the namespace uri
|
||||
|
@@ -124,6 +124,18 @@ public class DictionaryModelType
|
||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||
new JavaBehaviour(this, "onContentUpdate"));
|
||||
|
||||
// Register interest in the onPropertyUpdate policy for the dictionary model type
|
||||
policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||
new JavaBehaviour(this, "onUpdateProperties"));
|
||||
|
||||
// Register interest in the node delete policy
|
||||
policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||
|
||||
// Create the transaction listener
|
||||
this.transactionListener = new DictionaryModelTypeTransactionListener(this.nodeService, this.contentService);
|
||||
}
|
||||
@@ -133,8 +145,13 @@ public class DictionaryModelType
|
||||
*
|
||||
* @param nodeRef the node reference whose content has been updated
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onContentUpdate(NodeRef nodeRef)
|
||||
{
|
||||
queueModel(nodeRef);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void queueModel(NodeRef nodeRef)
|
||||
{
|
||||
Set<NodeRef> pendingModelUpdates = (Set<NodeRef>)AlfrescoTransactionSupport.getResource(KEY_PENDING_MODELS);
|
||||
if (pendingModelUpdates == null)
|
||||
@@ -147,9 +164,52 @@ public class DictionaryModelType
|
||||
AlfrescoTransactionSupport.bindListener(this.transactionListener);
|
||||
}
|
||||
|
||||
// TODO need to listen for a change in the modelActive attribute and update appropriatly
|
||||
/**
|
||||
* On update properties behaviour implementation
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @param before the values of the properties before update
|
||||
* @param after the values of the properties after the update
|
||||
*/
|
||||
public void onUpdateProperties(
|
||||
NodeRef nodeRef,
|
||||
Map<QName, Serializable> before,
|
||||
Map<QName, Serializable> after)
|
||||
{
|
||||
Boolean beforeValue = (Boolean)before.get(ContentModel.PROP_MODEL_ACTIVE);
|
||||
Boolean afterValue = (Boolean)after.get(ContentModel.PROP_MODEL_ACTIVE);
|
||||
|
||||
// TODO need to listen for node deletion and act accordingly
|
||||
if (beforeValue == null && afterValue != null)
|
||||
{
|
||||
queueModel(nodeRef);
|
||||
}
|
||||
else if (afterValue == null && beforeValue != null)
|
||||
{
|
||||
// Remove the model since the value has been cleared
|
||||
queueModel(nodeRef);
|
||||
}
|
||||
else if (beforeValue != null && afterValue != null && beforeValue.equals(afterValue) == false)
|
||||
{
|
||||
queueModel(nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
// Ignore if the node is a working copy
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
|
||||
{
|
||||
QName modelName = (QName)this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_NAME);
|
||||
if (modelName != null)
|
||||
{
|
||||
// Remove the model from the dictionary
|
||||
dictionaryDAO.removeModel(modelName);
|
||||
|
||||
// TODO how can we make this transactional ??
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dictionary model type transaction listener class.
|
||||
@@ -190,7 +250,7 @@ public class DictionaryModelType
|
||||
for (NodeRef nodeRef : pendingModels)
|
||||
{
|
||||
// Find out whether the model is active (by default it is)
|
||||
boolean isActive = true;
|
||||
boolean isActive = false;
|
||||
Boolean value = (Boolean)nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_ACTIVE);
|
||||
if (value != null)
|
||||
{
|
||||
@@ -198,36 +258,47 @@ public class DictionaryModelType
|
||||
}
|
||||
|
||||
// Ignore if the node is a working copy or if its inactive
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false &&
|
||||
isActive == true)
|
||||
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
|
||||
{
|
||||
// 1. Compile the model and update the details on the node
|
||||
// 2. Re-put the model
|
||||
|
||||
ContentReader contentReader = this.contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||
if (contentReader != null)
|
||||
if (isActive == true)
|
||||
{
|
||||
// Create a model from the current content
|
||||
M2Model m2Model = M2Model.createModel(contentReader.getContentInputStream());
|
||||
// TODO what do we do if we don't have a model??
|
||||
// 1. Compile the model and update the details on the node
|
||||
// 2. Re-put the model
|
||||
|
||||
// Try and compile the model
|
||||
ModelDefinition modelDefintion = m2Model.compile(dictionaryDAO, namespaceDAO).getModelDefinition();
|
||||
// TODO what do we do if the model does not compile
|
||||
ContentReader contentReader = this.contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||
if (contentReader != null)
|
||||
{
|
||||
// Create a model from the current content
|
||||
M2Model m2Model = M2Model.createModel(contentReader.getContentInputStream());
|
||||
// TODO what do we do if we don't have a model??
|
||||
|
||||
// Update the meta data for the model
|
||||
Map<QName, Serializable> props = this.nodeService.getProperties(nodeRef);
|
||||
props.put(ContentModel.PROP_MODEL_NAME, modelDefintion.getName());
|
||||
props.put(ContentModel.PROP_MODEL_DESCRIPTION, modelDefintion.getDescription());
|
||||
props.put(ContentModel.PROP_MODEL_AUTHOR, modelDefintion.getAuthor());
|
||||
props.put(ContentModel.PROP_MODEL_PUBLISHED_DATE, modelDefintion.getPublishedDate());
|
||||
props.put(ContentModel.PROP_MODEL_VERSION, modelDefintion.getVersion());
|
||||
this.nodeService.setProperties(nodeRef, props);
|
||||
// Try and compile the model
|
||||
ModelDefinition modelDefintion = m2Model.compile(dictionaryDAO, namespaceDAO).getModelDefinition();
|
||||
// TODO what do we do if the model does not compile
|
||||
|
||||
// TODO how do we get the dependancies for this model ??
|
||||
// Update the meta data for the model
|
||||
Map<QName, Serializable> props = this.nodeService.getProperties(nodeRef);
|
||||
props.put(ContentModel.PROP_MODEL_NAME, modelDefintion.getName());
|
||||
props.put(ContentModel.PROP_MODEL_DESCRIPTION, modelDefintion.getDescription());
|
||||
props.put(ContentModel.PROP_MODEL_AUTHOR, modelDefintion.getAuthor());
|
||||
props.put(ContentModel.PROP_MODEL_PUBLISHED_DATE, modelDefintion.getPublishedDate());
|
||||
props.put(ContentModel.PROP_MODEL_VERSION, modelDefintion.getVersion());
|
||||
this.nodeService.setProperties(nodeRef, props);
|
||||
|
||||
// Put the model
|
||||
dictionaryDAO.putModel(m2Model);
|
||||
// TODO how do we get the dependancies for this model ??
|
||||
|
||||
// Put the model
|
||||
dictionaryDAO.putModel(m2Model);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QName modelName = (QName)this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_NAME);
|
||||
if (modelName != null)
|
||||
{
|
||||
// Remove the model from the dictionary
|
||||
dictionaryDAO.removeModel(modelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,6 +322,7 @@ public class DictionaryModelType
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#afterRollback()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void afterRollback()
|
||||
{
|
||||
}
|
||||
|
@@ -112,6 +112,7 @@ public class DictionaryModelTypeTest extends BaseAlfrescoSpringTest
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private CheckOutCheckInService cociService;
|
||||
private DictionaryDAO dictionaryDAO;
|
||||
|
||||
/**
|
||||
* On setup in transaction override
|
||||
@@ -126,6 +127,7 @@ public class DictionaryModelTypeTest extends BaseAlfrescoSpringTest
|
||||
this.dictionaryService = (DictionaryService)this.applicationContext.getBean("dictionaryService");
|
||||
this.namespaceService = (NamespaceService)this.applicationContext.getBean("namespaceService");
|
||||
this.cociService = (CheckOutCheckInService)this.applicationContext.getBean("checkOutCheckInService");
|
||||
this.dictionaryDAO = (DictionaryDAO)this.applicationContext.getBean("dictionaryDAO");
|
||||
|
||||
}
|
||||
|
||||
@@ -224,4 +226,125 @@ public class DictionaryModelTypeTest extends BaseAlfrescoSpringTest
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void testIsActiveFlagAndDelete()
|
||||
{
|
||||
this.dictionaryDAO.removeModel(TEST_MODEL_ONE);
|
||||
|
||||
try
|
||||
{
|
||||
// Check that the model has not yet been loaded into the dictionary
|
||||
this.dictionaryService.getModel(TEST_MODEL_ONE);
|
||||
fail("This model has not yet been loaded into the dictionary service");
|
||||
}
|
||||
catch (DictionaryException exception)
|
||||
{
|
||||
// We expect this exception
|
||||
}
|
||||
|
||||
// Create a model node
|
||||
PropertyMap properties = new PropertyMap(1);
|
||||
final NodeRef modelNode = this.nodeService.createNode(
|
||||
this.rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "dictionaryModels"),
|
||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||
properties).getChildRef();
|
||||
assertNotNull(modelNode);
|
||||
|
||||
// Add the model content to the model node
|
||||
ContentWriter contentWriter = this.contentService.getWriter(modelNode, ContentModel.PROP_CONTENT, true);
|
||||
contentWriter.setEncoding("UTF-8");
|
||||
contentWriter.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||
contentWriter.putContent(MODEL_ONE_XML);
|
||||
|
||||
// End the transaction to force update
|
||||
setComplete();
|
||||
endTransaction();
|
||||
|
||||
TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionUtil.TransactionWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// The model should not yet be loaded
|
||||
try
|
||||
{
|
||||
// Check that the model has not yet been loaded into the dictionary
|
||||
DictionaryModelTypeTest.this.dictionaryService.getModel(TEST_MODEL_ONE);
|
||||
fail("This model has not yet been loaded into the dictionary service");
|
||||
}
|
||||
catch (DictionaryException exception)
|
||||
{
|
||||
// We expect this exception
|
||||
}
|
||||
|
||||
// Set the isActive flag
|
||||
DictionaryModelTypeTest.this.nodeService.setProperty(modelNode, ContentModel.PROP_MODEL_ACTIVE, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionUtil.TransactionWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// The model should now be loaded
|
||||
assertNotNull(DictionaryModelTypeTest.this.dictionaryService.getModel(TEST_MODEL_ONE));
|
||||
|
||||
// Set the isActive flag
|
||||
DictionaryModelTypeTest.this.nodeService.setProperty(modelNode, ContentModel.PROP_MODEL_ACTIVE, false);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionUtil.TransactionWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// The model should not be loaded
|
||||
try
|
||||
{
|
||||
// Check that the model has not yet been loaded into the dictionary
|
||||
DictionaryModelTypeTest.this.dictionaryService.getModel(TEST_MODEL_ONE);
|
||||
fail("This model has not yet been loaded into the dictionary service");
|
||||
}
|
||||
catch (DictionaryException exception)
|
||||
{
|
||||
// We expect this exception
|
||||
}
|
||||
|
||||
// Set the isActive flag
|
||||
DictionaryModelTypeTest.this.nodeService.setProperty(modelNode, ContentModel.PROP_MODEL_ACTIVE, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionUtil.TransactionWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// The model should now be loaded
|
||||
assertNotNull(DictionaryModelTypeTest.this.dictionaryService.getModel(TEST_MODEL_ONE));
|
||||
|
||||
DictionaryModelTypeTest.this.nodeService.deleteNode(modelNode);
|
||||
|
||||
// The model should not be loaded
|
||||
try
|
||||
{
|
||||
// Check that the model has not yet been loaded into the dictionary
|
||||
DictionaryModelTypeTest.this.dictionaryService.getModel(TEST_MODEL_ONE);
|
||||
fail("This model has not yet been loaded into the dictionary service");
|
||||
}
|
||||
catch (DictionaryException exception)
|
||||
{
|
||||
// We expect this exception
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user