Merged V2.1 to HEAD

6455: OpenOffice transformer and extractor register regardless of the initial connection state.
   6456: Fix for WCM-636 (Clicking OK twice while deleting web project results in exception)
   6457: Updated installers and associated config
   6458: AR-1669 Add getQnamePath to Javascript
   6459: Fix for AWC-1456 - Word and Excel documents were being stored as octet streams rather than their correct mimetype
   6460: Reverse order of reject & approve transitions, so that approve appears first in list of ui actions.
   6461: Removed Process.exe (often detected as a virus) and updated config wizard.
   6462: Switch to synchronous indexing for AVM by default
   6463: Better support to query the state of AVM indexes
   6464: Added Office 2007 document mimetypes and icons
   6465: Added Office 2007 icons without the typo this time


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6736 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-09-10 22:41:44 +00:00
parent 28d4278290
commit 1f3aabc6a0
17 changed files with 265 additions and 158 deletions

View File

@@ -24,7 +24,7 @@
<!-- Entries are of the form [SYNCHRONOUS | ASYNCHRONOUS |UNINDEXED]:[TYPE | NAME]:regexp --> <!-- Entries are of the form [SYNCHRONOUS | ASYNCHRONOUS |UNINDEXED]:[TYPE | NAME]:regexp -->
<property name="indexingDefinitions"> <property name="indexingDefinitions">
<list> <list>
<value>SYNCHRONOUS:TYPE:STAGING</value> <value>ASYNCHRONOUS:TYPE:STAGING</value>
<value>UNINDEXED:TYPE:STAGING_PREVIEW</value> <value>UNINDEXED:TYPE:STAGING_PREVIEW</value>
<value>UNINDEXED:TYPE:AUTHOR</value> <value>UNINDEXED:TYPE:AUTHOR</value>
<value>UNINDEXED:TYPE:AUTHOR_PREVIEW</value> <value>UNINDEXED:TYPE:AUTHOR_PREVIEW</value>

View File

@@ -306,6 +306,15 @@
<mimetype mimetype="message/rfc822" display="EMail"> <mimetype mimetype="message/rfc822" display="EMail">
<extension>msg</extension> <extension>msg</extension>
</mimetype> </mimetype>
<mimetype mimetype="application/vnd.openxmlformats-officedocument.wordprocessingml.document" display="Microsoft Word 2007">
<extension>docx</extension>
</mimetype>
<mimetype mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" display="Microsoft Excel 2007">
<extension>xlsx</extension>
</mimetype>
<mimetype mimetype="application/vnd.openxmlformats-officedocument.presentationml.presentation" display="Microsoft PowerPoint 2007">
<extension>pptx</extension>
</mimetype>
</mimetypes> </mimetypes>
</config> </config>

View File

@@ -572,7 +572,7 @@
<value>org.alfresco.service.cmr.security.AuthenticationService</value> <value>org.alfresco.service.cmr.security.AuthenticationService</value>
</property> </property>
<property name="target"> <property name="target">
<ref bean="authenticationServiceImpl"/> <ref bean="authenticationService"/>
</property> </property>
<property name="interceptorNames"> <property name="interceptorNames">
<list> <list>
@@ -938,7 +938,7 @@
</property> </property>
<property name="indexingDefinitions"> <property name="indexingDefinitions">
<list> <list>
<value>ASYNCHRONOUS:TYPE:STAGING</value> <value>SYNCHRONOUS:TYPE:STAGING</value>
<value>UNINDEXED:TYPE:STAGING_PREVIEW</value> <value>UNINDEXED:TYPE:STAGING_PREVIEW</value>
<value>UNINDEXED:TYPE:AUTHOR</value> <value>UNINDEXED:TYPE:AUTHOR</value>
<value>UNINDEXED:TYPE:AUTHOR_PREVIEW</value> <value>UNINDEXED:TYPE:AUTHOR_PREVIEW</value>

View File

