RM-550 (JS Error while declaring a record)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0-BUG-FIX@43661 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2012-11-16 15:05:06 +00:00
parent 08cc495c65
commit d4a6a842ba
2 changed files with 325 additions and 341 deletions

View File

@@ -29,6 +29,7 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
@@ -48,189 +49,174 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/
public class DeclareRecordAction extends RMActionExecuterAbstractBase
{
/** I18N */
private static final String MSG_UNDECLARED_ONLY_RECORDS = "rm.action.undeclared-only-records";
private static final String MSG_NO_DECLARE_MAND_PROP = "rm.action.no-declare-mand-prop";
/** I18N */
private static final String MSG_UNDECLARED_ONLY_RECORDS = "rm.action.undeclared-only-records";
private static final String MSG_NO_DECLARE_MAND_PROP = "rm.action.no-declare-mand-prop";
/** Logger */
private static Log logger = LogFactory.getLog(DeclareRecordAction.class);
/** Logger */
private static Log logger = LogFactory.getLog(DeclareRecordAction.class);
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action,
* org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{
if (recordsManagementService.isRecord(actionedUponNodeRef) == true)
{
if (recordsManagementService.isRecordDeclared(actionedUponNodeRef) == false)
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{
if (recordsManagementService.isRecord(actionedUponNodeRef) == true)
{
if (recordsManagementService.isRecordDeclared(actionedUponNodeRef) == false)
{
List<String> missingProperties = new ArrayList<String>(5);
// Aspect not already defined - check mandatory properties then add
if (mandatoryPropertiesSet(actionedUponNodeRef, missingProperties) == true)
{
List<String> missingProperties = new ArrayList<String>(5);
// Aspect not already defined - check mandatory properties then add
if (mandatoryPropertiesSet(actionedUponNodeRef, missingProperties) == true)
{
// Add the declared aspect
Map<QName, Serializable> declaredProps = new HashMap<QName, Serializable>(2);
declaredProps.put(PROP_DECLARED_AT, new Date());
declaredProps.put(PROP_DECLARED_BY, AuthenticationUtil.getRunAsUser());
this.nodeService.addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps);
// Add the declared aspect
Map<QName, Serializable> declaredProps = new HashMap<QName, Serializable>(2);
declaredProps.put(PROP_DECLARED_AT, new Date());
declaredProps.put(PROP_DECLARED_BY, AuthenticationUtil.getRunAsUser());
this.nodeService.addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps);
// remove all owner related rights
this.ownableService.setOwner(actionedUponNodeRef, OwnableService.NO_OWNER);
}
else
{
throw new AlfrescoRuntimeException(buildMissingPropertiesErrorString(missingProperties));
}
}
}
else
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNDECLARED_ONLY_RECORDS, actionedUponNodeRef.toString()));
}
}
private String buildMissingPropertiesErrorString(List<String> missingProperties)
{
StringBuilder builder = new StringBuilder(255);
builder.append(I18NUtil.getMessage(MSG_NO_DECLARE_MAND_PROP));
builder.append(" ");
for (String missingProperty : missingProperties)
{
builder.append(missingProperty)
.append(", ");
}
return builder.toString();
}
/**
* Helper method to check whether all the mandatory properties of the node have been set
*
* @param nodeRef
* node reference
* @return boolean true if all mandatory properties are set, false otherwise
*/
private boolean mandatoryPropertiesSet(NodeRef nodeRef, List<String> missingProperties)
{
boolean result = true;
Map<QName, Serializable> nodeRefProps = this.nodeService.getProperties(nodeRef);
QName nodeRefType = this.nodeService.getType(nodeRef);
TypeDefinition typeDef = this.dictionaryService.getType(nodeRefType);
for (PropertyDefinition propDef : typeDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
if (result != false)
{
Set<QName> aspects = this.nodeService.getAspects(nodeRef);
for (QName aspect : aspects)
{
AspectDefinition aspectDef = this.dictionaryService.getAspect(aspect);
for (PropertyDefinition propDef : aspectDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
}
}
return result;
}
/**
* Log information about missing properties.
*
* @param propDef property definition
* @param missingProperties missing properties
*/
private void logMissingProperty(PropertyDefinition propDef, List<String> missingProperties)
{
if (logger.isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Mandatory property missing: ").append(propDef.getName());
logger.warn(msg.toString());
}
missingProperties.add(propDef.getName().toString());
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
*/
@Override
public Set<QName> getProtectedAspects()
{
HashSet<QName> qnames = new HashSet<QName>();
qnames.add(ASPECT_DECLARED_RECORD);
return qnames;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
*/
@Override
protected boolean isExecutableImpl(NodeRef filePlanComponent, Map<String, Serializable> parameters, boolean throwException)
{
if (recordsManagementService.isRecord(filePlanComponent) == true)
{
if (recordsManagementService.isRecordDeclared(filePlanComponent) == false)
{
// Aspect not already defined - check mandatory properties then add
List<String> missingProperties = new ArrayList<String>(10);
if (mandatoryPropertiesSet(filePlanComponent, missingProperties) == true)
{
return true;
}
else
{
if (throwException)
{
throw new AlfrescoRuntimeException(buildMissingPropertiesErrorString(missingProperties));
}
else
{
return false;
}
}
// remove all owner related rights
this.ownableService.setOwner(actionedUponNodeRef, OwnableService.NO_OWNER);
}
else
{
return false;
logger.debug(buildMissingPropertiesErrorString(missingProperties));
action.setParameterValue(ActionExecuterAbstractBase.PARAM_RESULT, "missingProperties");
}
}
else
{
if (throwException)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNDECLARED_ONLY_RECORDS, filePlanComponent.toString()));
}
else
{
return false;
}
}
}
}
else
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNDECLARED_ONLY_RECORDS, actionedUponNodeRef.toString()));
}
}
private String buildMissingPropertiesErrorString(List<String> missingProperties)
{
StringBuilder builder = new StringBuilder(255);
builder.append(I18NUtil.getMessage(MSG_NO_DECLARE_MAND_PROP));
builder.append(" ");
for (String missingProperty : missingProperties)
{
builder.append(missingProperty)
.append(", ");
}
return builder.toString();
}
/**
* Helper method to check whether all the mandatory properties of the node have been set
*
* @param nodeRef node reference
* @return boolean true if all mandatory properties are set, false otherwise
*/
private boolean mandatoryPropertiesSet(NodeRef nodeRef, List<String> missingProperties)
{
boolean result = true;
Map<QName, Serializable> nodeRefProps = this.nodeService.getProperties(nodeRef);
QName nodeRefType = this.nodeService.getType(nodeRef);
TypeDefinition typeDef = this.dictionaryService.getType(nodeRefType);
for (PropertyDefinition propDef : typeDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
if (result != false)
{
Set<QName> aspects = this.nodeService.getAspects(nodeRef);
for (QName aspect : aspects)
{
AspectDefinition aspectDef = this.dictionaryService.getAspect(aspect);
for (PropertyDefinition propDef : aspectDef.getProperties().values())
{
if (propDef.isMandatory() == true)
{
if (nodeRefProps.get(propDef.getName()) == null)
{
logMissingProperty(propDef, missingProperties);
result = false;
break;
}
}
}
}
}
return result;
}
/**
* Log information about missing properties.
*
* @param propDef property definition
* @param missingProperties missing properties
*/
private void logMissingProperty(PropertyDefinition propDef, List<String> missingProperties)
{
if (logger.isWarnEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Mandatory property missing: ").append(propDef.getName());
logger.warn(msg.toString());
}
missingProperties.add(propDef.getName().toString());
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#getProtectedAspects()
*/
@Override
public Set<QName> getProtectedAspects()
{
HashSet<QName> qnames = new HashSet<QName>();
qnames.add(ASPECT_DECLARED_RECORD);
return qnames;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#isExecutableImpl(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, boolean)
*/
@Override
protected boolean isExecutableImpl(NodeRef filePlanComponent, Map<String, Serializable> parameters, boolean throwException)
{
if (recordsManagementService.isRecord(filePlanComponent) == true)
{
if (recordsManagementService.isRecordDeclared(filePlanComponent) == false)
{
// Aspect not already defined - check mandatory properties then add
List<String> missingProperties = new ArrayList<String>(10);
if (mandatoryPropertiesSet(filePlanComponent, missingProperties) == true)
{
return true;
}
}
return false;
}
else
{
if (throwException)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNDECLARED_ONLY_RECORDS, filePlanComponent.toString()));
}
else
{
return false;
}
}
}
}

