diff --git a/config/alfresco/extension/synchronous-avm-indexing-context.xml.sample b/config/alfresco/extension/asynchronous-avm-indexing-context.xml.sample
similarity index 95%
rename from config/alfresco/extension/synchronous-avm-indexing-context.xml.sample
rename to config/alfresco/extension/asynchronous-avm-indexing-context.xml.sample
index dd2cb08d78..e057aec635 100644
--- a/config/alfresco/extension/synchronous-avm-indexing-context.xml.sample
+++ b/config/alfresco/extension/asynchronous-avm-indexing-context.xml.sample
@@ -24,7 +24,7 @@
- SYNCHRONOUS:TYPE:STAGING
+ ASYNCHRONOUS:TYPE:STAGING
UNINDEXED:TYPE:STAGING_PREVIEW
UNINDEXED:TYPE:AUTHOR
UNINDEXED:TYPE:AUTHOR_PREVIEW
diff --git a/config/alfresco/mimetype/mimetype-map.xml b/config/alfresco/mimetype/mimetype-map.xml
index 7b43ada79f..d5683bdb6f 100644
--- a/config/alfresco/mimetype/mimetype-map.xml
+++ b/config/alfresco/mimetype/mimetype-map.xml
@@ -306,6 +306,15 @@
msg
+
+ docx
+
+
+ xlsx
+
+
+ pptx
+
diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml
index 0fc7ce3680..eef4296cf1 100644
--- a/config/alfresco/public-services-context.xml
+++ b/config/alfresco/public-services-context.xml
@@ -572,7 +572,7 @@
org.alfresco.service.cmr.security.AuthenticationService
-
+
@@ -938,7 +938,7 @@
- ASYNCHRONOUS:TYPE:STAGING
+ SYNCHRONOUS:TYPE:STAGING
UNINDEXED:TYPE:STAGING_PREVIEW
UNINDEXED:TYPE:AUTHOR
UNINDEXED:TYPE:AUTHOR_PREVIEW
diff --git a/config/alfresco/workflow/review_processdefinition.xml b/config/alfresco/workflow/review_processdefinition.xml
index cba8bbaa36..9866fe2e52 100644
--- a/config/alfresco/workflow/review_processdefinition.xml
+++ b/config/alfresco/workflow/review_processdefinition.xml
@@ -24,8 +24,8 @@
-
+
diff --git a/config/alfresco/workflow/submit_processdefinition.xml b/config/alfresco/workflow/submit_processdefinition.xml
index 0a17899baf..96a6ed3ab8 100644
--- a/config/alfresco/workflow/submit_processdefinition.xml
+++ b/config/alfresco/workflow/submit_processdefinition.xml
@@ -100,7 +100,6 @@
-
+
@@ -136,7 +136,6 @@
-
+
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index be342a431a..ffd2ae9c40 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -358,7 +358,14 @@ public class AVMServiceTest extends AVMServiceTestBase
tx.begin();
if(fService.getStore("avmAsynchronousTest") != null)
{
+ assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
fService.purgeStore("avmAsynchronousTest");
+ assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
+ assertFalse(fIndexingInterceptor.hasIndexBeenCreated("bananaStoreWoof"));
+ }
+ else
+ {
+ assertFalse(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
}
StoreRef storeRef = AVMNodeConverter.ToStoreRef("avmAsynchronousTest");
Indexer indexer = fIndexerAndSearcher.getIndexer(storeRef);
@@ -368,6 +375,12 @@ public class AVMServiceTest extends AVMServiceTestBase
avmIndexer.deleteIndex("avmAsynchronousTest", IndexMode.SYNCHRONOUS);
}
tx.commit();
+
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("bananaStoreWoof"));
+ assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ tx.commit();
// TODO: Suspend and resume indexing in case we are really unlucky and hit an index before we expect it.
@@ -379,8 +392,19 @@ public class AVMServiceTest extends AVMServiceTestBase
results.close();
fService.createStore("avmAsynchronousTest");
+
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ tx.commit();
+
fService.createSnapshot("avmAsynchronousTest", null, null);
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ tx.commit();
+
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(1, results.length());
results.close();
@@ -388,8 +412,27 @@ public class AVMServiceTest extends AVMServiceTestBase
fService.createDirectory("avmAsynchronousTest:/", "a");
fService.createDirectory("avmAsynchronousTest:/a", "b");
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
+
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
+ tx.commit();
+
fService.createSnapshot("avmAsynchronousTest", null, null);
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
+ assertFalse(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
+ assertEquals(IndexMode.ASYNCHRONOUS, fIndexingInterceptor.getIndexMode("avmAsynchronousTest"));
+ assertEquals(IndexMode.SYNCHRONOUS, fIndexingInterceptor.getIndexMode("main"));
+ assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 0));
+ assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 1));
+ assertFalse(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 2));
+ tx.commit();
+
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(1, results.length());
results.close();
@@ -400,6 +443,14 @@ public class AVMServiceTest extends AVMServiceTestBase
assertEquals(4, results.length());
results.close();
+
+ tx = fTransactionService.getUserTransaction();
+ tx.begin();
+ assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
+ assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
+ assertTrue(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
+ tx.commit();
+
fService.purgeStore("avmAsynchronousTest");
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
index 79046ae5bc..6449c72d35 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
@@ -31,6 +31,7 @@ import java.util.TreeMap;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
+import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -81,6 +82,8 @@ public class AVMServiceTestBase extends TestCase
*/
private long fStartTime;
+ protected static AVMSnapShotTriggeredIndexingMethodInterceptor fIndexingInterceptor;
+
protected static TransactionService fTransactionService;
protected static IndexerAndSearcher fIndexerAndSearcher;
@@ -104,6 +107,8 @@ public class AVMServiceTestBase extends TestCase
fIndexerAndSearcher = (IndexerAndSearcher)fContext.getBean("indexerAndSearcherFactory");
fTransactionService = (TransactionService)fContext.getBean("transactionComponent");
fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService");
+ fIndexingInterceptor = (AVMSnapShotTriggeredIndexingMethodInterceptor)fContext.getBean("avmSnapShotTriggeredIndexingMethodInterceptor");
+
AuthenticationService authService = (AuthenticationService)fContext.getBean("AuthenticationService");
authService.authenticate("admin", "admin".toCharArray());
CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener");
diff --git a/source/java/org/alfresco/repo/content/metadata/AbstractMetadataExtracterTest.java b/source/java/org/alfresco/repo/content/metadata/AbstractMetadataExtracterTest.java
index 249c5fc709..4bf7a04d73 100644
--- a/source/java/org/alfresco/repo/content/metadata/AbstractMetadataExtracterTest.java
+++ b/source/java/org/alfresco/repo/content/metadata/AbstractMetadataExtracterTest.java
@@ -50,7 +50,7 @@ import org.springframework.context.ApplicationContext;
*/
public abstract class AbstractMetadataExtracterTest extends TestCase
{
- private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+ protected static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
protected static final String QUICK_TITLE = "The quick brown fox jumps over the lazy dog";
protected static final String QUICK_DESCRIPTION = "Gym class featuring a brown fox and lazy dog";
diff --git a/source/java/org/alfresco/repo/content/metadata/MetadataExtracterRegistry.java b/source/java/org/alfresco/repo/content/metadata/MetadataExtracterRegistry.java
index 65945c2427..01aadbde22 100644
--- a/source/java/org/alfresco/repo/content/metadata/MetadataExtracterRegistry.java
+++ b/source/java/org/alfresco/repo/content/metadata/MetadataExtracterRegistry.java
@@ -49,7 +49,7 @@ public class MetadataExtracterRegistry
private static final Log logger = LogFactory.getLog(MetadataExtracterRegistry.class);
private List extracters;
- private Map extracterCache;
+ private Map> extracterCache;
/** Controls read access to the cache */
private Lock extracterCacheReadLock;
@@ -60,7 +60,7 @@ public class MetadataExtracterRegistry
{
// initialise lists
extracters = new ArrayList(10);
- extracterCache = new HashMap(17);
+ extracterCache = new HashMap>(17);
// create lock objects for access to the cache
ReadWriteLock extractionCacheLock = new ReentrantReadWriteLock();
@@ -104,7 +104,7 @@ public class MetadataExtracterRegistry
*/
public MetadataExtracter getExtracter(String sourceMimetype)
{
- MetadataExtracter extracter = null;
+ List extractors = null;
extracterCacheReadLock.lock();
try
{
@@ -112,7 +112,7 @@ public class MetadataExtracterRegistry
{
// the translation has been requested before
// it might have been null
- return extracterCache.get(sourceMimetype);
+ extractors = extracterCache.get(sourceMimetype);
}
}
finally
@@ -120,44 +120,59 @@ public class MetadataExtracterRegistry
extracterCacheReadLock.unlock();
}
- // the translation has not been requested before
- // get a write lock on the cache
- // no double check done as it is not an expensive task
- extracterCacheWriteLock.lock();
- try
+ if (extractors == null)
{
- // find the most suitable transformer - may be empty list
- extracter = findBestExtracter(sourceMimetype);
- // store the result even if it is null
- extracterCache.put(sourceMimetype, extracter);
- return extracter;
+ // No request has been made before
+ // Get a write lock on the cache
+ // No double check done as it is not an expensive task
+ extracterCacheWriteLock.lock();
+ try
+ {
+ // find the most suitable transformer - may be empty list
+ extractors = findBestExtracters(sourceMimetype);
+ // store the result even if it is null
+ extracterCache.put(sourceMimetype, extractors);
+ }
+ finally
+ {
+ extracterCacheWriteLock.unlock();
+ }
}
- finally
+
+ // We have the list of extractors that supposedly work (as registered).
+ // Take the first one that still claims to work
+ MetadataExtracter liveExtractor = null;
+ for (MetadataExtracter extractor : extractors)
{
- extracterCacheWriteLock.unlock();
+ // An extractor may dynamically become unavailable
+ if (!extractor.isSupported(sourceMimetype))
+ {
+ continue;
+ }
+ liveExtractor = extractor;
}
+ return liveExtractor;
}
/**
- * @param sourceMimetype The MIME type under examination
- * @return The fastest of the most reliable extracters in extracters
- * for the given MIME type, or null if none is available.
+ * @param sourceMimetype The MIME type under examination
+ * @return Returns a set of extractors that will work for the given mimetype
*/
- private MetadataExtracter findBestExtracter(String sourceMimetype)
+ private List findBestExtracters(String sourceMimetype)
{
- logger.debug("Finding best extracter for " + sourceMimetype);
+ logger.debug("Finding extractors for " + sourceMimetype);
- MetadataExtracter bestExtracter = null;
+ List extractors = new ArrayList(1);
- for (MetadataExtracter ext : extracters)
+ for (MetadataExtracter extractor : extracters)
{
- if (!ext.isSupported(sourceMimetype))
+ if (!extractor.isSupported(sourceMimetype))
{
// extraction not achievable
continue;
}
- bestExtracter = ext;
+ extractors.add(extractor);
}
- return bestExtracter;
+ return extractors;
}
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java
index f0463863c8..1b3b438973 100644
--- a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java
+++ b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java
@@ -80,25 +80,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
this.connection = connection;
}
- private synchronized void connect()
- {
- if (isConnected())
- {
- // just leave it
- }
- else
- {
- try
- {
- connection.connect();
- }
- catch (ConnectException e)
- {
- logger.warn(e.getMessage());
- }
- }
- }
-
/**
* Initialises the bean by establishing an UNO connection
*/
@@ -109,15 +90,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
// Base initialization
super.init();
-
- // attempt a connection
- connect();
- // Only allow registration if the connection is good
- if (!isConnected())
- {
- // Reconnections are only supported if the server is able to connection initially.
- super.setRegistry(null);
- }
}
/**
@@ -129,6 +101,19 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
return connection.isConnected();
}
+ /**
+ * Perform the default check, but also check if the OpenOffice connection is good.
+ */
+ @Override
+ public boolean isSupported(String sourceMimetype)
+ {
+ if (!isConnected())
+ {
+ return false;
+ }
+ return super.isSupported(sourceMimetype);
+ }
+
@Override
public Map extractRaw(ContentReader reader) throws Throwable
{
@@ -146,35 +131,32 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
String sourceUrl = toUrl(tempFromFile, connection);
// UNO Interprocess Bridge *should* be thread-safe, but...
- synchronized (connection)
+ XComponentLoader desktop = connection.getDesktop();
+ XComponent document = desktop.loadComponentFromURL(
+ sourceUrl,
+ "_blank",
+ 0,
+ new PropertyValue[] { property("Hidden", Boolean.TRUE) });
+ if (document == null)
{
- XComponentLoader desktop = connection.getDesktop();
- XComponent document = desktop.loadComponentFromURL(
- sourceUrl,
- "_blank",
- 0,
- new PropertyValue[] { property("Hidden", Boolean.TRUE) });
- if (document == null)
- {
- throw new FileNotFoundException("could not open source document: " + sourceUrl);
- }
- try
- {
- XDocumentInfoSupplier infoSupplier = (XDocumentInfoSupplier) UnoRuntime.queryInterface(
- XDocumentInfoSupplier.class, document);
- XPropertySet propSet = (XPropertySet) UnoRuntime.queryInterface(
- XPropertySet.class,
- infoSupplier
- .getDocumentInfo());
+ throw new FileNotFoundException("could not open source document: " + sourceUrl);
+ }
+ try
+ {
+ XDocumentInfoSupplier infoSupplier = (XDocumentInfoSupplier) UnoRuntime.queryInterface(
+ XDocumentInfoSupplier.class, document);
+ XPropertySet propSet = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class,
+ infoSupplier
+ .getDocumentInfo());
- putRawValue(KEY_TITLE, propSet.getPropertyValue("Title").toString(), rawProperties);
- putRawValue(KEY_DESCRIPTION, propSet.getPropertyValue("Subject").toString(), rawProperties);
- putRawValue(KEY_AUTHOR, propSet.getPropertyValue("Author").toString(), rawProperties);
- }
- finally
- {
- document.dispose();
- }
+ putRawValue(KEY_TITLE, propSet.getPropertyValue("Title").toString(), rawProperties);
+ putRawValue(KEY_DESCRIPTION, propSet.getPropertyValue("Subject").toString(), rawProperties);
+ putRawValue(KEY_AUTHOR, propSet.getPropertyValue("Author").toString(), rawProperties);
+ }
+ finally
+ {
+ document.dispose();
}
// Done
return rawProperties;
@@ -188,14 +170,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
return fic.getFileURLFromSystemPath("", file.getAbsolutePath());
}
- public double getReliability(String sourceMimetype)
- {
- if (isConnected())
- return super.getReliability(sourceMimetype);
- else
- return 0.0;
- }
-
private static PropertyValue property(String name, Object value)
{
PropertyValue property = new PropertyValue();
diff --git a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracterTest.java b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracterTest.java
index fae4e49e7e..c336a89b94 100644
--- a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracterTest.java
+++ b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracterTest.java
@@ -38,7 +38,7 @@ public class OpenOfficeMetadataExtracterTest extends AbstractMetadataExtracterTe
{
super.setUp();
- OpenOfficeConnection connection = new SocketOpenOfficeConnection();
+ OpenOfficeConnection connection = (OpenOfficeConnection) ctx.getBean("openOfficeConnection");
extracter = new OpenOfficeMetadataExtracter();
extracter.setMimetypeService(mimetypeMap);
diff --git a/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java b/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java
index f951cdf2b1..9a34a6e693 100644
--- a/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java
+++ b/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java
@@ -27,7 +27,6 @@ package org.alfresco.repo.content.transform;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.ConnectException;
import java.util.Map;
import net.sf.jooreports.converter.DocumentFamily;
@@ -46,8 +45,6 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.util.PropertyCheck;
import org.alfresco.util.TempFileProvider;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader;
/**
@@ -58,11 +55,7 @@ import org.springframework.core.io.DefaultResourceLoader;
*/
public class OpenOfficeContentTransformer extends AbstractContentTransformer
{
- private static Log logger = LogFactory.getLog(OpenOfficeContentTransformer.class);
-
private OpenOfficeConnection connection;
- /** Keep track of the initial connection state */
- private boolean initiallyConnected;
private OpenOfficeDocumentConverter converter;
private String documentFormatsConfiguration;
private DocumentFormatRegistry formatRegistry;
@@ -91,30 +84,6 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
return connection.isConnected();
}
- private synchronized boolean connect()
- {
- boolean success = false;
- if (isConnected())
- {
- // just leave it
- success = true;
- }
- else
- {
- try
- {
- connection.connect();
- success = true;
- }
- catch (ConnectException e)
- {
- logger.warn(e.getMessage());
- }
- }
- // Done
- return success;
- }
-
@Override
public void register()
{
@@ -140,18 +109,11 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
formatRegistry = new XmlDocumentFormatRegistry();
}
- // attempt to establish a connection
- initiallyConnected = connect();
-
// set up the converter
converter = new OpenOfficeDocumentConverter(connection);
- if (initiallyConnected)
- {
- // If the server starts with OO running, then it will attempt reconnections. Otherwise it will
- // just be wasting time trying to see if a connection is available all the time.
- super.register();
- }
+ // Register
+ super.register();
}
/**
@@ -161,16 +123,8 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
{
if (!isConnected())
{
- if (!initiallyConnected)
- {
- // It wasn't there to start with, so we won't bother trying to connect
- return 0.0;
- }
- // The connection may have gone away, so attempt to get it again
- if (!connect())
- {
- return 0.0;
- }
+ // The connection management is must take care of this
+ return 0.0;
}
// there are some conversions that fail, despite the converter believing them possible
diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java
index ddffb3d6eb..b3456b4f6b 100644
--- a/source/java/org/alfresco/repo/jscript/ScriptNode.java
+++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java
@@ -642,6 +642,19 @@ public class ScriptNode implements Serializable, Scopeable
return getAspects().contains(createQName(aspect));
}
+ /**
+ * @return QName path to this node. This can be used for Lucene PATH: style queries
+ */
+ public String getQnamePath()
+ {
+ return this.services.getNodeService().getPath(getNodeRef()).toPrefixString(this.services.getNamespaceService());
+ }
+
+ public String jsGet_qnamePath()
+ {
+ return getQnamePath();
+ }
+
/**
* @return Display path to this node
*/
diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
index b8f19d74c8..1db139777b 100644
--- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
+++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
@@ -638,6 +638,19 @@ public class FileFolderServiceImpl implements FileFolderService
{
// changed the name property
nodeService.setProperty(targetNodeRef, ContentModel.PROP_NAME, newName);
+
+ // May need to update the mimetype, to support apps using .tmp files when saving
+ ContentData contentData = (ContentData)nodeService.getProperty(targetNodeRef, ContentModel.PROP_CONTENT);
+ if (contentData != null)
+ {
+ String targetMimetype = contentData.getMimetype();
+ String newMimetype = mimetypeService.guessMimetype(newName);
+ if (!targetMimetype.equalsIgnoreCase(newMimetype))
+ {
+ contentData = ContentData.setMimetype(contentData, newMimetype);
+ nodeService.setProperty(targetNodeRef, ContentModel.PROP_CONTENT, contentData);
+ }
+ }
}
catch (DuplicateChildNodeNameException e)
{
diff --git a/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java b/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java
index e0e10b65c4..145bf1183e 100644
--- a/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java
+++ b/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java
@@ -4,6 +4,7 @@ import java.util.List;
import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
+import org.alfresco.repo.search.IndexMode;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
@@ -116,6 +117,11 @@ public class AVMFullIndexRecoveryComponent extends AbstractReindexComponent
else
// validate first
{
+ if(avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(store) == IndexMode.UNINDEXED)
+ {
+ return;
+ }
+
int lastActualSnapshotId = avmService.getLatestSnapshotID(store);
if (lastActualSnapshotId <= 0)
{
diff --git a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
index 76a2f4b82c..7fc067a77d 100644
--- a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
+++ b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
@@ -230,7 +230,7 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
avmIndexer.index(store, before, after, getIndexMode(store));
}
}
-
+
public void indexSnapshot(String store, int after)
{
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
@@ -279,7 +279,73 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
return false;
}
- private synchronized IndexMode getIndexMode(String store)
+ /**
+ * Check if the index is up to date according to its index defintion and that all asynchronous work is done.
+ *
+ * @param store
+ * @return
+ */
+ public boolean isIndexUpToDateAndSearchable(String store)
+ {
+
+ switch (getIndexMode(store))
+ {
+ case UNINDEXED:
+ return false;
+ case SYNCHRONOUS:
+ case ASYNCHRONOUS:
+ int last = avmService.getLatestSnapshotID(store);
+ StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
+ Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
+ if (indexer instanceof AVMLuceneIndexer)
+ {
+ AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
+ avmIndexer.flushPending();
+ return avmIndexer.isSnapshotSearchable(store, last);
+ }
+ return false;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Check if the index is up to date according to its index defintion i it does not check that all asynchronous work is done.
+ *
+ * @param store
+ * @return
+ */
+ public boolean isIndexUpToDate(String store)
+ {
+
+ switch (getIndexMode(store))
+ {
+ case UNINDEXED:
+ return true;
+ case SYNCHRONOUS:
+ case ASYNCHRONOUS:
+ int last = avmService.getLatestSnapshotID(store);
+ StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
+ Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
+ if (indexer instanceof AVMLuceneIndexer)
+ {
+ AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
+ avmIndexer.flushPending();
+ return avmIndexer.getLastIndexedSnapshot(store) == last;
+ }
+ return false;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Given an avm store name determine if it is indexed and if so how.
+ *
+ * @param store
+ * @return
+ */
+ public synchronized IndexMode getIndexMode(String store)
{
IndexMode mode = modeCache.get(store);
if (mode == null)
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
index 60bd5c0ac2..7c55933a7f 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
@@ -51,6 +51,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.search.IndexMode;
+import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -379,16 +380,16 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
if (desc != null)
{
-
+
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(endVersion, stringNodeRef);
-
+
Document xdoc = new Document();
xdoc.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
xdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
xdoc.add(new Field("TX", AlfrescoTransactionSupport.getTransactionId(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
-
+
boolean isAtomic = true;
-
+
Map properties = getIndexableProperties(desc, nodeRef, endVersion, stringNodeRef);
for (QName propertyName : properties.keySet())
{
@@ -402,11 +403,11 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true, properties);
}
}
-
+
StringBuilder qNameBuffer = new StringBuilder(64);
if (node.getIsRoot())
{
-
+
}
// pseudo roots?
else
@@ -492,7 +493,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
else
- // not a root node
+ // not a root node
{
xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO));
@@ -1375,7 +1376,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
String[] split = term.text().split(":");
int test = Integer.parseInt(split[3]);
- if(test > end)
+ if (test > end)
{
end = test;
}
@@ -1485,7 +1486,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
String[] split = term.text().split(":");
int test = Integer.parseInt(split[4]);
- if(test > end)
+ if (test > end)
{
end = test;
}