You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2005/02/16 18:21:26 UTC

svn commit: r154052 - in lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms: ant/LinkRewriteTask.java publication/util/ publication/util/LinkRewriter.java

Author: andreas
Date: Wed Feb 16 09:21:24 2005
New Revision: 154052

URL: http://svn.apache.org/viewcvs?view=rev&rev=154052
Log:
link rewriting: use document builder to match rewritable URLs

Added:
    lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/
    lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/LinkRewriter.java
Modified:
    lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/ant/LinkRewriteTask.java

Modified: lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/ant/LinkRewriteTask.java
URL: http://svn.apache.org/viewcvs/lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/ant/LinkRewriteTask.java?view=diff&r1=154051&r2=154052
==============================================================================
--- lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/ant/LinkRewriteTask.java (original)
+++ lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/ant/LinkRewriteTask.java Wed Feb 16 09:21:24 2005
@@ -19,27 +19,11 @@
 
 package org.apache.lenya.cms.ant;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.avalon.excalibur.io.FileUtil;
+import org.apache.lenya.cms.publication.Document;
 import org.apache.lenya.cms.publication.DocumentBuilder;
-import org.apache.lenya.cms.publication.DocumentBuildException;
 import org.apache.lenya.cms.publication.Publication;
-import org.apache.lenya.xml.DocumentHelper;
+import org.apache.lenya.cms.publication.util.LinkRewriter;
 import org.apache.tools.ant.BuildException;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
 
 /**
  * This task is used to rewrite internal links after a cut'n'paste operation, i.e.
@@ -49,28 +33,6 @@
  */
 public class LinkRewriteTask extends PublicationTask {
 
-    private static final class XMLFilenameFilter implements FilenameFilter {
-        /**
-         * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
-         */
-        public boolean accept(File dir, String name) {
-            File _file = new File(dir, name);
-            return _file.isFile() && FileUtil.getExtension(name).equals("xml");
-        }
-    }
-
-    private static final class DirectoryFilter implements FilenameFilter {
-        /**
-         * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
-         */
-        public boolean accept(File dir, String name) {
-            File _file = new File(dir, name);
-            return _file.isDirectory();
-        }
-    }
-
-    private String baseDir;
-    private String stylesheet;
     private String area;
     private String oldDocumentId;
     private String newDocumentId;
@@ -124,19 +86,10 @@
     }
 
     /**
-     * Get the stylesheet.
-     * @return the stylesheet
-     */
-    public String getStylesheet() {
-        return this.stylesheet;
-    }
-
-    /**
      * Set the stylesheet.
      * @param _stylesheet the stylesheet that transforms the links
      */
     public void setStylesheet(String _stylesheet) {
-        this.stylesheet = _stylesheet;
     }
 
     /**
@@ -144,142 +97,30 @@
      * @param _baseDir the base dir
      */
     public void setBaseDir(String _baseDir) {
-        this.baseDir = _baseDir;
-    }
-
-    /**
-     * Get the base dir.
-     * @return the base dir
-     */
-    private String getBaseDir() {
-        return this.baseDir;
     }
 
     /**
      * @see org.apache.tools.ant.Task#execute()
      */
     public void execute() throws BuildException {
-        log("baseDir: " + getBaseDir());
-        log("stylesheet: " + getStylesheet());
         try {
-            replace(
-                getBaseDir(),
-                getStylesheet(),
-                getArea(),
-                getOldDocumentId(),
-                getNewDocumentId());
+            
+            Publication pub = getPublication();
+            DocumentBuilder builder = pub.getDocumentBuilder();
+            
+            String oldTargetUrl = builder.buildCanonicalUrl(pub, getArea(), getOldDocumentId());
+            Document oldTargetDocument = builder.buildDocument(pub, oldTargetUrl);
+            
+            String newTargetUrl = builder.buildCanonicalUrl(pub, getArea(), getNewDocumentId());
+            Document newTargetDocument = builder.buildDocument(pub, newTargetUrl);
+            
+            LinkRewriter rewriter = new LinkRewriter();
+            rewriter.rewriteLinks(oldTargetDocument, newTargetDocument);
+            
         } catch (Exception e) {
             throw new BuildException(e);
         }
 
     }
 
