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:[EMAIL PROTECTED]">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>
- <profiles>
- <profile>
- <properties>
- <property>
- <name>confluence.userName</name>
- <value>user name</value>
- </property>
- <property>
- <name>confluence.password</name>
- <value>password</value>
- </property>
- </properties>
- <id>confluence</id>
- </profile>
- </profiles>
- * </pre>
+ * <profiles>
+ * <profile>
+ * <properties>
+ * <property>
+ * <name>confluence.userName</name>
+ * <value>user name</value>
+ * </property>
+ * <property>
+ * <name>confluence.password</name>
+ * <value>password</value>
+ * </property>
+ * </properties>
+ * <id>confluence</id>
+ * </profile>
+ * </profiles>
+ * </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 ©2001-2006 Apache Software Foundation
+ </div>
+
+</body>
+</html>