View File

@@ -50,175 +50,173 @@ import org.json.JSONTokener;
*/
public class RmActionPost extends DeclarativeWebScript
{
private static Log logger = LogFactory.getLog(RmActionPost.class);
private static Log logger = LogFactory.getLog(RmActionPost.class);
private static final String PARAM_NAME = "name";
private static final String PARAM_NODE_REF = "nodeRef";
private static final String PARAM_NODE_REFS = "nodeRefs";
private static final String PARAM_PARAMS = "params";
private static final String PARAM_NAME = "name";
private static final String PARAM_NODE_REF = "nodeRef";
private static final String PARAM_NODE_REFS = "nodeRefs";
private static final String PARAM_PARAMS = "params";
private NodeService nodeService;
private RecordsManagementActionService rmActionService;
private NodeService nodeService;
private RecordsManagementActionService rmActionService;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRecordsManagementActionService(RecordsManagementActionService rmActionService)
{
this.rmActionService = rmActionService;
}
public void setRecordsManagementActionService(RecordsManagementActionService rmActionService)
{
this.rmActionService = rmActionService;
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
String reqContentAsString;
try
{
reqContentAsString = req.getContent().getContent();
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Could not read content from req.", iox);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
String reqContentAsString;
try
{
reqContentAsString = req.getContent().getContent();
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Could not read content from req.", iox);
}
String actionName = null;
List<NodeRef> targetNodeRefs = null;
Map<String, Serializable> actionParams = new HashMap<String, Serializable>(3);
String actionName = null;
List<NodeRef> targetNodeRefs = new ArrayList<NodeRef>(1);
Map<String, Serializable> actionParams = new HashMap<String, Serializable>(3);
try
{
JSONObject jsonObj = new JSONObject(new JSONTokener(reqContentAsString));
try
{
JSONObject jsonObj = new JSONObject(new JSONTokener(reqContentAsString));
// Get the action name
if (jsonObj.has(PARAM_NAME) == true)
// Get the action name
if (jsonObj.has(PARAM_NAME) == true)
{
actionName = jsonObj.getString(PARAM_NAME);
}
// Get the target references
if (jsonObj.has(PARAM_NODE_REF) == true)
{
NodeRef nodeRef = new NodeRef(jsonObj.getString(PARAM_NODE_REF));
targetNodeRefs.add(nodeRef);
}
if (jsonObj.has(PARAM_NODE_REFS) == true)
{
JSONArray jsonArray = jsonObj.getJSONArray(PARAM_NODE_REFS);
if (jsonArray.length() != 0)
{
actionName = jsonObj.getString(PARAM_NAME);
targetNodeRefs = new ArrayList<NodeRef>(jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++)
{
NodeRef nodeRef = new NodeRef(jsonArray.getString(i));
targetNodeRefs.add(nodeRef);
}
}
}
// Get the target references
if (jsonObj.has(PARAM_NODE_REF) == true)
// params are optional.
if (jsonObj.has(PARAM_PARAMS))
{
JSONObject paramsObj = jsonObj.getJSONObject(PARAM_PARAMS);
for (Iterator<String> iter = paramsObj.keys(); iter.hasNext(); )
{
NodeRef nodeRef = new NodeRef(jsonObj.getString(PARAM_NODE_REF));
targetNodeRefs = new ArrayList<NodeRef>(1);
targetNodeRefs.add(nodeRef);
String nextKeyString = iter.next();
Object nextValue = paramsObj.get(nextKeyString);
// Check for date values
if (nextValue instanceof JSONObject)
{
if (((JSONObject)nextValue).has("iso8601") == true)
{
String dateStringValue = ((JSONObject)nextValue).getString("iso8601");
nextValue = ISO8601DateFormat.parse(dateStringValue);
}
}
actionParams.put(nextKeyString, (Serializable)nextValue);
}
if (jsonObj.has(PARAM_NODE_REFS) == true)
}
}
catch (JSONException exception)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unable to parse request JSON.");
}
// validate input: check for mandatory params.
// Some RM actions can be posted without a nodeRef.
if (actionName == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"A mandatory parameter has not been provided in URL");
}
// Check that all the nodes provided exist and build report string
StringBuffer targetNodeRefsString = new StringBuffer(30);
boolean firstTime = true;
for (NodeRef targetNodeRef : targetNodeRefs)
{
if (nodeService.exists(targetNodeRef) == false)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,
"The targetNode does not exist (" + targetNodeRef.toString() + ")");
}
// Build the string
if (firstTime == true)
{
firstTime = false;
}
else
{
targetNodeRefsString.append(", ");
}
targetNodeRefsString.append(targetNodeRef.toString());
}
// Proceed to execute the specified action on the specified node.
if (logger.isDebugEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Executing Record Action ")
.append(actionName)
.append(", (")
.append(targetNodeRefsString.toString())
.append("), ")
.append(actionParams);
logger.debug(msg.toString());
}
Map<String, Object> model = new HashMap<String, Object>();
if (targetNodeRefs.isEmpty())
{
RecordsManagementActionResult result = this.rmActionService.executeRecordsManagementAction(actionName, actionParams);
if (result.getValue() != null)
{
model.put("result", result.getValue().toString());
}
}
else
{
Map<NodeRef, RecordsManagementActionResult> resultMap = this.rmActionService.executeRecordsManagementAction(targetNodeRefs, actionName, actionParams);
Map<String, String> results = new HashMap<String, String>(resultMap.size());
for (NodeRef nodeRef : resultMap.keySet())
{
Object value = resultMap.get(nodeRef).getValue();
if (value != null)
{
JSONArray jsonArray = jsonObj.getJSONArray(PARAM_NODE_REFS);
if (jsonArray.length() != 0)
{
targetNodeRefs = new ArrayList<NodeRef>(jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++)
{
NodeRef nodeRef = new NodeRef(jsonArray.getString(i));
targetNodeRefs.add(nodeRef);
}
}
results.put(nodeRef.toString(), resultMap.get(nodeRef).getValue().toString());
}
}
model.put("results", results);
}
// params are optional.
if (jsonObj.has(PARAM_PARAMS))
{
JSONObject paramsObj = jsonObj.getJSONObject(PARAM_PARAMS);
for (Iterator iter = paramsObj.keys(); iter.hasNext(); )
{
Object nextKey = iter.next();
String nextKeyString = (String)nextKey;
Object nextValue = paramsObj.get(nextKeyString);
model.put("message", "Successfully queued action [" + actionName + "] on " + targetNodeRefsString.toString());
// Check for date values
if (nextValue instanceof JSONObject)
{
if (((JSONObject)nextValue).has("iso8601") == true)
{
String dateStringValue = ((JSONObject)nextValue).getString("iso8601");
nextValue = ISO8601DateFormat.parse(dateStringValue);
}
}
actionParams.put(nextKeyString, (Serializable)nextValue);
}
}
}
catch (JSONException exception)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unable to parse request JSON.");
}
// validate input: check for mandatory params.
// Some RM actions can be posted without a nodeRef.
if (actionName == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"A mandatory parameter has not been provided in URL");
}
// Check that all the nodes provided exist and build report string
StringBuffer targetNodeRefsString = new StringBuffer(30);
boolean firstTime = true;
for (NodeRef targetNodeRef : targetNodeRefs)
{
if (nodeService.exists(targetNodeRef) == false)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,
"The targetNode does not exist (" + targetNodeRef.toString() + ")");
}
// Build the string
if (firstTime == true)
{
firstTime = false;
}
else
{
targetNodeRefsString.append(", ");
}
targetNodeRefsString.append(targetNodeRef.toString());
}
// Proceed to execute the specified action on the specified node.
if (logger.isDebugEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Executing Record Action ")
.append(actionName)
.append(", (")
.append(targetNodeRefsString.toString())
.append("), ")
.append(actionParams);
logger.debug(msg.toString());
}
Map<String, Object> model = new HashMap<String, Object>();
if (targetNodeRefs.isEmpty())
{
RecordsManagementActionResult result = this.rmActionService.executeRecordsManagementAction(actionName, actionParams);
if (result.getValue() != null)
{
model.put("result", result.getValue().toString());
}
}
else
{
Map<NodeRef, RecordsManagementActionResult> resultMap = this.rmActionService.executeRecordsManagementAction(targetNodeRefs, actionName, actionParams);
Map<String, String> results = new HashMap<String, String>(resultMap.size());
for (NodeRef nodeRef : resultMap.keySet())
{
Object value = resultMap.get(nodeRef).getValue();
if (value != null)
{
results.put(nodeRef.toString(), resultMap.get(nodeRef).getValue().toString());
}
}
model.put("results", results);
}
model.put("message", "Successfully queued action [" + actionName + "] on " + targetNodeRefsString.toString());
return model;
}
return model;
}
}