View Javadoc

1   /**
2    * This file Copyright (c) 2003-2011 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.link;
35  
36  import info.magnolia.cms.beans.config.ContentRepository;
37  import info.magnolia.cms.beans.config.ServerConfiguration;
38  import info.magnolia.cms.beans.config.URI2RepositoryManager;
39  import info.magnolia.cms.beans.runtime.File;
40  import info.magnolia.cms.core.Content;
41  import info.magnolia.cms.core.HierarchyManager;
42  import info.magnolia.cms.core.NodeData;
43  import info.magnolia.cms.i18n.I18nContentSupportFactory;
44  import info.magnolia.context.MgnlContext;
45  
46  import java.util.regex.Matcher;
47  import java.util.regex.Pattern;
48  
49  import javax.jcr.PropertyType;
50  import javax.jcr.RepositoryException;
51  
52  import org.apache.commons.lang.StringUtils;
53  import org.slf4j.Logger;
54  import org.slf4j.LoggerFactory;
55  
56  /**
57   * Deprecated.
58   * @deprecated since 4.0 use {@link info.magnolia.link.Link} instead
59   */
60  public class UUIDLink {
61  
62      private String repository;
63      private String handle;
64      private String uuid;
65      private String nodeDataName;
66      private String extension;
67      private Content node;
68      private NodeData nodeData;
69      private String fileName;
70      private String fallbackHandle;
71      private String anchor;
72      private String parameters;
73  
74      /**
75       * Pattern to find a magnolia formatted link.
76       */
77      public static Pattern UUID_PATTERN = Pattern.compile("\\$\\{link:\\{uuid:\\{([^\\}]*)\\}," // the
78                                                                                                 // uuid
79                                                                                                 // of
80                                                                                                 // the
81                                                                                                 // node
82              + "repository:\\{([^\\}]*)\\}," + "(workspace:\\{[^\\}]*\\},)?" // is
83                                                                              // not
84                                                                              // supported
85                                                                              // anymore
86              + "(path|handle):\\{([^\\}]*)\\}" // fallback handle should not be
87                                                // used unless the uuid is invalid
88              + "(,nodeData:\\{([^\\}]*)\\}," // in case we point to a binary
89                                              // (node data has no uuid!)
90              + "extension:\\{([^\\}]*)\\})?" // the extension to be used in
91                                              // rendering
92              + "\\}\\}" // the handle
93              + "(#([^\\?\"]*))?" // anchor
94              + "(\\?([^\"]*))?"); // parameters
95  
96      protected static final Pattern LINK_PATTERN = Pattern.compile("(/[^\\.\"#\\?]*)" + // the
97                                                                                         // handle
98              "(\\.([\\w[^#\\?]]+))?" + // extension (if any)
99              "(#([^\\?\"]*))?" + // anchor
100             "(\\?([^\"]*))?" // parameters
101     );
102 
103     /**
104      * Logger.
105      */
106     private static Logger log = LoggerFactory.getLogger(UUIDLink.class);
107 
108     /**
109      * Use parseUUIDLink() or parseLink() to initialize the link object.
110      */
111     public UUIDLink() {
112     }
113 
114     public UUIDLink parseUUIDLink(String uuidLink) throws UUIDLinkException {
115         Matcher matcher = UUID_PATTERN.matcher(uuidLink);
116         if (matcher.matches()) {
117             initByUUIDPatternMatcher(matcher);
118         } else {
119             throw new UUIDLinkException("can't parse [ " + uuidLink + "]");
120         }
121         return this;
122     }
123 
124     UUIDLink initByUUIDPatternMatcher(Matcher matcher) {
125         uuid = matcher.group(1);
126         repository = StringUtils.defaultIfEmpty(matcher.group(2), ContentRepository.WEBSITE);
127         fallbackHandle = matcher.group(5);
128         nodeDataName = matcher.group(7);
129         extension = matcher.group(8);
130         anchor = matcher.group(10);
131         parameters = matcher.group(12);
132         return this;
133     }
134 
135     public UUIDLink parseLink(String link) throws UUIDLinkException {
136         // ignore context handle if existing
137         link = StringUtils.removeStart(link, MgnlContext.getContextPath());
138 
139         Matcher matcher = LINK_PATTERN.matcher(link);
140         if (matcher.matches()) {
141             String orgHandle = matcher.group(1);
142             orgHandle = I18nContentSupportFactory.getI18nSupport().toRawURI(orgHandle);
143             String repository = URI2RepositoryManager.getInstance().getRepository(orgHandle);
144             String handle = URI2RepositoryManager.getInstance().getHandle(orgHandle);
145             init(repository, handle, matcher.group(3), matcher.group(5), matcher.group(7));
146         } else {
147             throw new UUIDLinkException("can't parse [ " + link + "]");
148         }
149         return this;
150     }
151 
152     public UUIDLink initWithHandle(String repository, String handle) throws UUIDLinkException {
153         init(repository, handle, null, null, null);
154         return this;
155     }
156 
157     protected void init(String repository, String path, String extension, String anchor, String parameters) throws UUIDLinkException {
158         this.repository = repository;
159         this.extension = extension;
160         this.anchor = anchor;
161         this.parameters = parameters;
162 
163         try {
164             HierarchyManager hm = MgnlContext.getHierarchyManager(repository);
165             if (hm.isExist(path) && !hm.isNodeData(path)) {
166                 node = hm.getContent(path);
167             }
168             if (node == null) {
169                 // this is a binary containing the name at the end this name is stored as an attribute but is not part of the handle
170                 if (hm.isNodeData(StringUtils.substringBeforeLast(path, "/"))) {
171                     fileName = StringUtils.substringAfterLast(path, "/");
172                     path = StringUtils.substringBeforeLast(path, "/");
173                 }
174 
175                 // link to the binary node data
176                 if (hm.isNodeData(path)) {
177                     nodeDataName = StringUtils.substringAfterLast(path, "/");
178                     path = StringUtils.substringBeforeLast(path, "/");
179                     node = hm.getContent(path);
180                     nodeData = node.getNodeData(nodeDataName);
181                 }
182             }
183             if (node != null) {
184                 uuid = node.getUUID();
185             }
186             this.handle = path;
187         } catch (RepositoryException e) {
188             throw new UUIDLinkException("can't find node " + path + " in repository " + repository, e);
189         }
190 
191         if (node == null) {
192             throw new UUIDLinkException("can't find node " + path + " in repository " + repository);
193         }
194     }
195 
196     public String toPattern() {
197         return "${link:{" + "uuid:{" + getUUID() + "}," + "repository:{" + getRepository() + "}," + "handle:{" + getHandle() + "}," // original handle represented by the uuid
198                 + "nodeData:{" + StringUtils.defaultString(getNodeDataName()) + "}," // in case of binaries
199                 + "extension:{" + StringUtils.defaultString(getExtension()) + "}" // the extension to use if no extension can be resolved otherwise
200                 + "}}" + (StringUtils.isNotEmpty(getAnchor()) ? "#" + getAnchor() : "") + (StringUtils.isNotEmpty(getParameters()) ? "?" + getParameters() : "");
201     }
202 
203     public String getExtension() {
204         if (StringUtils.isEmpty(this.extension) && this.getNodeData() != null) {
205             if (this.getNodeData().getType() == PropertyType.BINARY) {
206                 File binary = new File(nodeData);
207                 extension = binary.getExtension();
208             }
209         }
210         return StringUtils.defaultIfEmpty(this.extension, ServerConfiguration.getInstance().getDefaultExtension());
211     }
212 
213     public void setExtension(String extension) {
214         this.extension = extension;
215     }
216 
217     public String getFileName() {
218         if (StringUtils.isEmpty(this.fileName) && this.getNodeData() != null) {
219             if (this.getNodeData().getType() == PropertyType.BINARY) {
220                 File binary = new File(nodeData);
221                 fileName = binary.getFileName();
222             }
223         }
224         return fileName;
225     }
226 
227     public void setFileName(String fileName) {
228         this.fileName = fileName;
229     }
230 
231     public Content getNode() {
232 
233         if (this.node == null) {
234             HierarchyManager hm = MgnlContext.getHierarchyManager(repository);
235             if (StringUtils.isNotEmpty(uuid)) {
236                 try {
237                     node = hm.getContentByUUID(uuid);
238                 } catch (RepositoryException e) {
239                     log.warn("can't get node with uuid [{}] will try stored handle [{}]", new String[] { uuid, handle });
240                 }
241             }
242 
243             // uuid is not defined or resolving by uuid failed
244             if (this.node == null && StringUtils.isNotEmpty(handle)) {
245                 try {
246                     node = hm.getContent(handle);
247                 } catch (RepositoryException e1) {
248                     log.warn("can't read node by using handle [{}]", handle);
249                 }
250             }
251         }
252         return this.node;
253     }
254 
255     public void setNode(Content node) {
256         this.node = node;
257     }
258 
259     public NodeData getNodeData() {
260         if (this.nodeData == null && StringUtils.isNotEmpty(this.nodeDataName) && this.getNode() != null) {
261             this.nodeData = this.getNode().getNodeData(this.nodeDataName);
262         }
263         return this.nodeData;
264     }
265 
266     public void setNodeData(NodeData nodeData) {
267         this.nodeData = nodeData;
268     }
269 
270     public String getNodeDataName() {
271         return this.nodeDataName;
272     }
273 
274     public void setNodeDataName(String nodeDataName) {
275         this.nodeDataName = nodeDataName;
276     }
277 
278     public String getHandle() {
279         if (StringUtils.isEmpty(this.handle)) {
280             if (getNode() != null) {
281                 handle = getNode().getHandle();
282             } else {
283                 handle = this.getFallbackHandle();
284             }
285         }
286         return this.handle;
287     }
288 
289     public void setHandle(String path) {
290         this.handle = path;
291     }
292 
293     public String getRepository() {
294         return this.repository;
295     }
296 
297     public void setRepository(String repository) {
298         this.repository = repository;
299     }
300 
301     public String getUUID() {
302         if (StringUtils.isEmpty(this.uuid) && this.getNode() != null) {
303             this.uuid = this.getNode().getUUID();
304         }
305         return this.uuid;
306     }
307 
308     public void setUUID(String uuid) {
309         this.uuid = uuid;
310     }
311 
312     public String getFallbackHandle() {
313         return this.fallbackHandle;
314     }
315 
316     public void setFallbackHandle(String fallbackPath) {
317         this.fallbackHandle = fallbackPath;
318     }
319 
320     public String getAnchor() {
321         return this.anchor;
322     }
323 
324     public void setAnchor(String anchor) {
325         this.anchor = anchor;
326     }
327 
328     public String getParameters() {
329         return this.parameters;
330     }
331 
332     public void setParameters(String parameters) {
333         this.parameters = parameters;
334     }
335 }