From: <pb...@fe...> - 2012-12-17 13:08:05
|
Author: pboy Date: 2012-12-17 13:07:53 +0000 (Mon, 17 Dec 2012) New Revision: 2410 Modified: releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentBundle.java releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentItem.java releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ui/category/CategorizedObjectsList.java releases/2.0.0/ccm-core/src/com/arsdigita/categorization/Category.java releases/2.0.0/ccm-core/src/com/arsdigita/categorization/CategoryCollection.java Log: Fixed sort order in object lists (backport r2407). (on behalf of JensP) Modified: releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentBundle.java =================================================================== --- releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentBundle.java 2012-12-17 13:04:19 UTC (rev 2409) +++ releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentBundle.java 2012-12-17 13:07:53 UTC (rev 2410) @@ -670,7 +670,8 @@ CategoryCollection categories = source.getCategoryCollection(); while (categories.next()) { final Category category = categories.getCategory(); - category.addChild(this); + + category.addChild(this, categories.getSortKey()); category.save(); // XXX remove me } categories.close(); Modified: releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentItem.java =================================================================== --- releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentItem.java 2012-12-17 13:04:19 UTC (rev 2409) +++ releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ContentItem.java 2012-12-17 13:07:53 UTC (rev 2410) @@ -1893,6 +1893,7 @@ } // If live Bundle already exists, recategorize. + // jensp 2012: Behavior changed. The ContentBundle will also be republished. if (PARENT.equals(attribute)) { ACSObject parent = ((ContentItem) source).getParent(); if (parent != null && copier.getCopyType() @@ -1906,9 +1907,7 @@ //published because the ContentBundle was not republished. //Moved the next lines out of the if below to enable //republishing of the ContentBundle - final ContentBundle liveBundle = - (ContentBundle) bundle. - createPendingVersion(null); + final ContentBundle liveBundle = (ContentBundle) bundle.createPendingVersion(null); /* * if (liveBundle == null) { } else { Set liveCatSet = new * HashSet(); Set draftCatSet = new HashSet(); Modified: releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ui/category/CategorizedObjectsList.java =================================================================== --- releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ui/category/CategorizedObjectsList.java 2012-12-17 13:04:19 UTC (rev 2409) +++ releases/2.0.0/ccm-cms/src/com/arsdigita/cms/ui/category/CategorizedObjectsList.java 2012-12-17 13:07:53 UTC (rev 2410) @@ -35,7 +35,6 @@ import java.math.BigDecimal; import javax.servlet.ServletException; - /** * A List of all objects currently categorized under this category * @@ -52,25 +51,36 @@ setModelBuilder(new CategorizedObjectsModelBuilder()); - Label label = new Label(GlobalizationUtil.globalize - ("cms.ui.category.item.none")); + Label label = new Label(GlobalizationUtil.globalize("cms.ui.category.item.none")); label.setFontWeight(Label.ITALIC); setEmptyView(label); } /** - * This actually performs the sorting + * This actually performs the sorting */ public void respond(PageState ps) throws ServletException { - String event = ps.getControlEventName(); + final String event = ps.getControlEventName(); if (NEXT_EVENT.equals(event) || PREV_EVENT.equals(event)) { - BigDecimal selectedID = new BigDecimal(ps.getControlEventValue()); - Category parent = getCategory(ps); + final BigDecimal selectedID = new BigDecimal(ps.getControlEventValue()); + final Category parent = getCategory(ps); + + final ContentItem selectedItem = new ContentItem(selectedID); + final BigDecimal selectedDraftId = selectedItem.getDraftVersion().getID(); - if (CMS.getContext().getSecurityManager().canAccess - (SecurityManager.CATEGORY_ADMIN)) { - parent.swapSortKeys(selectedID, getSwapID(parent,selectedID,event)); + if (CMS.getContext().getSecurityManager().canAccess(SecurityManager.CATEGORY_ADMIN)) { + final BigDecimal swapId = getSwapID(parent, selectedID, event); + parent.swapSortKeys(selectedID, swapId); + final ContentItem swapItem = new ContentItem(swapId); + final BigDecimal swapDraftId = swapItem.getDraftVersion().getID(); + + final BigDecimal sortKey1 = parent.getSortKey(selectedItem); + final BigDecimal sortKey2 = parent.getSortKey(swapItem); + + parent.setSortKey(new ContentItem(selectedDraftId), sortKey1); + parent.setSortKey(new ContentItem(swapDraftId), sortKey2); + } } else { super.respond(ps); @@ -83,9 +93,8 @@ boolean foundSelectedID = false; if (category != null && category.hasChildObjects()) { - CategorizedCollection items = category.getObjects - (ContentItem.BASE_DATA_OBJECT_TYPE); - items.addEqualsFilter(ContentItem.VERSION,ContentItem.LIVE); + CategorizedCollection items = category.getObjects(ContentItem.BASE_DATA_OBJECT_TYPE); + items.addEqualsFilter(ContentItem.VERSION, ContentItem.LIVE); items.sort(true); while (items.next()) { BigDecimal thisID = items.getACSObject().getID(); @@ -111,14 +120,14 @@ private class CategorizedObjectsModelBuilder extends LockableImpl implements ListModelBuilder { + public final ListModel makeModel(final List list, final PageState state) { final Category category = getCategory(state); if (category != null && category.hasChildObjects()) { - CategorizedCollection items = category.getObjects - (ContentItem.BASE_DATA_OBJECT_TYPE); - items.addEqualsFilter(ContentItem.VERSION,ContentItem.LIVE); + CategorizedCollection items = category.getObjects(ContentItem.BASE_DATA_OBJECT_TYPE); + items.addEqualsFilter(ContentItem.VERSION, ContentItem.LIVE); items.sort(true); return new CategorizedCollectionListModel(items); } else { @@ -131,6 +140,7 @@ * A {@link ListModel} that iterates over categorized objects via an iterator */ private static class CategorizedCollectionListModel implements ListModel { + private CategorizedCollection m_objs; private ACSObject m_object; @@ -140,7 +150,7 @@ } public boolean next() { - if ( m_objs.next() ) { + if (m_objs.next()) { m_object = (ACSObject) m_objs.getDomainObject(); return true; } else { Modified: releases/2.0.0/ccm-core/src/com/arsdigita/categorization/Category.java =================================================================== --- releases/2.0.0/ccm-core/src/com/arsdigita/categorization/Category.java 2012-12-17 13:04:19 UTC (rev 2409) +++ releases/2.0.0/ccm-core/src/com/arsdigita/categorization/Category.java 2012-12-17 13:07:53 UTC (rev 2410) @@ -109,9 +109,9 @@ * */ public static final String BASE_DATA_OBJECT_TYPE = - "com.arsdigita.categorization.Category"; + "com.arsdigita.categorization.Category"; private static final String BASE_DATA_OBJECT_PACKAGE = - "com.arsdigita.categorization"; + "com.arsdigita.categorization"; /** * The * <code>PrivilegeDescriptor corresponding</code> to the privilege to @@ -119,7 +119,7 @@ * */ public static final PrivilegeDescriptor MAP_DESCRIPTOR = - new PrivilegeDescriptor( + new PrivilegeDescriptor( "map_to_category"); // Quasimodo: Begin private static CategorizationConfig s_config = CategorizationConfig @@ -185,7 +185,7 @@ * An attribute name for the underlying data object. */ public static final String IGNORE_PARENT_INDEX_ITEM = - "ignoreParentIndexItem"; + "ignoreParentIndexItem"; /** * An attribute name for the underlying data object. */ @@ -197,7 +197,7 @@ public static final String LOCALIZATIONS = "localizations"; // some named queries in the pdl files private static final String CHILD_CATEGORY_IDS = - "com.arsdigita.categorization.childCategoryIDs"; + "com.arsdigita.categorization.childCategoryIDs"; private static final String CURRENT_SORT_KEY = "currentSortKey"; private HierarchyDenormalization m_hierarchy; // Quasimodo: Begin @@ -416,7 +416,8 @@ public String getName(String locale) { // Test for localized version - if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection. + if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null + && m_categoryLocalizationCollection. localizationExists(locale)) { // Return value of isEnabled from localized version, so categories could be disabled depending on locale @@ -517,7 +518,7 @@ * @return category path */ public String getPreferredQualifiedName(String delimiter, - boolean includeRoot) { + boolean includeRoot) { // is this a synonym? CategoryCollection cc = new CategoryCollection(getRelatedCategories( PREFERRED)); @@ -525,7 +526,7 @@ Category preferred = cc.getCategory(); cc.close(); String preferredPath = preferred.getQualifiedName(delimiter, - includeRoot); + includeRoot); return preferredPath + " (" + getName() + ")"; } else { return getQualifiedName(delimiter, includeRoot); @@ -602,7 +603,8 @@ // Test for localized version // HACK - if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection. + if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null + && m_categoryLocalizationCollection. localizationExists(locale)) { // Return value of isEnabled from localized version, so categories could be disabled depending on locale @@ -679,7 +681,8 @@ public String getURL(String locale) { // Test for localized version - if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection. + if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null + && m_categoryLocalizationCollection. localizationExists(locale)) { // Return value of isEnabled from localized version, so categories could be disabled depending on locale @@ -751,7 +754,8 @@ } // Test for localized version - if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection. + if (locale != null && !locale.isEmpty() && m_categoryLocalizationCollection != null + && m_categoryLocalizationCollection. localizationExists(locale)) { // Return value of isEnabled from localized version, so categories could be disabled depending on locale @@ -950,8 +954,8 @@ try { if (children.next()) { throw new CategorizationException("This category is the default parent of another category." - + " You must explicitly delete the child categories first. " - + "Child category: " + children. + + " You must explicitly delete the child categories first. " + + "Child category: " + children. getDataObject()); } } finally { @@ -959,13 +963,13 @@ } DataAssociationCursor objects = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); if (objects != null) { try { if (objects.next()) { throw new CategorizationException("This category has child objects. You must delete " - + " any such objects explicitly, before deleting the " - + " category. Child object: " + objects. + + " any such objects explicitly, before deleting the " + + " category. Child object: " + objects. getDataObject()); } } finally { @@ -999,7 +1003,7 @@ public void deleteCategorySubtree() { // we get the association between this category and its children DataAssociationCursor cursor = - ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); + ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); while (cursor.next()) { DataObject link = cursor.getLink(); @@ -1038,7 +1042,7 @@ } DataAssociationCursor cursor = - ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); + ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); while (cursor.next()) { DataObject link = cursor.getLink(); @@ -1047,7 +1051,7 @@ remove(RELATED_CATEGORIES, cursor.getDataObject()); if ("child".equals(relationType)) { Category category = new Category(cursor.getDataObject()); - parent.addChild(category); + parent.addChild(category, null); if (Boolean.TRUE.equals(isDefault)) { category.setDefaultParentCategory(parent); } @@ -1104,13 +1108,18 @@ * categories and becomes a CHILD category.</p> * * @param object the domain object to categorize + * @param sortKey optional sort key. May be <code>null</code> * * @pre !isAbstract() * @pre canMap() * */ + public void addChild(ACSObject object, BigDecimal sortKey) { + addMapping(object, "child", sortKey); + } + public void addChild(ACSObject object) { - addMapping(object, "child"); + addChild(object, null); } /** @@ -1149,21 +1158,25 @@ /** * Adds the passed in object to the correct association. + * + * @param acsObj Object to add to the category + * @param relationType Type of the relation + * @param sortKey Optional sort key. May be <code>null</code>. * * @pre canMap() */ - private void addMapping(ACSObject acsObj, String relationType) { + private void addMapping(ACSObject acsObj, String relationType, BigDecimal sortKey) { if (acsObj instanceof Category) { addMapping((Category) acsObj, relationType); return; } Assert.isFalse(isAbstract(), - "You cannot categorize an object " - + "within an abstract category. If you are " - + "seeing this message then your UI is " - + "allowing you to do something that you " - + "are not allowed to do and you " - + "should email your site administrator."); + "You cannot categorize an object " + + "within an abstract category. If you are " + + "seeing this message then your UI is " + + "allowing you to do something that you " + + "are not allowed to do and you " + + "should email your site administrator."); if (RELATED.equals(relationType)) { throw new CategorizationException( @@ -1172,21 +1185,24 @@ } DataAssociationCursor cursor = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); cursor.addEqualsFilter(ID, acsObj.getID()); if (cursor.size() == 0) { // if the cursor.size() > 0 then the object is already // a child and does not need to be added again. - add(CHILD_OBJECTS, acsObj); + DataObject link = add(CHILD_OBJECTS, acsObj); + if (sortKey != null) { + link.set("sortKey", sortKey); + } Categorization.triggerMapEvent(this, acsObj); if (s_log.isDebugEnabled()) { s_log.debug(acsObj + " added to " + CHILD_OBJECTS + " of catID=" - + getID() + " type=" + relationType + " (ignored)"); + + getID() + " type=" + relationType + " (ignored)"); } } else { if (s_log.isDebugEnabled()) { s_log.debug(acsObj + " is already related to catID=" + getID() - + " type=" + relationType + " (ignored)"); + + " type=" + relationType + " (ignored)"); } } } @@ -1195,8 +1211,8 @@ // Let's check for loops. if ("child".equals(relationType) && category.isMemberOfSubtree(this)) { throw new CategorizationException("The object that you are " - + "trying to add as a child is already " - + "a member of the subtree."); + + "trying to add as a child is already " + + "a member of the subtree."); } @@ -1204,7 +1220,7 @@ // Otherwise, we add and then update. DataAssociationCursor cursor = - ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); + ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); cursor.addEqualsFilter(ID, category.getID()); DataObject link; if (cursor.next()) { @@ -1223,7 +1239,7 @@ cursor.close(); if (s_log.isDebugEnabled()) { s_log.debug("updating related catID=" + category.getID() + " type=" - + relationType + " default=false"); + + relationType + " default=false"); } link.set(REL_TYPE, relationType); @@ -1400,7 +1416,7 @@ */ public long getParentCategoryCount() { DataAssociationCursor cursor = - ((DataAssociation) get(PARENTS)).cursor(); + ((DataAssociation) get(PARENTS)).cursor(); try { return cursor.size(); } finally { @@ -1432,7 +1448,7 @@ boolean found = false; DataAssociationCursor cursor = - ((DataAssociation) get(PARENTS)).cursor(); + ((DataAssociation) get(PARENTS)).cursor(); while (cursor.next()) { DataObject category = cursor.getDataObject(); DataObject link = cursor.getLink(); @@ -1468,7 +1484,7 @@ } DataAssociationCursor cursor = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); cursor.addEqualsFilter(ID, child.getID()); if (cursor.next()) { @@ -1534,7 +1550,7 @@ } DataAssociationCursor cursor = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); cursor.addEqualsFilter(ID, child.getID()); if (cursor.next()) { @@ -1590,7 +1606,7 @@ private void swapCategoryKeys(int key, int nextKey) { swapKeys(getSession().retrieveDataOperation( "com.arsdigita.categorization.swapCategoryWithNextCategory"), - key, nextKey); + key, nextKey); } /** @@ -1599,7 +1615,7 @@ private void swapObjectKeys(int key, int nextKey) { swapKeys(getSession().retrieveDataOperation( "com.arsdigita.categorization.swapObjectWithNextObject"), - key, nextKey); + key, nextKey); } /** @@ -1628,6 +1644,24 @@ } } + public BigDecimal getSortKey(final ACSObject object) { + return getSortKey(object.getID()); + } + + public BigDecimal getSortKey(final BigDecimal objId) { + final DataAssociationCursor cursor = ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + cursor.addEqualsFilter(ID, objId); + if (cursor.next()) { + return (BigDecimal) cursor.getLink().get(SORT_KEY); + } + + return null; + } + + public void setSortKey(ACSObject object, int key) { + setSortKey(object, new BigDecimal(key)); + } + /** * Explicitly sets the sort key for this child object (category or * otherwise). @@ -1635,19 +1669,19 @@ * @param child The child object or category to set the sortKey for * @param key The integer to use for the sortKey */ - public void setSortKey(ACSObject child, int key) { + public void setSortKey(ACSObject child, BigDecimal key) { if (isCategory(child)) { setSortKey((Category) child, key); return; } DataAssociationCursor cursor = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); cursor.addEqualsFilter(ID, child.getID()); if (cursor.next()) { DataObject link = cursor.getLink(); - link.set(SORT_KEY, new BigDecimal(key)); + link.set(SORT_KEY, key); } cursor.close(); } @@ -1668,7 +1702,7 @@ BigDecimal key2; DataAssociationCursor cursor = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); cursor.addEqualsFilter(ID, childID1); if (cursor.next()) { link1 = cursor.getLink(); @@ -1714,10 +1748,10 @@ */ public DataAssociationCursor getRelatedCategories(String relation) { Assert.isTrue(relation.equals(CHILD) || relation.equals(RELATED) - || relation.equals(PREFERRED), - " invalid relation {" + relation + "}"); + || relation.equals(PREFERRED), + " invalid relation {" + relation + "}"); DataAssociationCursor cursor = - ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); + ((DataAssociation) get(RELATED_CATEGORIES)).cursor(); cursor.addEqualsFilter("link.relationType", relation); return cursor; } @@ -1799,7 +1833,7 @@ } StringBuilder sb = - new StringBuilder(path.length() + pathExtension.length() + 1); + new StringBuilder(path.length() + pathExtension.length() + 1); sb.append(path).append(".").append(pathExtension); return sb.toString(); } @@ -1813,7 +1847,7 @@ */ public long getNumberOfChildObjects() { DataAssociationCursor association = - ((DataAssociation) get(CHILD_OBJECTS)).cursor(); + ((DataAssociation) get(CHILD_OBJECTS)).cursor(); if (association == null) { return 0; } else { @@ -1838,7 +1872,7 @@ */ public Category getDefaultParentCategory() { DataAssociationCursor cursor = - ((DataAssociation) get(PARENTS)).cursor(); + ((DataAssociation) get(PARENTS)).cursor(); cursor.addEqualsFilter("link.isDefault", Boolean.TRUE); try { @@ -1850,7 +1884,7 @@ } throw new CategoryNotFoundException("The Category " + this + " does " - + "not have a default parent"); + + "not have a default parent"); } /** @@ -1901,7 +1935,7 @@ */ public CategoryCollection getDefaultAscendants() { DataCollection collection = - getSession().retrieve(BASE_DATA_OBJECT_TYPE); + getSession().retrieve(BASE_DATA_OBJECT_TYPE); String ids = (String) get(DEFAULT_ANCESTORS); if (ids == null) { @@ -1958,7 +1992,7 @@ */ public CategorizedCollection getDescendantObjects() { return getDescendantObjects(ACSObject.BASE_DATA_OBJECT_TYPE, - "categories.roTransParents"); + "categories.roTransParents"); } private static String appendID(String path) { @@ -1968,7 +2002,7 @@ } public CategorizedCollection getDescendantObjects(String objectType, - String path) { + String path) { s_log.info("retrieving objectType=" + objectType + "; path=" + path); final CategorizedCollection result = new CategorizedCollection(getSession(). retrieve(objectType)); @@ -2041,6 +2075,7 @@ public String getToken() { return m_token; } + } @Override @@ -2059,7 +2094,7 @@ DataCollection dc = SessionManager.getSession().retrieve( "com.arsdigita.categorization.UseContext"); dc.addFilter("categoryOwner.id = :ownerID").set("ownerID", - acsObj.getID()); + acsObj.getID()); return dc; } @@ -2106,9 +2141,9 @@ DataObject secondRoot = cats.getDataObject(); cats.close(); throw new IllegalStateException("there is more than one root for object:\n" - + object + "\nfirst root: " - + triple + "\nsecond root: " - + secondRoot); + + object + "\nfirst root: " + + triple + "\nsecond root: " + + secondRoot); } cats.close(); } @@ -2149,14 +2184,14 @@ * @param root the root category for the object */ public static void setRootForObject(ACSObject acsObj, Category rootCat, - String context) { + String context) { DataCollection rootCats = getRootCategoriesAssoc(acsObj); rootCats.addEqualsFilter(USE_CONTEXT, context); if (rootCats.next()) { DataObject triple = rootCats.getDataObject(); triple.set(ROOT_CATEGORY, - DomainServiceInterfaceExposer.getDataObject(rootCat)); + DomainServiceInterfaceExposer.getDataObject(rootCat)); rootCats.close(); return; } @@ -2173,9 +2208,9 @@ throw new UncheckedWrapperException(ex); } triple.set(CATEGORY_OWNER, - DomainServiceInterfaceExposer.getDataObject(acsObj)); + DomainServiceInterfaceExposer.getDataObject(acsObj)); triple.set(ROOT_CATEGORY, - DomainServiceInterfaceExposer.getDataObject(rootCat)); + DomainServiceInterfaceExposer.getDataObject(rootCat)); triple.set(USE_CONTEXT, context); } @@ -2292,7 +2327,7 @@ * Add a new language set to this category */ public boolean addLanguage(String locale, String name, String description, - String url) { + String url) { // If locale don't exist if (!locale.isEmpty() && m_categoryLocalizationCollection != null && !m_categoryLocalizationCollection. @@ -2344,4 +2379,5 @@ return false; } + } Modified: releases/2.0.0/ccm-core/src/com/arsdigita/categorization/CategoryCollection.java =================================================================== --- releases/2.0.0/ccm-core/src/com/arsdigita/categorization/CategoryCollection.java 2012-12-17 13:04:19 UTC (rev 2409) +++ releases/2.0.0/ccm-core/src/com/arsdigita/categorization/CategoryCollection.java 2012-12-17 13:07:53 UTC (rev 2410) @@ -21,6 +21,7 @@ import com.arsdigita.kernel.ACSObject; import com.arsdigita.kernel.ACSObjectCollection; import com.arsdigita.persistence.DataCollection; +import java.math.BigDecimal; /** * Represents a collection of categories. @@ -84,6 +85,10 @@ return getCategory(); } + public BigDecimal getSortKey() { + return (BigDecimal) get("link.sortKey"); + } + /** * Sorts the category collection by the category sort key. * |