Author: rwatler Date: Wed Nov 30 19:52:33 2005 New Revision: 350140 URL: http://svn.apache.org/viewcvs?rev=350140&view=rev Log: complete implementation of Folder document order and NodeSet comparator based ordering
Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderImpl.java portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderOrderList.java portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/page/document/impl/NodeSetImpl.java portals/jetspeed-2/trunk/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderImpl.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderImpl.java?rev=350140&r1=350139&r2=350140&view=diff ============================================================================== --- portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderImpl.java (original) +++ portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderImpl.java Wed Nov 30 19:52:33 2005 @@ -18,6 +18,7 @@ import java.security.AccessController; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.ListIterator; @@ -57,6 +58,8 @@ private List orders; private FolderOrderList documentOrder; + private boolean documentOrderComparatorValid; + private Comparator documentOrderComparator; private NodeSet allNodeSet; private NodeSet foldersNodeSet; private NodeSet pagesNodeSet; @@ -196,6 +199,86 @@ allNodeSet = null; } + /** + * createDocumentOrderComparator + * + * @return document order comparator + */ + private Comparator createDocumentOrderComparator() + { + if (!documentOrderComparatorValid) + { + documentOrderComparatorValid = true; + // return null if no document order exists; + // (null implies natural ordering by name) + final List documentOrder = getDocumentOrder(); + if ((documentOrder == null) || documentOrder.isEmpty()) + { + return null; + } + // create new document order comparator + documentOrderComparator = new Comparator() + { + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) + { + // Compare node names using document order; + // use indicies as names if found in document + // order to force explicitly ordered items + // ahead of unordered items + String name1 = (String)o1; + int index1 = documentOrder.indexOf(name1); + if (index1 >= 0) + { + // use order index as name1 + name1 = String.valueOf(index1); + } + String name2 = (String)o2; + int index2 = documentOrder.indexOf(name2); + if (index2 >= 0) + { + // use order index as name2 + name2 = String.valueOf(index2); + if (index1 >= 0) + { + // pad order indicies for numeric string compare + while (name1.length() != name2.length()) + { + if (name1.length() < name2.length()) + { + name1 = "0" + name1; + } + else + { + name2 = "0" + name2; + } + } + } + } + // compare names and/or indicies + return name1.compareTo(name2); + } + }; + } + return documentOrderComparator; + } + + /** + * clearDocumentOrderComparator + */ + void clearDocumentOrderComparator() + { + // clear node set ordering + documentOrderComparatorValid = false; + documentOrderComparator = null; + // clear previously cached node sets + allNodeSet = null; + foldersNodeSet = null; + pagesNodeSet = null; + } + /* (non-Javadoc) * @see org.apache.jetspeed.page.document.impl.NodeImpl#newPageMetadata(java.util.Collection) */ @@ -455,11 +538,11 @@ { if (folders != null) { - foldersNodeSet = new NodeSetImpl(folders); + foldersNodeSet = new NodeSetImpl(folders, createDocumentOrderComparator()); } else { - foldersNodeSet = new NodeSetImpl(); + foldersNodeSet = NodeSetImpl.EMPTY_NODE_SET; } } return foldersNodeSet; @@ -478,11 +561,11 @@ { if (pages != null) { - pagesNodeSet = new NodeSetImpl(pages); + pagesNodeSet = new NodeSetImpl(pages, createDocumentOrderComparator()); } else { - pagesNodeSet = new NodeSetImpl(); + pagesNodeSet = NodeSetImpl.EMPTY_NODE_SET; } } return pagesNodeSet; @@ -514,11 +597,11 @@ } if (!all.isEmpty()) { - allNodeSet = new NodeSetImpl(all); + allNodeSet = new NodeSetImpl(all, createDocumentOrderComparator()); } else { - allNodeSet = new NodeSetImpl(); + allNodeSet = NodeSetImpl.EMPTY_NODE_SET; } } return allNodeSet; @@ -577,7 +660,7 @@ { // not permitted, copy previously permitted nodes // to new filteredNodes node set with same comparator - filteredNodes = new NodeSetImpl(); + filteredNodes = new NodeSetImpl(nodes); Iterator copyIter = nodes.iterator(); while (copyIter.hasNext()) { Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderOrderList.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderOrderList.java?rev=350140&r1=350139&r2=350140&view=diff ============================================================================== --- portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderOrderList.java (original) +++ portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/om/folder/impl/FolderOrderList.java Wed Nov 30 19:52:33 2005 @@ -128,6 +128,8 @@ break; } } + // clear all cached folder ordering + folder.clearDocumentOrderComparator(); } /* (non-Javadoc) @@ -145,12 +147,14 @@ */ public Object remove(int index) { - // implement for modifiable AbstractList: - // save removed element + // implement for modifiable AbstractList FolderOrder removed = (FolderOrder)folder.accessFolderOrders().remove(index); if (removed != null) { + // save removed element getRemovedFolderOrders().add(removed); + // clear all cached folder ordering + folder.clearDocumentOrderComparator(); } return removed; } @@ -169,6 +173,8 @@ newFolderOrder.setSortOrder(folderOrder.getSortOrder()); // save replaced element getRemovedFolderOrders().add(folderOrder); + // clear all cached folder ordering + folder.clearDocumentOrderComparator(); // return unwrapped folder order name string return folderOrder.getName(); } Modified: portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/page/document/impl/NodeSetImpl.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/page/document/impl/NodeSetImpl.java?rev=350140&r1=350139&r2=350140&view=diff ============================================================================== --- portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/page/document/impl/NodeSetImpl.java (original) +++ portals/jetspeed-2/trunk/components/page-manager/src/java/org/apache/jetspeed/page/document/impl/NodeSetImpl.java Wed Nov 30 19:52:33 2005 @@ -15,12 +15,14 @@ */ package org.apache.jetspeed.page.document.impl; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Pattern; +import org.apache.commons.collections.map.LRUMap; import org.apache.jetspeed.page.document.Node; import org.apache.jetspeed.page.document.NodeSet; @@ -32,24 +34,66 @@ */ public class NodeSetImpl implements NodeSet { - private List nodes; - private Map nodesByName; + public static final NodeSetImpl EMPTY_NODE_SET = new NodeSetImpl(); - public NodeSetImpl() - { - } - public NodeSetImpl(List nodes) + private static final Map patternCache = new LRUMap(128); + + private Map nodes; + private Comparator comparator; + + public NodeSetImpl(List nodes, Comparator comparator) { - this.nodes = new ArrayList(nodes.size()); - this.nodesByName = new HashMap((nodes.size() / 2) + 1); + this.nodes = new TreeMap(comparator); Iterator addIter = nodes.iterator(); while (addIter.hasNext()) { Node node = (Node)addIter.next(); - this.nodes.add(node); - if (!this.nodesByName.containsKey(node.getName())) + if (!this.nodes.containsKey(node.getName())) { - this.nodesByName.put(node.getName(), node); + this.nodes.put(node.getName(), node); + } + } + this.comparator = comparator; + } + + public NodeSetImpl(List nodes) + { + this(nodes, null); + } + + public NodeSetImpl(Comparator comparator) + { + this.comparator = comparator; + } + + public NodeSetImpl(NodeSet nodeSet) + { + this((nodeSet instanceof NodeSetImpl) ? ((NodeSetImpl)nodeSet).comparator : (Comparator)null); + } + + public NodeSetImpl() + { + } + + /** + * getCachedPattern + * + * @param regex pattern + * @return cached pattern + */ + private Pattern getCachedPattern(String regex) + { + synchronized (patternCache) + { + if (patternCache.containsKey(regex)) + { + return (Pattern)patternCache.get(regex); + } + else + { + Pattern pattern = Pattern.compile(regex); + patternCache.put(regex, pattern); + return pattern; } } } @@ -61,13 +105,11 @@ { if (nodes == null) { - nodes = new ArrayList(8); - nodesByName = new HashMap(5); + nodes = new TreeMap(comparator); } - nodes.add(node); - if (!nodesByName.containsKey(node.getName())) + if (!nodes.containsKey(node.getName())) { - nodesByName.put(node.getName(), node); + nodes.put(node.getName(), node); } } @@ -76,9 +118,9 @@ */ public Node get(String name) { - if (nodesByName != null) + if (nodes != null) { - return (Node)nodesByName.get(name); + return (Node)nodes.get(name); } return null; } @@ -90,7 +132,7 @@ { if (nodes != null) { - return nodes.iterator(); + return nodes.values().iterator(); } return null; } @@ -100,7 +142,21 @@ */ public NodeSet subset(String type) { - return null; // NYI + NodeSetImpl subset = null; + Iterator nodeItr = nodes.values().iterator(); + while (nodeItr.hasNext()) + { + Node node = (Node) nodeItr.next(); + if (node.getType().equals(type)) + { + if (subset == null) + { + subset = new NodeSetImpl(comparator); + } + subset.add(node); + } + } + return subset; } /* (non-Javadoc) @@ -108,7 +164,22 @@ */ public NodeSet inclusiveSubset(String regex) { - return null; // NYI + Pattern pattern = getCachedPattern(regex); + NodeSetImpl subset = null; + Iterator nodeItr = nodes.values().iterator(); + while (nodeItr.hasNext()) + { + Node node = (Node) nodeItr.next(); + if (pattern.matcher(node.getName()).matches()) + { + if (subset == null) + { + subset = new NodeSetImpl(comparator); + } + subset.add(node); + } + } + return subset; } /* (non-Javadoc) @@ -116,7 +187,22 @@ */ public NodeSet exclusiveSubset(String regex) { - return null; // NYI + Pattern pattern = getCachedPattern(regex); + NodeSetImpl subset = null; + Iterator nodeItr = nodes.values().iterator(); + while (nodeItr.hasNext()) + { + Node node = (Node) nodeItr.next(); + if (!pattern.matcher(node.getName()).matches()) + { + if (subset == null) + { + subset = new NodeSetImpl(comparator); + } + subset.add(node); + } + } + return subset; } /* (non-Javadoc) @@ -138,7 +224,7 @@ { if (nodes != null) { - return nodes.contains(node); + return nodes.containsValue(node); } return false; } Modified: portals/jetspeed-2/trunk/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java?rev=350140&r1=350139&r2=350140&view=diff ============================================================================== --- portals/jetspeed-2/trunk/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java (original) +++ portals/jetspeed-2/trunk/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java Wed Nov 30 19:52:33 2005 @@ -241,9 +241,21 @@ pageManager.updatePage(page); assertNotNull(page.getParent()); + assertEquals(page.getParent().getId(), folder.getId()); assertNotNull(folder.getPages()); assertEquals(1, folder.getPages().size()); + + page = pageManager.newPage("/another-page.psml"); + page.setTitle("Another Page"); + pageManager.updatePage(page); + assertNotNull(page.getParent()); + assertEquals(page.getParent().getId(), folder.getId()); + page = pageManager.newPage("/some-other-page.psml"); + page.setTitle("Some Other Page"); + pageManager.updatePage(page); + assertNotNull(page.getParent()); assertEquals(page.getParent().getId(), folder.getId()); + assertEquals(3, folder.getPages().size()); PageSecurity pageSecurity = pageManager.newPageSecurity(); List constraintsDefs = new ArrayList(2); @@ -277,8 +289,8 @@ pageManager.updatePageSecurity(pageSecurity); assertNotNull(pageSecurity.getParent()); - assertNotNull(folder.getPageSecurity()); assertEquals(pageSecurity.getParent().getId(), folder.getId()); + assertNotNull(folder.getPageSecurity()); // test duplicate creates try @@ -310,14 +322,15 @@ } // test folder/page creation with attributes on deep path + Folder deepFolder = null; int pathIndex = deepFolderPath.indexOf('/', 1); while ((pathIndex != -1) && (pathIndex <= deepFolderPath.length())) { - folder = pageManager.newFolder(deepFolderPath.substring(0, pathIndex)); - pageManager.updateFolder(folder); - assertNotNull(folder.getParent()); - assertNotNull(((Folder)folder.getParent()).getFolders()); - assertEquals(1, ((Folder)folder.getParent()).getFolders().size()); + deepFolder = pageManager.newFolder(deepFolderPath.substring(0, pathIndex)); + pageManager.updateFolder(deepFolder); + assertNotNull(deepFolder.getParent()); + assertNotNull(((Folder)deepFolder.getParent()).getFolders()); + assertEquals(1, ((Folder)deepFolder.getParent()).getFolders().size()); if (pathIndex < deepFolderPath.length()) { @@ -332,10 +345,29 @@ pathIndex = -1; } } - page = pageManager.newPage(deepPagePath); - pageManager.updatePage(page); - assertNotNull(page.getParent()); - assertEquals(page.getParent().getId(), folder.getId()); + Page deepPage = pageManager.newPage(deepPagePath); + pageManager.updatePage(deepPage); + assertNotNull(deepPage.getParent()); + assertEquals(deepPage.getParent().getId(), deepFolder.getId()); + + // test folder nodesets + assertNotNull(folder.getFolders()); + assertEquals(1, folder.getFolders().size()); + assertNotNull(folder.getAll()); + assertEquals(5, folder.getAll().size()); + Iterator all = folder.getAll().iterator(); + assertEquals("some-other-page.psml", ((Node)all.next()).getName()); + assertEquals("default-page.psml", ((Node)all.next()).getName()); + assertEquals("__subsite-rootx", ((Node)all.next()).getName()); + assertEquals("another-page.psml", ((Node)all.next()).getName()); + assertEquals("page.security", ((Node)all.next()).getName()); + assertNotNull(folder.getAll().subset(Page.DOCUMENT_TYPE)); + assertEquals(3, folder.getAll().subset(Page.DOCUMENT_TYPE).size()); + assertNotNull(folder.getAll().inclusiveSubset(".*other.*")); + assertEquals(2, folder.getAll().inclusiveSubset(".*other.*").size()); + assertNull(folder.getAll().inclusiveSubset("nomatch")); + assertNotNull(folder.getAll().exclusiveSubset(".*-page.psml")); + assertEquals(2, folder.getAll().exclusiveSubset(".*-page.psml").size()); } public void testGets() throws Exception @@ -469,9 +501,17 @@ assertNull(check.getParent()); assertNotNull(check.getPageSecurity()); assertNotNull(check.getPages()); - assertEquals(1, check.getPages().size()); + assertEquals(3, check.getPages().size()); assertNotNull(check.getFolders()); assertEquals(1, check.getFolders().size()); + assertNotNull(check.getAll()); + assertEquals(5, check.getAll().size()); + Iterator all = check.getAll().iterator(); + assertEquals("some-other-page.psml", ((Node)all.next()).getName()); + assertEquals("default-page.psml", ((Node)all.next()).getName()); + assertEquals("__subsite-rootx", ((Node)all.next()).getName()); + assertEquals("another-page.psml", ((Node)all.next()).getName()); + assertEquals("page.security", ((Node)all.next()).getName()); } catch (FolderNotFoundException e) { @@ -528,6 +568,12 @@ folder.getDocumentOrder().add("UPDATED"); folder.getDocumentOrder().add("some-other-page.psml"); pageManager.updateFolder(folder); + + assertNotNull(folder.getAll()); + assertEquals(5, folder.getAll().size()); + Iterator all = folder.getAll().iterator(); + assertEquals("default-page.psml", ((Node)all.next()).getName()); + assertEquals("some-other-page.psml", ((Node)all.next()).getName()); } public void testRemoves() throws Exception @@ -604,7 +650,7 @@ public void testEvents() throws Exception { // verify listener functionality and operation counts - assertEquals(19, newNodeCount); + assertEquals(21, newNodeCount); assertEquals(3, updatedNodeCount); assertEquals(1, removedNodeCount); } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]