diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml
index 67dd4d0d3c..a04badb9ac 100644
--- a/config/alfresco/content-services-context.xml
+++ b/config/alfresco/content-services-context.xml
@@ -99,6 +99,9 @@
+
+ ${policy.content.update.ignoreEmpty}
+
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index c5c3a25253..895f0989cf 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -377,6 +377,11 @@ repo.remote.endpoint=/service
# Create home folders as people are created (true) or create them lazily (false)
home.folder.creation.eager=true
+# Should we consider zero byte content to be the same as no content when firing
+# content update policies? Prevents 'premature' firing of inbound content rules
+# for some clients such as Mac OS X Finder
+policy.content.update.ignoreEmpty=false
+
# The well known RMI registry port is defined in the alfresco-shared.properties file
# host will need to be changed from localhost to make the services available to other
# computers.
diff --git a/source/java/org/alfresco/cmis/search/CMISQueryServiceImpl.java b/source/java/org/alfresco/cmis/search/CMISQueryServiceImpl.java
index 6dc270f4ae..fbbcc79adb 100644
--- a/source/java/org/alfresco/cmis/search/CMISQueryServiceImpl.java
+++ b/source/java/org/alfresco/cmis/search/CMISQueryServiceImpl.java
@@ -36,6 +36,7 @@ import org.alfresco.repo.search.impl.querymodel.QueryEngine;
import org.alfresco.repo.search.impl.querymodel.QueryEngineResults;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
/**
@@ -135,7 +136,12 @@ public class CMISQueryServiceImpl implements CMISQueryService
wrapped.put(selector, current);
}
}
- CMISResultSet cmis = new CMISResultSetImpl(wrapped, options, nodeService, query, cmisDictionaryService, alfrescoDictionaryService);
+ LimitBy limitBy = null;
+ if ((null != results.getResults()) && !results.getResults().isEmpty() && (null != results.getResults().values()) && !results.getResults().values().isEmpty())
+ {
+ limitBy = results.getResults().values().iterator().next().getResultSetMetaData().getLimitedBy();
+ }
+ CMISResultSet cmis = new CMISResultSetImpl(wrapped, options, limitBy, nodeService, query, cmisDictionaryService, alfrescoDictionaryService);
return cmis;
}
diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java
index b3da974f2e..9a2e8921a8 100644
--- a/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java
+++ b/source/java/org/alfresco/cmis/search/CMISResultSetImpl.java
@@ -37,6 +37,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
@@ -48,6 +49,8 @@ public class CMISResultSetImpl implements CMISResultSet, Serializable
private static final long serialVersionUID = 2014688399588268994L;
private Map wrapped;
+
+ private LimitBy limitBy;
CMISQueryOptions options;
@@ -59,11 +62,12 @@ public class CMISResultSetImpl implements CMISResultSet, Serializable
DictionaryService alfrescoDictionaryService;
- public CMISResultSetImpl(Map wrapped, CMISQueryOptions options, NodeService nodeService, Query query, CMISDictionaryService cmisDictionaryService,
- DictionaryService alfrescoDictionaryService)
+ public CMISResultSetImpl(Map wrapped, CMISQueryOptions options, LimitBy limitBy, NodeService nodeService, Query query,
+ CMISDictionaryService cmisDictionaryService, DictionaryService alfrescoDictionaryService)
{
this.wrapped = wrapped;
this.options = options;
+ this.limitBy = limitBy;
this.nodeService = nodeService;
this.query = query;
this.cmisDictionaryService = cmisDictionaryService;
@@ -94,7 +98,7 @@ public class CMISResultSetImpl implements CMISResultSet, Serializable
*/
public CMISResultSetMetaData getMetaData()
{
- return new CMISResultSetMetaDataImpl(options, query, cmisDictionaryService, alfrescoDictionaryService);
+ return new CMISResultSetMetaDataImpl(options, query, limitBy, cmisDictionaryService, alfrescoDictionaryService);
}
/*
diff --git a/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java b/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java
index a709c39b4b..e2223d1dd0 100644
--- a/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java
+++ b/source/java/org/alfresco/cmis/search/CMISResultSetMetaDataImpl.java
@@ -49,16 +49,18 @@ public class CMISResultSetMetaDataImpl implements CMISResultSetMetaData
{
private CMISQueryOptions options;
private SearchParameters searchParams;
+ private LimitBy limitBy;
private Map columnMetaData;
private Map selectorMetaData;
- public CMISResultSetMetaDataImpl(CMISQueryOptions options, Query query, CMISDictionaryService cmisDictionaryService, DictionaryService alfrescoDictionaryService)
+ public CMISResultSetMetaDataImpl(CMISQueryOptions options, Query query, LimitBy limitBy, CMISDictionaryService cmisDictionaryService,
+ DictionaryService alfrescoDictionaryService)
{
this.options = options;
this.searchParams = new SearchParameters(options);
-
+ this.limitBy = limitBy;
Map selectors = query.getSource().getSelectors();
selectorMetaData = new LinkedHashMap();
for(Selector selector : selectors.values())
@@ -177,7 +179,7 @@ public class CMISResultSetMetaDataImpl implements CMISResultSetMetaData
public LimitBy getLimitedBy()
{
- throw new UnsupportedOperationException();
+ return limitBy;
}
public PermissionEvaluationMode getPermissionEvaluationMode()
diff --git a/source/java/org/alfresco/repo/content/ContentServiceImpl.java b/source/java/org/alfresco/repo/content/ContentServiceImpl.java
index 1ac48bd755..6cdf598e8b 100644
--- a/source/java/org/alfresco/repo/content/ContentServiceImpl.java
+++ b/source/java/org/alfresco/repo/content/ContentServiceImpl.java
@@ -96,6 +96,8 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
/** the store for all temporarily created content */
private ContentStore tempStore;
private ContentTransformer imageMagickContentTransformer;
+ /** Should we consider zero byte content to be the same as no content? */
+ private boolean ignoreEmptyContent;
/**
* The policy component
@@ -153,8 +155,12 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
{
this.imageMagickContentTransformer = imageMagickContentTransformer;
}
-
-
+
+ public void setIgnoreEmptyContent(boolean ignoreEmptyContent)
+ {
+ this.ignoreEmptyContent = ignoreEmptyContent;
+ }
+
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@@ -232,8 +238,10 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
{
ContentData beforeValue = (ContentData) before.get(propertyQName);
ContentData afterValue = (ContentData) after.get(propertyQName);
- boolean hasContentBefore = ContentData.hasContent(beforeValue);
- boolean hasContentAfter = ContentData.hasContent(afterValue);
+ boolean hasContentBefore = ContentData.hasContent(beforeValue)
+ && (!ignoreEmptyContent || beforeValue.getSize() > 0);
+ boolean hasContentAfter = ContentData.hasContent(afterValue)
+ && (!ignoreEmptyContent || afterValue.getSize() > 0);
// There are some shortcuts here
if (!hasContentBefore && !hasContentAfter)
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java
index fc6d6ef05d..217fb5c4a9 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java
@@ -1443,6 +1443,10 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp
private boolean isCategorised(AspectDefinition aspDef)
{
+ if(aspDef == null)
+ {
+ return false;
+ }
AspectDefinition current = aspDef;
while (current != null)
{
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java
index 7ff76523cd..985bde4c64 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java
@@ -316,7 +316,6 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS
field = expandAttributeFieldName(field);
PropertyDefinition propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1)));
- // Handle .size and .mimetype
if(propertyDef == null)
{
if(field.endsWith(".size"))
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java
index 059e6b886b..c5c21ccb4e 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java
@@ -1099,8 +1099,35 @@ public class ADMLuceneTest extends TestCase implements DictionaryListener
// ftsQueryWithCount(searcher, "TEXT:(brown *(5) dog)", 1);
// ftsQueryWithCount(searcher, "TEXT:(brown *(6) dog)", 1);
//
-// // ftsQueryWithCount(searcher, "brown..dog", 1); // is this allowed??
-// // ftsQueryWithCount(searcher, "cm:content:brown..dog", 1);
+// try
+// {
+// ftsQueryWithCount(searcher, "brown..dog", 1); // is this allowed??
+// fail("Range query should not be supported against type d:content");
+// }
+// catch(UnsupportedOperationException e)
+// {
+//
+// }
+//
+// try
+// {
+// ftsQueryWithCount(searcher, "TEXT:brown..dog", 1);
+// fail("Range query should not be supported against type d:content");
+// }
+// catch(UnsupportedOperationException e)
+// {
+//
+// }
+//
+// try
+// {
+// ftsQueryWithCount(searcher, "cm:content:brown..dog", 1);
+// fail("Range query should not be supported against type d:content");
+// }
+// catch(UnsupportedOperationException e)
+// {
+//
+// }
//
// QName qname = QName.createQName(TEST_NAMESPACE, "float\\-ista");
// ftsQueryWithCount(searcher, qname + ":3.40", 1);
@@ -3068,6 +3095,25 @@ public class ADMLuceneTest extends TestCase implements DictionaryListener
results = searcher.query(spN);
results.close();
+ // test sort on unkown properties ALF-4193
+
+ spN = new SearchParameters();
+ spN.addStore(rootNodeRef.getStoreRef());
+ spN.setLanguage(SearchService.LANGUAGE_LUCENE);
+ spN.setQuery("PATH:\"//.\"");
+ spN.addSort("PARENT", false);
+ results = searcher.query(spN);
+ results.close();
+
+ spN = new SearchParameters();
+ spN.addStore(rootNodeRef.getStoreRef());
+ spN.setLanguage(SearchService.LANGUAGE_LUCENE);
+ spN.setQuery("PATH:\"//.\"");
+ spN.addSort("@PARENT:PARENT", false);
+ results = searcher.query(spN);
+ results.close();
+
+
luceneFTS.resume();