@@ -24,8 +24,8 @@
</script> </script>
</event> </event>
</task> </task>
<transition name="reject" to="rejected" />
<transition name="approve" to="approved" /> <transition name="approve" to="approved" />
<transition name="reject" to="rejected" />
</task-node> </task-node>
<task-node name="rejected"> <task-node name="rejected">

View File

@@ -100,7 +100,6 @@
</event> </event>
</task> </task>
<transition name="reject" to="endreview" />
<transition name="approve" to="submitserialreview"> <transition name="approve" to="submitserialreview">
<script> <script>
<variable name="wcmwf_approveCnt" access="read, write"/> <variable name="wcmwf_approveCnt" access="read, write"/>
@@ -109,6 +108,7 @@
</expression> </expression>
</script> </script>
</transition> </transition>
<transition name="reject" to="endreview" />
</task-node> </task-node>
@@ -136,7 +136,6 @@
</script> </script>
</event> </event>
</task> </task>
<transition name="reject" to="joinparallelreview" />
<transition name="approve" to="joinparallelreview"> <transition name="approve" to="joinparallelreview">
<script> <script>
<variable name="wcmwf_approveCnt" access="read,write" /> <variable name="wcmwf_approveCnt" access="read,write" />
@@ -145,6 +144,7 @@
</expression> </expression>
</script> </script>
</transition> </transition>
<transition name="reject" to="joinparallelreview" />
</task-node> </task-node>
<join name="joinparallelreview"> <join name="joinparallelreview">

View File

@@ -358,7 +358,14 @@ public class AVMServiceTest extends AVMServiceTestBase
tx.begin(); tx.begin();
if(fService.getStore("avmAsynchronousTest") != null) if(fService.getStore("avmAsynchronousTest") != null)
{ {
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
fService.purgeStore("avmAsynchronousTest"); fService.purgeStore("avmAsynchronousTest");
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("bananaStoreWoof"));
}
else
{
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
} }
StoreRef storeRef = AVMNodeConverter.ToStoreRef("avmAsynchronousTest"); StoreRef storeRef = AVMNodeConverter.ToStoreRef("avmAsynchronousTest");
Indexer indexer = fIndexerAndSearcher.getIndexer(storeRef); Indexer indexer = fIndexerAndSearcher.getIndexer(storeRef);
@@ -369,6 +376,12 @@ public class AVMServiceTest extends AVMServiceTestBase
} }
tx.commit(); 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. // TODO: Suspend and resume indexing in case we are really unlucky and hit an index before we expect it.
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
@@ -379,8 +392,19 @@ public class AVMServiceTest extends AVMServiceTestBase
results.close(); results.close();
fService.createStore("avmAsynchronousTest"); fService.createStore("avmAsynchronousTest");
tx = fTransactionService.getUserTransaction();
tx.begin();
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
tx.commit();
fService.createSnapshot("avmAsynchronousTest", null, null); fService.createSnapshot("avmAsynchronousTest", null, null);
tx = fTransactionService.getUserTransaction();
tx.begin();
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
tx.commit();
results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(1, results.length()); assertEquals(1, results.length());
results.close(); results.close();
@@ -388,8 +412,27 @@ public class AVMServiceTest extends AVMServiceTestBase
fService.createDirectory("avmAsynchronousTest:/", "a"); fService.createDirectory("avmAsynchronousTest:/", "a");
fService.createDirectory("avmAsynchronousTest:/a", "b"); fService.createDirectory("avmAsynchronousTest:/a", "b");
fService.createDirectory("avmAsynchronousTest:/a/b", "c"); 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); 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:\"//.\""); results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(1, results.length()); assertEquals(1, results.length());
results.close(); results.close();
@@ -400,6 +443,14 @@ public class AVMServiceTest extends AVMServiceTestBase
assertEquals(4, results.length()); assertEquals(4, results.length());
results.close(); 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"); fService.purgeStore("avmAsynchronousTest");
results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");

View File

