mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
13853: Merged V3.0 to V3.1 13008: Merged V2.2 to V3.0 12824: (record only) Change admin access to the web project staging store to be read-only in the virtualization view - ETWOTWO-933 13031: (Record only) AMP fix for ETWOTWO-968: Space rules are not run when saving from MS Word 13040: Merged V2.2 to V3.0 12824: (record-only) - already done via r13005 (ETWOTWO-933) 13145: Merged V2.2 to V3.0: 13089: (record-only) Fix "Read-Write transaction started within read-only transaction" exception. ETWOTWO-1055. 13091: (record-only) Fix for NFS server "Read-Write transaction started within read-only transaction" exception. ETWOTWO-1054. 13508: ETHREEOH-1548 - allow config to reset (even if null/cache) 13514: ETHREEOH-1548 (follow-on fix) - to allow config to reset (even if null/cache) and also reduce 5 caches to 1 13848: Merged V2.2 to V3.0 13188: *RECORD ONLY* Using correct ooo startup context - does not work for *nix. Fixed in 3.0sp1 13212: *RECORD ONLY* AMP for ETWOTWO-984 13342: *RECORD ONLY* Merge info stuff 13435: Merged V2.1 to V2.2 12307: Merged DEV/V2.1SP7 to 2.1 11927: ETWOONE-396 12112: ETWOONE-396 13442: *RECORD ONLY* Updated version to 2.2.4dev 13468: *RECORD ONLY* Removed svn:mergeinfo crud 13470: I18NUtil doesn't cause NPE if message key doesn't exist 13471: Fixed ETWOTWO-1133: Incorrect CRC32 Values for non-ASCII names 13475: Test fix: I18NUtil.getMessage() no longer returns null, leading to NPEs if message bundle is missing 13476: Reverted back to null return values. Will save for fixing on HEAD. 13749: Fixed ALFCOM-2655: MLTranslationInterceptor doesn't handle getType method 13803: ETWOTWO-710 13819: *RECORD ONLY* ACT-6420 - Office 2003 "Install for all users" - DO NOT MERGE 13827: ETWOTWO-1172 - authority exists now checks nodeRef result ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.0:r12824,13008,13031,13040,13089,13091,13145,13848 Merged /alfresco/BRANCHES/V2.2:r12824,13188,13212,13342,13442,13468,13470-13471,13475-13476,13749,13803,13827 Merged /alfresco/BRANCHES/V3.1:r13853 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14763 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.ChildAssoc;
|
||||
import org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.repo.domain.QNameDAO;
|
||||
import org.alfresco.repo.domain.hibernate.ChildAssocImpl;
|
||||
import org.alfresco.repo.node.db.NodeDaoService;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.hibernate.SQLQuery;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.type.LongType;
|
||||
import org.hibernate.type.StringType;
|
||||
import org.springframework.orm.hibernate3.HibernateCallback;
|
||||
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
|
||||
|
||||
/**
|
||||
* Fixes <a href=https://issues.alfresco.com/jira/browse/ETWOTWO-1133>ETWOTWO-1133</a>.
|
||||
* Checks all CRC values for <b>alf_child_assoc.child_node_name_crc</b>.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since V2.2SP4
|
||||
*/
|
||||
public class FixNameCrcValuesPatch extends AbstractPatch
|
||||
{
|
||||
private static final String MSG_SUCCESS = "patch.fixNameCrcValues.result";
|
||||
private static final String MSG_REWRITTEN = "patch.fixNameCrcValues.fixed";
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
private NodeDaoService nodeDaoService;
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
public FixNameCrcValuesPatch()
|
||||
{
|
||||
}
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeDaoService The service that generates the CRC values
|
||||
*/
|
||||
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||
{
|
||||
this.nodeDaoService = nodeDaoService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param qnameDAO resolved QNames
|
||||
*/
|
||||
public void setQnameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
this.qnameDAO = qnameDAO;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkProperties()
|
||||
{
|
||||
super.checkProperties();
|
||||
checkPropertyNotNull(sessionFactory, "sessionFactory");
|
||||
checkPropertyNotNull(nodeDaoService, "nodeDaoService");
|
||||
checkPropertyNotNull(qnameDAO, "qnameDAO");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
// initialise the helper
|
||||
HibernateHelper helper = new HibernateHelper();
|
||||
helper.setSessionFactory(sessionFactory);
|
||||
|
||||
try
|
||||
{
|
||||
String msg = helper.fixCrcValues();
|
||||
// done
|
||||
return msg;
|
||||
}
|
||||
finally
|
||||
{
|
||||
helper.closeWriter();
|
||||
}
|
||||
}
|
||||
|
||||
private class HibernateHelper extends HibernateDaoSupport
|
||||
{
|
||||
private File logFile;
|
||||
private FileChannel channel;
|
||||
|
||||
private HibernateHelper() throws IOException
|
||||
{
|
||||
logFile = new File("./FixNameCrcValuesPatch.log");
|
||||
// open the file for appending
|
||||
RandomAccessFile outputFile = new RandomAccessFile(logFile, "rw");
|
||||
channel = outputFile.getChannel();
|
||||
// move to the end of the file
|
||||
channel.position(channel.size());
|
||||
// add a newline and it's ready
|
||||
writeLine("").writeLine("");
|
||||
writeLine("FixNameCrcValuesPatch executing on " + new Date());
|
||||
}
|
||||
|
||||
private HibernateHelper write(Object obj) throws IOException
|
||||
{
|
||||
channel.write(ByteBuffer.wrap(obj.toString().getBytes("UTF-8")));
|
||||
return this;
|
||||
}
|
||||
private HibernateHelper writeLine(Object obj) throws IOException
|
||||
{
|
||||
write(obj);
|
||||
write("\n");
|
||||
return this;
|
||||
}
|
||||
private void closeWriter()
|
||||
{
|
||||
try { channel.close(); } catch (Throwable e) {}
|
||||
}
|
||||
|
||||
public String fixCrcValues() throws Exception
|
||||
{
|
||||
// get the association types to check
|
||||
@SuppressWarnings("unused")
|
||||
List<Long> childAssocIds = findMismatchedCrcs();
|
||||
|
||||
int updated = 0;
|
||||
for (Long childAssocId : childAssocIds)
|
||||
{
|
||||
ChildAssoc assoc = (ChildAssoc) getHibernateTemplate().get(ChildAssocImpl.class, childAssocId);
|
||||
if (assoc == null)
|
||||
{
|
||||
// Missing now ...
|
||||
continue;
|
||||
}
|
||||
// Get the old CRC
|
||||
long oldCrc = assoc.getChildNodeNameCrc();
|
||||
// Get the child node
|
||||
Node childNode = assoc.getChild();
|
||||
// Get the name
|
||||
String childName = (String) nodeDaoService.getNodeProperty(childNode.getId(), ContentModel.PROP_NAME);
|
||||
if (childName == null)
|
||||
{
|
||||
childName = childNode.getUuid();
|
||||
}
|
||||
// Update the CRC
|
||||
long crc = getCrc(childName);
|
||||
// Update the assoc
|
||||
assoc.setChildNodeNameCrc(crc);
|
||||
// Persist
|
||||
updated++;
|
||||
getSession().flush();
|
||||
getSession().clear();
|
||||
// Record
|
||||
writeLine(I18NUtil.getMessage(MSG_REWRITTEN, childNode.getId(), childName, oldCrc, crc));
|
||||
}
|
||||
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS, updated, logFile);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Long> findMismatchedCrcs() throws Exception
|
||||
{
|
||||
final Long qnameId = qnameDAO.getOrCreateQName(ContentModel.PROP_NAME).getFirst();
|
||||
|
||||
final List<Long> childAssocIds = new ArrayList<Long>(1000);
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
SQLQuery query = session
|
||||
.createSQLQuery(
|
||||
" SELECT " +
|
||||
" ca.id AS child_assoc_id," +
|
||||
" ca.child_node_name_crc AS child_assoc_crc," +
|
||||
" np.string_value AS node_name," +
|
||||
" n.uuid as node_uuid" +
|
||||
" FROM" +
|
||||
" alf_child_assoc ca" +
|
||||
" JOIN alf_node n ON (ca.child_node_id = n.id AND ca.child_node_name_crc > 0)" +
|
||||
" JOIN alf_node_properties np on (np.node_id = n.id AND np.qname_id = :qnameId)" +
|
||||
"");
|
||||
query.setLong("qnameId", qnameId);
|
||||
query.addScalar("child_assoc_id", new LongType());
|
||||
query.addScalar("child_assoc_crc", new LongType());
|
||||
query.addScalar("node_name", new StringType());
|
||||
query.addScalar("node_uuid", new StringType());
|
||||
return query.scroll(ScrollMode.FORWARD_ONLY);
|
||||
}
|
||||
};
|
||||
ScrollableResults rs = null;
|
||||
try
|
||||
{
|
||||
rs = (ScrollableResults) getHibernateTemplate().execute(callback);
|
||||
while (rs.next())
|
||||
{
|
||||
Long assocId = (Long) rs.get(0);
|
||||
Long dbCrc = (Long) rs.get(1);
|
||||
String name = (String) rs.get(2);
|
||||
String uuid = (String) rs.get(3);
|
||||
long utf8Crc = -1L;
|
||||
if (name != null)
|
||||
{
|
||||
utf8Crc = getCrc(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
utf8Crc = getCrc(uuid);
|
||||
}
|
||||
// Check
|
||||
if (dbCrc != null && utf8Crc == dbCrc.longValue())
|
||||
{
|
||||
// It is a match, so ignore
|
||||
continue;
|
||||
}
|
||||
childAssocIds.add(assocId);
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
logger.error("Failed to query for child name CRCs", e);
|
||||
writeLine("Failed to query for child name CRCs: " + e.getMessage());
|
||||
throw new PatchException("Failed to query for child name CRCs", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (rs != null)
|
||||
{
|
||||
try { rs.close(); } catch (Throwable e) { writeLine("Failed to close resultset: " + e.getMessage()); }
|
||||
}
|
||||
}
|
||||
return childAssocIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str the name that will be converted to lowercase
|
||||
* @return the CRC32 calcualted on the lowercase version of the string
|
||||
*/
|
||||
private long getCrc(String str)
|
||||
{
|
||||
CRC32 crc = new CRC32();
|
||||
try
|
||||
{
|
||||
crc.update(str.toLowerCase().getBytes("UTF-8")); // https://issues.alfresco.com/jira/browse/ALFCOM-1335
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new RuntimeException("UTF-8 encoding is not supported");
|
||||
}
|
||||
return crc.getValue();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user