KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > util > LinkUtil


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.util;
14
15 import info.magnolia.cms.beans.config.ContentRepository;
16 import info.magnolia.cms.core.Content;
17 import info.magnolia.cms.core.HierarchyManager;
18 import info.magnolia.cms.core.search.Query;
19 import info.magnolia.cms.core.search.QueryManager;
20 import info.magnolia.cms.core.search.QueryResult;
21
22 import java.util.Iterator JavaDoc;
23 import java.util.regex.Matcher JavaDoc;
24 import java.util.regex.Pattern JavaDoc;
25
26 import javax.jcr.RepositoryException;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33 /**
34  * Util to store links in a format so that one can make relative pathes on the public site. Later we will store the
35  * UUID, but in the current version the UUID is changeing during activation!
36  * <p>
37  * It stores the links in the following format: ${link:{uuid:{},path:{}}}. We store allready the UUID.
38  * @author philipp
39  * @version $Revision: 6889 $ ($Author: gjoseph $)
40  */

41 public final class LinkUtil {
42
43     /**
44      * The HierarchyManager to get the uuid
45      */

46     private static HierarchyManager hm = ContentRepository.getHierarchyManager(ContentRepository.WEBSITE);
47
48     /**
49      * Pattern to find a link
50      */

51     private static final Pattern JavaDoc linkPattern = Pattern.compile("(<a[^>]+href[ ]*=[ ]*\")(/[^\"]*).html((#[^\"]*)?\"[^>]*>)"); //$NON-NLS-1$
52

53     /**
54      * Pattern that matches external and mailto: links.
55      */

56     private static final Pattern JavaDoc externalLinkPattern = Pattern.compile("^(\\w*://|mailto:|javascript:).*");
57
58     /**
59      * Pattern to find a magnolia formatted link
60      */

61     private static Pattern JavaDoc uuidPattern = Pattern.compile("\\$\\{link:\\{uuid:\\{([^\\}]*)\\}," //$NON-NLS-1$
62
+ "repository:\\{[^\\}]*\\}," // has value website unless we support it //$NON-NLS-1$
63
+ "workspace:\\{[^\\}]*\\}," // has value default unless we support it //$NON-NLS-1$
64
+ "path:\\{([^\\}]*)\\}\\}\\}"); //$NON-NLS-1$
65

66     /**
67      * Logger.
68      */

69     private static Logger log = LoggerFactory.getLogger(LinkUtil.class);
70
71     /**
72      * Determines if the given link is internal and relative.
73      */

74     public static boolean isInternalRelativeLink(String JavaDoc href) {
75         // TODO : this could definitely be improved
76
return !externalLinkPattern.matcher(href).matches() && !href.startsWith("/") && !href.startsWith("#");
77     }
78
79     /**
80      * Transforms all the links to the magnolia format. Used during storing.
81      * @param str html
82      * @return html with changed hrefs
83      */

84     public static String JavaDoc convertAbsoluteLinksToUUIDs(String JavaDoc str) {
85         // get all link tags
86
Matcher JavaDoc matcher = linkPattern.matcher(str);
87         StringBuffer JavaDoc res = new StringBuffer JavaDoc();
88         while (matcher.find()) {
89             String JavaDoc path = matcher.group(2);
90             String JavaDoc uuid = makeUUIDFromAbsolutePath(path);
91             matcher.appendReplacement(res, "$1\\${link:{" //$NON-NLS-1$
92
+ "uuid:{" //$NON-NLS-1$
93
+ uuid
94                 + "}," //$NON-NLS-1$
95
+ "repository:{website}," //$NON-NLS-1$
96
+ "workspace:{default}," //$NON-NLS-1$
97
+ "path:{" //$NON-NLS-1$
98
+ path
99                 + "}}}$3"); //$NON-NLS-1$
100
}
101         matcher.appendTail(res);
102         return res.toString();
103     }
104
105     /**
106      * Convert the mangolia format to absolute (repository friendly) pathes
107      * @param str html
108      * @return html with absolute links
109      */

110     public static String JavaDoc convertUUIDsToAbsoluteLinks(String JavaDoc str) {
111         Matcher JavaDoc matcher = uuidPattern.matcher(str);
112         StringBuffer JavaDoc res = new StringBuffer JavaDoc();
113         while (matcher.find()) {
114             String JavaDoc absolutePath = null;
115             String JavaDoc uuid = matcher.group(1);
116
117             if (StringUtils.isNotEmpty(uuid)) {
118                 absolutePath = LinkUtil.makeAbsolutePathFromUUID(uuid);
119             }
120
121             // can't find the uuid
122
if (StringUtils.isEmpty(absolutePath)) {
123                 absolutePath = matcher.group(2);
124                 log.error(
125                     "Was not able to get the page by jcr:uuid nor by mgnl:uuid. Will use the saved path {}",
126                     absolutePath);
127             }
128             matcher.appendReplacement(res, absolutePath + ".html"); //$NON-NLS-1$
129
}
130         matcher.appendTail(res);
131         return res.toString();
132     }
133
134     /**
135      * Transforms stored magnolia style links to relative links. This is used to display them in the browser
136      * @param str html
137      * @param page the links are relative to this page
138      * @return html with proper links
139      */

140     public static String JavaDoc convertUUIDsToRelativeLinks(String JavaDoc str, Content page) {
141         Matcher JavaDoc matcher = uuidPattern.matcher(str);
142         StringBuffer JavaDoc res = new StringBuffer JavaDoc();
143         while (matcher.find()) {
144             String JavaDoc absolutePath = null;
145             String JavaDoc uuid = matcher.group(1);
146
147             if (StringUtils.isNotEmpty(uuid)) {
148                 absolutePath = LinkUtil.makeAbsolutePathFromUUID(uuid);
149             }
150
151             // can't find the uuid
152
if (StringUtils.isEmpty(absolutePath)) {
153                 absolutePath = matcher.group(2);
154                 log.warn(
155                     "Was not able to get the page by jcr:uuid nor by mgnl:uuid. Will use the saved path {}",
156                     absolutePath);
157             }
158
159             // to relative path
160
String JavaDoc relativePath = makeRelativePath(absolutePath, page);
161             matcher.appendReplacement(res, relativePath);
162         }
163         matcher.appendTail(res);
164         return res.toString();
165     }
166
167     /**
168      * Transforms a uuid to a absolute path beginning with a /. This path is used to get the page from the repository.
169      * The editor needs this kind of links
170      * @param uuid uuid
171      * @return path
172      */

173     public static String JavaDoc makeAbsolutePathFromUUID(String JavaDoc uuid) {
174         Content content = null;
175
176         // first use the jcr:uuid (since 2.2)
177
try {
178             content = hm.getContentByUUID(uuid);
179         }
180
181         // then the old mgnl:uuid
182
// TODO remove this in later versions
183
catch (Exception JavaDoc e) {
184             log.info("Was not able to get the page by the jcr:uuid. will try the old mgnl:uuid");
185
186             QueryManager qmanager = hm.getQueryManager();
187
188             if (qmanager != null) {
189                 // this uses magnolia uuid
190
content = getContentByMgnlUUID(qmanager, uuid);
191             }
192             else {
193                 log.info(
194                     "SearchManager not configured for website repositoy, unable to generate absolute path for UUID {}",
195                     uuid);
196             }
197         }
198
199         if (content != null) {
200             return content.getHandle();
201         }
202         return null;
203     }
204
205     /**
206      * Make a absolute path relative. It adds ../ until the root is reached
207      * @param absolutePath absolute path
208      * @param page page to be relative to
209      * @return relative path
210      */

211     public static String JavaDoc makeRelativePath(String JavaDoc absolutePath, Content page) {
212         StringBuffer JavaDoc relativePath = new StringBuffer JavaDoc();
213         int level;
214         try {
215             level = page.getLevel();
216         }
217         catch (RepositoryException e) {
218             level = 0;
219         }
220
221         for (int i = 1; i < level; i++) {
222             relativePath.append("../"); //$NON-NLS-1$
223
}
224
225         if (absolutePath.startsWith("/")) {
226             relativePath.append(StringUtils.substringAfter(absolutePath, "/"));
227         }
228         else {
229             relativePath.append(absolutePath);
230         }
231
232         relativePath.append(".html"); //$NON-NLS-1$
233

234         return relativePath.toString();
235     }
236
237     /**
238      * Convert a path to a uuid
239      * @param path path to the page
240      * @return the uuid if found
241      */

242     public static String JavaDoc makeUUIDFromAbsolutePath(String JavaDoc path) {
243         try {
244             return hm.getContent(path).getUUID();
245         }
246         catch (RepositoryException e) {
247             return path;
248         }
249     }
250
251     /**
252      * Util has no public constructor
253      */

254     private LinkUtil() {
255     }
256
257     /**
258      * Used for old content
259      * @param queryManager
260      * @param uuid
261      * @return
262      * @deprecated
263      */

264     private static Content getContentByMgnlUUID(QueryManager queryManager, String JavaDoc uuid) {
265         try {
266             String JavaDoc statement = "SELECT * FROM nt:base where mgnl:uuid like '" + uuid + "'"; //$NON-NLS-1$ //$NON-NLS-2$
267
Query q = queryManager.createQuery(statement, Query.SQL);
268             QueryResult result = q.execute();
269             Iterator JavaDoc it = result.getContent().iterator();
270             while (it.hasNext()) {
271                 Content foundObject = (Content) it.next();
272                 return foundObject;
273             }
274         }
275         catch (RepositoryException e) {
276             log.error("Exception caught", e);
277         }
278         return null;
279     }
280
281 }
Popular Tags