cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r488198 - in /incubator/cayenne/main/trunk/other/confluence-maven-plugin: ./ src/main/java/org/apache/cayenne/other/plugin/confluence/ src/main/resources/ src/main/resources/doctemplates/
Date Mon, 18 Dec 2006 10:21:26 GMT
Author: aadamchik
Date: Mon Dec 18 02:21:25 2006
New Revision: 488198

URL: http://svn.apache.org/viewvc?view=rev&rev=488198
Log:
making a self-contained Confluence doc plugin

Added:
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/.classpath
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/.project
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocGenerator.java
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPage.java
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPageRenderer.java
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/default.vm
Modified:
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/pom.xml
    incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/ConfluenceExportMojo.java

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/.classpath
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/.classpath?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/.classpath (added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/.classpath Mon Dec 18 02:21:25
2006
@@ -0,0 +1,7 @@
+<classpath>
+	<classpathentry kind="src" path="src/main/java" />
+	<classpathentry kind="src" path="src/test/java" output="target/test-classes" />
+	<classpathentry kind="output" path="target/classes" />
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" />
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" />
+</classpath>
\ No newline at end of file

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/.project
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/.project?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/.project (added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/.project Mon Dec 18 02:21:25
2006
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>confluence-maven-plugin</name>
+	<comment>Apache Cayenne is a powerful, full-featured Java Object
+		Relational Mapping framework currently in incubation.</comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Modified: incubator/cayenne/main/trunk/other/confluence-maven-plugin/pom.xml
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/pom.xml?view=diff&rev=488198&r1=488197&r2=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/pom.xml (original)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/pom.xml Mon Dec 18 02:21:25
2006
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-    Copyright 2006 The Apache Software Foundation
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+	Copyright 2006 The Apache Software Foundation
+	
+	Licensed under the Apache License, Version 2.0 (the "License");
+	you may not use this file except in compliance with the License.
+	You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing, software
+	distributed under the License is distributed on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	See the License for the specific language governing permissions and
+	limitations under the License.
 -->
 <project>
 	<parent>
@@ -27,23 +27,34 @@
 	<name>Cayenne Maven2 Plugins :: Confluence</name>
 	<dependencies>
 		<dependency>
-			<groupId>org.apache.cayenne.other</groupId>
-			<artifactId>cayenne-build-tools</artifactId>
-			<version>${pom.version}</version>
-		</dependency>
-		<dependency>
 			<groupId>org.apache.maven</groupId>
 			<artifactId>maven-archiver</artifactId>
 			<version>2.2</version>
 		</dependency>
 		<dependency>
-			<groupId>commons-logging</groupId>
-			<artifactId>commons-logging</artifactId>
-		</dependency>
-		<dependency>
 			<groupId>org.apache.maven</groupId>
 			<artifactId>maven-plugin-api</artifactId>
 			<version>2.0.4</version>
+		</dependency>
+		<dependency>
+			<groupId>com.atlassian.confluence</groupId>
+			<artifactId>confluence-soap</artifactId>
+			<version>2.0</version>
+		</dependency>
+		<dependency>
+			<groupId>axis</groupId>
+			<artifactId>axis</artifactId>
+			<version>1.4</version>
+		</dependency>
+		<dependency>
+			<groupId>velocity</groupId>
+			<artifactId>velocity</artifactId>
+			<version>1.4</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.cayenne.core</groupId>
+			<artifactId>cayenne-jdk1.4</artifactId>
+			<version>3.0-incubating-SNAPSHOT</version>
 		</dependency>
 	</dependencies>
 </project>

Modified: incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/ConfluenceExportMojo.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/ConfluenceExportMojo.java?view=diff&rev=488198&r1=488197&r2=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/ConfluenceExportMojo.java
(original)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/ConfluenceExportMojo.java
Mon Dec 18 02:21:25 2006
@@ -20,49 +20,46 @@
 
 import java.net.URL;
 
-import org.apache.cayenne.tools.ant.docgen.DocGenerator;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 
 /**
- * A goal to export confluence documentation
+ * A goal to export Confluence documentation.
  * 
  * @author <a href="mailto:bdudney@apache.org">Bill Dudney</a>
- * @version $Id$
- *
+ * 
  * @goal export
  */
 public class ConfluenceExportMojo extends AbstractMojo {
 	/**
 	 * The directory to put the exported documentation into
 	 * 
-	 * @parameter expression="${project.build.directory}/${export.spaceName}"
+	 * @parameter expression="${project.build.directory}/${confluence.spaceName}"
 	 */
 	private String outputDirectory;
 
 	/**
-	 * The velocity template to use - defaults to 
-	 * loading 'doctemplates/default.vm' from the classpath
+	 * The velocity template to use - defaults to loading
+	 * 'doctemplates/default.vm' from the classpath
 	 * 
 	 * @parameter
 	 */
 	private String velocityTemplate;
 
 	/**
-	 * The root url to the confluence instance
-	 * For example in Cayenne: http://cwiki.apache.org/confluence/
-	 * is the root URL and the space name is CAYDOC
+	 * The root url to the Confluence instance For example in Cayenne:
+	 * http://cwiki.apache.org/confluence/ is the base URL.
 	 * 
-	 * @parameter expression="${export.rootURL}"
+	 * @parameter expression="${confluence.baseUrl}"
 	 * @required
 	 */
-	private URL rootURL;
+	private URL baseUrl;
 
 	/**
 	 * The name of the confluence space to export
 	 * 
-	 * @parameter expression="${export.spaceName}"
+	 * @parameter expression="${confluence.spaceName}"
 	 * @required
 	 */
 	private String spaceName;
@@ -70,40 +67,41 @@
 	/**
 	 * The page in the space to start with
 	 * 
-	 * @parameter expression="${export.startPage}"
+	 * @parameter expression="${confluence.startPage}"
 	 * @required
 	 */
 	private String startPage;
 
 	/**
-	 * The username to log in as - define it on the commandline via the 
-	 * -Dconfluence.userName=user_name option
-	 * or set the userName and password in your ~/.m2/settings.xml file
-	 * like this;
+	 * The username to log in as - define it on the commandline via the
+	 * -Dconfluence.userName=user_name option or set the userName and password
+	 * in your ~/.m2/settings.xml file like this;
+	 * 
 	 * <pre>
-  &lt;profiles&gt;
-    &lt;profile&gt;
-      &lt;properties&gt;
-	&lt;property&gt;
-	  &lt;name&gt;confluence.userName&lt;/name&gt;
-	  &lt;value&gt;user name&lt;/value&gt;
-	&lt;/property&gt;
-	&lt;property&gt;
-	  &lt;name&gt;confluence.password&lt;/name&gt;
-	  &lt;value&gt;password&lt;/value&gt;
-	&lt;/property&gt;
-      &lt;/properties&gt;
-      &lt;id&gt;confluence&lt;/id&gt;
-    &lt;/profile&gt;
-  &lt;/profiles&gt;
-	 * </pre> 
+	 *     	 &lt;profiles&gt;
+	 *     	 &lt;profile&gt;
+	 *     	 &lt;properties&gt;
+	 *     	 &lt;property&gt;
+	 *     	 &lt;name&gt;confluence.userName&lt;/name&gt;
+	 *     	 &lt;value&gt;user name&lt;/value&gt;
+	 *     	 &lt;/property&gt;
+	 *     	 &lt;property&gt;
+	 *     	 &lt;name&gt;confluence.password&lt;/name&gt;
+	 *     	 &lt;value&gt;password&lt;/value&gt;
+	 *     	 &lt;/property&gt;
+	 *     	 &lt;/properties&gt;
+	 *     	 &lt;id&gt;confluence&lt;/id&gt;
+	 *     	 &lt;/profile&gt;
+	 *     	 &lt;/profiles&gt;
+	 * </pre>
+	 * 
 	 * @parameter expression="${confluence.userName}"
 	 * @required
 	 */
 	private String userName;
 
 	/**
-	 * The username to log in as - define it on the commandline via the 
+	 * The username to log in as - define it on the commandline via the
 	 * -Dconfluence.password=password option
 	 * 
 	 * @parameter expression="${confluence.password}"
@@ -112,28 +110,25 @@
 	private String password;
 
 	/**
-	 * where the actual work takes place
+	 * Worker method.
 	 */
 	public void execute() throws MojoExecutionException, MojoFailureException {
-        getLog().info("Exporting space '" + spaceName + "' to " + outputDirectory);
+		getLog().info(
+				"Exporting space '" + spaceName + "' to " + outputDirectory);
 
-        try {
-            DocGenerator generator = new DocGenerator(
-                    rootURL.toString(),
-                    spaceName,
-                    outputDirectory,
-                    startPage,
-                    userName,
-                    password,
-                    velocityTemplate);
-
-            getLog().info("Confluence base URL '" + generator.getBaseUrl() + "'");
-            generator.generateDocs();
-        }
-        catch (Exception e) {
-        	e.printStackTrace();
-            throw new MojoExecutionException("Failed to export: " + spaceName + " from: "
+ rootURL, e);
-        }
+		try {
+			DocGenerator generator = new DocGenerator(baseUrl.toString(),
+					spaceName, outputDirectory, startPage, userName, password,
+					velocityTemplate);
+
+			getLog().info(
+					"Confluence base URL '" + generator.getBaseUrl() + "'");
+			generator.generateDocs();
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new MojoExecutionException("Failed to export: " + spaceName
+					+ " from: " + baseUrl, e);
+		}
 	}
 
 	public String getOutputDirectory() {
@@ -160,12 +155,12 @@
 		this.password = password;
 	}
 
-	public URL getRootURL() {
-		return rootURL;
+	public URL getBaseUrl() {
+		return baseUrl;
 	}
 
-	public void setRootURL(URL rootURL) {
-		this.rootURL = rootURL;
+	public void setBaseUrl(URL rootURL) {
+		this.baseUrl = rootURL;
 	}
 
 	public String getSpaceName() {
@@ -191,5 +186,4 @@
 	public void setUserName(String userName) {
 		this.userName = userName;
 	}
-
 }

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocGenerator.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocGenerator.java?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocGenerator.java
(added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocGenerator.java
Mon Dec 18 02:21:25 2006
@@ -0,0 +1,207 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.other.plugin.confluence;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Iterator;
+
+import org.objectstyle.confluence.rpc.soap_axis.confluenceservice_v1.ConfluenceSoapService;
+import org.objectstyle.confluence.rpc.soap_axis.confluenceservice_v1.ConfluenceSoapServiceProxy;
+
+import com.atlassian.confluence.rpc.soap.beans.RemoteAttachment;
+import com.atlassian.confluence.rpc.soap.beans.RemotePage;
+import com.atlassian.confluence.rpc.soap.beans.RemotePageSummary;
+
+/**
+ * Generates standalone documentation for Cayenne based on Confluence content.
+ * 
+ * @author Cris Daniluk
+ */
+public class DocGenerator {
+	private static final String DEFAULT_TEMPLATE = "doctemplates/default.vm";
+
+	private static final String ENDPOINT_SUFFIX = "/rpc/soap-axis/confluenceservice-v1";
+
+	private String baseUrl;
+
+	private String spaceKey;
+
+	private String docBase;
+
+	private String startPage;
+
+	private String token;
+
+	private ConfluenceSoapService service;
+
+	private String username;
+
+	private String password;
+
+	private String template;
+
+	private DocPageRenderer parser;
+
+	public DocGenerator(String baseUrl, String spaceKey, String docBase,
+			String startPage, String username, String password, String template) {
+
+		ConfluenceSoapServiceProxy service = new ConfluenceSoapServiceProxy();
+
+		// derive service URL from base URL
+		if (baseUrl != null) {
+			if (baseUrl.endsWith("/")) {
+				baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+			}
+
+			String endpoint = baseUrl + ENDPOINT_SUFFIX;
+			service.setEndpoint(endpoint);
+		}
+		// service base URL from service default URL
+		else if (service.getEndpoint().endsWith(ENDPOINT_SUFFIX)) {
+			String endpoint = service.getEndpoint();
+			baseUrl = endpoint.substring(0, endpoint.length()
+					- ENDPOINT_SUFFIX.length());
+		} else {
+			throw new IllegalArgumentException(
+					"Null base url and invalid service URL");
+		}
+
+		this.baseUrl = baseUrl;
+		this.service = service;
+		this.spaceKey = spaceKey;
+		this.docBase = docBase;
+		this.startPage = startPage;
+		this.username = username;
+		this.password = password;
+
+		if (template == null) {
+			this.template = DEFAULT_TEMPLATE;
+		} else {
+			this.template = template;
+		}
+	}
+
+	public void generateDocs() throws Exception {
+
+		login();
+
+		// only works for adminstrators
+		// String url = service.exportSite(token, true);
+
+		// URL foo = new URL(url);
+		createPath(docBase);
+
+		// Build a page hierarchy first..
+		DocPage page = getPage(null, startPage);
+
+		iterateChildren(page);
+
+		// Now render the content nodes..
+		renderPage(page, docBase);
+
+	}
+
+	protected void iterateChildren(DocPage parent) throws Exception {
+
+		RemotePageSummary[] children = getChildren(parent);
+		for (int i = 0; i < children.length; i++) {
+
+			DocPage child = getPage(parent, children[i].getTitle());
+			parent.addChild(child);
+			iterateChildren(child);
+
+		}
+
+	}
+
+	protected void renderPage(DocPage page, String basePath) throws Exception {
+		String currentPath = basePath + "/" + page.getTitle();
+
+		createPath(currentPath);
+
+		FileWriter fw = new FileWriter(currentPath + "/index.html");
+		parser.render(page, fw);
+		fw.close();
+
+		writeAttachments(currentPath, page);
+
+		for (Iterator childIter = page.getChildren().iterator(); childIter
+				.hasNext();) {
+			renderPage((DocPage) childIter.next(), currentPath);
+		}
+
+	}
+
+	protected RemotePageSummary[] getChildren(DocPage page) throws Exception {
+		return service.getChildren(token, page.getId());
+	}
+
+	protected void writeAttachments(String basePath, DocPage page)
+			throws Exception {
+		RemoteAttachment[] attachments = service.getAttachments(token, page
+				.getId());
+
+		for (int j = 0; j < attachments.length; j++) {
+
+			FileOutputStream fos = null;
+			try {
+				fos = new FileOutputStream(basePath + "/"
+						+ attachments[j].getFileName());
+
+				fos.write(getAttachmentData(page, attachments[j]));
+			} finally {
+				fos.close();
+			}
+
+		}
+	}
+
+	protected byte[] getAttachmentData(DocPage page, RemoteAttachment attachment)
+			throws Exception {
+		return service.getAttachmentData(token, page.getId(), attachment
+				.getFileName(), 0);
+	}
+
+	protected void login() throws Exception {
+		token = service.login(username, password);
+		parser = new DocPageRenderer(service, baseUrl, token, spaceKey,
+				template);
+	}
+
+	protected DocPage getPage(DocPage parentPage, String pageTitle)
+			throws Exception {
+		RemotePage page = service.getPage(token, spaceKey, pageTitle);
+		return new DocPage(parentPage, page.getTitle(), page.getId(), page
+				.getContent());
+	}
+
+	protected void createPath(String path) {
+		new File(path).mkdirs();
+
+	}
+
+	public String getBaseUrl() {
+		return baseUrl;
+	}
+}

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPage.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPage.java?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPage.java
(added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPage.java
Mon Dec 18 02:21:25 2006
@@ -0,0 +1,209 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.other.plugin.confluence;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a TOC entry. This has a lot of tree-like search functions, but I
+ * did not find a tree implementation that I thought was worth using for this.
+ * 
+ * @author Cris Daniluk
+ */
+public class DocPage {
+
+	private static final Pattern orderingPattern = Pattern
+			.compile("\n?\\{excerpt(.*?)\\}");
+
+	private static final Map titleMap = new HashMap();
+
+	private String title = null;
+
+	private long id;
+
+	private String rawContent;
+
+	private DocPage parentRef;
+
+	private List children = null;
+
+	private List ordering;
+
+	private int depth;
+
+	public static DocPage getPageByTitle(String title) {
+		return (DocPage) titleMap.get(title);
+	}
+
+	public DocPage(DocPage parentRef, String title, long id, String rawContent) {
+		this.parentRef = parentRef;
+		this.title = title;
+		this.id = id;
+		this.rawContent = rawContent;
+
+		titleMap.put(title, this);
+
+		// Look for a page ordering...
+		Matcher matcher = orderingPattern.matcher(rawContent);
+		if (matcher.find()) {
+			int regionStart = matcher.end() + 1;
+			matcher.find();
+
+			ordering = Arrays.asList(rawContent.substring(regionStart,
+					matcher.start()).split("\n"));
+
+		}
+
+		if (parentRef == null) {
+			depth = 1;
+		} else if (ordering == null && parentRef.ordering != null) {
+			ordering = parentRef.ordering;
+		}
+
+		children = new ArrayList();
+	}
+
+	public void addChild(DocPage child) {
+		child.depth = depth + 1;
+		children.add(child);
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public int getDepth() {
+		return depth;
+	}
+
+	public List getChildren() {
+		// If an ordering is present, sort by it...
+		if (ordering != null) {
+
+			Collections.sort(children, new Comparator() {
+
+				public int compare(Object arg0, Object arg1) {
+					// we're the only one who modified this list, so we can
+					// trust it
+					// (and live with the consequences if we're wrong)
+					DocPage child0 = (DocPage) arg0;
+					DocPage child1 = (DocPage) arg1;
+
+					if (child0.getTitle().equals(child1.getTitle())) {
+						return 0;
+					} else if (ordering.indexOf(child1.getTitle()) == -1) {
+						// if its not on the list, float it to the bottom
+						return 1;
+					}
+					if (ordering.indexOf(child0.getTitle()) < ordering
+							.indexOf(child1.getTitle())) {
+						return -1;
+					} else {
+						return 1;
+					}
+				}
+
+			});
+		} else {
+
+			// no beanutils, so do this manually...
+			Collections.sort(children, new Comparator() {
+
+				public int compare(Object arg0, Object arg1) {
+					DocPage child0 = (DocPage) arg0;
+					DocPage child1 = (DocPage) arg1;
+					return (child0.getTitle().compareTo(child1.getTitle()));
+				}
+
+			});
+		}
+		return Collections.unmodifiableList(children);
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public String getRawContent() {
+		return rawContent;
+	}
+
+	public DocPage getParentRef() {
+		return parentRef;
+	}
+
+	public DocPage findPageId(long searchId) {
+
+		return findChild(this, searchId);
+	}
+
+	public boolean hasDescendent(DocPage page) {
+		if (findChild(this, page.getId()) != null) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Get the "module" root. This returns the next-to-top element in the tree.
+	 */
+	public DocPage getRoot() {
+		DocPage base = this;
+		while (base.parentRef != null && base.parentRef.parentRef != null) {
+			base = base.parentRef;
+		}
+		return base;
+	}
+
+	private DocPage findChild(DocPage page, long searchId) {
+
+		if (page.getId() == searchId) {
+			return page;
+		}
+		Iterator pageIter = page.getChildren().iterator();
+		while (pageIter.hasNext()) {
+			DocPage match = findChild((DocPage) pageIter.next(), searchId);
+			if (match != null) {
+				return match;
+			}
+		}
+		return null;
+	}
+
+	public String getLinkPath() {
+		return buildLinkPath(this);
+	}
+
+	private String buildLinkPath(DocPage page) {
+		if (page.getParentRef() == null) {
+			return page.getTitle();
+		}
+		return buildLinkPath(page.getParentRef()) + "/" + page.getTitle();
+	}
+}

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPageRenderer.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPageRenderer.java?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPageRenderer.java
(added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/java/org/apache/cayenne/other/plugin/confluence/DocPageRenderer.java
Mon Dec 18 02:21:25 2006
@@ -0,0 +1,245 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.other.plugin.confluence;
+
+import java.io.Writer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.gen.ClassGeneratorResourceLoader;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.NullLogSystem;
+import org.objectstyle.confluence.rpc.soap_axis.confluenceservice_v1.ConfluenceSoapService;
+
+/**
+ * Extracts embedded links from Confluence documentation and converts them to
+ * local fs references
+ * 
+ * @author Cris Daniluk
+ */
+public class DocPageRenderer {
+
+	private static final String URL_PREFIX = "/confluence";
+
+	/**
+	 * Only attachments within the page are supported right now. This could
+	 * easily be adjusted to find attachments in external documents if
+	 * necessary.
+	 */
+	private static final Pattern attachmentPattern = Pattern
+			.compile("(href|src)=\"" + URL_PREFIX
+					+ "/download/attachments/(.*?)/(.*?)\"");
+
+	/**
+	 * When browsing the local filesystem, browsers like %20 (hex encoded)
+	 * instead of + (legacy HTTP 0.9) for spaces.
+	 */
+	private static final Pattern spaceEncoderPattern = Pattern
+			.compile("href=\"(?!http://).*?\\+.*?\"");
+
+	/**
+	 * Not all images are supported - only the ones referenced by current docs.
+	 */
+	private static final Pattern confluenceImagePattern = Pattern
+			.compile("src=\"" + URL_PREFIX + "/images/icons/(.*?)\"");
+
+	/**
+	 * Take any confluence links to non-doc content and add the url
+	 */
+	private Pattern confluenceLinkPattern = Pattern.compile("href=\"("
+			+ URL_PREFIX + "/display/.*?)\"");
+
+	private Pattern embeddedLinkPattern;
+
+	private ConfluenceSoapService service;
+
+	private String token;
+
+	private String spaceKey;
+
+	private String baseUrl;
+
+	private VelocityContext velCtxt;
+
+	private Template pageTemplate;
+
+	public DocPageRenderer(ConfluenceSoapService service, String baseUrl,
+			String token, String spaceKey, String template) throws Exception {
+
+		// Note that these regexps have a fairly narrow capture - since the HTML
+		// is
+		// machine-generated,
+		// we're kind of assuming it is well-formed
+		embeddedLinkPattern = Pattern.compile("href=\"" + URL_PREFIX
+				+ "/display/" + spaceKey + "/(.*?)\"");
+
+		this.service = service;
+		this.baseUrl = baseUrl;
+		this.token = token;
+		this.spaceKey = spaceKey;
+
+		velCtxt = new VelocityContext();
+
+		initializeClassTemplate(template);
+	}
+
+	private void initializeClassTemplate(String template) throws Exception {
+		VelocityEngine velocityEngine = new VelocityEngine();
+		try {
+
+			// use ClasspathResourceLoader for velocity templates lookup
+			// if Cayenne URL is not null, load resource from this URL
+			Properties props = new Properties();
+
+			// null logger that will prevent velocity.log from being generated
+			props.put(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
+					NullLogSystem.class.getName());
+
+			props.put("resource.loader", "cayenne");
+
+			props.put("cayenne.resource.loader.class",
+					ClassGeneratorResourceLoader.class.getName());
+
+			velocityEngine.init(props);
+		} catch (Exception ex) {
+			throw new CayenneRuntimeException("Can't initialize Velocity", ex);
+		}
+
+		pageTemplate = velocityEngine.getTemplate(template);
+	}
+
+	public void render(DocPage page, Writer out) throws Exception {
+
+		// Add the TOC, unless this is the top-level page
+		StringBuffer toc = new StringBuffer();
+		if (page.getParentRef() != null) {
+			toc.append("<div id=\"cayenne_toc\">\n");
+
+			DocPage root = page.getRoot();
+
+			iterateChildren(toc, page, root);
+			toc.append("</div>\n");
+		}
+
+		// Figure out the level of nesting for relative links
+		String basePath = "";
+		for (int i = 1; i <= page.getDepth(); i++) {
+			basePath += "../";
+		}
+
+		String renderedContent = null;
+		try {
+			renderedContent = service.renderContent(token, spaceKey, page
+					.getId(), page.getRawContent(), new HashMap(Collections
+					.singletonMap("style", "clean")));
+		} catch (Throwable t) {
+			// could have hit a DOS prevention bit so
+			// sleep for 250ms and try again
+			Thread.sleep(250);
+			renderedContent = service.renderContent(token, spaceKey, page
+					.getId(), page.getRawContent(), new HashMap(Collections
+					.singletonMap("style", "clean")));
+		}
+		// Replace cross-doc links
+		Matcher linkMatcher = embeddedLinkPattern.matcher(renderedContent);
+		StringBuffer replacementBuffer = new StringBuffer();
+		while (linkMatcher.find()) {
+			DocPage destPage = DocPage.getPageByTitle(linkMatcher.group(1)
+					.replace('+', ' '));
+
+			// If we don't understand the link, just leave it alone to be safe
+			if (destPage == null) {
+				continue;
+			}
+			linkMatcher.appendReplacement(replacementBuffer, "href=\""
+					+ basePath + destPage.getLinkPath() + "/index.html\"");
+		}
+		linkMatcher.appendTail(replacementBuffer);
+
+		renderedContent = replacementBuffer.toString();
+
+		// renderedContent =
+		// embeddedLinkPattern.matcher(renderedContent).replaceAll("href=\"$1/index.html\"");
+
+		// Replace attachment links
+		renderedContent = attachmentPattern.matcher(renderedContent)
+				.replaceAll("$1=\"$3\"");
+
+		// Convert confluence images to relative links
+		renderedContent = confluenceImagePattern.matcher(renderedContent)
+				.replaceAll("src=\"" + basePath + "images/$1\"");
+
+		// Replace wiki links
+		renderedContent = confluenceLinkPattern.matcher(renderedContent)
+				.replaceAll("href=\"" + baseUrl + "$1\"");
+
+		// Convert local links with + to %20 to make browsers happy (wtf?)
+		Matcher matcher = spaceEncoderPattern.matcher(renderedContent);
+
+		replacementBuffer = new StringBuffer();
+		while (matcher.find()) {
+			matcher.appendReplacement(replacementBuffer, matcher.group(0)
+					.replace("+", "%20"));
+		}
+		matcher.appendTail(replacementBuffer);
+
+		renderedContent = replacementBuffer.toString();
+
+		velCtxt.put("page", page);
+		velCtxt.put("basePath", basePath);
+		velCtxt.put("pageContent", toc.toString() + renderedContent);
+
+		pageTemplate.merge(velCtxt, out);
+
+	}
+
+	private void iterateChildren(StringBuffer toc, DocPage currentPage,
+			DocPage basePage) {
+		toc.append("<ul>\n");
+		for (Iterator baseIter = basePage.getChildren().iterator(); baseIter
+				.hasNext();) {
+
+			DocPage child = (DocPage) baseIter.next();
+
+			toc.append("<li>").append("<a href=\"");
+			for (int i = 1; i <= currentPage.getDepth(); i++) {
+				toc.append("../");
+			}
+			toc.append(child.getLinkPath()).append("/index.html\">");
+			toc.append(child.getTitle()).append("</a>");
+			if (child.hasDescendent(currentPage)) {
+				// render children
+				iterateChildren(toc, currentPage, child);
+			}
+
+			toc.append("</li>\n");
+		}
+
+		toc.append("</ul>\n");
+	}
+}

Added: incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/default.vm
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/default.vm?view=auto&rev=488198
==============================================================================
--- incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/default.vm
(added)
+++ incubator/cayenne/main/trunk/other/confluence-maven-plugin/src/main/resources/doctemplates/default.vm
Mon Dec 18 02:21:25 2006
@@ -0,0 +1,40 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+-->
+<html>
+  <head>
+    <title>Apache Cayenne Documentation - ${page.title}</title>
+    <style type="text/css">@import "${basePath}style.css";</style>
+  </head>
+<body>
+  <div class="header">
+    <div style="float: left;"><a href="http://incubator.apache.org/cayenne/"><img
src="${basePath}images/logo.gif" align="absmiddle" border="0"></a></div>
+    <span class="logoSpaceLink"><a href="${basePath}index.html">Cayenne User
Documentation</a></span><br />
+    <span class="pagetitle">${page.title}</span>
+  </div>
+${pageContent}
+</div>
+  <div class="clearer">.</div>
+  <div style="height: 12px; background-image: url('${basePath}images/border_bottom.gif');
background-repeat: repeat-x;"></div>
+
+  <div class="smalltext copyright">
+    Copyright &copy;2001-2006 Apache Software Foundation
+  </div>
+
+</body>
+</html>



Mime
View raw message