- 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:
Roy Wetherall
2006-01-10 14:51:45 +00:00
parent 2558f93b97
commit aed810b0c3
4 changed files with 257 additions and 32 deletions

View File

@@ -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);
}

View File

@@ -99,6 +99,28 @@ public class DictionaryDAOImpl implements DictionaryDAO
// Publish new Model Definition
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);
}
}
/**

View File

@@ -44,7 +44,7 @@ public class DictionaryModelType
{
/** Key to the pending models */
private static final String KEY_PENDING_MODELS = "dictionaryModelType.pendingModels";
/** The dictionary DAO */
private DictionaryDAO dictionaryDAO;
@@ -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);
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);
}
}
// TODO need to listen for node deletion and act accordingly
@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
// 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);
// TODO how do we get the dependancies for this model ??
// Put the model
dictionaryDAO.putModel(m2Model);
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??
// Try and compile the model
ModelDefinition modelDefintion = m2Model.compile(dictionaryDAO, namespaceDAO).getModelDefinition();
// TODO what do we do if the model does not compile
// 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);
// 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()
{
}

View File

@@ -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;
}
});
}
}