Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B2C509C46 for ; Tue, 6 Mar 2012 20:42:21 +0000 (UTC) Received: (qmail 49458 invoked by uid 500); 6 Mar 2012 20:42:21 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 49414 invoked by uid 500); 6 Mar 2012 20:42:21 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 49407 invoked by uid 99); 6 Mar 2012 20:42:21 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Mar 2012 20:42:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Mar 2012 20:42:19 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 2FAB52388980; Tue, 6 Mar 2012 20:41:59 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1297701 - in /cxf/web: bin/update-site pom.xml src/main/java/org/apache/cxf/cwiki/Page.java src/main/java/org/apache/cxf/cwiki/SiteExporter.java template/docs.cfg template/main.cfg Date: Tue, 06 Mar 2012 20:41:58 -0000 To: commits@cxf.apache.org From: dkulp@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120306204159.2FAB52388980@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dkulp Date: Tue Mar 6 20:41:58 2012 New Revision: 1297701 URL: http://svn.apache.org/viewvc?rev=1297701&view=rev Log: Bunch of updates to make the site generation faster and better: 1) Multithread when doing multiple spaces (CXF + CXF20DOC) 2) Only get the banner/navigation/quicklinks once 3) Handle {children} tags so an added or delete page will automatically update pages that use the {children} tag for contents 4) Experimental support for {include:Page}. Will flush out when I start working on Camel's site. Added: cxf/web/template/docs.cfg cxf/web/template/main.cfg Modified: cxf/web/bin/update-site cxf/web/pom.xml cxf/web/src/main/java/org/apache/cxf/cwiki/Page.java cxf/web/src/main/java/org/apache/cxf/cwiki/SiteExporter.java Modified: cxf/web/bin/update-site URL: http://svn.apache.org/viewvc/cxf/web/bin/update-site?rev=1297701&r1=1297700&r2=1297701&view=diff ============================================================================== --- cxf/web/bin/update-site (original) +++ cxf/web/bin/update-site Tue Mar 6 20:41:58 2012 @@ -1,6 +1,4 @@ #!/bin/sh -mvn -Pconfluence,main,nochecks package exec:java $@ -[ $? -eq 0 ] || exit -1 -mvn -Pconfluence,docs,nochecks exec:java $@ +mvn -Pconfluence,nochecks -e package exec:java $@ [ $? -eq 0 ] || exit -1 Modified: cxf/web/pom.xml URL: http://svn.apache.org/viewvc/cxf/web/pom.xml?rev=1297701&r1=1297700&r2=1297701&view=diff ============================================================================== --- cxf/web/pom.xml (original) +++ cxf/web/pom.xml Tue Mar 6 20:41:58 2012 @@ -37,6 +37,7 @@ ${basedir}/content + true @@ -57,7 +58,7 @@ org.ccil.cowan.tagsoup tagsoup - 1.2 + 1.2.1 @@ -79,14 +80,8 @@ org.apache.cxf.cwiki.SiteExporter - -cache - ${cache.file} -d - ${output.dir} - -space - ${space.key} - -template - ${basedir}/template/template.vm + ${site.output} -password ${confluence.password} -user @@ -95,6 +90,8 @@ ${svn.arg1} ${svn.arg2} + ${basedir}/template/main.cfg + ${basedir}/template/docs.cfg @@ -111,21 +108,5 @@ -commit - - docs - - ${site.output}/cache/docs.pageCache - ${site.output}/docs - CXF20DOC - - - - main - - ${site.output}/cache/main.pageCache - ${site.output}/ - CXF - - Modified: cxf/web/src/main/java/org/apache/cxf/cwiki/Page.java URL: http://svn.apache.org/viewvc/cxf/web/src/main/java/org/apache/cxf/cwiki/Page.java?rev=1297701&r1=1297700&r2=1297701&view=diff ============================================================================== --- cxf/web/src/main/java/org/apache/cxf/cwiki/Page.java (original) +++ cxf/web/src/main/java/org/apache/cxf/cwiki/Page.java Tue Mar 6 20:41:58 2012 @@ -23,6 +23,8 @@ package org.apache.cxf.cwiki; import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; @@ -43,9 +45,13 @@ public class Page implements Serializabl final String title; final String url; Map attachments; + Set includes; + Map childrenOf; - transient String content; - + transient String renderedContent; + transient String renderedDivContent; + transient String divIdForContent; + public Page(Document doc) throws Exception { //org.apache.cxf.helpers.XMLUtils.printDOM(doc.getDocumentElement()); id = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "id"); @@ -54,6 +60,68 @@ public class Page implements Serializabl url = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "url"); String mod = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "modified"); modified = DatatypeFactory.newInstance().newXMLGregorianCalendar(mod); + + String c = DOMUtils.getChildContent(doc.getDocumentElement().getFirstChild(), "content"); + if (c != null) { + int idx = c.indexOf("{children"); + while (idx != -1) { + if (childrenOf == null) { + childrenOf = new HashMap(); + } + 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(); + } + includes.add(inc); + idx = c.indexOf("{include:", idx2); + } + } + } + + public boolean hasChildrenOf(String t, int d) { + if (childrenOf == null) { + return false; + } + Integer i = childrenOf.get(t); + if (i == null) { + return false; + } + return d <= i; + } + + public boolean includesPage(String s) { + if (includes == null) { + return false; + } + return includes.contains(s); } public String getId() { @@ -70,10 +138,10 @@ public class Page implements Serializabl } public void setContent(String c) { - content = c; + renderedContent = c; } public String getContent() { - return content; + return renderedContent; } public String getURL() { return url; @@ -113,4 +181,19 @@ public class Page implements Serializabl } return attachments.get(aid); } + + public void setContentForDivId(String divId, String content) { + renderedDivContent = content; + divIdForContent = divId; + } + + public String getContentForDivId(String divId) { + if (divId == null) { + return renderedContent; + } + if (divId.equals(divIdForContent)) { + return renderedDivContent; + } + return null; + } } Modified: cxf/web/src/main/java/org/apache/cxf/cwiki/SiteExporter.java URL: http://svn.apache.org/viewvc/cxf/web/src/main/java/org/apache/cxf/cwiki/SiteExporter.java?rev=1297701&r1=1297700&r2=1297701&view=diff ============================================================================== --- cxf/web/src/main/java/org/apache/cxf/cwiki/SiteExporter.java (original) +++ cxf/web/src/main/java/org/apache/cxf/cwiki/SiteExporter.java Tue Mar 6 20:41:58 2012 @@ -76,75 +76,65 @@ import org.ccil.cowan.tagsoup.XMLWriter; /** * */ -public class SiteExporter { +public class SiteExporter implements Runnable { static final String HOST = "https://cwiki.apache.org"; static final String ROOT = HOST + "/confluence"; static final String RPC_ROOT = "/rpc/soap-axis/confluenceservice-v1"; - - static final String SOAPNS = "http://soap.rpc.confluence.atlassian.com"; - static final Set GLOBAL_PAGES = new HashSet(); - static { - GLOBAL_PAGES.add("Navigation"); - GLOBAL_PAGES.add("Banner"); - GLOBAL_PAGES.add("QuickLinks"); - } + static boolean debug; + static String userName = "cxf-export-user"; + static String password; + + static boolean svn; + static boolean commit; + static StringBuilder svnCommitMessage = new StringBuilder(); + + static File rootOutputDir = new File("."); + static String loginToken; + static Dispatch dispatch; - Dispatch dispatch; Map pages = new HashMap(); List modifiedPages = new LinkedList(); - - String userName = "cxf-export-user"; - String password; + Set globalPages = new HashSet(); + String spaceKey = "CXF"; String pageCacheFile = "pagesConfig.obj"; - String templateName = "template.vm"; + String templateName = "template/template.vm"; boolean forceAll; - boolean svn; - boolean commit; - StringBuilder svnCommitMessage = new StringBuilder(); - File outputDir = new File("."); + File outputDir = rootOutputDir; - String loginToken; Template template; - boolean debug; - public SiteExporter(List args) throws Exception { + public SiteExporter(String fileName, boolean force) throws Exception { + forceAll = force; - + Properties props = new Properties(); + props.load(new FileInputStream(fileName)); - ListIterator it = args.listIterator(); - while (it.hasNext()) { - String s = it.next(); - if ("-debug".equals(s)) { - debug = true; - } else if ("-d".equals(s)) { - outputDir = new File(it.next()); - } else if ("-user".equals(s)) { - userName = it.next(); - } else if ("-password".equals(s)) { - password = it.next(); - } else if ("-space".equals(s)) { - spaceKey = it.next(); - } else if ("-cache".equals(s)) { - pageCacheFile = it.next(); - } else if ("-force".equals(s)) { - forceAll = true; - } else if ("-template".equals(s)) { - templateName = it.next(); - } else if ("-svn".equals(s)) { - svn = true; - } else if ("-commit".equals(s)) { - commit = true; - } + if (props.containsKey("spaceKey")) { + spaceKey = props.getProperty("spaceKey"); + } + if (props.containsKey("pageCacheFile")) { + pageCacheFile = props.getProperty("pageCacheFile"); + } + if (props.containsKey("templateName")) { + templateName = props.getProperty("templateName"); + } + if (props.containsKey("outputDir")) { + outputDir = new File(rootOutputDir, props.getProperty("outputDir")); + } + if (props.containsKey("globalPages")) { + String globals = props.getProperty("globalPages"); + String[] pgs = globals.split(","); + globalPages.addAll(Arrays.asList(pgs)); } - Properties props = new Properties(); + props = new Properties(); String clzName = URLResourceLoader.class.getName(); props.put("resource.loader", "url"); props.put("url.resource.loader.class", clzName); @@ -162,7 +152,7 @@ public class SiteExporter { outputDir.mkdirs(); } - public Dispatch getDispatch() { + public static synchronized Dispatch getDispatch() { if (dispatch == null) { Service service = Service.create(new QName(SOAPNS, "Service")); service.addPort(new QName(SOAPNS, "Port"), @@ -181,14 +171,34 @@ public class SiteExporter { return dispatch; } - public void run() throws Exception { - loadPagesCache(); + public void run() { + try { + doExport(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void forcePage(String s) throws Exception { + Page p = findPage(s); + if (p != null) { + pages.remove(p.getId()); + modifiedPages.add(p); + } + } + + public void doExport() throws Exception { + if (!forceAll) { + loadPagesCache(); + } // debug stuff, force regen of a page - //modifiedPages.add(findPage("Navigation")); - //modifiedPages.add(findPage("FAQ")); + //forcePage("Navigation"); + //forcePage("Index"); + //forcePage("Custom Transport"); if (modifiedPages.isEmpty() && checkRSS()) { + System.out.println("(" + spaceKey + ") No changes detected from RSS"); return; } @@ -196,7 +206,7 @@ public class SiteExporter { loadPages(); for (Page p : modifiedPages) { - if (GLOBAL_PAGES.contains(p.getTitle())) { + if (globalPages.contains(p.getTitle())) { modifiedPages = new LinkedList(pages.values()); break; } @@ -211,13 +221,7 @@ public class SiteExporter { savePages(); } - if (commit) { - File file = FileUtils.createTempFile("svncommit", "txt"); - FileWriter writer = new FileWriter(file); - writer.write(svnCommitMessage.toString()); - writer.close(); - callSvn("commit", "-F", file.getAbsolutePath(), outputDir.getAbsolutePath()); - } + } @@ -248,11 +252,11 @@ public class SiteExporter { if (p != null) { //found a modified page - need to rebuild if (cal.compare(p.getModifiedTime()) > 0) { - System.out.println("Changed page found: " + title); + System.out.println("(" + spaceKey + ") Changed page found: " + title); return false; } } else { - System.out.println("Did not find page for: " + title); + System.out.println("(" + spaceKey + ") Did not find page for: " + title); return false; } } @@ -261,7 +265,7 @@ public class SiteExporter { } private void savePages() throws Exception { - File file = new File(pageCacheFile); + File file = new File(rootOutputDir, pageCacheFile); file.getParentFile().mkdirs(); FileOutputStream fout = new FileOutputStream(file); ObjectOutputStream oout = new ObjectOutputStream(fout); @@ -274,10 +278,11 @@ public class SiteExporter { int count = 0; for (Page p : modifiedPages) { count++; - System.out.println("Rendering " + p.getTitle() + " (" + count + "/" + total + ")"); + System.out.println("(" + spaceKey + ") Rendering " + p.getTitle() + + " (" + count + "/" + total + ")"); loadAttachments(p); - loadPageContent(p); + loadPageContent(p, null); VelocityContext ctx = new VelocityContext(); ctx.put("exporter", this); ctx.put("page", p); @@ -299,15 +304,17 @@ public class SiteExporter { } } } - - private void callSvn(String ... commands) throws Exception { + void callSvn(String ... commands) throws Exception { + callSvn(outputDir, commands); + } + static void callSvn(File dir, String ... commands) throws Exception { if (svn) { List cmds = new ArrayList(); cmds.add("svn"); cmds.add("--non-interactive"); cmds.addAll(Arrays.asList(commands)); Process p = Runtime.getRuntime().exec(cmds.toArray(new String[cmds.size()]), - new String[0], outputDir); + new String[0], dir); if (p.waitFor() != 0) { IOUtils.copy(p.getErrorStream(), System.err); } @@ -438,22 +445,23 @@ public class SiteExporter { return buffer.toString(); } - public String getPageContent(String title, String id) throws Exception { + public String getPageContent(String title, String divId) throws Exception { Page p = findPage(title); - return loadPageContent(p, id); + String s = p.getContentForDivId(divId); + if (s == null) { + s = loadPageContent(p, divId); + } + return s; } public String getPageContent(String title) throws Exception { Page p = findPage(title); String s = p.getContent(); if (s == null) { - loadPageContent(p); + loadPageContent(p, null); } return p.getContent(); } - private void loadPageContent(Page p) throws Exception { - loadPageContent(p, null); - } - private String loadPageContent(Page p, String id) throws Exception { + private String loadPageContent(Page p, String divId) throws Exception { Document doc = XMLUtils.newDocument(); Element el = doc.createElementNS(SOAPNS, "ns1:renderContent"); Element el2 = doc.createElement("in0"); @@ -488,43 +496,47 @@ public class SiteExporter { doc = getDispatch().invoke(doc); String content = doc.getDocumentElement().getFirstChild().getTextContent().trim(); - content = updateContentLinks(p, content, id); - if (id == null) { + content = updateContentLinks(p, content, divId); + if (divId == null) { p.setContent(content); + } else { + p.setContentForDivId(divId, content); } return content; } - private void doLogin() throws Exception { - Document doc = XMLUtils.newDocument(); - Element el = doc.createElementNS(SOAPNS, "ns1:login"); - Element el2 = doc.createElement("in0"); - - if (userName == null) { - System.out.println("Enter username: "); - el2.setTextContent(System.console().readLine()); - } else { - el2.setTextContent(userName); - } - el.appendChild(el2); - el2 = doc.createElement("in1"); - el.appendChild(el2); - if (password == null) { - System.out.println("Enter password: "); - el2.setTextContent(new String(System.console().readPassword())); - } else { - el2.setTextContent(password); + private static synchronized void doLogin() throws Exception { + if (loginToken == null) { + Document doc = XMLUtils.newDocument(); + Element el = doc.createElementNS(SOAPNS, "ns1:login"); + Element el2 = doc.createElement("in0"); + + if (userName == null) { + System.out.println("Enter username: "); + el2.setTextContent(System.console().readLine()); + } else { + el2.setTextContent(userName); + } + el.appendChild(el2); + el2 = doc.createElement("in1"); + el.appendChild(el2); + if (password == null) { + System.out.println("Enter password: "); + el2.setTextContent(new String(System.console().readPassword())); + } else { + el2.setTextContent(password); + } + doc.appendChild(el); + doc = getDispatch().invoke(doc); + loginToken = doc.getDocumentElement().getFirstChild().getTextContent(); } - doc.appendChild(el); - doc = getDispatch().invoke(doc); - loginToken = doc.getDocumentElement().getFirstChild().getTextContent(); } public void loadPagesCache() throws Exception { - File file = new File(pageCacheFile); + File file = new File(rootOutputDir, pageCacheFile); if (file.exists()) { - FileInputStream fin = new FileInputStream(pageCacheFile); + FileInputStream fin = new FileInputStream(file); ObjectInputStream oin = new ObjectInputStream(fin); pages = CastUtils.cast((Map)oin.readObject()); oin.close(); @@ -543,19 +555,24 @@ public class SiteExporter { doc = getDispatch().invoke(doc); Set allPages = new HashSet(pages.keySet()); + Set newPages = new HashSet(); //XMLUtils.printDOM(doc.getDocumentElement()); Node nd = doc.getDocumentElement().getFirstChild().getFirstChild(); while (nd != null) { if (nd instanceof Element) { - loadPage((Element)nd, allPages); + loadPage((Element)nd, allPages, newPages); } nd = nd.getNextSibling(); } - + for (Page p : newPages) { + //pages have been added, need to check + checkForChildren(p); + } for (String id : allPages) { //these pages have been deleted Page p = pages.remove(id); + checkForChildren(p); File file = new File(outputDir, p.createFileName()); if (file.exists()) { @@ -566,8 +583,49 @@ public class SiteExporter { file.delete(); } } + while (checkIncludes()) { + // nothing + } + + } + + public boolean checkIncludes() { + for (Page p : modifiedPages) { + if (checkIncludes(p)) { + return true; + } + } + return false; + } + + public boolean checkIncludes(Page p) { + for (Page p2 : pages.values()) { + if (p2.includesPage(p.getTitle()) + && !modifiedPages.contains(p2)) { + modifiedPages.add(p2); + return true; + } + } + return false; + } + public void checkForChildren(Page p) { + Page parent = pages.get(p.getParentId()); + int d = 1; + while (parent != null) { + for (Page p2 : pages.values()) { + if (p2.hasChildrenOf(parent.getTitle(), d) + && !modifiedPages.contains(p2)) { + modifiedPages.add(p2); + } + } + parent = pages.get(parent.getParentId()); + d++; + } } - public void loadPage(Element pageSumEl, Set allPages) throws Exception { + + public void loadPage(Element pageSumEl, + Set allPages, + Set newPages) throws Exception { Document doc = XMLUtils.newDocument(); Element el = doc.createElementNS(SOAPNS, "ns1:getPage"); Element el2 = doc.createElement("in0"); @@ -580,10 +638,13 @@ public class SiteExporter { doc = getDispatch().invoke(doc); Page page = new Page(doc); - Page oldPage = pages.get(page.getId()); + Page oldPage = pages.put(page.getId(), page); if (oldPage == null || page.getModifiedTime().compare(oldPage.getModifiedTime()) > 0) { modifiedPages.add(page); - pages.put(page.getId(), page); + if (oldPage == null) { + //need to check parents to see if it has a {children} tag so we can re-render + newPages.add(page); + } } if (allPages.contains(page.getId())) { allPages.remove(page.getId()); @@ -621,8 +682,47 @@ public class SiteExporter { } public static void main(String[] args) throws Exception { - new SiteExporter(Arrays.asList(args)).run(); + ListIterator it = Arrays.asList(args).listIterator(); + List files = new ArrayList(); + boolean forceAll = false; + while (it.hasNext()) { + String s = it.next(); + if ("-debug".equals(s)) { + debug = true; + } else if ("-user".equals(s)) { + userName = it.next(); + } else if ("-password".equals(s)) { + password = it.next(); + } else if ("-d".equals(s)) { + rootOutputDir = new File(it.next()); + } else if ("-force".equals(s)) { + forceAll = true; + } else if ("-svn".equals(s)) { + svn = true; + } else if ("-commit".equals(s)) { + commit = true; + } else if (s != null && s.length() > 0) { + files.add(s); + } + } + + List threads = new ArrayList(files.size()); + for (String file : files) { + Thread t = new Thread(new SiteExporter(file, forceAll)); + threads.add(t); + t.start(); + } + for (Thread t : threads) { + t.join(); + } + + if (commit) { + File file = FileUtils.createTempFile("svncommit", "txt"); + FileWriter writer = new FileWriter(file); + writer.write(svnCommitMessage.toString()); + writer.close(); + callSvn(rootOutputDir, "commit", "-F", file.getAbsolutePath(), rootOutputDir.getAbsolutePath()); + svnCommitMessage.setLength(0); + } } - - } Added: cxf/web/template/docs.cfg URL: http://svn.apache.org/viewvc/cxf/web/template/docs.cfg?rev=1297701&view=auto ============================================================================== --- cxf/web/template/docs.cfg (added) +++ cxf/web/template/docs.cfg Tue Mar 6 20:41:58 2012 @@ -0,0 +1,6 @@ +spaceKey: CXF20DOC +pageCacheFile:/cache/docs.pageCache +templateName:template/template.vm +outputDir:/docs +globalPages:Navigation,Banner,QuickLinks + Added: cxf/web/template/main.cfg URL: http://svn.apache.org/viewvc/cxf/web/template/main.cfg?rev=1297701&view=auto ============================================================================== --- cxf/web/template/main.cfg (added) +++ cxf/web/template/main.cfg Tue Mar 6 20:41:58 2012 @@ -0,0 +1,6 @@ +spaceKey: CXF +pageCacheFile:cache/main.pageCache +templateName:template/template.vm +outputDir:/ +globalPages:Navigation,Banner,QuickLinks +