Merged V1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4133 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4145 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4147 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4148 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4151 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4152 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4157 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4159 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4161 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4162 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4169 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4175 .
   
   Skipped:
      4146, 4151, 4153, 4156, 4157, 4160, 4163-4167 (inclusive)
   Last included:
      4175



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4176 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-10-20 02:03:05 +00:00
parent be167f60cf
commit ed140c671f
17 changed files with 235 additions and 62 deletions

View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -30,6 +31,7 @@ import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -51,6 +53,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class UniqueChildNamePatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.uniqueChildName.result";
private static final String ERR_UNABLE_TO_FIX = "patch.uniqueChildName.err.unable_to_fix";
private static final String MSG_COPY_OF = "patch.uniqueChildName.copyOf";
/** the number of associations to process at a time */
private static final int MAX_RESULTS = 1000;
@@ -143,6 +146,7 @@ public class UniqueChildNamePatch extends AbstractPatch
@SuppressWarnings("unused")
List<QName> assocTypeQNames = getUsedAssocQNames();
boolean unableToFix = false;
int fixed = 0;
int processed = 0;
// check loop through all associations, looking for duplicates
@@ -185,8 +189,10 @@ public class UniqueChildNamePatch extends AbstractPatch
String usedChildName = childName;
processed++;
boolean duplicate = false;
int duplicateNumber = 0;
while(true)
{
duplicateNumber++;
try
{
// push the name back to the node
@@ -195,11 +201,46 @@ public class UniqueChildNamePatch extends AbstractPatch
}
catch (DuplicateChildNodeNameException e)
{
// there was a duplicate, so adjust the name and change the node property
duplicate = true;
// assign a new name
usedChildName = childName + I18NUtil.getMessage(MSG_COPY_OF, processed);
// try again
if (duplicateNumber == 10)
{
// Try removing the secondary parent associations
writeLine(" Removing secondary parents of node " + childNode.getId());
Collection<ChildAssoc> parentAssocs = childNode.getParentAssocs();
for (ChildAssoc parentAssoc : parentAssocs)
{
if (!parentAssoc.getIsPrimary())
{
write(" - ").writeLine(parentAssoc);
// remove it
getSession().delete(parentAssoc);
}
}
// flush to ensure the database gets the changes
getSession().flush();
// try again to be sure
continue;
}
else if (duplicateNumber > 10)
{
// after 10 attempts, we have to admit defeat. Perhaps there is a larger issue.
Collection<ChildAssoc> parentAssocs = childNode.getParentAssocs();
write(" Unable to set child name '" + usedChildName + "' for node " + childNode.getId());
writeLine(" with parent associations:");
for (ChildAssoc parentAssoc : parentAssocs)
{
write(" - ").writeLine(parentAssoc);
}
duplicate = false;
unableToFix = true;
break;
}
else
{
// there was a duplicate, so adjust the name and change the node property
duplicate = true;
// assign a new name
usedChildName = childName + I18NUtil.getMessage(MSG_COPY_OF, processed, duplicateNumber);
}
}
}
// if duplicated, report it
@@ -209,11 +250,11 @@ public class UniqueChildNamePatch extends AbstractPatch
// get the node path
NodeRef parentNodeRef = childAssoc.getParent().getNodeRef();
Path path = nodeService.getPath(parentNodeRef);
writeLine(" Changed duplicated child name:");
writeLine(" Parent: " + parentNodeRef);
writeLine(" Parent path: " + path);
writeLine(" Duplicate name: " + childName);
writeLine(" Replaced with: " + usedChildName);
writeLine(" Changed duplicated child name:");
writeLine(" Parent: " + parentNodeRef);
writeLine(" Parent path: " + path);
writeLine(" Duplicate name: " + childName);
writeLine(" Replaced with: " + usedChildName);
}
}
// clear the session to preserve memory
@@ -222,10 +263,17 @@ public class UniqueChildNamePatch extends AbstractPatch
}
}
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, processed, fixed, logFile);
return msg;
// check if it was successful or not
if (unableToFix)
{
throw new PatchException(ERR_UNABLE_TO_FIX, logFile);
}
else
{
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, processed, fixed, logFile);
return msg;
}
}
@SuppressWarnings("unchecked")

View File

