mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.2 to HEAD
7534: Merged V2.1 to HEAD 7398: XPath metadata extractor selector handles malformed and empty XML files 7401: Fix AR-1879: JBPM Timer never fires 7413: Contribution: Integrity checker ignores exceptions that would normally trigger transaction retries. 7416: AR-1884.Unicode wildcard processing. 7417: Added filtering of pseudo files when a partial wildcard search path is used, such as '*.csv'. AR-1889. 7436: AR-1863: major version's can now be created via the web service API; 7451: Fix for handling of UTF-8 application/x-www-form-urlencoded encoded form arguments as raised in support ticket 242 7458: Fix for AR-1900 7520: Fix to Template API where content was not retrievable from custom d:content properties on a node git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8413 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -844,9 +844,36 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
|
||||
if ( WildCard.containsWildcards(searchFileSpec))
|
||||
{
|
||||
// Check if the folder has any associated pseudo files
|
||||
// Get the list of pseudo files for the search path
|
||||
|
||||
pseudoList = searchFolderState.getPseudoFileList();
|
||||
|
||||
// Check if the wildcard is for all files or a subset
|
||||
|
||||
if ( searchFileSpec.equals( "*") == false && pseudoList != null && pseudoList.numberOfFiles() > 0)
|
||||
{
|
||||
// Generate a subset of pseudo files that match the wildcard search pattern
|
||||
|
||||
WildCard wildCard = new WildCard( searchFileSpec, false);
|
||||
PseudoFileList filterList = null;
|
||||
|
||||
for ( int i = 0; i > pseudoList.numberOfFiles(); i++)
|
||||
{
|
||||
PseudoFile pseudoFile = pseudoList.getFileAt( i);
|
||||
if ( wildCard.matchesPattern( pseudoFile.getFileName()))
|
||||
{
|
||||
// Add the pseudo file to the filtered list
|
||||
|
||||
if ( filterList == null)
|
||||
filterList = new PseudoFileList();
|
||||
filterList.addFile( pseudoFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Use the filtered pseudo file list, or null if there were no matches
|
||||
|
||||
pseudoList = filterList;
|
||||
}
|
||||
}
|
||||
else if ( results == null || results.size() == 0)
|
||||
{
|
||||
|
@@ -114,6 +114,19 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
Map<QName, Serializable> destination,
|
||||
Map<String, Set<QName>> mapping)
|
||||
{
|
||||
// Check the content length
|
||||
if (reader.getSize() == 0)
|
||||
{
|
||||
// There is no content. We don't spoof any properties so there can be nothing extracted.
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"XML document has zero length, so bypassing extraction: \n" +
|
||||
" Document: " + reader);
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
MetadataExtracter extracter = null;
|
||||
// Select a worker
|
||||
for (ContentWorkerSelector<MetadataExtracter> selector : selectors)
|
||||
@@ -123,6 +136,10 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
extracter = selector.getWorker(spawnedReader);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// The selector failed, so try another
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader.isChannelOpen())
|
||||
@@ -149,8 +166,14 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
// Did we find anything?
|
||||
if (extracter == null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"No working metadata extractor could be found: \n" +
|
||||
" Document: " + reader);
|
||||
}
|
||||
// There will be no properties extracted
|
||||
modifiedProperties = Collections.emptyMap();
|
||||
modifiedProperties = destination;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -176,7 +199,7 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
"XML metadata extractor redirected: \n" +
|
||||
" Reader: " + reader + "\n" +
|
||||
" Extracter: " + extracter + "\n" +
|
||||
" Extracted: " + modifiedProperties);
|
||||
" Metadata: " + modifiedProperties);
|
||||
}
|
||||
return modifiedProperties;
|
||||
}
|
||||
|
@@ -67,6 +67,8 @@ public class XmlMetadataExtracterTest extends TestCase
|
||||
{
|
||||
private static final String FILE_ALFRESCO_MODEL = "xml-metadata/alfresco-model-sample.xml";
|
||||
private static final String FILE_ECLIPSE_PROJECT = "xml-metadata/eclipse-project-sample.xml";
|
||||
private static final String FILE_EMPTY = "xml-metadata/empty-sample.xml";
|
||||
private static final String FILE_MALFORMED = "xml-metadata/malformed-sample.xml";
|
||||
|
||||
private static final String CTX_LOCATION = "classpath:xml-metadata/xml-metadata-test-context.xml";
|
||||
private static final ApplicationContext ctx = new ClassPathXmlApplicationContext(CTX_LOCATION);
|
||||
@@ -157,6 +159,38 @@ public class XmlMetadataExtracterTest extends TestCase
|
||||
assertEquals("JavaCC Nature", checkProperties.get(ContentModel.PROP_DESCRIPTION));
|
||||
}
|
||||
|
||||
public void testEmptyFile() throws Exception
|
||||
{
|
||||
// Get an empty file
|
||||
ContentReader reader = getReader(FILE_EMPTY);
|
||||
assertTrue(reader.exists());
|
||||
|
||||
// Pass it to the extracter
|
||||
PropertyMap checkProperties = new PropertyMap();
|
||||
checkProperties.put(ContentModel.PROP_TITLE, getName());
|
||||
xmlMetadataExtracter.extract(reader, checkProperties);
|
||||
|
||||
// The map should be unaffected
|
||||
assertNotNull("Properties changed by empty file extraction", checkProperties.get(ContentModel.PROP_TITLE));
|
||||
assertEquals("Properties changed by empty file extraction", getName(), checkProperties.get(ContentModel.PROP_TITLE));
|
||||
}
|
||||
|
||||
public void testMalformedFile() throws Exception
|
||||
{
|
||||
// Get an empty file
|
||||
ContentReader reader = getReader(FILE_MALFORMED);
|
||||
assertTrue(reader.exists());
|
||||
|
||||
// Pass it to the extracter
|
||||
PropertyMap checkProperties = new PropertyMap();
|
||||
checkProperties.put(ContentModel.PROP_TITLE, getName());
|
||||
xmlMetadataExtracter.extract(reader, checkProperties);
|
||||
|
||||
// The map should be unaffected
|
||||
assertNotNull("Properties changed by malformed file extraction", checkProperties.get(ContentModel.PROP_TITLE));
|
||||
assertEquals("Properties changed by malformed file extraction", getName(), checkProperties.get(ContentModel.PROP_TITLE));
|
||||
}
|
||||
|
||||
public void testRootElementNameSelector() throws Exception
|
||||
{
|
||||
// Load the example files
|
||||
|
@@ -35,6 +35,7 @@ import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
@@ -670,6 +671,24 @@ public class IntegrityChecker
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// This means that integrity checking itself failed. This is serious.
|
||||
// There are some exceptions that can be handled by transaction retries, so
|
||||
// we attempt to handle these and let them get out to trigger the retry.
|
||||
// Thanks to Carina Lansing.
|
||||
Throwable retryThrowable = RetryingTransactionHelper.extractRetryCause(e);
|
||||
if (retryThrowable != null)
|
||||
{
|
||||
// The transaction will be retrying on this, so there's no need for the aggressive
|
||||
// reporting that would normally happen
|
||||
if (e instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
// log it as an error and move to next event
|
||||
IntegrityRecord exceptionRecord = new IntegrityRecord("" + e.getMessage());
|
||||
|
@@ -353,7 +353,7 @@ public class RetryingTransactionHelper
|
||||
* @param cause the cause to examine
|
||||
* @return Returns the original cause if it is a valid retry cause, otherwise <tt>null</tt>
|
||||
*/
|
||||
private Throwable extractRetryCause(Throwable cause)
|
||||
public static Throwable extractRetryCause(Throwable cause)
|
||||
{
|
||||
Throwable retryCause = ExceptionStackUtil.getCause(cause, RETRY_EXCEPTIONS);
|
||||
if (retryCause == null)
|
||||
|
@@ -457,6 +457,8 @@ public class WorkflowInterpreter extends BaseInterpreter
|
||||
}
|
||||
}
|
||||
|
||||
List<WorkflowTimer> timers = new ArrayList<WorkflowTimer>();
|
||||
|
||||
if (id.equals("all"))
|
||||
{
|
||||
for (WorkflowDefinition def : workflowService.getAllDefinitions())
|
||||
@@ -464,11 +466,7 @@ public class WorkflowInterpreter extends BaseInterpreter
|
||||
List<WorkflowInstance> workflows = workflowService.getActiveWorkflows(def.id);
|
||||
for (WorkflowInstance workflow : workflows)
|
||||
{
|
||||
List<WorkflowTimer> timers = workflowService.getTimers(workflow.id);
|
||||
for (WorkflowTimer timer : timers)
|
||||
{
|
||||
out.println("id: " + timer.id + " , name: " + timer.name + " , due date: " + timer.dueDate + " , path: " + timer.path.id + " , node: " + timer.path.node.name + " , process: " + timer.path.instance.id + " , task: " + timer.task.name + "(" + timer.task.id + ")");
|
||||
}
|
||||
timers.addAll(workflowService.getTimers(workflow.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,11 +475,22 @@ public class WorkflowInterpreter extends BaseInterpreter
|
||||
List<WorkflowInstance> workflows = workflowService.getActiveWorkflows(id);
|
||||
for (WorkflowInstance workflow : workflows)
|
||||
{
|
||||
List<WorkflowTimer> timers = workflowService.getTimers(workflow.id);
|
||||
for (WorkflowTimer timer : timers)
|
||||
{
|
||||
out.println("id: " + timer.id + " , name: " + timer.name + " , due date: " + timer.dueDate + " , path: " + timer.path.id + " , node: " + timer.path.node.name + " , process: " + timer.path.instance.id + " , task: " + timer.task.name + "(" + timer.task.id + ")");
|
||||
}
|
||||
timers.addAll(workflowService.getTimers(workflow.id));
|
||||
}
|
||||
}
|
||||
|
||||
for (WorkflowTimer timer : timers)
|
||||
{
|
||||
out.print("id: " + timer.id + " , name: " + timer.name + " , due date: " + timer.dueDate + " , path: " + timer.path.id + " , node: " + timer.path.node.name + " , process: " + timer.path.instance.id);
|
||||
if (timer.task != null)
|
||||
{
|
||||
out.print(" , task: " + timer.task.name + "(" + timer.task.id + ")");
|
||||
}
|
||||
out.println();
|
||||
if (timer.error != null)
|
||||
{
|
||||
out.println("error executing timer id " + timer.id);
|
||||
out.println(timer.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -84,21 +84,14 @@ public class AlfrescoTimer extends Timer
|
||||
}
|
||||
|
||||
// execute timer
|
||||
if (username == null)
|
||||
executeResult = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
|
||||
{
|
||||
executeResult = super.execute(jbpmContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
executeResult = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
|
||||
@SuppressWarnings("synthetic-access")
|
||||
public Boolean doWork() throws Exception
|
||||
{
|
||||
@SuppressWarnings("synthetic-access")
|
||||
public Boolean doWork() throws Exception
|
||||
{
|
||||
return AlfrescoTimer.super.execute(jbpmContext);
|
||||
}
|
||||
}, username);
|
||||
}
|
||||
return AlfrescoTimer.super.execute(jbpmContext);
|
||||
}
|
||||
}, (username == null) ? "system" : username);
|
||||
|
||||
return executeResult;
|
||||
}
|
||||
|
@@ -2868,9 +2868,14 @@ public class JBPMEngine extends BPMEngine
|
||||
WorkflowTimer workflowTimer = new WorkflowTimer();
|
||||
workflowTimer.id = createGlobalId(new Long(timer.getId()).toString());
|
||||
workflowTimer.name = timer.getName();
|
||||
workflowTimer.error = timer.getException();
|
||||
workflowTimer.dueDate = timer.getDueDate();
|
||||
workflowTimer.path = createWorkflowPath(timer.getToken());
|
||||
workflowTimer.task = createWorkflowTask(timer.getTaskInstance());
|
||||
TaskInstance taskInstance = timer.getTaskInstance();
|
||||
if (taskInstance != null)
|
||||
{
|
||||
workflowTimer.task = createWorkflowTask(taskInstance);
|
||||
}
|
||||
return workflowTimer;
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,9 @@ public class WorkflowTimer
|
||||
/** Due Date */
|
||||
public Date dueDate;
|
||||
|
||||
/** Error */
|
||||
public String error;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
0
source/test-resources/xml-metadata/empty-sample.xml
Normal file
0
source/test-resources/xml-metadata/empty-sample.xml
Normal file
8
source/test-resources/xml-metadata/malformed-sample.xml
Normal file
8
source/test-resources/xml-metadata/malformed-sample.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Repository</name>
|
||||
<comment>JavaCC Nature</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
Reference in New Issue
Block a user