You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by bo...@apache.org on 2013/09/22 23:33:10 UTC
svn commit: r1525452 [1/2] - in /tapestry/tapestry-site/trunk: ./
src/main/java/org/apache/cxf/cwiki/ template/
Author: bobharner
Date: Sun Sep 22 21:33:09 2013
New Revision: 1525452
URL: http://svn.apache.org/r1525452
Log:
Replaced our copy of the SiteExporter Java source with Dan Kulp's latest (http://svn.apache.org/repos/asf/cxf/web/src, which has lots of bug fixes), and updated the template file to match. Alternatively we could have done an svn:external, and maybe that'd be best for the future.
Added:
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java (with props)
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java (with props)
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java (with props)
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java (with props)
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Space.java (with props)
Modified:
tapestry/tapestry-site/trunk/README
tapestry/tapestry-site/trunk/pom.xml
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/ConfluenceCleanupWriter.java
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Page.java
tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/SiteExporter.java
tapestry/tapestry-site/trunk/template/template.vm
Modified: tapestry/tapestry-site/trunk/README
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/README?rev=1525452&r1=1525451&r2=1525452&view=diff
==============================================================================
--- tapestry/tapestry-site/trunk/README (original)
+++ tapestry/tapestry-site/trunk/README Sun Sep 22 21:33:09 2013
@@ -1,8 +1,8 @@
This is SiteExporter utility, used to export (publish) the Tapestry Confluence
wiki content (pages and their attachments) to static web content directories and
-files. To run this manually, you need to have a copy of the Tapestry static
-website checked out to a local directory:
+files. To run this program manually, you need to have a copy of the Tapestry
+static website checked out to a local directory:
svn checkout https://svn.apache.org/repos/infra/websites/production/tapestry/content
@@ -36,16 +36,43 @@ run from BuildBot):
mvn -Pconfluence exec:java
-To export ALL pages in the wiki space (for example, after you have changed
-the Velocity template file:
+How to regenerate all pages of a given Confluence space
+=======================================================
+
+By default, only modified pages (as indicated by RSS feed) are regenerated.
+However, sometime it is necessary to regenerate all pages of a given
+Confluence space. For example, after changing the export template or modifying
+the navigation pages. To force regeneration of all pages of a given Confluence
+space delete the main.pageCache file from your copy of the
+following SVN directory:
+
+https://svn.apache.org/repos/infra/websites/production/tapestry/content/cache/
+
+At that point you can either commit the deletion and wait for BuildBot to notice the change
+(via an hourly cron), or you can use Maven to re-export all Confluence files to your local
+computer:
mvn -Pconfluence,force exec:java
-After you have updated the static content locally, you'll need to commit any
-changes in the content directory via the usual Subversion commit. The changes
-should be "live" in just a few seconds, due to the svnpubsub process.
+after which you'll need to commit any changes in the content directory via a Subversion
+commit. The changes should be "live" in just a few seconds, due to the svnpubsub process.
+
+*Most* of the site content is managed through Confluence. However, some content
+is (and should be) checked into directly into the svn:
+
+ - 5.3.7/ (and any other 5.x.x versions)
+ - dtd/
+ - images/
+ - resources/
+ - schema/
+ - styles/
+ - tapestry3/
+ - tapestry4.1/
+The Confluence spaces are exported and checked into the svn using a BuildBot
+process:
+ - http://ci.apache.org/builders/tapestry-site-production
Modified: tapestry/tapestry-site/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/pom.xml?rev=1525452&r1=1525451&r2=1525452&view=diff
==============================================================================
--- tapestry/tapestry-site/trunk/pom.xml (original)
+++ tapestry/tapestry-site/trunk/pom.xml Sun Sep 22 21:33:09 2013
@@ -28,11 +28,11 @@
<parent>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-parent</artifactId>
- <version>2.5.2</version>
+ <version>2.6.8</version>
</parent>
<properties>
- <cxf.version>2.5.2</cxf.version>
+ <cxf.version>2.6.8</cxf.version>
<extra.arg></extra.arg>
<svn.arg1></svn.arg1>
<svn.arg2></svn.arg2>
Added: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java?rev=1525452&view=auto
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java (added)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java Sun Sep 22 21:33:09 2013
@@ -0,0 +1,123 @@
+/**
+ * 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.cxf.cwiki;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.helpers.DOMUtils;
+
+/**
+ *
+ */
+public class AbstractPage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ final String id;
+ final String title;
+ final String url;
+
+ Map<String, String> attachments;
+
+ transient String directory;
+
+ public AbstractPage(Element root) throws Exception {
+ // org.apache.cxf.helpers.XMLUtils.printDOM(doc.getDocumentElement());
+
+ id = DOMUtils.getChildContent(root, "id");
+ title = DOMUtils.getChildContent(root, "title");
+ url = DOMUtils.getChildContent(root, "url");
+ }
+
+ public AbstractPage(AbstractPage source) {
+ this.id = source.id;
+ this.title = source.title;
+ this.url = source.url;
+ this.directory = source.directory;
+ }
+
+ public String getDirectory() {
+ return directory == null ? "" : directory;
+ }
+
+ public String getPath() {
+ return getDirectory() + createFileName();
+ }
+
+ public String createFileName() {
+ StringBuffer buffer = new StringBuffer();
+ char array[] = title.toLowerCase().toCharArray();
+ boolean separated = true;
+ for (int x = 0; x < array.length; x++) {
+ if ("abcdefghijklmnopqrstuvwxyz0123456789".indexOf(array[x]) >= 0) {
+ buffer.append(Character.toLowerCase(array[x]));
+ separated = false;
+ } else if ("\r\n\t -".indexOf(array[x]) >= 0) {
+ if (separated) {
+ continue;
+ }
+ buffer.append('-');
+ separated = true;
+ }
+ }
+ if (buffer.length() == 0) {
+ return id + ".html";
+ }
+ return buffer.append(".html").toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getURL() {
+ return url;
+ }
+
+ public boolean getHasCode() {
+ return false;
+ }
+
+ public String toString() {
+ return "AbstractPage[id=" + id + ",title=" + title + ",url=" + url + "]";
+ }
+
+ public void addAttachment(String aid, String filename) {
+ if (attachments == null) {
+ attachments = new HashMap<String, String>();
+ }
+ attachments.put(aid, filename);
+ }
+ public String getAttachmentFilename(String aid) {
+ if (attachments == null) {
+ return null;
+ }
+ return attachments.get(aid);
+ }
+
+}
Propchange: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/AbstractPage.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java?rev=1525452&view=auto
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java (added)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java Sun Sep 22 21:33:09 2013
@@ -0,0 +1,83 @@
+/**
+ * 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.cxf.cwiki;
+
+import java.io.Serializable;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.helpers.DOMUtils;
+
+/**
+ *
+ */
+public class BlogEntrySummary extends AbstractPage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ final XMLGregorianCalendar published;
+
+ // BlogEntrySummary does not have version field but the BlogEntry does.
+ // We load and set the version separately. It will be used to decide
+ // whether the blog entry needs to be re-rendered or not.
+ int version;
+
+ public BlogEntrySummary(Element root) throws Exception {
+ super(root);
+
+ String mod = DOMUtils.getChildContent(root, "publishDate");
+ published = DatatypeFactory.newInstance().newXMLGregorianCalendar(mod);
+ }
+
+ public String getDirectory() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(String.valueOf(published.getYear()));
+ builder.append("/");
+ if (published.getMonth() < 10) {
+ builder.append("0");
+ }
+ builder.append(String.valueOf(published.getMonth()));
+ builder.append("/");
+ if (published.getDay() < 10) {
+ builder.append("0");
+ }
+ builder.append(String.valueOf(published.getDay()));
+ builder.append("/");
+ return builder.toString();
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ void setVersion(int version) {
+ this.version = version;
+ }
+
+ public XMLGregorianCalendar getPublished() {
+ return published;
+ }
+
+ public String toString() {
+ return "BlogEntrySummary[id=" + id + ",title=" + title + ",version=" + version + ",url=" + url + "]";
+ }
+}
Propchange: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/BlogEntrySummary.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/ConfluenceCleanupWriter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/ConfluenceCleanupWriter.java?rev=1525452&r1=1525451&r2=1525452&view=diff
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/ConfluenceCleanupWriter.java (original)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/ConfluenceCleanupWriter.java Sun Sep 22 21:33:09 2013
@@ -19,6 +19,7 @@
package org.apache.cxf.cwiki;
+import java.io.File;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
@@ -36,14 +37,14 @@ import org.ccil.cowan.tagsoup.XMLWriter;
*/
public class ConfluenceCleanupWriter extends XMLWriter {
- private final Page page;
+ private final AbstractPage page;
private final SiteExporter exporter;
private final String divId;
private final String divCls;
private final Stack<Integer> trStack = new Stack<Integer>();
private int curTrCount;
- public ConfluenceCleanupWriter(SiteExporter exp, Writer writer, Page page,
+ public ConfluenceCleanupWriter(SiteExporter exp, Writer writer, AbstractPage page,
String id, String divCls) {
super(writer);
this.page = page;
@@ -52,6 +53,85 @@ public class ConfluenceCleanupWriter ext
this.divCls = divCls;
}
+ private File getPageDirectory() {
+ String pageDir = page.getDirectory();
+ if (pageDir.length() > 0) {
+ return new File(exporter.outputDir, pageDir);
+ } else {
+ return exporter.outputDir;
+ }
+ }
+
+ private String findPageWithURL(String url) throws Exception {
+ String location = findPageWithURL(exporter, url);
+ if (location == null) {
+ for (SiteExporter siteExporter : SiteExporter.siteExporters) {
+ if (exporter == siteExporter) {
+ continue;
+ }
+ location = findPageWithURL(siteExporter, url);
+ if (location != null) {
+ break;
+ }
+ }
+ }
+ return location;
+ }
+
+ private String findPageWithURL(SiteExporter siteExporter, String url) throws Exception {
+ if (siteExporter.getSpace().getURL().endsWith(url)) {
+ String prefix = getRelativePath(SiteExporter.rootOutputDir, getPageDirectory(), siteExporter.outputDir);
+ String location = prefix + "index.html";
+ if (exporter != siteExporter) {
+ System.out.println("Cross space link to " + location);
+ }
+ return location;
+ } else {
+ AbstractPage p = siteExporter.findPageByURL(url);
+ if (p == null) {
+ p = siteExporter.findBlogEntryByURL(url);
+ }
+ if (p != null) {
+ String prefix = getRelativePath(SiteExporter.rootOutputDir, getPageDirectory(), siteExporter.outputDir);
+ String location = prefix + p.getPath();
+ if (exporter != siteExporter) {
+ System.out.println("Cross space link to " + location);
+ }
+ return location;
+ }
+ }
+ return null;
+ }
+
+ private String findPageByID(String id) throws Exception {
+ String location = findPageByID(exporter, id);
+ if (location == null) {
+ for (SiteExporter siteExporter : SiteExporter.siteExporters) {
+ if (exporter == siteExporter) {
+ continue;
+ }
+ location = findPageByID(siteExporter, id);
+ if (location != null) {
+ break;
+ }
+ }
+ }
+ return location;
+ }
+
+ private String findPageByID(SiteExporter siteExporter, String url) throws Exception {
+ AbstractPage p = siteExporter.findPageByID(url);
+ if (p != null) {
+ String prefix = getRelativePath(SiteExporter.rootOutputDir, getPageDirectory(), siteExporter.outputDir);
+ String location = prefix + p.getPath();
+ if (exporter != siteExporter) {
+ System.out.println("Cross space link (via id) to " + location);
+ }
+ return location;
+ }
+ return null;
+ }
+
//CHECKSTYLE:OFF
public void startElement(String uri, String localName, String qName, final Attributes atts)
throws SAXException {
@@ -76,9 +156,9 @@ public class ConfluenceCleanupWriter ext
href = href.substring(0, href.indexOf('?'));
}
try {
- final Page p = exporter.findPageByURL(href);
+ String p = findPageWithURL(href);
if (p != null) {
- newAtts.addMapping("href", p.createFileName() + params);
+ newAtts.addMapping("href", p + params);
} else {
if (href.indexOf('~') == -1) {
//link to a user page is OK, don't warn about it
@@ -93,14 +173,23 @@ public class ConfluenceCleanupWriter ext
} else if (href != null && href.startsWith("/confluence/plugins/")) {
newAtts.addMapping("href", SiteExporter.ROOT + href.substring(11));
} else if (href != null && href.contains("/confluence/pages/viewpage.action")) {
+ String params = "";
+ if (href.indexOf('#') != -1) {
+ params = href.substring(href.indexOf('#'));
+ href = href.substring(0, href.indexOf('#'));
+ }
int idx = href.indexOf("pageId=");
String id = href.substring(idx + 7);
- Page p = exporter.findPageByID(id);
- if (p != null) {
- newAtts.addMapping("href", p.createFileName());
- } else {
- System.out.println("Could not find page for id: " + id
- + " linked from " + page.getTitle());
+ try {
+ String location = findPageByID(id);
+ if (location != null) {
+ newAtts.addMapping("href", location + params);
+ } else {
+ System.out.println("Could not find page for id: " + id
+ + " linked from " + page.getTitle());
+ }
+ } catch (Exception e) {
+ throw new SAXException(e);
}
} else if (href != null && href.contains("/confluence/download/attachments")) {
href = href.substring(href.lastIndexOf("/"));
@@ -130,24 +219,13 @@ public class ConfluenceCleanupWriter ext
}
} else if ("img".equals(localName.toLowerCase())
|| "img".equals(qName.toLowerCase())) {
- String href = atts.getValue("src");
+ String href = exporter.stripHost(atts.getValue("src"));
if ("absmiddle".equalsIgnoreCase(atts.getValue("align"))) {
newAtts.addMapping("align", "middle");
}
String cls = atts.getValue("class");
if (href != null && href.startsWith("/confluence/images/")) {
- //newAtts.addMapping("src", SiteExporter.HOST + href);
- try
- {
- String name = exporter.loadIcon(href);
- String dirName = "/" + SiteExporter.CONFLUENCE_IMAGES;
- newAtts.addMapping("src", dirName + "/" + name);
- }
- catch (Exception e)
- {
- System.out.println("Could not download icon " + href
- + " linked from " + page.getTitle());
- }
+ newAtts.addMapping("src", SiteExporter.HOST + href);
} else if (href != null && href.startsWith("/confluence/download/attachments")) {
if (cls == null) {
href = href.substring(0, href.lastIndexOf('?'));
@@ -155,7 +233,7 @@ public class ConfluenceCleanupWriter ext
String dirName = page.createFileName();
dirName = dirName.substring(0, dirName.lastIndexOf(".")) + ".data";
- newAtts.addMapping("src", dirName + href);
+ newAtts.addMapping("src", dirName + href.replaceAll("\\+", "-"));
} else if (cls.contains("userLogo")) {
String name = href;
try {
@@ -169,7 +247,7 @@ public class ConfluenceCleanupWriter ext
newAtts.addMapping("src", dirName + name);
} else {
- newAtts.addMapping("src", SiteExporter.HOST + href);
+ newAtts.addMapping("src", SiteExporter.HOST + href.replaceAll("\\+", "-"));
}
} else if (href != null && href.startsWith("/confluence/download/thumbnails")) {
String name = href;
@@ -321,4 +399,32 @@ public class ConfluenceCleanupWriter ext
}
}
+ private static String getRelativePath(File root, File current, File other) throws Exception {
+ if (current.equals(other)) {
+ return "";
+ }
+
+ String rootPath = root.getCanonicalPath();
+ String currentPath = current.getCanonicalPath();
+ StringBuilder builder = new StringBuilder();
+ while (!rootPath.equals(currentPath)) {
+ current = current.getParentFile();
+ currentPath = current.getCanonicalPath();
+ builder.append("../");
+ }
+
+ String otherPath = other.getCanonicalPath();
+
+ if (rootPath.equals(otherPath)) {
+ // nothing to do
+ } else if (otherPath.startsWith(rootPath)) {
+ String name = otherPath.substring(rootPath.length() + 1);
+ builder.append(name);
+ builder.append("/");
+ } else {
+ throw new RuntimeException("Non-relative locations: " + rootPath + " " + otherPath);
+ }
+
+ return builder.toString();
+ }
}
Modified: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Page.java?rev=1525452&r1=1525451&r2=1525452&view=diff
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Page.java (original)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Page.java Sun Sep 22 21:33:09 2013
@@ -21,91 +21,276 @@ package org.apache.cxf.cwiki;
import java.io.Serializable;
+import java.io.StringReader;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.DOMUtils;
+import org.ccil.cowan.tagsoup.Parser;
/**
*
*/
-public class Page implements Serializable {
+public class Page extends AbstractPage implements Serializable {
+
+
private static final long serialVersionUID = 1L;
+ private static final Map<String, String> CODE_TYPE_MAP = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+ static {
+ CODE_TYPE_MAP.put("applescript", "shBrushAppleScript.js");
+ CODE_TYPE_MAP.put("actionscript3", "shBrushAS3.js");
+ CODE_TYPE_MAP.put("as3", "shBrushAS3.js");
+ CODE_TYPE_MAP.put("bash", "shBrushBash.js");
+ CODE_TYPE_MAP.put("shell", "shBrushBash.js");
+ CODE_TYPE_MAP.put("coldfusion", "shBrushColdFusion.js");
+ CODE_TYPE_MAP.put("cpp", "shBrushCpp.js");
+ CODE_TYPE_MAP.put("c", "shBrushCpp.js");
+ CODE_TYPE_MAP.put("c#", "shBrushCSharp.js");
+ CODE_TYPE_MAP.put("c-sharp", "shBrushCSharp.js");
+ CODE_TYPE_MAP.put("csharp", "shBrushCSharp.js");
+ CODE_TYPE_MAP.put("css", "shBrushCss.js");
+ CODE_TYPE_MAP.put("delphi", "shBrushDelphi.js");
+ CODE_TYPE_MAP.put("pascal", "shBrushDelphi.js");
+ CODE_TYPE_MAP.put("diff", "shBrushDiff.js");
+ CODE_TYPE_MAP.put("patch", "shBrushDiff.js");
+ CODE_TYPE_MAP.put("pas", "shBrushDiff.js");
+ CODE_TYPE_MAP.put("erl", "shBrushErlang.js");
+ CODE_TYPE_MAP.put("erlang", "shBrushErlang.js");
+ CODE_TYPE_MAP.put("groovy", "shBrushGroovy.js");
+ CODE_TYPE_MAP.put("java", "shBrushJava.js");
+ CODE_TYPE_MAP.put("jfx", "shBrushJavaFX.js");
+ CODE_TYPE_MAP.put("javafx", "shBrushJavaFX.js");
+ CODE_TYPE_MAP.put("js", "shBrushJScript.js");
+ CODE_TYPE_MAP.put("jscript", "shBrushJScript.js");
+ CODE_TYPE_MAP.put("javascript", "shBrushJScript.js");
+ CODE_TYPE_MAP.put("perl", "shBrushPerl.js");
+ CODE_TYPE_MAP.put("pl", "shBrushPerl.js");
+ CODE_TYPE_MAP.put("php", "shBrushPhp.js");
+ CODE_TYPE_MAP.put("text", "shBrushPlain.js");
+ CODE_TYPE_MAP.put("plain", "shBrushPlain.js");
+ CODE_TYPE_MAP.put("none", "shBrushPlain.js");
+ CODE_TYPE_MAP.put("py", "shBrushPython.js");
+ CODE_TYPE_MAP.put("python", "shBrushPython.js");
+ CODE_TYPE_MAP.put("powershell", "shBrushPowerShell.js");
+ CODE_TYPE_MAP.put("ps", "shBrushPowerShell.js");
+ CODE_TYPE_MAP.put("posh", "shBrushPowerShell.js");
+ CODE_TYPE_MAP.put("ruby", "shBrushRuby.js");
+ CODE_TYPE_MAP.put("rails", "shBrushRuby.js");
+ CODE_TYPE_MAP.put("ror", "shBrushRuby.js");
+ CODE_TYPE_MAP.put("rb", "shBrushRuby.js");
+ CODE_TYPE_MAP.put("sass", "shBrushSass.js");
+ CODE_TYPE_MAP.put("scss", "shBrushSass.js");
+ CODE_TYPE_MAP.put("scala", "shBrushScala.js");
+ CODE_TYPE_MAP.put("sql", "shBrushSql.js");
+ CODE_TYPE_MAP.put("vb", "shBrushVb.js");
+ CODE_TYPE_MAP.put("vbnet", "shBrushVb.js");
+ CODE_TYPE_MAP.put("xml", "shBrushXml.js");
+ CODE_TYPE_MAP.put("xhtml", "shBrushXml.js");
+ CODE_TYPE_MAP.put("xslt", "shBrushXml.js");
+ CODE_TYPE_MAP.put("html", "shBrushXml.js");
+ CODE_TYPE_MAP.put("html/xml", "shBrushXml.js");
+ }
- XMLGregorianCalendar modified;
- final String id;
+ final XMLGregorianCalendar modified;
final String parent;
- final String title;
- final String url;
+ final String spaceKey;
Map<String, String> attachments;
Set<String> includes;
Map<String, Integer> childrenOf;
+ boolean hasBlog;
+ Set<String> codeTypes;
transient String renderedContent;
transient String renderedDivContent;
transient String divIdForContent;
+
+ transient SiteExporter exporter;
- public Page(Document doc) throws Exception {
+ public Page(Document doc, SiteExporter exp) throws Exception {
+ this(DOMUtils.getFirstElement(doc.getDocumentElement()), exp);
+ }
+
+ public Page(Element root, SiteExporter exp) throws Exception {
+ super(root);
+ exporter = exp;
//org.apache.cxf.helpers.XMLUtils.printDOM(doc.getDocumentElement());
- id = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "id");
- parent = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "parentId");
- title = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "title");
- url = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "url");
- String mod = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "modified");
- if(mod == null)
- mod = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "publishDate");
+
+ parent = DOMUtils.getChildContent(root, "parentId");
+ spaceKey = DOMUtils.getChildContent(root, "space");
+
+ String mod = DOMUtils.getChildContent(root, "modified");
modified = DatatypeFactory.newInstance().newXMLGregorianCalendar(mod);
+ modified.setMillisecond(0);
- String c = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "content");
+ String c = DOMUtils.getChildContent(root, "content");
if (c != null) {
- int idx = c.indexOf("{children");
- while (idx != -1) {
- if (childrenOf == null) {
- childrenOf = new HashMap<String, Integer>();
- }
- idx += 9;
- if (c.charAt(idx) != '}') {
- // {children:page=Foo|...}
- idx++;
- int idx2 = c.indexOf('}', idx);
+ if (exp.getAPIVersion() == 2) {
+ checkContentV2(c);
+ } else {
+ checkContentV1(c);
+ }
+ }
+ }
+ /*
+ * Makes a shallow copy without any content
+ */
+ public Page(Page source) {
+ super(source);
+ this.modified = source.modified;
+ this.parent = source.parent;
+ this.spaceKey = source.spaceKey;
+ this.attachments = source.attachments;
+ this.includes = source.includes;
+ this.childrenOf = source.childrenOf;
+ this.exporter = source.exporter;
+ this.hasBlog = source.hasBlog;
+ this.codeTypes = source.codeTypes;
+ }
+
+ private void checkContentV2(final String c) {
+ try {
+ //if ("JAX-WS Dispatch API".equals(title)) {
+ // System.out.println(c);
+ //}
+
+ XMLReader reader = new Parser();
+ reader.setFeature(Parser.namespacesFeature, true);
+ reader.setFeature(Parser.namespacePrefixesFeature, true);
+ reader.setProperty(Parser.schemaProperty, new org.ccil.cowan.tagsoup.HTMLSchema() {
+ {
+ //problem with nested lists that the confluence {toc} macro creates
+ elementType("ul", M_LI, M_BLOCK | M_LI, 0);
+ }
+ });
+ reader.setContentHandler(new V2ContentHandler(this));
+ reader.parse(new InputSource(new StringReader(c)));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void checkContentV1(String c) {
+ int idx = c.indexOf("{children");
+ while (idx != -1) {
+ if (childrenOf == null) {
+ childrenOf = new HashMap<String, Integer>();
+ }
+ idx += 9;
+ if (c.charAt(idx) != '}') {
+ // {children:page=Foo|...}
+ idx++;
+ int idx2 = c.indexOf('}', idx);
+ String paramString = c.substring(idx, idx2);
+ String params[] = paramString.split("\\||=");
+ String page = null;
+ int depth = 1;
+ for (int x = 0; x < params.length; x++) {
+ if ("page".equals(params[x])) {
+ page = params[x + 1];
+ x++;
+ } else if ("depth".equals(params[x])) {
+ depth = Integer.parseInt(params[x + 1]);
+ x++;
+ }
+ }
+ childrenOf.put(page, depth);
+ } else {
+ childrenOf.put(title, 1);
+ }
+ idx = c.indexOf("{children", idx);
+ }
+
+ idx = c.indexOf("{include:");
+ while (idx != -1) {
+ int idx2 = c.indexOf("}", idx);
+ String inc = c.substring(idx + 9, idx2);
+ if (includes == null) {
+ includes = new CopyOnWriteArraySet<String>();
+ }
+ includes.add(inc);
+ idx = c.indexOf("{include:", idx2);
+ }
+ idx = c.indexOf("{blog-posts");
+ if (idx != -1) {
+ hasBlog = true;
+ }
+ handleCode(c);
+ }
+
+ private void handleCode(String c) {
+ int idx = c.indexOf("{code");
+ while (idx != -1) {
+ String type = "java";
+ idx += 5;
+ if (c.charAt(idx) != '}') {
+ idx++;
+ int idx2 = c.indexOf('}', idx);
+ if (idx2 != -1) {
String paramString = c.substring(idx, idx2);
String params[] = paramString.split("\\||=");
- String page = null;
- int depth = 1;
for (int x = 0; x < params.length; x++) {
- if ("page".equals(params[x])) {
- page = params[x + 1];
- x++;
- } else if ("depth".equals(params[x])) {
- depth = Integer.parseInt(params[x + 1]);
+ if ("type".equalsIgnoreCase(params[x])) {
+ type = params[x + 1];
x++;
+ } else if (CODE_TYPE_MAP.containsKey(params[x].toLowerCase())) {
+ type = params[x];
}
}
- childrenOf.put(page, depth);
- } else {
- childrenOf.put(title, 1);
}
- idx = c.indexOf("{children", idx);
}
-
- idx = c.indexOf("{include:");
- while (idx != -1) {
- int idx2 = c.indexOf("}", idx);
- String inc = c.substring(idx + 9, idx2);
- if (includes == null) {
- includes = new CopyOnWriteArraySet<String>();
+
+ if (codeTypes == null) {
+ codeTypes = new CopyOnWriteArraySet<String>();
+ }
+ codeTypes.add(type);
+ idx = c.indexOf("{code", idx + 1);
+ }
+ idx = c.indexOf("{snippet");
+ while (idx != -1) {
+ String type = "java";
+ idx += 8;
+ if (c.charAt(idx) != '}') {
+ idx++;
+ int idx2 = c.indexOf('}', idx);
+ if (idx2 != -1) {
+ String paramString = c.substring(idx, idx2);
+ String params[] = paramString.split("\\||=");
+ for (int x = 0; x < params.length; x++) {
+ if ("lang".equalsIgnoreCase(params[x])) {
+ type = params[x + 1];
+ x++;
+ } else if (CODE_TYPE_MAP.containsKey(params[x].toLowerCase())) {
+ type = params[x];
+ }
+ }
}
- includes.add(inc);
- idx = c.indexOf("{include:", idx2);
}
- }
+
+ if (codeTypes == null) {
+ codeTypes = new CopyOnWriteArraySet<String>();
+ }
+ codeTypes.add(type);
+ idx = c.indexOf("{snippet", idx + 1);
+ }
}
public boolean hasChildrenOf(String t, int d) {
@@ -126,15 +311,11 @@ public class Page implements Serializabl
return includes.contains(s);
}
- public String getId() {
- return id;
- }
+
public String getParentId() {
return parent;
}
- public String getTitle() {
- return title;
- }
+
public XMLGregorianCalendar getModifiedTime() {
return modified;
}
@@ -142,33 +323,13 @@ public class Page implements Serializabl
public void setContent(String c) {
renderedContent = c;
}
+
public String getContent() {
return renderedContent;
}
- public String getURL() {
- return url;
- }
-
- public String createFileName() {
- StringBuffer buffer = new StringBuffer();
- char array[] = getTitle().toLowerCase().toCharArray();
- boolean separated = true;
- for (int x = 0; x < array.length; x++) {
- if ("abcdefghijklmnopqrstuvwxyz0123456789".indexOf(array[x]) >= 0) {
- buffer.append(Character.toLowerCase(array[x]));
- separated = false;
- } else if ("\r\n\t -".indexOf(array[x]) >= 0) {
- if (separated) {
- continue;
- }
- buffer.append('-');
- separated = true;
- }
- }
- if (buffer.length() == 0) {
- return getId() + ".html";
- }
- return buffer.append(".html").toString();
+
+ public String getSpaceKey() {
+ return spaceKey;
}
public void addAttachment(String aid, String filename) {
@@ -198,4 +359,257 @@ public class Page implements Serializabl
}
return null;
}
+
+ public String getLink() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<a href=\"");
+ buffer.append(url);
+ buffer.append("\" title=\"");
+ buffer.append(title);
+ buffer.append("\">");
+ buffer.append(title);
+ buffer.append("</a>");
+ return buffer.toString();
+ }
+
+ public Space getSpace() {
+ return SiteExporter.getSpace(spaceKey);
+ }
+
+ public boolean hasChildren() {
+ return exporter.hasChildren(this);
+ }
+
+ public List<Page> getChildren() {
+ return exporter.getChildren(this);
+ }
+
+ protected void setExporter(SiteExporter exporter) {
+ this.exporter = exporter;
+ }
+
+ protected SiteExporter getExporter() {
+ return exporter;
+ }
+
+ public boolean hasBlog() {
+ return hasBlog;
+ }
+
+ public boolean getHasCode() {
+ return hasCode();
+ }
+
+ public boolean hasCode() {
+ if (codeTypes != null && !codeTypes.isEmpty()) {
+ return true;
+ }
+ if (includes != null) {
+ for (String i : includes) {
+ try {
+ Page p = exporter.findPage(i);
+ if (p != null && p.hasCode()) {
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return false;
+ }
+
+ public Set<String> getCodeScripts() throws Exception {
+ Set<String> scripts = new HashSet<String>();
+ if (codeTypes != null) {
+ for (String s : codeTypes) {
+ String sc = CODE_TYPE_MAP.get(s);
+ if (sc == null) {
+ System.out.println("WARNING: no code highlighter for " + s);
+ } else {
+ scripts.add(sc);
+ }
+ }
+ }
+ if (scripts.isEmpty()) {
+ scripts.add(CODE_TYPE_MAP.get("java"));
+ scripts.add(CODE_TYPE_MAP.get("plain"));
+ }
+ if (includes != null) {
+ for (String i : includes) {
+ try {
+ Page p = exporter.findPage(i);
+ if (p != null && p.hasCode()) {
+ scripts.addAll(p.getCodeScripts());
+ } else if (p == null) {
+ System.out.println(" Did not find page " + i);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return scripts;
+ }
+
+
+ static class V2ContentHandler implements ContentHandler {
+ private final Page page;
+
+ enum State {
+ NONE,
+ CHILDREN,
+ INCLUDE,
+ BLOG_POSTS,
+ CODE,
+ };
+ private State state = State.NONE;
+ private Map<String, String> params = new HashMap<String, String>();
+ private String paramName;
+
+ V2ContentHandler(Page pg) {
+ page = pg;
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ }
+
+ public void startDocument() throws SAXException {
+ }
+
+ public void endDocument() throws SAXException {
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts)
+ throws SAXException {
+ if ("macro".equals(localName)) {
+ String s = atts.getValue(uri, "name");
+ if ("children".equals(s)) {
+ state = State.CHILDREN;
+ } else if ("include".equals(s)) {
+ state = State.INCLUDE;
+ } else if ("blog-posts".equals(s)) {
+ state = State.BLOG_POSTS;
+ } else if ("code".equals(s)) {
+ state = State.CODE;
+ } else if ("snippet".equals(s)) {
+ state = State.CODE;
+ } else if ("unmigrated-wiki-markup".equals(s)) {
+ System.out.println("WARNING: Page " + page.title + " has unmigrated wiki content.");
+ //no idea what is in there, lets just turn on the code highlighting
+ if (page.codeTypes == null) {
+ page.codeTypes = new CopyOnWriteArraySet<String>();
+ }
+ page.codeTypes.add("java");
+ page.codeTypes.add("xml");
+ page.codeTypes.add("plain");
+ } else {
+ //System.out.println("Unknown macro: " + s);
+ }
+ params.clear();
+ paramName = null;
+ } else if ("parameter".equals(localName)) {
+ paramName = atts.getValue(uri, "name");
+ } else if ("default-parameter".equals(localName)) {
+ paramName = "default-parameter";
+ }
+ }
+
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if ("macro".equals(localName)) {
+ switch (state) {
+ case CHILDREN: {
+ String pageName = params.get("page");
+ String depth = params.get("depth");
+ if (depth == null || "".equals(depth.trim())) {
+ depth = "1";
+ }
+ if (page.childrenOf == null) {
+ page.childrenOf = new HashMap<String, Integer>();
+ }
+ if (pageName == null) {
+ page.childrenOf.put(page.title, Integer.parseInt(depth));
+ } else {
+ page.childrenOf.put(pageName, Integer.parseInt(depth));
+ }
+ params.clear();
+ state = State.NONE;
+ break;
+ }
+ case INCLUDE: {
+ if (page.includes == null) {
+ page.includes = new CopyOnWriteArraySet<String>();
+ }
+ String inc = params.get("default-parameter");
+ if (inc == null) {
+ inc = params.get("title");
+ }
+ if (inc == null) {
+ System.out.println(page.title + ": Did not find an include name " + params);
+ } else {
+ page.includes.add(inc);
+ }
+ break;
+ }
+ case BLOG_POSTS:
+ page.hasBlog = true;
+ break;
+ case CODE: {
+ if (page.codeTypes == null) {
+ page.codeTypes = new CopyOnWriteArraySet<String>();
+ }
+ String lang = null;
+ for (Map.Entry<String, String> ent : params.entrySet()) {
+ if ("language".equals(ent.getKey())) {
+ lang = ent.getValue();
+ } else if (ent.getKey().contains(":")) {
+ String parts[] = ent.getKey().split(":");
+ for (String s : parts) {
+ if (("title".equals(s) && !params.containsKey("title"))
+ || (!params.containsKey("language")
+ && ("xml".equals(s) || "java".equals(s)))) {
+ System.out.println("WARNING Page " + page.title + " has a broken code block");
+ }
+ }
+ }
+ }
+ if (StringUtils.isEmpty(lang)) {
+ lang = "java";
+ }
+ page.codeTypes.add(lang);
+ break;
+ }
+ default:
+ state = State.NONE;
+ break;
+ }
+ } else if ("parameter".equals(localName)) {
+ paramName = null;
+ } else if ("default-parameter".equals(localName)) {
+ paramName = null;
+ }
+ }
+
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (paramName != null) {
+ params.put(paramName, new String(ch, start, length));
+ }
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ }
+
+ public void processingInstruction(String target, String data) throws SAXException {
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ }
+ }
+
}
Added: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java?rev=1525452&view=auto
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java (added)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java Sun Sep 22 21:33:09 2013
@@ -0,0 +1,63 @@
+/**
+ * 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.cxf.cwiki;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class PageManager {
+
+ private SiteExporter exporter;
+ private String dir;
+ private Map<String, Page> pages = new HashMap<String, Page>();
+
+ public PageManager(SiteExporter exporter) {
+ this.exporter = exporter;
+ }
+
+ public void setDirectory(String d) {
+ this.dir = d;
+ }
+
+ public Page getPage(String spaceKey, String title) throws Exception {
+ // XXX: spaceKey must match exporter.getSpace().getKey()
+
+ // lookup cached page
+ Page cachedPage = pages.get(title);
+ if (cachedPage == null) {
+ // lookup real page
+ Page page = exporter.findPage(title);
+ if (page != null) {
+ cachedPage = new Page(page);
+ cachedPage.directory = dir;
+ exporter.loadPageContent(cachedPage, null, null);
+ pages.put(title, cachedPage);
+ } else {
+ System.err.println("Page not found: " + title);
+ }
+ }
+
+ return cachedPage;
+ }
+
+}
Propchange: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/PageManager.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java?rev=1525452&view=auto
==============================================================================
--- tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java (added)
+++ tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java Sun Sep 22 21:33:09 2013
@@ -0,0 +1,52 @@
+/**
+ * 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.cxf.cwiki;
+
+/**
+ *
+ */
+public class Renderer {
+
+ protected SiteExporter exporter;
+
+ public Renderer(SiteExporter exporter) {
+ this.exporter = exporter;
+ }
+
+ public String convertWikiToXHtml(Object context, String content) {
+ if (content != null) {
+ int start = 0;
+ if (content.startsWith("<div")) {
+ int pos = content.indexOf(">", 1);
+ if (pos != -1) {
+ start = pos + 1;
+ }
+ }
+ int end = content.length();
+ if (content.endsWith("</div>")) {
+ end -= "</div>".length();
+ }
+ content = content.substring(start, end);
+ }
+
+ return content;
+ }
+
+}
Propchange: tapestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki/Renderer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain