KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > cms > publication > util > LinkRewriter


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.lenya.cms.publication.util;
18
19 import java.io.File JavaDoc;
20 import java.io.FileFilter JavaDoc;
21 import java.io.FilenameFilter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.List JavaDoc;
26
27 import javax.xml.parsers.ParserConfigurationException JavaDoc;
28
29 import org.apache.avalon.excalibur.io.FileUtil;
30 import org.apache.lenya.cms.publication.Document;
31 import org.apache.lenya.cms.publication.DocumentBuilder;
32 import org.apache.lenya.cms.publication.Publication;
33 import org.apache.lenya.xml.DocumentHelper;
34 import org.apache.xpath.XPathAPI;
35 import org.w3c.dom.Attr JavaDoc;
36 import org.w3c.dom.Node JavaDoc;
37 import org.w3c.dom.NodeList JavaDoc;
38 import org.xml.sax.SAXException JavaDoc;
39
40 /**
41  * Rewrite the links in a publication. This is used after renaming / moving a
42  * document.
43  *
44  * @version $Id:$
45  */

46 public class LinkRewriter {
47
48     private FileFilter JavaDoc directoryFilter = new FileFilter JavaDoc() {
49
50         public boolean accept(File JavaDoc file) {
51             return file.isDirectory();
52         }
53     };
54
55     private FileFilter JavaDoc xmlFileFilter = new FileFilter JavaDoc() {
56
57         public boolean accept(File JavaDoc file) {
58             return file.isFile() && FileUtil.getExtension(file.getName()).equals("xml");
59         }
60     };
61
62     /**
63      * Ctor.
64      */

65     public LinkRewriter() {
66     }
67
68     /**
69      * Rewrites the links to a document and all its descendants, including all
70      * language versions.
71      * @param originalTargetDocument The original target document.
72      * @param newTargetDocument The new target document.
73      * @param contextPath The servlet context path.
74      */

75     public void rewriteLinks(Document originalTargetDocument, Document newTargetDocument,
76             String JavaDoc contextPath) {
77
78         Publication publication = originalTargetDocument.getPublication();
79         String JavaDoc area = originalTargetDocument.getArea();
80         File JavaDoc[] files = getDocumentFiles(publication, area);
81
82         DocumentBuilder builder = publication.getDocumentBuilder();
83
84         try {
85             for (int fileIndex = 0; fileIndex < files.length; fileIndex++) {
86                 org.w3c.dom.Document JavaDoc xmlDocument = DocumentHelper.readDocument(files[fileIndex]);
87                 boolean linksRewritten = false;
88
89                 String JavaDoc[] xPaths = publication.getRewriteAttributeXPaths();
90                 for (int xPathIndex = 0; xPathIndex < xPaths.length; xPathIndex++) {
91                     NodeList JavaDoc nodes = XPathAPI.selectNodeList(xmlDocument, xPaths[xPathIndex]);
92                     for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
93                         Node JavaDoc node = nodes.item(nodeIndex);
94                         if (node.getNodeType() != Node.ATTRIBUTE_NODE) {
95                             throw new RuntimeException JavaDoc("The XPath [" + xPaths[xPathIndex]
96                                     + "] may only match attribute nodes!");
97                         }
98                         Attr JavaDoc attribute = (Attr JavaDoc) node;
99                         final String JavaDoc url = attribute.getValue();
100
101                         if (url.startsWith(contextPath + "/" + publication.getId())) {
102                             final String JavaDoc webappUrl = url.substring(contextPath.length());
103                             
104                             if (builder.isDocument(publication, webappUrl)) {
105                                 Document targetDocument = builder.buildDocument(publication, webappUrl);
106
107                                 if (matches(targetDocument, originalTargetDocument)) {
108                                     String JavaDoc newTargetUrl = getNewTargetURL(targetDocument,
109                                             originalTargetDocument,
110                                             newTargetDocument);
111                                     attribute.setValue(contextPath + newTargetUrl);
112                                     linksRewritten = true;
113                                 }
114                             }
115                         }
116                     }
117                 }
118
119                 if (linksRewritten) {
120                     DocumentHelper.writeDocument(xmlDocument, files[fileIndex]);
121                 }
122             }
123         } catch (Exception JavaDoc e) {
124             throw new RuntimeException JavaDoc(e);
125         }
126     }
127
128     /**
129      * Checks if targetDocument refers to originalTargetDocument, to one of its
130      * language versions, to one of its descendants, or to a language version of
131      * one of the descendants.
132      * @param targetDocument The target document.
133      * @param originalTargetDocument The original target document.
134      * @return A boolean value.
135      */

136     protected boolean matches(Document targetDocument, Document originalTargetDocument) {
137         String JavaDoc matchString = originalTargetDocument.getId() + "/";
138         String JavaDoc testString = targetDocument.getId() + "/";
139         return testString.startsWith(matchString);
140     }
141
142     /**
143      * Rewrites a document.
144      * @param targetDocument The target document to rewrite.
145      * @param originalTargetDocument The original target document.
146      * @param newTargetDocument The new target document.
147      * @return A string.
148      */

149     protected String JavaDoc getNewTargetURL(Document targetDocument, Document originalTargetDocument,
150             Document newTargetDocument) {
151         String JavaDoc originalId = originalTargetDocument.getId();
152         String JavaDoc targetId = targetDocument.getId();
153         String JavaDoc childString = targetId.substring(originalId.length());
154
155         DocumentBuilder builder = targetDocument.getPublication().getDocumentBuilder();
156         String JavaDoc newTargetUrl = builder.buildCanonicalUrl(newTargetDocument.getPublication(),
157                 newTargetDocument.getArea(),
158                 newTargetDocument.getId() + childString,
159                 targetDocument.getLanguage());
160
161         return newTargetUrl;
162     }
163
164     /**
165      * Returns all XML files in a specific area.
166      * @param publication The publication.
167      * @param area The area.
168      * @return An array of files.
169      */

170     protected File JavaDoc[] getDocumentFiles(Publication publication, String JavaDoc area) {
171         File JavaDoc directory = publication.getContentDirectory(area);
172         List JavaDoc files = getDocumentFiles(directory);
173         return (File JavaDoc[]) files.toArray(new File JavaDoc[files.size()]);
174     }
175
176     /**
177      * Returns all XML files in a specific directory.
178      * @param directory The directory.
179      * @return A list of files.
180      */

181     protected List JavaDoc getDocumentFiles(File JavaDoc directory) {
182
183         List JavaDoc list = new ArrayList JavaDoc();
184
185         File JavaDoc[] directories = directory.listFiles(directoryFilter);
186         for (int i = 0; i < directories.length; i++) {
187             list.addAll(getDocumentFiles(directories[i]));
188         }
189         File JavaDoc[] xmlFiles = directory.listFiles(xmlFileFilter);
190         list.addAll(Arrays.asList(xmlFiles));
191         return list;
192     }
193
194 }
Popular Tags