-    /**
-     * Rewrites links
-     * @param file The starting point for the link rewrite
-     * @param transformer The transformer to use for the link rewrite
-     * @throws TransformerException
-     * @throws ParserConfigurationException
-     * @throws SAXException
-     * @throws IOException
-     */
-    private void replace_internal(File file, Transformer transformer)
-        throws TransformerException, ParserConfigurationException, SAXException, IOException {
-
-        FilenameFilter directoryFilter = new DirectoryFilter();
-
-        FilenameFilter xmlFileFilter = new XMLFilenameFilter();
-
-        log("root file: " + file.getCanonicalPath());
-        assert(file.isDirectory());
-
-        File[] children = file.listFiles(directoryFilter);
-        for (int i = 0; i < children.length; i++) {
-            replace_internal(children[i], transformer);
-        }
-        File[] xmlFiles = file.listFiles(xmlFileFilter);
-
-        javax.xml.parsers.DocumentBuilder documentBuilder = DocumentHelper.createBuilder();
-
-        for (int i = 0; i < xmlFiles.length; i++) {
-            File tmpFile = File.createTempFile("linkRewrite", "tmp");
-            FileOutputStream os = new FileOutputStream(tmpFile);
-            log("transform " + xmlFiles[i].getCanonicalPath());
-
-            Document document = documentBuilder.parse(xmlFiles[i]);
-            DOMSource domSource = new DOMSource(document);
-            
-			StreamResult result = new StreamResult(os);
-            transformer.transform(domSource, result);
-            result.getOutputStream().close();
-
-            if (!tmpFile.renameTo(xmlFiles[i])) {
-			  FileUtil.copyFile(tmpFile, xmlFiles[i]);
-			  FileUtil.forceDelete(tmpFile);
-            }
-        }
-    }
-
-    /**
-     * Rewrites links by traversing a directory tree and applying a rewrite transformation
-     * to XML files in the directory.
-     * @param rootDirName The root directory for the rewrite
-     * @param _stylesheet The stylesheet to use for rewriting
-     * @param _area The area to use for rewriting
-     * @param _oldDocumentId The old document id
-     * @param _newDocumentId The new document id
-     * 
-     * @throws TransformerException
-     * @throws ParserConfigurationException
-     * @throws SAXException
-     * @throws IOException
-     */
-    private void replace(
-        String rootDirName,
-        String _stylesheet,
-        String _area,
-        String _oldDocumentId,
-        String _newDocumentId)
-        throws TransformerException, ParserConfigurationException, SAXException, IOException {
-
-        File rootDir = new File(rootDirName);
-        TransformerFactory tFactory = TransformerFactory.newInstance();
-
-        Transformer transformer = tFactory.newTransformer(new StreamSource(_stylesheet));
-
-        Publication publication = getPublication();
-        DocumentBuilder builder = publication.getDocumentBuilder();
-
-        // replace all internal links
-        String oldURL =
-            getContextPrefix() + builder.buildCanonicalUrl(publication, _area, _oldDocumentId);
-        String newURL =
-            getContextPrefix() + builder.buildCanonicalUrl(publication, _area, _newDocumentId);
-
-        log("Replace '" + oldURL + "' by '" + newURL + "'");
-        transformer.setParameter("urlbefore", oldURL);
-        transformer.setParameter("urlafter", newURL);
-
-        replace_internal(rootDir, transformer);
-
-        // now also do the replacement for all language versions
-        String[] languages = publication.getLanguages();
-        for (int i = 0; i < languages.length; i++) {
-            String language = languages[i];
-
-            oldURL =
-                getContextPrefix()
-                    + builder.buildCanonicalUrl(publication, _area, _oldDocumentId, language);
-            newURL =
-                getContextPrefix()
-                    + builder.buildCanonicalUrl(publication, _area, _newDocumentId, language);
-
-            log("Replace '" + oldURL + "' by '" + newURL + "'");
-            transformer.setParameter("urlbefore", oldURL);
-            transformer.setParameter("urlafter", newURL);
-            transformer.setParameter("language", language);
-
-            replace_internal(rootDir, transformer);
-        }
-    }
 }

