mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V4.0-BUG-FIX to HEAD
33836: Fix for ALF-10651 Fix patches that trigger reindexing and ALF-10656 SOLR: Patches execute search during bootstrap causing deadlock 33842: Fixes ALF-12797: i18n strings in activiti-admin login-screen escaped properly 33844: Fix for ALF-10651 Fix patches that trigger reindexing and ALF-10656 SOLR: Patches execute search during bootstrap causing deadlock - batch touch to limit the in clause size generated 33845: Manually added extra core Share extensions needed for the V4.0 Records Management module from the development branch. - Refactored JSON property decorators for the Document Library data webscripts - Document List banners (e.g. working copy) moved into metadata template config - Ability to override default document/folder title within Document Library (<title> element in metadata template - unused in core code) - Additional extension point in surf-doclist to override remote data URL - Better handling for missing content property 33852: ALF-12725: Merged V3.4-BUG-FIX (3.4.9) to V4.0-BUG-FIX (4.0.1) 33849: Merged V3 (3.4.8) to V3.4-BUG-FIX (3.4.9) 33848: ALF-10976 (relates to ALF-10412) Fixed bug to do with preview being stuck as always being 'Content cannot be previewed. Do you wish to download?' or a 'blank preview after a transformer is not found' for all content with the same mimetype. Cache in ThumbnailRegistory.getThumbnailDefinitions() now understands that transformers may have an upper content size limit. The choice between the two options was based on the size of the first file previewed of each mimetype. Needed to add getMaxSourceSizeBytes() to support this (see below). - refactored (previous refactor was incomplete) ContentTransformer so that the two halfs of isTransformable is now split into sub methods isTransformableMimetypes and isTransformableSize. This is why there are so many files changed. - Moved getMaxSourceSizeBytes() from AbstractContentTransformerLimits to ContentTransformer as there were becomming too many places in the code that needed needed to check if the ContentTransformer was an instanceof AbstractContentTransformerLimits before calling this method. - TransformerDebug now uses KB MB GB values in output to make it simpler to read. - TransformerDebug now uses thousand separaters in millisecond values to make it simpler to read. - TransformerDebug now reports the 'parent' transformer name rather than the sub-transformer name when an unavailable transformer is found. Makes it simpler to tie up with the 'available transformer' list with the new pushIsTransformableSize() calls. - TransformerDebug now uses trace logging for calls from ThumbnailRegistory.isThumbnailDefinitionAvailable() as it is normally followed by a ContentService.transform() which is logged at debug level anyway. - TransformerDebug now turns logging level to trace if the file size is 0 bytes. Request from Jan. Not sure how one uploads such a file! - Modified ComplexContentTransformer.isTransformable() so that it checks the mimetypes before the sizes so that TransformerDebug does not report 'unavailable transformers' that don't support the mimetype conversion. - Modified ComplexContentTransformer.getLimits and ComplexContentTransformer.isPageLimitSupported() to include the limits from the first sub transformer. Was not an issue until ContentTransformer.getMaxSourceSizeBytes() was introduced. - Added logger to RhinoScriptProcessor to debug requests run javascript on the server. - Dropped the sourceUrl parameter from ThumbnailRegistry.getThumbnailDefinitions() which was introduced with limits as it is logicall not needed. 33853: DiskInterface.renameFile() can now throw PermissionDeniedException to return a different status to the client. Part of ALF-12717. 33856: Merged V3.4-BUG-FIX to V4.0-BUG-FIX 33835: ALF-12546: Remove references to retired RegPaths.exe from installed apply_amps.bat script 33843: Fix for ALF-12775 33855: Merged V3.4 to V3.4-BUG-FIX 33851: ALF-12588: Documents Intermittently Do Not Appear in Share - Fix by Alex Busel for regression I accidentally caused in 3.4.6 - Simple typo in mergeDeletions() caused path deletions to sometimes not get applied or get processed twice - Yikes! git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@33857 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -19,91 +19,134 @@
|
||||
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.patch.PatchDAO;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.importer.ImporterBootstrap;
|
||||
import org.alfresco.repo.search.Indexer;
|
||||
import org.alfresco.repo.search.IndexerAndSearcher;
|
||||
import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryParser;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* Patch usr:user and cm:person objects so that the user name properties are in the
|
||||
* index in untokenized form. If not authentication may fail in mixed language use.
|
||||
* Patch usr:user and cm:person objects so that the user name properties are in the index in untokenized form. If not
|
||||
* authentication may fail in mixed language use.
|
||||
*
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class CalendarModelUriPatch extends AbstractPatch
|
||||
{
|
||||
private static final String MSG_SUCCESS = "patch.calendarModelNamespacePatch.result";
|
||||
|
||||
|
||||
private static final String URI_BEFORE = "com.infoaxon.alfresco.calendar";
|
||||
private static final String URI_AFTER = "http://www.alfresco.org/model/calendar";
|
||||
|
||||
private ImporterBootstrap importerBootstrap;
|
||||
private IndexerAndSearcher indexerAndSearcher;
|
||||
|
||||
private static final String URI_AFTER = "http://www.alfresco.org/model/calendar";
|
||||
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
private PatchDAO patchDAO;
|
||||
|
||||
private NodeDAO nodeDAO;
|
||||
|
||||
private RetryingTransactionHelper retryingTransactionHelper;
|
||||
|
||||
private static long BATCH_SIZE = 100000L;
|
||||
|
||||
|
||||
|
||||
|
||||
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
|
||||
{
|
||||
this.importerBootstrap = importerBootstrap;
|
||||
}
|
||||
|
||||
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
|
||||
{
|
||||
this.indexerAndSearcher = indexerAndSearcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param qnameDAO the qnameDAO to set
|
||||
*/
|
||||
public void setQnameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
this.qnameDAO = qnameDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param patchDAO the patchDAO to set
|
||||
*/
|
||||
public void setPatchDAO(PatchDAO patchDAO)
|
||||
{
|
||||
this.patchDAO = patchDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeDAO the nodeDAO to set
|
||||
*/
|
||||
public void setNodeDAO(NodeDAO nodeDAO)
|
||||
{
|
||||
this.nodeDAO = nodeDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryingTransactionHelper the retryingTransactionHelper to set
|
||||
*/
|
||||
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||
{
|
||||
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||
}
|
||||
|
||||
protected void checkProperties()
|
||||
{
|
||||
super.checkProperties();
|
||||
checkPropertyNotNull(patchDAO, "patchDAO");
|
||||
checkPropertyNotNull(qnameDAO, "qnameDAO");
|
||||
checkPropertyNotNull(nodeDAO, "nodeDAO");
|
||||
checkPropertyNotNull(retryingTransactionHelper, "retryingTransactionHelper");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
Long maxNodeId = patchDAO.getMaxAdmNodeID();
|
||||
long count = 0L;
|
||||
|
||||
// Make sure the old name spaces exists before we update it ...
|
||||
qnameDAO.getOrCreateNamespace(URI_BEFORE);
|
||||
Pair<Long, String> before = qnameDAO.getOrCreateNamespace(URI_BEFORE);
|
||||
for (Long i = 0L; i < maxNodeId; i+=BATCH_SIZE)
|
||||
{
|
||||
Work work = new Work(before.getFirst(), i);
|
||||
count += retryingTransactionHelper.doInTransaction(work, false, true);
|
||||
}
|
||||
|
||||
// modify namespace for all calendar entries
|
||||
qnameDAO.updateNamespace(URI_BEFORE, URI_AFTER);
|
||||
|
||||
// reindex the calendar entries
|
||||
int count = reindex("TYPE:\\{" + AbstractLuceneQueryParser.escape(URI_BEFORE) + "\\}*", importerBootstrap.getStoreRef());
|
||||
|
||||
return I18NUtil.getMessage(MSG_SUCCESS, count);
|
||||
}
|
||||
|
||||
private int reindex(String query, StoreRef store)
|
||||
|
||||
private class Work implements RetryingTransactionHelper.RetryingTransactionCallback<Integer>
|
||||
{
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp.setQuery(query);
|
||||
sp.addStore(store);
|
||||
Indexer indexer = indexerAndSearcher.getIndexer(store);
|
||||
ResultSet rs = null;
|
||||
int count = 0;
|
||||
try
|
||||
long nsId;
|
||||
|
||||
long lower;
|
||||
|
||||
Work(long nsId, long lower)
|
||||
{
|
||||
rs = searchService.query(sp);
|
||||
count = rs.length();
|
||||
for (ResultSetRow row : rs)
|
||||
{
|
||||
indexer.updateNode(row.getNodeRef());
|
||||
}
|
||||
this.nsId = nsId;
|
||||
this.lower = lower;
|
||||
}
|
||||
finally
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback#execute()
|
||||
*/
|
||||
@Override
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
if (rs != null)
|
||||
{
|
||||
rs.close();
|
||||
}
|
||||
List<Long> nodeIds = patchDAO.getNodesByTypeUriId(nsId, lower, lower + BATCH_SIZE);
|
||||
nodeDAO.touchNodes(nodeDAO.getCurrentTransactionId(true), nodeIds);
|
||||
return nodeIds.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
@@ -18,23 +18,15 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.mimetype.MimetypeDAO;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.patch.PatchDAO;
|
||||
import org.alfresco.repo.search.Indexer;
|
||||
import org.alfresco.repo.search.IndexerAndSearcher;
|
||||
import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryParser;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
@@ -57,18 +49,21 @@ public class GenericMimetypeRenamePatch extends AbstractPatch
|
||||
private static final String MSG_DONE_REINDEX = "patch.genericMimetypeUpdate.doneReindex";
|
||||
|
||||
/* Helper DAOs */
|
||||
private IndexerAndSearcher indexerAndSearcher;
|
||||
|
||||
private MimetypeDAO mimetypeDAO;
|
||||
|
||||
private PatchDAO patchDAO;
|
||||
|
||||
|
||||
private NodeDAO nodeDAO;
|
||||
|
||||
private RetryingTransactionHelper retryingTransactionHelper;
|
||||
|
||||
private static long BATCH_SIZE = 100000L;
|
||||
|
||||
|
||||
/** Mimetype mappings */
|
||||
private Map<String, String> mimetypeMappings;
|
||||
private boolean reindex;
|
||||
|
||||
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
|
||||
{
|
||||
this.indexerAndSearcher = indexerAndSearcher;
|
||||
}
|
||||
|
||||
public void setMimetypeDAO(MimetypeDAO mimetypeDAO)
|
||||
{
|
||||
@@ -90,36 +85,46 @@ public class GenericMimetypeRenamePatch extends AbstractPatch
|
||||
this.reindex = reindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param nodeDAO the nodeDAO to set
|
||||
*/
|
||||
public void setNodeDAO(NodeDAO nodeDAO)
|
||||
{
|
||||
this.nodeDAO = nodeDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryingTransactionHelper the retryingTransactionHelper to set
|
||||
*/
|
||||
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||
{
|
||||
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||
}
|
||||
|
||||
protected void checkProperties()
|
||||
{
|
||||
super.checkProperties();
|
||||
checkPropertyNotNull(indexerAndSearcher, "indexerAndSearcher");
|
||||
checkPropertyNotNull(mimetypeDAO, "mimetypeDAO");
|
||||
checkPropertyNotNull(patchDAO, "patchDAO");
|
||||
checkPropertyNotNull(mimetypeMappings, "mimetypeMappings");
|
||||
checkPropertyNotNull(nodeDAO, "nodeDAO");
|
||||
checkPropertyNotNull(retryingTransactionHelper, "retryingTransactionHelper");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
// First get all the available stores that we might want to reindex
|
||||
List<StoreRef> storeRefsList = nodeService.getStores();
|
||||
Set<StoreRef> storeRefs = new HashSet<StoreRef>();
|
||||
for (StoreRef storeRef : storeRefsList)
|
||||
{
|
||||
// We want workspace://SpacesStore or related MT stores
|
||||
if (storeRef.getIdentifier().endsWith("SpacesStore"))
|
||||
{
|
||||
storeRefs.add(storeRef);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder(I18NUtil.getMessage(MSG_START));
|
||||
|
||||
Long maxNodeId = patchDAO.getMaxAdmNodeID();
|
||||
|
||||
for (Map.Entry<String, String> element : mimetypeMappings.entrySet())
|
||||
{
|
||||
String oldMimetype = element.getKey();
|
||||
String newMimetype = element.getValue();
|
||||
|
||||
|
||||
// First check if the mimetype is used at all
|
||||
Pair<Long, String> oldMimetypePair = mimetypeDAO.getMimetype(oldMimetype);
|
||||
if (oldMimetypePair == null)
|
||||
@@ -127,7 +132,20 @@ public class GenericMimetypeRenamePatch extends AbstractPatch
|
||||
// Not used
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// pull all affectsed nodes into a new transaction id indexed
|
||||
|
||||
if(reindex)
|
||||
{
|
||||
long count = 0L;
|
||||
for (Long i = 0L; i < maxNodeId; i+=BATCH_SIZE)
|
||||
{
|
||||
Work work = new Work(oldMimetypePair.getFirst(), i);
|
||||
count += retryingTransactionHelper.doInTransaction(work, false, true);
|
||||
}
|
||||
result.append(I18NUtil.getMessage(MSG_INDEXED, count, "(All stores)"));
|
||||
}
|
||||
|
||||
// Check if the new mimetype exists
|
||||
Pair<Long, String> newMimetypePair = mimetypeDAO.getMimetype(newMimetype);
|
||||
int updateCount = 0;
|
||||
@@ -144,16 +162,6 @@ public class GenericMimetypeRenamePatch extends AbstractPatch
|
||||
updateCount = patchDAO.updateContentMimetypeIds(oldMimetypeId, newMimetypeId);
|
||||
}
|
||||
result.append(I18NUtil.getMessage(MSG_UPDATED, updateCount, oldMimetype, newMimetype));
|
||||
if (reindex)
|
||||
{
|
||||
// Update Lucene
|
||||
int reindexCount = 0;
|
||||
for (StoreRef storeRef : storeRefs)
|
||||
{
|
||||
reindexCount += reindex(oldMimetype, storeRef);
|
||||
result.append(I18NUtil.getMessage(MSG_INDEXED, reindexCount, storeRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Done
|
||||
if (reindex)
|
||||
@@ -167,33 +175,30 @@ public class GenericMimetypeRenamePatch extends AbstractPatch
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private int reindex(String oldMimetype, StoreRef store)
|
||||
|
||||
|
||||
private class Work implements RetryingTransactionHelper.RetryingTransactionCallback<Integer>
|
||||
{
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp.setQuery("@" + AbstractLuceneQueryParser.escape(ContentModel.PROP_CONTENT.toString()) +
|
||||
".mimetype:\"" + oldMimetype + "\"");
|
||||
sp.addStore(store);
|
||||
Indexer indexer = indexerAndSearcher.getIndexer(store);
|
||||
ResultSet rs = null;
|
||||
int count = 0;
|
||||
try
|
||||
long mimetypeId;
|
||||
|
||||
long lower;
|
||||
|
||||
Work(long mimetypeId, long lower)
|
||||
{
|
||||
rs = searchService.query(sp);
|
||||
count = rs.length();
|
||||
for (ResultSetRow row : rs)
|
||||
{
|
||||
indexer.updateNode(row.getNodeRef());
|
||||
}
|
||||
this.mimetypeId = mimetypeId;
|
||||
this.lower = lower;
|
||||
}
|
||||
finally
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback#execute()
|
||||
*/
|
||||
@Override
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
if (rs != null)
|
||||
{
|
||||
rs.close();
|
||||
}
|
||||
List<Long> nodeIds = patchDAO.getNodesByContentPropertyMimetypeId(mimetypeId, lower, lower + BATCH_SIZE);
|
||||
nodeDAO.touchNodes(nodeDAO.getCurrentTransactionId(true), nodeIds);
|
||||
return nodeIds.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
@@ -19,18 +19,15 @@
|
||||
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.patch.PatchDAO;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.importer.ImporterBootstrap;
|
||||
import org.alfresco.repo.search.Indexer;
|
||||
import org.alfresco.repo.search.IndexerAndSearcher;
|
||||
import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryParser;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
@@ -56,38 +53,50 @@ public class QNamePatch extends AbstractPatch
|
||||
private String qnameStringAfter;
|
||||
private String reindexClass;
|
||||
|
||||
/* Injected services */
|
||||
private ImporterBootstrap importerBootstrap;
|
||||
private IndexerAndSearcher indexerAndSearcher;
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
/**
|
||||
* Sets the importerBootstrap.
|
||||
* @param importerBootstrap.
|
||||
*/
|
||||
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
|
||||
{
|
||||
this.importerBootstrap = importerBootstrap;
|
||||
}
|
||||
private PatchDAO patchDAO;
|
||||
|
||||
private NodeDAO nodeDAO;
|
||||
|
||||
private RetryingTransactionHelper retryingTransactionHelper;
|
||||
|
||||
private static long BATCH_SIZE = 100000L;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the IndexerAndSearcher.
|
||||
* @param indexerAndSearcher
|
||||
*/
|
||||
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
|
||||
{
|
||||
this.indexerAndSearcher = indexerAndSearcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the QNameDAO.
|
||||
* @param qnameDAO
|
||||
* @param qnameDAO the qnameDAO to set
|
||||
*/
|
||||
public void setQnameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
this.qnameDAO = qnameDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param patchDAO the patchDAO to set
|
||||
*/
|
||||
public void setPatchDAO(PatchDAO patchDAO)
|
||||
{
|
||||
this.patchDAO = patchDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeDAO the nodeDAO to set
|
||||
*/
|
||||
public void setNodeDAO(NodeDAO nodeDAO)
|
||||
{
|
||||
this.nodeDAO = nodeDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryingTransactionHelper the retryingTransactionHelper to set
|
||||
*/
|
||||
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||
{
|
||||
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the QName to be patched.
|
||||
* @param qnameStringBefore the long-form QName to be patched from. {namespaceURI}localName
|
||||
@@ -116,6 +125,17 @@ public class QNamePatch extends AbstractPatch
|
||||
this.reindexClass = reindexClass;
|
||||
}
|
||||
|
||||
protected void checkProperties()
|
||||
{
|
||||
super.checkProperties();
|
||||
checkPropertyNotNull(patchDAO, "patchDAO");
|
||||
checkPropertyNotNull(qnameDAO, "qnameDAO");
|
||||
checkPropertyNotNull(nodeDAO, "nodeDAO");
|
||||
checkPropertyNotNull(retryingTransactionHelper, "retryingTransactionHelper");
|
||||
checkPropertyNotNull(qnameStringAfter, "qnameStringAfter");
|
||||
checkPropertyNotNull(qnameStringBefore, "qnameStringBefore");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
@@ -124,46 +144,61 @@ public class QNamePatch extends AbstractPatch
|
||||
QName qnameBefore = QName.createQName(this.qnameStringBefore);
|
||||
QName qnameAfter = QName.createQName(this.qnameStringAfter);
|
||||
|
||||
if (qnameDAO.getQName(qnameBefore) != null)
|
||||
Long maxNodeId = patchDAO.getMaxAdmNodeID();
|
||||
|
||||
Pair<Long, QName> before = qnameDAO.getQName(qnameBefore);
|
||||
|
||||
for (Long i = 0L; i < maxNodeId; i+=BATCH_SIZE)
|
||||
{
|
||||
Work work = new Work(before.getFirst(), i);
|
||||
retryingTransactionHelper.doInTransaction(work, false, true);
|
||||
}
|
||||
|
||||
if (before != null)
|
||||
{
|
||||
qnameDAO.updateQName(qnameBefore, qnameAfter);
|
||||
}
|
||||
|
||||
// Optionally perform a focussed reindexing of the removed QName.
|
||||
if ("TYPE".equals(reindexClass) ||
|
||||
"ASPECT".equals(reindexClass))
|
||||
{
|
||||
reindex(reindexClass + ":" + AbstractLuceneQueryParser.escape(qnameStringBefore), importerBootstrap.getStoreRef());
|
||||
}
|
||||
|
||||
|
||||
return I18NUtil.getMessage(MSG_SUCCESS, qnameBefore, qnameAfter);
|
||||
}
|
||||
|
||||
private int reindex(String query, StoreRef store)
|
||||
private class Work implements RetryingTransactionHelper.RetryingTransactionCallback<Integer>
|
||||
{
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp.setQuery(query);
|
||||
sp.addStore(store);
|
||||
Indexer indexer = indexerAndSearcher.getIndexer(store);
|
||||
ResultSet rs = null;
|
||||
int count = 0;
|
||||
try
|
||||
long qnameId;
|
||||
|
||||
long lower;
|
||||
|
||||
Work(long qnameId, long lower)
|
||||
{
|
||||
rs = searchService.query(sp);
|
||||
count = rs.length();
|
||||
for (ResultSetRow row : rs)
|
||||
{
|
||||
indexer.updateNode(row.getNodeRef());
|
||||
}
|
||||
this.qnameId = qnameId;
|
||||
this.lower = lower;
|
||||
}
|
||||
finally
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback#execute()
|
||||
*/
|
||||
@Override
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
if (rs != null)
|
||||
if ("TYPE".equals(reindexClass))
|
||||
{
|
||||
rs.close();
|
||||
List<Long> nodeIds = patchDAO.getNodesByTypeQNameId(qnameId, lower, lower + BATCH_SIZE);
|
||||
nodeDAO.touchNodes(nodeDAO.getCurrentTransactionId(true), nodeIds);
|
||||
return nodeIds.size();
|
||||
}
|
||||
else if ("ASPECT".equals(reindexClass))
|
||||
{
|
||||
List<Long> nodeIds = patchDAO.getNodesByAspectQNameId(qnameId, lower, lower + BATCH_SIZE);
|
||||
nodeDAO.touchNodes(nodeDAO.getCurrentTransactionId(true), nodeIds);
|
||||
return nodeIds.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user