@@ -31,6 +31,7 @@ import java.util.TreeMap;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.search.IndexerAndSearcher; import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser; import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -81,6 +82,8 @@ public class AVMServiceTestBase extends TestCase
*/ */
private long fStartTime; private long fStartTime;
protected static AVMSnapShotTriggeredIndexingMethodInterceptor fIndexingInterceptor;
protected static TransactionService fTransactionService; protected static TransactionService fTransactionService;
protected static IndexerAndSearcher fIndexerAndSearcher; protected static IndexerAndSearcher fIndexerAndSearcher;
@@ -104,6 +107,8 @@ public class AVMServiceTestBase extends TestCase
fIndexerAndSearcher = (IndexerAndSearcher)fContext.getBean("indexerAndSearcherFactory"); fIndexerAndSearcher = (IndexerAndSearcher)fContext.getBean("indexerAndSearcherFactory");
fTransactionService = (TransactionService)fContext.getBean("transactionComponent"); fTransactionService = (TransactionService)fContext.getBean("transactionComponent");
fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService"); fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService");
fIndexingInterceptor = (AVMSnapShotTriggeredIndexingMethodInterceptor)fContext.getBean("avmSnapShotTriggeredIndexingMethodInterceptor");
AuthenticationService authService = (AuthenticationService)fContext.getBean("AuthenticationService"); AuthenticationService authService = (AuthenticationService)fContext.getBean("AuthenticationService");
authService.authenticate("admin", "admin".toCharArray()); authService.authenticate("admin", "admin".toCharArray());
CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener"); CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener");

View File

@@ -50,7 +50,7 @@ import org.springframework.context.ApplicationContext;
*/ */
public abstract class AbstractMetadataExtracterTest extends TestCase 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_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"; protected static final String QUICK_DESCRIPTION = "Gym class featuring a brown fox and lazy dog";

View File

@@ -49,7 +49,7 @@ public class MetadataExtracterRegistry
private static final Log logger = LogFactory.getLog(MetadataExtracterRegistry.class); private static final Log logger = LogFactory.getLog(MetadataExtracterRegistry.class);
private List<MetadataExtracter> extracters; private List<MetadataExtracter> extracters;
private Map<String, MetadataExtracter> extracterCache; private Map<String, List<MetadataExtracter>> extracterCache;
/** Controls read access to the cache */ /** Controls read access to the cache */
private Lock extracterCacheReadLock; private Lock extracterCacheReadLock;
@@ -60,7 +60,7 @@ public class MetadataExtracterRegistry
{ {
// initialise lists // initialise lists
extracters = new ArrayList<MetadataExtracter>(10); extracters = new ArrayList<MetadataExtracter>(10);
extracterCache = new HashMap<String, MetadataExtracter>(17); extracterCache = new HashMap<String, List<MetadataExtracter>>(17);
// create lock objects for access to the cache // create lock objects for access to the cache
ReadWriteLock extractionCacheLock = new ReentrantReadWriteLock(); ReadWriteLock extractionCacheLock = new ReentrantReadWriteLock();
@@ -104,7 +104,7 @@ public class MetadataExtracterRegistry
*/ */
public MetadataExtracter getExtracter(String sourceMimetype) public MetadataExtracter getExtracter(String sourceMimetype)
{ {
MetadataExtracter extracter = null; List<MetadataExtracter> extractors = null;
extracterCacheReadLock.lock(); extracterCacheReadLock.lock();
try try
{ {
@@ -112,7 +112,7 @@ public class MetadataExtracterRegistry
{ {
// the translation has been requested before // the translation has been requested before
// it might have been null // it might have been null
return extracterCache.get(sourceMimetype); extractors = extracterCache.get(sourceMimetype);
} }
} }
finally finally
@@ -120,44 +120,59 @@ public class MetadataExtracterRegistry
extracterCacheReadLock.unlock(); extracterCacheReadLock.unlock();
} }
// the translation has not been requested before if (extractors == null)
// 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 // No request has been made before
extracter = findBestExtracter(sourceMimetype); // Get a write lock on the cache
// store the result even if it is null // No double check done as it is not an expensive task
extracterCache.put(sourceMimetype, extracter); extracterCacheWriteLock.lock();
return extracter; 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 * @param sourceMimetype The MIME type under examination
* @return The fastest of the most reliable extracters in <code>extracters</code> * @return Returns a set of extractors that will work for the given mimetype
* for the given MIME type, or null if none is available.
*/ */
private MetadataExtracter findBestExtracter(String sourceMimetype) private List<MetadataExtracter> findBestExtracters(String sourceMimetype)
{ {
logger.debug("Finding best extracter for " + sourceMimetype); logger.debug("Finding extractors for " + sourceMimetype);
MetadataExtracter bestExtracter = null; List<MetadataExtracter> extractors = new ArrayList<MetadataExtracter>(1);
for (MetadataExtracter ext : extracters) for (MetadataExtracter extractor : extracters)
{ {
if (!ext.isSupported(sourceMimetype)) if (!extractor.isSupported(sourceMimetype))
{ {
// extraction not achievable // extraction not achievable
continue; continue;
} }
bestExtracter = ext; extractors.add(extractor);
} }
return bestExtracter; return extractors;
} }
} }

