diff --git a/source/meta-inf/application.xml b/source/META-INF/application.xml
similarity index 100%
rename from source/meta-inf/application.xml
rename to source/META-INF/application.xml
diff --git a/source/java/org/alfresco/web/app/context/UIContextService.java b/source/java/org/alfresco/web/app/context/UIContextService.java
index d79c4f9103..20614cc0cf 100644
--- a/source/java/org/alfresco/web/app/context/UIContextService.java
+++ b/source/java/org/alfresco/web/app/context/UIContextService.java
@@ -94,6 +94,27 @@ public final class UIContextService implements Serializable
this.registeredBeans.remove(bean);
}
+ /**
+ * Returns a registered bean or null
+ *
+ * @param className (fully qualified name)
+ *
+ * @return IContextListener
+ */
+ public IContextListener getRegisteredBean(String className)
+ {
+ IContextListener bean = null;
+ for (Class clazz : this.registeredBeans.keySet())
+ {
+ if (clazz.getName().equals(className))
+ {
+ bean = this.registeredBeans.get(clazz);
+ break;
+ }
+ }
+ return bean;
+ }
+
/**
* Call to notify all register beans that the UI context has changed and they should
* refresh themselves as appropriate.
diff --git a/source/java/org/alfresco/web/bean/TemplateMailHelperBean.java b/source/java/org/alfresco/web/bean/TemplateMailHelperBean.java
index e731baf1f9..e6b99efd5b 100644
--- a/source/java/org/alfresco/web/bean/TemplateMailHelperBean.java
+++ b/source/java/org/alfresco/web/bean/TemplateMailHelperBean.java
@@ -34,6 +34,7 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.util.UrlUtil;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.BaseTemplateContentServlet;
import org.alfresco.web.app.servlet.FacesHelper;
@@ -154,6 +155,7 @@ public class TemplateMailHelperBean implements Serializable
}
model.put("space", parentNodeRef);
}
+ model.put("shareUrl", UrlUtil.getShareUrl(services.getSysAdminParams()));
body = services.getTemplateService().processTemplate("freemarker", templateRef.toString(), model);
}
diff --git a/source/java/org/alfresco/web/bean/categories/CategoriesDialog.java b/source/java/org/alfresco/web/bean/categories/CategoriesDialog.java
index 97b7744829..46878b4758 100644
--- a/source/java/org/alfresco/web/bean/categories/CategoriesDialog.java
+++ b/source/java/org/alfresco/web/bean/categories/CategoriesDialog.java
@@ -64,9 +64,12 @@ public class CategoriesDialog extends BaseDialogBean implements IContextListener
private static final long serialVersionUID = -1254971127977205987L;
public static final String KEY_CATEGORY = "category";
+ public static final String KEY_CATEGORY_FLAG = "categoryFlag";
public static final String PARAM_CATEGORY_REF = "categoryRef";
+ public static final String CATEGORIES_DIALOG_CLASS_NAME = "org.alfresco.web.bean.categories.CategoriesDialog";
+
private static final String VIEW_ICONS = "icons";
private static final String VIEW_DETAILS = "details";
@@ -460,19 +463,20 @@ public class CategoriesDialog extends BaseDialogBean implements IContextListener
}
/**
- * If category.equals(handler.label) then the breadcrumb reverts one step back
- * (needed for deleting)
- * Else current breadcrumb is updated accordingly to the current category
- * (needed for editing)
+ * If category.equals(handler.label) then the breadcrumb reverts one step back
+ * (for deleting)
+ *
+ * Else current breadcrumb is updated accordingly to the current category
+ * (for editing)
*/
- protected void removeFromBreadcrumb(String category)
+ protected void removeFromBreadcrumb(String categoryToRemove, String categoryFlag)
{
// remove this node from the breadcrumb if required
List location = getLocation();
CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
// see if the current breadcrumb location is our Category
- if (category.equals(handler.label))
+ if (categoryToRemove.equals(handler.label))
{
location.remove(location.size() - 1);
@@ -483,14 +487,20 @@ public class CategoriesDialog extends BaseDialogBean implements IContextListener
this.setCurrentCategory(handler.nodeRef);
}
}
+ else if (categoryFlag.equals("true"))
+ {
+ // We don't need to modify the breadcrumb, as editing/deleting is made through an icon.
+ // the dialog should get back to the original location.
+ this.setCurrentCategory(handler.nodeRef);
+ }
else
{
if (getCategory() != null)
{
handler = new CategoryBreadcrumbHandler(
getCategory().getNodeRef(), Repository.getNameForNode(getNodeService(), getCategory().getNodeRef()));
- location.set(location.size() - 1, handler);
- this.setCurrentCategory(handler.nodeRef);
+ location.set(location.size() - 1, handler);
+ this.setCurrentCategory(handler.nodeRef);
}
}
}
@@ -628,16 +638,22 @@ public class CategoriesDialog extends BaseDialogBean implements IContextListener
@Override
public void restored()
{
- Object categoryToRemove = FacesContext.getCurrentInstance().getExternalContext().
- getRequestMap().get(KEY_CATEGORY);
- if (categoryToRemove != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("Removing group '" + categoryToRemove + "' from breadcrumb");
-
- removeFromBreadcrumb((String)categoryToRemove);
- }
- contextUpdated();
+ Object categoryToRemove = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(KEY_CATEGORY);
+ Object categoryFlag = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(KEY_CATEGORY_FLAG);
+ if (categoryToRemove != null)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Removing group '" + categoryToRemove + "' from breadcrumb");
+ if (categoryFlag != null)
+ {
+ removeFromBreadcrumb((String)categoryToRemove, (String)categoryFlag);
+ }
+ else
+ {
+ removeFromBreadcrumb((String)categoryToRemove, Boolean.FALSE.toString());
+ }
+ }
+ contextUpdated();
}
public String getViewMode()
diff --git a/source/java/org/alfresco/web/bean/categories/DeleteCategoryDialog.java b/source/java/org/alfresco/web/bean/categories/DeleteCategoryDialog.java
index 6ea518442f..e9b000fef4 100644
--- a/source/java/org/alfresco/web/bean/categories/DeleteCategoryDialog.java
+++ b/source/java/org/alfresco/web/bean/categories/DeleteCategoryDialog.java
@@ -36,8 +36,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.cmr.search.CategoryService.Depth;
import org.alfresco.service.cmr.search.CategoryService.Mode;
-import org.springframework.extensions.surf.util.ParameterCheck;
import org.alfresco.web.app.Application;
+import org.alfresco.web.app.context.UIContextService;
+import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
@@ -45,14 +46,16 @@ import org.alfresco.web.ui.common.ReportedException;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
import org.alfresco.web.ui.common.component.data.UIRichList;
-import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.surf.util.ParameterCheck;
public class DeleteCategoryDialog extends BaseDialogBean
{
private static final long serialVersionUID = -8929785826091612856L;
+ private static Log logger = LogFactory.getLog(DeleteCategoryDialog.class);
+
private static final String DEFAULT_OUTCOME = "finish";
private final static String MSG_DELETE_CATEGORY = "delete_category";
private final static String MSG_DELETE = "delete";
@@ -84,12 +87,14 @@ public class DeleteCategoryDialog extends BaseDialogBean
/** Currently visible category Node */
private Node category = null;
- private static Log logger = LogFactory.getLog(DeleteCategoryDialog.class);
+ private Boolean categoryFlag = false;
+
@Override
public void init(Map parameters)
{
this.isFinished = false;
+ this.categoryFlag = false;
// retrieve parameters
String categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
@@ -109,7 +114,9 @@ public class DeleteCategoryDialog extends BaseDialogBean
// add the category to the request object so it gets picked up by
// category dialog, this will allow it to be removed from the breadcrumb
context.getExternalContext().getRequestMap().put(
- CategoriesDialog.KEY_CATEGORY, this.category.getName());
+ CategoriesDialog.KEY_CATEGORY, this.category.getName());
+ context.getExternalContext().getRequestMap().put(
+ CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
return outcome;
}
@@ -187,6 +194,16 @@ public class DeleteCategoryDialog extends BaseDialogBean
this.category = category;
}
+ public Boolean getCategoryFlag()
+ {
+ return categoryFlag;
+ }
+
+ public void setCategoryFlag(Boolean categoryFlag)
+ {
+ this.categoryFlag = categoryFlag;
+ }
+
/**
* @param node Set the Node to be used for the current category screen action.
*/
@@ -226,14 +243,6 @@ public class DeleteCategoryDialog extends BaseDialogBean
*/
public List getLocation()
{
- if (this.location == null)
- {
- List loc = new ArrayList(8);
- CategoriesDialog categoriesDialog = new CategoriesDialog();
- loc.add(categoriesDialog.new CategoryBreadcrumbHandler(null, Application.getMessage(FacesContext.getCurrentInstance(), MSG_CATEGORIES)));
-
- setLocation(loc);
- }
return this.location;
}
@@ -378,24 +387,15 @@ public class DeleteCategoryDialog extends BaseDialogBean
}
};
NodeRef categoryNodeRef = txnHelper.doInTransaction(callback);
-
- // remove this node from the breadcrumb if required
+
+ // Figure out if the deletion is made by an icon or by a list of actions
+ CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
+ .getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
+ setLocation(categoriesDialog.getLocation());
List location = getLocation();
- IBreadcrumbHandler handler = location.get(location.size() - 1);
-
- // see if the current breadcrumb location is our node
- if (categoryNodeRef.equals(((IRepoBreadcrumbHandler) handler).getNodeRef()))
- {
- location.remove(location.size() - 1);
-
- // now work out which node to set the list to refresh against
- if (location.size() != 0)
- {
- handler = location.get(location.size() - 1);
- this.setCurrentCategory(((IRepoBreadcrumbHandler) handler).getNodeRef());
- }
- }
-
+ CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
+ setCategoryFlag(!handler.toString().equals(getCategory().getName()));
+
// clear action context
setActionCategory(null);
}
diff --git a/source/java/org/alfresco/web/bean/categories/EditCategoryDialog.java b/source/java/org/alfresco/web/bean/categories/EditCategoryDialog.java
index 3d99468614..c98ca9bb1c 100644
--- a/source/java/org/alfresco/web/bean/categories/EditCategoryDialog.java
+++ b/source/java/org/alfresco/web/bean/categories/EditCategoryDialog.java
@@ -38,6 +38,8 @@ import org.alfresco.service.cmr.search.CategoryService.Mode;
import org.alfresco.service.namespace.QName;
import org.springframework.extensions.surf.util.ParameterCheck;
import org.alfresco.web.app.Application;
+import org.alfresco.web.app.context.UIContextService;
+import org.alfresco.web.bean.categories.CategoriesDialog.CategoryBreadcrumbHandler;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
@@ -66,6 +68,8 @@ public class EditCategoryDialog extends BaseDialogBean
/** Currently visible category Node */
private Node category = null;
+ private Boolean categoryFlag = false;
+
String categoryRef = null;
/** Category path breadcrumb location */
@@ -85,6 +89,7 @@ public class EditCategoryDialog extends BaseDialogBean
public void init(Map parameters)
{
this.isFinished = false;
+ this.categoryFlag = false;
// retrieve parameters
categoryRef = parameters.get(CategoriesDialog.PARAM_CATEGORY_REF);
@@ -105,6 +110,8 @@ public class EditCategoryDialog extends BaseDialogBean
// category dialog, this will allow it to be edited in the breadcrumb
context.getExternalContext().getRequestMap().put(
CategoriesDialog.KEY_CATEGORY, this.category.getName());
+ context.getExternalContext().getRequestMap().put(
+ CategoriesDialog.KEY_CATEGORY_FLAG, this.categoryFlag.toString());
return outcome;
}
@@ -167,6 +174,16 @@ public class EditCategoryDialog extends BaseDialogBean
this.category = category;
}
+ public Boolean getCategoryFlag()
+ {
+ return categoryFlag;
+ }
+
+ public void setCategoryFlag(Boolean categoryFlag)
+ {
+ this.categoryFlag = categoryFlag;
+ }
+
public Collection getMembers()
{
return members;
@@ -242,14 +259,6 @@ public class EditCategoryDialog extends BaseDialogBean
*/
public List getLocation()
{
- if (this.location == null)
- {
- List loc = new ArrayList(8);
- CategoriesDialog categoriesDialog = new CategoriesDialog();
- loc.add(categoriesDialog.new CategoryBreadcrumbHandler(null, Application.getMessage(FacesContext.getCurrentInstance(), MSG_CATEGORIES)));
-
- setLocation(loc);
- }
return this.location;
}
@@ -287,12 +296,22 @@ public class EditCategoryDialog extends BaseDialogBean
getNodeService().setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, getDescription());
}
- // edit the node in the breadcrumb if required
- CategoriesDialog categoriesDialog = new CategoriesDialog();
+ //Figure out if the editing is made by an icon or by a list of actions
+ CategoriesDialog categoriesDialog = (CategoriesDialog) UIContextService.getInstance(FacesContext.getCurrentInstance())
+ .getRegisteredBean(CategoriesDialog.CATEGORIES_DIALOG_CLASS_NAME);
+ setLocation(categoriesDialog.getLocation());
List location = getLocation();
- IBreadcrumbHandler handler = categoriesDialog.new CategoryBreadcrumbHandler(nodeRef, Repository.getNameForNode(getNodeService(), nodeRef));
- location.set(location.size() - 1, handler);
- setCategory(new Node(nodeRef));
+ CategoryBreadcrumbHandler handler = (CategoryBreadcrumbHandler) location.get(location.size() - 1);
+ if (!handler.toString().equals(getCategory().getName()))
+ {
+ setCategoryFlag(true);
+ }
+ else
+ {
+ setCategoryFlag(false);
+ }
+ Node categoryNode = new Node(nodeRef);
+ setCategory(categoryNode);
}
catch (Throwable err)
{
diff --git a/source/java/org/alfresco/web/bean/coci/EditOnlineDialog.java b/source/java/org/alfresco/web/bean/coci/EditOnlineDialog.java
index 2a9cb24b14..934652b525 100644
--- a/source/java/org/alfresco/web/bean/coci/EditOnlineDialog.java
+++ b/source/java/org/alfresco/web/bean/coci/EditOnlineDialog.java
@@ -33,6 +33,7 @@ import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
+import org.springframework.extensions.webscripts.ui.common.StringUtils;
/**
* This base dialog class provides methods for online editing. It does
@@ -132,7 +133,7 @@ public class EditOnlineDialog extends CCCheckoutFileDialog
else
{
// make content available to the html editing screen
- property.setDocumentContent(reader.getContentString());
+ property.setDocumentContent(StringUtils.stripUnsafeHTMLTags(reader.getContentString(), false));
property.setEditorOutput(null);
// navigate to appropriate screen
diff --git a/source/java/org/alfresco/web/bean/search/SearchContext.java b/source/java/org/alfresco/web/bean/search/SearchContext.java
index 306cf8e366..122e8d30c2 100644
--- a/source/java/org/alfresco/web/bean/search/SearchContext.java
+++ b/source/java/org/alfresco/web/bean/search/SearchContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2011 Alfresco Software Limited.
+ * Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -153,13 +153,12 @@ public class SearchContext implements Serializable
// the QName for the well known "name" attribute
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, ELEMENT_NAME));
+ StringBuilder plBuf = new StringBuilder("(");
+ StringBuilder mnBuf = new StringBuilder("-(");
+
// match against content text
String text = this.text.trim();
- StringBuilder fullTextBuf = new StringBuilder(64);
- StringBuilder nameAttrBuf = new StringBuilder(128);
- StringBuilder additionalAttrsBuf = new StringBuilder(128);
-
if (text.length() != 0 && text.length() >= minimum)
{
if (text.indexOf(' ') == -1 && text.charAt(0) != '"')
@@ -178,15 +177,16 @@ public class SearchContext implements Serializable
// prepend NOT operator if supplied
if (operatorNOT)
{
- fullTextBuf.append(OP_NOT);
- nameAttrBuf.append(OP_NOT);
+ processSearchTextAttribute(nameAttr, text, mode == SEARCH_FILE_NAMES_CONTENTS || mode == SEARCH_ALL, mnBuf);
}
- processSearchTextAttribute(nameAttr, text, nameAttrBuf, fullTextBuf);
- for (QName qname : this.simpleSearchAdditionalAttrs)
+ // prepend AND operator if supplied
+ if (operatorAND)
{
- processSearchAttribute(qname, text, additionalAttrsBuf, false, operatorNOT);
+ processSearchTextAttribute(nameAttr, text, mode == SEARCH_FILE_NAMES_CONTENTS || mode == SEARCH_ALL, plBuf);
}
+
+ processSearchAdditionalAttribute(text, operatorNOT, operatorAND, mnBuf, plBuf, this.simpleSearchAdditionalAttrs);
}
}
else
@@ -196,11 +196,11 @@ public class SearchContext implements Serializable
{
// as a single quoted phrase
String quotedSafeText = '"' + QueryParser.escape(text.substring(1, text.length() - 1)) + '"';
- fullTextBuf.append("TEXT:").append(quotedSafeText);
- nameAttrBuf.append("@").append(nameAttr).append(":").append(quotedSafeText);
+ plBuf.append("TEXT:").append(quotedSafeText);
+ plBuf.append(" @").append(nameAttr).append(":").append(quotedSafeText);
for (QName qname : this.simpleSearchAdditionalAttrs)
{
- additionalAttrsBuf.append(" @").append(
+ plBuf.append(" @").append(
Repository.escapeQName(qname)).append(":").append(quotedSafeText);
}
}
@@ -209,10 +209,6 @@ public class SearchContext implements Serializable
// as individual search terms
StringTokenizer t = new StringTokenizer(text, " ");
- fullTextBuf.append('(');
- nameAttrBuf.append('(');
- additionalAttrsBuf.append('(');
-
int termCount = 0;
int tokenCount = t.countTokens();
for (int i=0; i= minimum)
{
+ StringBuilder buf = new StringBuilder(128);
+ if (plBuf.length() > 2)
+ {
+ buf.append(plBuf);
+ if (mnBuf.length() > 3)
+ {
+ buf.append(" AND ");
+ }
+ }
+ if (mnBuf.length() > 3)
+ {
+ buf.append(mnBuf);
+ }
// text query for name and/or full text specified
switch (mode)
{
case SearchContext.SEARCH_ALL:
- query = '(' + fileTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + additionalAttrsQuery + ' ' + fullTextQuery + ')' + ')' +
+ query = '(' + fileTypeQuery + " AND " + '(' + buf + ')' + ')' +
' ' +
- '(' + folderTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + additionalAttrsQuery + "))";
+ '(' + folderTypeQuery + " AND " + '(' + buf + "))";
break;
case SearchContext.SEARCH_FILE_NAMES:
- query = fileTypeQuery + " AND " + nameAttrQuery;
- break;
-
case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
- query = fileTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + fullTextQuery + ')';
+ query = fileTypeQuery + " AND " + '(' + buf + ')';
break;
case SearchContext.SEARCH_SPACE_NAMES:
- query = folderTypeQuery + " AND " + nameAttrQuery;
+ query = folderTypeQuery + " AND " + buf;
break;
default:
@@ -474,19 +468,6 @@ public class SearchContext implements Serializable
return query;
}
- /**
- * Build the lucene search terms required for the specified attribute and append to a buffer.
- * Supports text values with a wildcard '*' character as the prefix and/or the suffix.
- *
- * @param qname QName of the attribute
- * @param value Non-null value of the attribute
- * @param buf Buffer to append lucene terms to
- */
- private static void processSearchAttribute(QName qname, String value, StringBuilder buf)
- {
- processSearchAttribute(qname, value, buf, true, false);
- }
-
/**
* Build the lucene search terms required for the specified attribute and append to a buffer.
* Supports text values with a wildcard '*' character as the prefix and/or the suffix.
@@ -497,11 +478,9 @@ public class SearchContext implements Serializable
* @param andOp If true apply the '+' AND operator as the prefix to the attribute term
* @param notOp If true apply the '-' NOT operator as the prefix to the attribute term
*/
- private static void processSearchAttribute(QName qname, String value, StringBuilder buf, boolean andOp, boolean notOp)
+ private static void processSearchAttribute(QName qname, String value, StringBuilder buf)
{
- if (andOp) buf.append('+');
- else if (notOp) buf.append('-');
- buf.append('@').append(Repository.escapeQName(qname)).append(":\"")
+ buf.append(" @").append(Repository.escapeQName(qname)).append(":\"")
.append(SearchContext.escape(value)).append("\" ");
}
@@ -514,11 +493,33 @@ public class SearchContext implements Serializable
* @param attrBuf Attribute search buffer to append lucene terms to
* @param textBuf Text search buffer to append lucene terms to
*/
- private static void processSearchTextAttribute(String qname, String value, StringBuilder attrBuf, StringBuilder textBuf)
+ private static void processSearchTextAttribute(String qname, String value, boolean appendText, StringBuilder mnBuf)
{
- textBuf.append("TEXT:\"").append(SearchContext.escape(value)).append('"');
- attrBuf.append('@').append(qname).append(":\"")
+ mnBuf.append('@').append(qname).append(":\"")
.append(SearchContext.escape(value)).append('"');
+ if (appendText)
+ {
+ mnBuf.append(" TEXT:\"").append(SearchContext.escape(value)).append("\" ");
+ }
+ }
+
+ private static void processSearchAdditionalAttribute(String value, boolean operatorNOT, boolean operatorAND, StringBuilder mnBuf, StringBuilder plBuf,
+ List simpleSearchAdditionalAttrs)
+ {
+ for (QName qname : simpleSearchAdditionalAttrs)
+ {
+ // prepend NOT operator if supplied
+ if (operatorNOT)
+ {
+ processSearchAttribute(qname, value, mnBuf);
+ }
+
+ // prepend AND operator if supplied
+ if (operatorAND)
+ {
+ processSearchAttribute(qname, value, plBuf);
+ }
+ }
}
/**
diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
index 5fada356b6..2355d9913b 100644
--- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
+++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java
@@ -834,6 +834,9 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
out.write(bundle.getString(MSG_ACTIONS));
out.write("");
+ // assets copy to set checkbox value by node index
+ List assetsCopy = new ArrayList(assets);
+
// move conflicts to top of list
if (diffCount > 0)
{
@@ -871,8 +874,9 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
out.write(id);
out.write("' value='");
// the value is a username index followed by a node lookup index
- out.write(Integer.toString(index) + '_' + Integer.toString(rowIndex++));
+ out.write(Integer.toString(index) + '_' + Integer.toString(assetsCopy.indexOf(node)));
out.write("'>");
+ rowIndex++;
if (isGhost == false)
{