Added: lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/LinkRewriter.java
URL: http://svn.apache.org/viewcvs/lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/LinkRewriter.java?view=auto&rev=154052
==============================================================================
--- lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/LinkRewriter.java (added)
+++ lenya/branches/BRANCH_1_2_X/src/java/org/apache/lenya/cms/publication/util/LinkRewriter.java Wed Feb 16 09:21:24 2005
@@ -0,0 +1,187 @@
+/*
+ * Copyright  1999-2004 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.
+ *
+ */
+package org.apache.lenya.cms.publication.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.avalon.excalibur.io.FileUtil;
+import org.apache.lenya.cms.publication.Document;
+import org.apache.lenya.cms.publication.DocumentBuilder;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.xml.DocumentHelper;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Rewrite the links in a publication. This is used after renaming / moving a
+ * document.
+ * 
+ * @version $Id:$
+ */
+public class LinkRewriter {
+
+    private FileFilter directoryFilter = new FileFilter() {
+
+        public boolean accept(File file) {
+            return file.isDirectory();
+        }
+    };
+
+    private FileFilter xmlFileFilter = new FileFilter() {
+
+        public boolean accept(File file) {
+            return file.isFile() && FileUtil.getExtension(file.getName()).equals("xml");
+        }
+    };
+
+    /**
+     * Ctor.
+     */
+    public LinkRewriter() {
+    }
+
+    /**
+     * Rewrites the links to a document and all its descendants, including all
+     * language versions.
+     * @param originalTargetDocument The original target document.
+     * @param newTargetDocument The new target document.
+     */
+    public void rewriteLinks(Document originalTargetDocument, Document newTargetDocument) {
+
+        Publication publication = originalTargetDocument.getPublication();
+        String area = originalTargetDocument.getArea();
+        File[] files = getDocumentFiles(publication, area);
+
+        DocumentBuilder builder = publication.getDocumentBuilder();
+
+        try {
+            for (int fileIndex = 0; fileIndex < files.length; fileIndex++) {
+                org.w3c.dom.Document xmlDocument = DocumentHelper.readDocument(files[fileIndex]);
+                boolean linksRewritten = false;
+                
+                String[] xPaths = publication.getRewriteAttributeXPaths();
+                for (int xPathIndex = 0; xPathIndex < xPaths.length; xPathIndex++) {
+                    NodeList nodes = XPathAPI.selectNodeList(xmlDocument, xPaths[xPathIndex]);
+                    for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
+                        Node node = nodes.item(nodeIndex);
+                        if (node.getNodeType() != Node.ATTRIBUTE_NODE) {
+                            throw new RuntimeException("The XPath [" + xPaths[xPathIndex]
+                                    + "] may only match attribute nodes!");
+                        }
+                        Attr attribute = (Attr) node;
+                        String url = attribute.getValue();
+                        if (builder.isDocument(publication, url)) {
+                            Document targetDocument = builder.buildDocument(publication, url);
+
+                            if (matches(targetDocument, originalTargetDocument)) {
+                                String newTargetUrl = getNewTargetURL(targetDocument,
+                                        originalTargetDocument,
+                                        newTargetDocument);
+                                attribute.setValue(newTargetUrl);
+                                linksRewritten = true;
+                            }
+                        }
+                    }
+                }
+                
+                if (linksRewritten) {
+                    DocumentHelper.writeDocument(xmlDocument, files[fileIndex]);
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Checks if targetDocument refers to originalTargetDocument, to one of its
+     * language versions, to one of its descendants, or to a language version of
+     * one of the descendants.
+     * @param targetDocument The target document.
+     * @param originalTargetDocument The original target document.
+     * @return A boolean value.
+     */
+    protected boolean matches(Document targetDocument, Document originalTargetDocument) {
+        String matchString = originalTargetDocument.getId() + "/";
+        String testString = targetDocument.getId() + "/";
+        return testString.startsWith(matchString);
+    }
+
+    /**
+     * Rewrites a document.
+     * @param targetDocument The target document to rewrite.
+     * @param originalTargetDocument The original target document.
+     * @param newTargetDocument The new target document.
+     * @return A string.
+     */
+    protected String getNewTargetURL(Document targetDocument, Document originalTargetDocument,
+            Document newTargetDocument) {
+        String originalId = originalTargetDocument.getId();
+        String targetId = targetDocument.getId();
+        String childString = targetId.substring(originalId.length());
+
+        DocumentBuilder builder = targetDocument.getPublication().getDocumentBuilder();
+        String newTargetUrl = builder.buildCanonicalUrl(newTargetDocument.getPublication(),
+                newTargetDocument.getArea(),
+                newTargetDocument.getId() + childString,
+                targetDocument.getLanguage());
+
+        return newTargetUrl;
+    }
+
+    /**
+     * Returns all XML files in a specific area.
+     * @param publication The publication.
+     * @param area The area.
+     * @return An array of files.
+     */
+    protected File[] getDocumentFiles(Publication publication, String area) {
+        File directory = publication.getContentDirectory(area);
+        List files = getDocumentFiles(directory);
+        return (File[]) files.toArray(new File[files.size()]);
+    }
+
+    /**
+     * Returns all XML files in a specific directory.
+     * @param directory The directory.
+     * @return A list of files.
+     */
+    protected List getDocumentFiles(File directory) {
+
+        List list = new ArrayList();
+
+        File[] directories = directory.listFiles(directoryFilter);
+        for (int i = 0; i < directories.length; i++) {
+            list.addAll(getDocumentFiles(directories[i]));
+        }
+        File[] xmlFiles = directory.listFiles(xmlFileFilter);
+        list.addAll(Arrays.asList(xmlFiles));
+        return list;
+    }
+
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org