View File

@@ -80,25 +80,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
this.connection = connection; 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 * Initialises the bean by establishing an UNO connection
*/ */
@@ -109,15 +90,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
// Base initialization // Base initialization
super.init(); 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(); 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 @Override
public Map<String, Serializable> extractRaw(ContentReader reader) throws Throwable public Map<String, Serializable> extractRaw(ContentReader reader) throws Throwable
{ {
@@ -146,35 +131,32 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
String sourceUrl = toUrl(tempFromFile, connection); String sourceUrl = toUrl(tempFromFile, connection);
// UNO Interprocess Bridge *should* be thread-safe, but... // 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(); throw new FileNotFoundException("could not open source document: " + sourceUrl);
XComponent document = desktop.loadComponentFromURL( }
sourceUrl, try
"_blank", {
0, XDocumentInfoSupplier infoSupplier = (XDocumentInfoSupplier) UnoRuntime.queryInterface(
new PropertyValue[] { property("Hidden", Boolean.TRUE) }); XDocumentInfoSupplier.class, document);
if (document == null) XPropertySet propSet = (XPropertySet) UnoRuntime.queryInterface(
{ XPropertySet.class,
throw new FileNotFoundException("could not open source document: " + sourceUrl); infoSupplier
} .getDocumentInfo());
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_TITLE, propSet.getPropertyValue("Title").toString(), rawProperties);
putRawValue(KEY_DESCRIPTION, propSet.getPropertyValue("Subject").toString(), rawProperties); putRawValue(KEY_DESCRIPTION, propSet.getPropertyValue("Subject").toString(), rawProperties);
putRawValue(KEY_AUTHOR, propSet.getPropertyValue("Author").toString(), rawProperties); putRawValue(KEY_AUTHOR, propSet.getPropertyValue("Author").toString(), rawProperties);
} }
finally finally
{ {
document.dispose(); document.dispose();
}
} }
// Done // Done
return rawProperties; return rawProperties;
@@ -188,14 +170,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
return fic.getFileURLFromSystemPath("", file.getAbsolutePath()); 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) private static PropertyValue property(String name, Object value)
{ {
PropertyValue property = new PropertyValue(); PropertyValue property = new PropertyValue();

View File

@@ -38,7 +38,7 @@ public class OpenOfficeMetadataExtracterTest extends AbstractMetadataExtracterTe
{ {
super.setUp(); super.setUp();
OpenOfficeConnection connection = new SocketOpenOfficeConnection(); OpenOfficeConnection connection = (OpenOfficeConnection) ctx.getBean("openOfficeConnection");
extracter = new OpenOfficeMetadataExtracter(); extracter = new OpenOfficeMetadataExtracter();
extracter.setMimetypeService(mimetypeMap); extracter.setMimetypeService(mimetypeMap);

View File

@@ -27,7 +27,6 @@ package org.alfresco.repo.content.transform;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.ConnectException;
import java.util.Map; import java.util.Map;
import net.sf.jooreports.converter.DocumentFamily; 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.service.cmr.repository.MimetypeService;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
/** /**
@@ -58,11 +55,7 @@ import org.springframework.core.io.DefaultResourceLoader;
*/ */
public class OpenOfficeContentTransformer extends AbstractContentTransformer public class OpenOfficeContentTransformer extends AbstractContentTransformer
{ {
private static Log logger = LogFactory.getLog(OpenOfficeContentTransformer.class);
private OpenOfficeConnection connection; private OpenOfficeConnection connection;
/** Keep track of the initial connection state */
private boolean initiallyConnected;
private OpenOfficeDocumentConverter converter; private OpenOfficeDocumentConverter converter;
private String documentFormatsConfiguration; private String documentFormatsConfiguration;
private DocumentFormatRegistry formatRegistry; private DocumentFormatRegistry formatRegistry;
@@ -91,30 +84,6 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
return connection.isConnected(); 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 @Override
public void register() public void register()
{ {
@@ -140,18 +109,11 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
formatRegistry = new XmlDocumentFormatRegistry(); formatRegistry = new XmlDocumentFormatRegistry();
} }
// attempt to establish a connection
initiallyConnected = connect();
// set up the converter // set up the converter
converter = new OpenOfficeDocumentConverter(connection); converter = new OpenOfficeDocumentConverter(connection);
if (initiallyConnected) // Register
{ super.register();
// 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();
}
} }
/** /**
@@ -161,16 +123,8 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer
{ {
if (!isConnected()) if (!isConnected())
{ {
if (!initiallyConnected) // The connection management is must take care of this
{ return 0.0;
// 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;
}
} }
// there are some conversions that fail, despite the converter believing them possible // there are some conversions that fail, despite the converter believing them possible

View File

@@ -642,6 +642,19 @@ public class ScriptNode implements Serializable, Scopeable
return getAspects().contains(createQName(aspect)); 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 * @return Display path to this node
*/ */

View File

@@ -638,6 +638,19 @@ public class FileFolderServiceImpl implements FileFolderService
{ {
// changed the name property // changed the name property
nodeService.setProperty(targetNodeRef, ContentModel.PROP_NAME, newName); 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) catch (DuplicateChildNodeNameException e)
{ {

View File

@@ -4,6 +4,7 @@ import java.util.List;
import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode; import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.search.IndexMode;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
@@ -116,6 +117,11 @@ public class AVMFullIndexRecoveryComponent extends AbstractReindexComponent
else else
// validate first // validate first
{ {
if(avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(store) == IndexMode.UNINDEXED)
{
return;
}
int lastActualSnapshotId = avmService.getLatestSnapshotID(store); int lastActualSnapshotId = avmService.getLatestSnapshotID(store);
if (lastActualSnapshotId <= 0) if (lastActualSnapshotId <= 0)
{ {

View File

@@ -279,7 +279,73 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
return false; 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); IndexMode mode = modeCache.get(store);
if (mode == null) if (mode == null)

View File

@@ -51,6 +51,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer; import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.search.IndexMode; 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.FTSIndexerAware;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -492,7 +493,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
} }
else 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)); 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<String> impl
{ {
String[] split = term.text().split(":"); String[] split = term.text().split(":");
int test = Integer.parseInt(split[3]); int test = Integer.parseInt(split[3]);
if(test > end) if (test > end)
{ {
end = test; end = test;
} }
@@ -1485,7 +1486,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{ {
String[] split = term.text().split(":"); String[] split = term.text().split(":");
int test = Integer.parseInt(split[4]); int test = Integer.parseInt(split[4]);
if(test > end) if (test > end)
{ {
end = test; end = test;
} }