mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
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:
@@ -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>
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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">
|
||||||
|
@@ -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">
|
||||||
|
@@ -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:\"//.\"");
|
||||||
|
@@ -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");
|
||||||
|
@@ -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";
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user