Universal Wiki Converter
- new hierarchy class that can be used to create a hierarchy from the page's filename. Useful if the hierarchy data is maintained with a filename like this: Parent%2FChild. With that example the hierarchy would truncate the page/node name to Child and identify that the parent node in the hierarchy was Parent. Requires that all Leaf node child names be unique. You MUST handle any naming collisions prior to applying this hierarchy to your data. delimiter can be set with a property: filename-hierarchy-delimiter


git-svn-id: https://studio.plugins.atlassian.com/svn/UWC/devel@165659 2c54a935-e501-0410-bc05-97a93f6bca70
diff --git a/sampleData/hierarchy/filename/confluenceSettings.properties b/sampleData/hierarchy/filename/confluenceSettings.properties
new file mode 100644
index 0000000..7a9ff19
--- /dev/null
+++ b/sampleData/hierarchy/filename/confluenceSettings.properties
@@ -0,0 +1,19 @@
+#Thu Sep 17 15:02:42 EDT 2009
+current.tab.index=0
+space=uwctest
+url=localhost:1990/confluence
+trustpass=
+uploadOrphanAttachments=false
+pageChooserDir=
+attachments=
+trustall=
+attachment.size.max=-1
+sendToConfluence=true
+pattern=
+login=admin
+truststore=
+feedback.option=true
+password=admin
+wikitype=mediawiki
+## All pages
+pages=/Users/laura/Code/Subversion/uwc-spac/devel/sampleData/hierarchy/filename/simple
diff --git a/sampleData/hierarchy/filename/converter.testfilenamehier.properties b/sampleData/hierarchy/filename/converter.testfilenamehier.properties
new file mode 100644
index 0000000..e440ac5
--- /dev/null
+++ b/sampleData/hierarchy/filename/converter.testfilenamehier.properties
@@ -0,0 +1,3 @@
+TestHierarchy.0000.nosvn.filter=com.atlassian.uwc.filters.NoSvnFilter
+TestHierarchy.0002.switch.hierarchy-builder=UseBuilder
+TestHierarchy.0003.classname.hierarchy-builder=com.atlassian.uwc.hierarchies.FilenameHierarchy
diff --git a/sampleData/hierarchy/filename/simple/Root b/sampleData/hierarchy/filename/simple/Root
new file mode 100644
index 0000000..9339e13
--- /dev/null
+++ b/sampleData/hierarchy/filename/simple/Root
@@ -0,0 +1 @@
+Root
diff --git a/sampleData/hierarchy/filename/simple/Root%2FBranch b/sampleData/hierarchy/filename/simple/Root%2FBranch
new file mode 100644
index 0000000..5245317
--- /dev/null
+++ b/sampleData/hierarchy/filename/simple/Root%2FBranch
@@ -0,0 +1 @@
+Branch
diff --git a/sampleData/hierarchy/filename/simple/Root%2FBranch%2FChild b/sampleData/hierarchy/filename/simple/Root%2FBranch%2FChild
new file mode 100644
index 0000000..ef16875
--- /dev/null
+++ b/sampleData/hierarchy/filename/simple/Root%2FBranch%2FChild
@@ -0,0 +1 @@
+Child
diff --git a/sampleData/hierarchy/filename/simple/Root%2FLeaf b/sampleData/hierarchy/filename/simple/Root%2FLeaf
new file mode 100644
index 0000000..71b0188
--- /dev/null
+++ b/sampleData/hierarchy/filename/simple/Root%2FLeaf
@@ -0,0 +1 @@
+Leaf
diff --git a/src/com/atlassian/uwc/hierarchies/FilenameHierarchy.java b/src/com/atlassian/uwc/hierarchies/FilenameHierarchy.java
new file mode 100644
index 0000000..b83723e
--- /dev/null
+++ b/src/com/atlassian/uwc/hierarchies/FilenameHierarchy.java
@@ -0,0 +1,93 @@
+package com.atlassian.uwc.hierarchies;
+
+import java.util.Collection;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+import com.atlassian.uwc.ui.Page;
+
+/**
+ * NOTE: This hierarchy will truncate the page name to the leaf node of the filename with a settable delimiter property
+ * for identifying nodes. It presumes all leaf nodes are unique. Any naming collisions MUST be dealt with prior to 
+ * this hierarchy being applied.
+ */
+public class FilenameHierarchy implements HierarchyBuilder {
+
+	private static final String DEFAULT_DELIM = "%2F";
+	public static final String PROPKEY_DELIM = "filename-hierarchy-delimiter";
+	Properties props = new Properties();
+	Logger log = Logger.getLogger(this.getClass());
+	private String delim = DEFAULT_DELIM;
+	
+	@Override
+	public HierarchyNode buildHierarchy(Collection<Page> pages) {
+		log.info("Building Filename Hierarchy");
+		
+		if (pages == null || pages.isEmpty()) {
+			log.error("Cannot build hierarchy. Pages object is null or empty.");
+			return null;
+		}
+		
+		initProperties();
+
+		return getAllNodes(pages);
+	}
+	
+	private void initProperties() {
+		if (getProperties().containsKey(PROPKEY_DELIM)) 
+			delim = getProperties().getProperty(PROPKEY_DELIM, DEFAULT_DELIM);
+		
+	}
+
+	public HierarchyNode getAllNodes(Collection<Page> pages) {
+		HierarchyNode root = new HierarchyNode();
+		for (Page page : pages) {
+			if (page != null) {
+				log.debug("Page [name, filename, abspath]: [" + page.getName() + ", " + page.getFile().getName() + ", " + page.getFile().getAbsolutePath()+"]");
+				root = buildRelationships(page, root);
+			}
+		}
+		log.debug("Hierarchy: " + root.toString());
+		return root;
+	}
+
+	private HierarchyNode buildRelationships(Page page, HierarchyNode root) {
+		//get the original filename of the page
+		String origFilename = page.getFile().getName();
+		//construct the set of Strings that will represent page names and nodes
+		String[] names = origFilename.split(this.delim);
+		//for each, if the node exists, get it, if not create a placeholder
+		HierarchyNode current = root;
+		for (int i = 0; i < names.length; i++) {
+			String name = names[i];
+			HierarchyNode node = getNode(current, name);
+			current.addChild(node);
+			current = node;
+		}
+		page.setName(current.getName());
+		current.setPage(page);
+		return root;
+	}
+
+	private HierarchyNode getNode(HierarchyNode node, String name) {
+		for (HierarchyNode child : node.getChildren()) {
+			if (child.getName().equalsIgnoreCase(name)) return child;
+		}
+		HierarchyNode newnode = new HierarchyNode();
+		newnode.setName(name);
+		return newnode;
+	}
+
+	@Override
+	public void setProperties(Properties properties) {
+		this.props = properties;
+
+	}
+
+	@Override
+	public Properties getProperties() {
+		return this.props;
+	}
+
+}
diff --git a/src/com/atlassian/uwc/hierarchies/FilenameHierarchyTest.java b/src/com/atlassian/uwc/hierarchies/FilenameHierarchyTest.java
new file mode 100644
index 0000000..a296606
--- /dev/null
+++ b/src/com/atlassian/uwc/hierarchies/FilenameHierarchyTest.java
@@ -0,0 +1,206 @@
+package com.atlassian.uwc.hierarchies;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import com.atlassian.uwc.filters.NoSvnFilter;
+import com.atlassian.uwc.ui.Page;
+
+//NOTE: a valid set of pages for testing will need a valid file associated with that page node
+public class FilenameHierarchyTest extends TestCase {
+
+	FilenameHierarchy tester = null;
+	private final String SAMPLEDIR_SIMPLE = "sampleData/hierarchy/filename/simple";
+	Logger log = Logger.getLogger(this.getClass());
+	Vector<Page> pages = null;
+	Properties props = null;
+	
+	protected void setUp() throws Exception {
+		tester = new FilenameHierarchy();
+		PropertyConfigurator.configure("log4j.properties");
+		pages = new Vector<Page>();
+		props = new Properties();
+		props.setProperty(FilenameHierarchy.PROPKEY_DELIM, "%2F");
+		tester.setProperties(props);
+	}
+	
+	public void testBuildHierarchy_OnePage_OneNode() {
+		addOnePageToList(SAMPLEDIR_SIMPLE + File.separator + "Root");
+		
+		HierarchyNode actual = tester.buildHierarchy(pages);
+		assertNotNull(actual);
+		
+		Set<HierarchyNode> nodes = actual.getChildren();
+		assertNotNull(nodes);
+		assertEquals(1, nodes.size());
+		for (HierarchyNode root : nodes) {
+			assertEquals("Root", root.getName());
+			
+			Page rootpage = root.getPage();
+			assertNotNull(rootpage);
+			assertNotNull(rootpage.getName());
+			assertEquals("Root", rootpage.getName());
+			
+			assertTrue(root.getChildren().isEmpty());
+		}
+		
+	}
+
+
+	public void testBuildHierarchy_OnePage_TwoNodes() {
+		addOnePageToList(SAMPLEDIR_SIMPLE + File.separator + "Root%2FLeaf");
+		
+		HierarchyNode actual = tester.buildHierarchy(pages);
+		assertNotNull(actual);
+		
+		Set<HierarchyNode> nodes = actual.getChildren();
+		assertNotNull(nodes);
+		assertEquals(1, nodes.size());
+		for (HierarchyNode root : nodes) {
+			assertEquals("Root", root.getName());
+			assertNull(root.getPage()); //cause we only had the leaf page
+			
+			Vector<HierarchyNode> children = asVector(root.getChildren());
+			assertEquals(1, children.size());
+			HierarchyNode child = children.get(0);
+			assertEquals("Leaf", child.getName());
+			
+			Page childpage = child.getPage();
+			assertNotNull(childpage);
+			assertEquals("Leaf", childpage.getName());
+			
+			assertTrue(child.getChildren().isEmpty());
+		}
+	}
+	
+
+	public void testBuildHierarchy_OnePage_ThreeNodes() {
+		addOnePageToList(SAMPLEDIR_SIMPLE + File.separator + "Root%2FBranch%2FChild");
+		
+		HierarchyNode actual = tester.buildHierarchy(pages);
+		assertNotNull(actual);
+		
+		Set<HierarchyNode> nodes = actual.getChildren();
+		assertNotNull(nodes);
+		assertEquals(1, nodes.size());
+		for (HierarchyNode root : nodes) {
+			assertEquals("Root", root.getName());
+			assertNull(root.getPage());
+			
+			Vector<HierarchyNode> children = asVector(root.getChildren());
+			assertEquals(1, children.size());
+			HierarchyNode child = children.get(0);
+			assertEquals("Branch", child.getName());
+			assertNull(child.getPage());
+			
+			Vector<HierarchyNode> gchildren = asVector(child.getChildren());
+			assertEquals(1, gchildren.size());
+			HierarchyNode leaf = gchildren.get(0);
+			assertEquals("Child", leaf.getName());
+			
+			Page leafpage = leaf.getPage();
+			assertNotNull(leafpage);
+			assertEquals("Child", leafpage.getName());
+			
+			assertTrue(leaf.getChildren().isEmpty());
+		}
+	}
+	
+	public void testBuildHierarchy_TwoPages() {
+		addOnePageToList(SAMPLEDIR_SIMPLE + File.separator + "Root%2FLeaf");
+		addOnePageToList(SAMPLEDIR_SIMPLE + File.separator + "Root");
+		
+		HierarchyNode actual = tester.buildHierarchy(pages);
+		assertNotNull(actual);
+		
+		Set<HierarchyNode> nodes = actual.getChildren();
+		assertNotNull(nodes);
+		assertEquals(1, nodes.size());
+		for (HierarchyNode root : nodes) {
+			assertEquals("Root", root.getName());
+			Page rootpage = root.getPage();
+			assertNotNull(rootpage);
+			assertEquals("Root", rootpage.getName());
+			
+			Vector<HierarchyNode> children = asVector(root.getChildren());
+			assertEquals(1, children.size());
+			HierarchyNode child = children.get(0);
+			assertEquals("Leaf", child.getName());
+			
+			Page childpage = child.getPage();
+			assertNotNull(childpage);
+			assertEquals("Leaf", childpage.getName());
+			
+			assertTrue(child.getChildren().isEmpty());
+		}
+	}
+
+	public void testBuildHierarchy_Simple() {
+		File dir = new File(SAMPLEDIR_SIMPLE);
+		File[] listFiles = dir.listFiles(new NoSvnFilter());
+		assertEquals(4, listFiles.length);
+		for (File file : listFiles) {
+			pages.add(new Page(file));
+		}
+		
+		HierarchyNode actual = tester.buildHierarchy(pages);
+		assertNotNull(actual);
+		
+		Vector<HierarchyNode> nodes = asVector(actual.getChildren());
+		assertNotNull(nodes);
+		assertEquals(1, nodes.size());
+		HierarchyNode root = nodes.get(0);
+		assertNotNull(root.getPage());
+		assertEquals("Root", root.getName());
+		assertEquals("Root", root.getPage().getName());
+		
+		Vector<HierarchyNode> nodes2 = asVector(root.getChildren());
+		assertNotNull(nodes2);
+		assertEquals(2, nodes2.size());
+		int branchindex = (nodes2.get(0).getName().startsWith("B"))?0:1; //we do this 'cause Sets aren't predictable
+		int leafindex = branchindex == 0?1:0;
+		HierarchyNode branch = nodes2.get(branchindex);
+		HierarchyNode leaf = nodes2.get(leafindex);
+		assertNotNull(leaf.getPage());
+		assertEquals("Leaf", leaf.getName());
+		assertEquals("Leaf", leaf.getPage().getName());
+		assertTrue(leaf.getChildren().isEmpty());
+		assertNotNull(branch.getPage());
+		assertEquals("Branch", branch.getName());
+		assertEquals("Branch", branch.getPage().getName());
+		
+		Vector<HierarchyNode> nodes3 = asVector(branch.getChildren());
+		assertNotNull(nodes3);
+		assertEquals(1, nodes3.size());
+		HierarchyNode child = nodes3.get(0);
+		assertNotNull(child.getPage());
+		assertEquals("Child", child.getName());
+		assertEquals("Child", child.getPage().getName());
+		assertTrue(child.getChildren().isEmpty());
+	}
+
+
+	// helper methods
+
+	private void addOnePageToList(String path) {
+		File file = new File(path);
+		assertTrue(file.exists());
+		Page page = new Page(file);
+		pages.add(page);
+	}
+	
+	private Vector<HierarchyNode> asVector(Set<HierarchyNode> children) {
+		Vector<HierarchyNode> nodes = new Vector<HierarchyNode>();
+		nodes.addAll(children);
+		return nodes;
+	}
+	
+}