@@ -25,7 +25,6 @@ import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
* @author Derek Hulley
@@ -124,9 +123,12 @@ public class ChildAssocImpl implements ChildAssoc, Serializable
{
StringBuffer sb = new StringBuffer(32);
sb.append("ChildAssoc")
.append("[ parent=").append(parent)
.append(", child=").append(child)
.append("[ id=").append(id)
.append(", parent=").append(parent.getId())
.append(", child=").append(child.getId())
.append(", child name=").append(childNodeName)
.append(", child name crc=").append(childNodeNameCrc)
.append(", assoc type=").append(getTypeQName())
.append(", assoc name=").append(getQname())
.append(", isPrimary=").append(isPrimary)
.append("]");

View File

@@ -29,7 +29,7 @@
unique="false"
not-null="false"
cascade="none" />
<property name="changeTxnId" column="change_txn_id" type="string" length="56" not-null="true" index="CHANGE_TXN_ID"/>
<property name="changeTxnId" column="change_txn_id" type="string" length="56" not-null="true" />
</class>
<class

View File

@@ -67,6 +67,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
private static final String PLACEHOLDER_SCRIPT_DIALECT = "\\$\\{db\\.script\\.dialect\\}";
private static final String MSG_EXECUTING_SCRIPT = "schema.update.msg.executing_script";
private static final String MSG_OPTIONAL_STATEMENT_FAILED = "schema.update.msg.optional_statement_failed";
private static final String ERR_STATEMENT_FAILED = "schema.update.err.statement_failed";
private static final String ERR_UPDATE_FAILED = "schema.update.err.update_failed";
private static final String ERR_VALIDATION_FAILED = "schema.update.err.validation_failed";
@@ -504,10 +505,18 @@ public class SchemaBootstrap extends AbstractLifecycleBean
}
// have we reached the end of a statement?
boolean execute = false;
boolean optional = false;
if (sql.endsWith(";"))
{
sql = sql.substring(0, sql.length() - 1);
execute = true;
optional = false;
}
else if (sql.endsWith(";(optional)"))
{
sql = sql.substring(0, sql.length() - 11);
execute = true;
optional = true;
}
// append to the statement being built up
sb.append(" ").append(sql);
@@ -515,7 +524,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
if (execute)
{
sql = sb.toString();
executeStatement(connection, sql, line, scriptFile);
executeStatement(connection, sql, optional, line, scriptFile);
sb = new StringBuilder(1024);
}
}
@@ -531,7 +540,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean
* Execute the given SQL statement, absorbing exceptions that we expect during
* schema creation or upgrade.
*/
private void executeStatement(Connection connection, String sql, int line, File file) throws Exception
private void executeStatement(Connection connection, String sql, boolean optional, int line, File file) throws Exception
{
Statement stmt = connection.createStatement();
try
@@ -544,10 +553,18 @@ public class SchemaBootstrap extends AbstractLifecycleBean
}
catch (SQLException e)
{
String msg = I18NUtil.getMessage(ERR_STATEMENT_FAILED, sql, e.getMessage(), file.getAbsolutePath(), line);
// ignore exceptions generated by the creation of indexes that already exist
logger.error(msg);
throw e;
if (optional)
{
// it was marked as optional, so we just ignore it
String msg = I18NUtil.getMessage(MSG_OPTIONAL_STATEMENT_FAILED, sql, e.getMessage(), file.getAbsolutePath(), line);
logger.warn(msg);
}
else
{
String err = I18NUtil.getMessage(ERR_STATEMENT_FAILED, sql, e.getMessage(), file.getAbsolutePath(), line);
logger.error(err);
throw e;
}
}
finally
{

View File

@@ -158,7 +158,7 @@ public class CategoryNode extends Node
}
@Override
public boolean isCategory()
public boolean getIsCategory()
{
return true;
}

View File

@@ -427,7 +427,7 @@ public class Node implements Serializable, Scopeable
/**
* @return true if this Node is a container (i.e. a folder)
*/
public boolean isContainer()
public boolean getIsContainer()
{
if (isContainer == null)
{
@@ -441,13 +441,13 @@ public class Node implements Serializable, Scopeable
public boolean jsGet_isContainer()
{
return isContainer();
return getIsContainer();
}
/**
* @return true if this Node is a Document (i.e. with content)
*/
public boolean isDocument()
public boolean getIsDocument()
{
if (isDocument == null)
{
@@ -460,13 +460,13 @@ public class Node implements Serializable, Scopeable
public boolean jsGet_isDocument()
{
return isDocument();
return getIsDocument();
}
/**
* @return true if the Node is a Category
*/
public boolean isCategory()
public boolean getIsCategory()
{
// this valid is overriden by the CategoryNode sub-class
return false;
@@ -474,7 +474,7 @@ public class Node implements Serializable, Scopeable
public boolean jsGet_isCategory()
{
return isCategory();
return getIsCategory();
}
/**
@@ -567,7 +567,7 @@ public class Node implements Serializable, Scopeable
{
if (this.imageResolver != null)
{
if (isDocument())
if (getIsDocument())
{
return this.imageResolver.resolveImagePathForName(getName(), true);
}
@@ -594,7 +594,7 @@ public class Node implements Serializable, Scopeable
{
if (this.imageResolver != null)
{
if (isDocument())
if (getIsDocument())
{
return this.imageResolver.resolveImagePathForName(getName(), false);
}
@@ -740,7 +740,7 @@ public class Node implements Serializable, Scopeable
*/
public String getUrl()
{
if (isDocument() == true)
if (getIsDocument() == true)
{
try
{
@@ -1646,7 +1646,7 @@ public class Node implements Serializable, Scopeable
this.imageResolver);
// add the current node as either the document/space as appropriate
if (this.isDocument())
if (this.getIsDocument())
{
model.put("document", new TemplateNode(this.nodeRef, this.services, this.imageResolver));
model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services, this.imageResolver));

View File

@@ -834,8 +834,16 @@ public class IndexInfo
// luceneIndexer.flushPending();
IndexReader deltaReader = buildAndRegisterDeltaReader(id);
IndexReader reader = new MultiReader(new IndexReader[] {
IndexReader reader = null;
if (deletions == null || deletions.size() == 0)
{
reader = new MultiReader(new IndexReader[] {mainIndexReader, deltaReader });
}
else
{
reader = new MultiReader(new IndexReader[] {
new FilterIndexReaderByNodeRefs2(mainIndexReader, deletions, deleteOnlyNodes), deltaReader });
}
reader = ReferenceCountingReadOnlyIndexReaderFactory.createReader("MainReader"+id, reader);
ReferenceCounting refCounting = (ReferenceCounting)reader;
refCounting.incrementReferenceCount();