1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.link;
35
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38
39 import javax.jcr.RepositoryException;
40 import javax.jcr.PathNotFoundException;
41
42 import org.apache.commons.lang.StringUtils;
43
44 import info.magnolia.cms.beans.config.URI2RepositoryManager;
45 import info.magnolia.cms.core.Content;
46 import info.magnolia.cms.core.HierarchyManager;
47 import info.magnolia.cms.core.NodeData;
48 import info.magnolia.cms.i18n.I18nContentSupportFactory;
49 import info.magnolia.context.MgnlContext;
50 import info.magnolia.repository.RepositoryConstants;
51
52
53
54
55
56
57
58
59 public class LinkFactory {
60 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LinkFactory.class);
61
62
63
64
65
66
67 public static Link createLink(Content node) {
68 return new Link(node);
69 }
70
71
72
73
74
75
76 public static Link createLink(NodeData nodeData) throws LinkException {
77 try {
78 return new Link(nodeData.getParent().getWorkspace().getName(), nodeData.getParent(), nodeData);
79 } catch (RepositoryException e) {
80 throw new LinkException("can't find node " + nodeData , e);
81 }
82 }
83
84
85
86
87
88
89
90 public static Link createLink(String repository, String uuid) throws LinkException {
91 try {
92 return new Link(MgnlContext.getHierarchyManager(repository).getContentByUUID(uuid));
93 } catch (RepositoryException e) {
94 throw new LinkException("can't get node with uuid " + uuid + " and repository " + repository);
95 }
96 }
97
98
99
100
101
102
103
104
105
106
107
108 public static Link createLink(String repository, String path, String extension, String anchor, String parameters) throws LinkException {
109 Content node = null;
110 String fileName = null;
111 String nodeDataName = null;
112 NodeData nodeData = null;
113 try {
114 HierarchyManager hm = MgnlContext.getHierarchyManager(repository);
115 boolean exists = false;
116 try {
117
118
119 Class parser = Class.forName("org.apache.jackrabbit.spi.commons.conversion.PathParser");
120 parser.getMethod("checkFormat", new Class[] {String.class}).invoke(null, new Object[] {path});
121 } catch (Exception e) {
122 if ("org.apache.jackrabbit.spi.commons.conversion.MalformedPathException".equals(e.getClass().getName())) {
123
124 exists = false;
125 } else {
126
127 }
128 }
129 exists = hm.isExist(path) && !hm.isNodeData(path);
130 if (exists) {
131 node = hm.getContent(path);
132 }
133 if (node == null) {
134
135
136 if (hm.isNodeData(StringUtils.substringBeforeLast(path, "/"))) {
137 fileName = StringUtils.substringAfterLast(path, "/");
138 path = StringUtils.substringBeforeLast(path, "/");
139 }
140
141
142 if (hm.isNodeData(path)) {
143 nodeDataName = StringUtils.substringAfterLast(path, "/");
144 path = StringUtils.substringBeforeLast(path, "/");
145 node = hm.getContent(path);
146 nodeData = node.getNodeData(nodeDataName);
147 }
148 }
149 if (node == null) {
150 throw new LinkException("can't find node " + path + " in repository " + repository);
151 }
152 } catch (RepositoryException e) {
153 throw new LinkException("can't get node with path " + path + " from repository " + repository);
154 }
155
156 Link link = new Link(node);
157 link.setAnchor(anchor);
158 link.setExtension(extension);
159 link.setParameters(parameters);
160 link.setFileName(fileName);
161 link.setNodeDataName(nodeDataName);
162 link.setNodeData(nodeData);
163 link.setHandle(path);
164 return link;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 public static Link createLink(String uuid, String repository, String fallbackHandle, String nodeDataName, String extension, String anchor, String parameters) throws LinkException {
181 final String defaultRepository = StringUtils.defaultIfEmpty(repository, RepositoryConstants.WEBSITE);
182 Link link;
183 try {
184 link = createLink(defaultRepository, uuid);
185 } catch (LinkException e) {
186 try {
187 final Content node = MgnlContext.getHierarchyManager(defaultRepository).getContent(fallbackHandle != null? fallbackHandle:"");
188 link = createLink(node);
189 } catch (PathNotFoundException pnfe) {
190 log.warn("Can't find node with uuid {} or handle {} in repository {}", new Object[]{ uuid, fallbackHandle, defaultRepository});
191 link = new Link();
192 link.setUUID(uuid);
193 } catch (RepositoryException re) {
194 log.warn("Can't find node with uuid {} or handle {} in repository {}", new Object[]{ uuid, fallbackHandle, defaultRepository});
195 link = new Link();
196 link.setUUID(uuid);
197 }
198 }
199 link.setFallbackHandle(fallbackHandle);
200 link.setNodeDataName(nodeDataName);
201 link.setExtension(extension);
202 link.setAnchor(anchor);
203 link.setParameters(parameters);
204
205 return link;
206 }
207
208
209
210
211
212
213 public static Link parseUUIDLink(String uuidLink) throws LinkException{
214 Matcher matcher = LinkFactory.UUID_PATTERN.matcher(uuidLink);
215 if(matcher.matches()){
216 return createLink(matcher.group(1), matcher.group(2), matcher.group(5), matcher.group(7), matcher.group(8), matcher.group(10), matcher.group(12));
217 }
218 throw new LinkException("can't parse [ " + uuidLink + "]");
219 }
220
221
222
223
224
225
226 public static Link parseLink(String link) throws LinkException{
227
228 link = StringUtils.removeStart(link, MgnlContext.getContextPath());
229
230 Matcher matcher = LinkFactory.LINK_PATTERN.matcher(link);
231 if(matcher.matches()){
232 String orgHandle = matcher.group(1);
233 orgHandle = I18nContentSupportFactory.getI18nSupport().toRawURI(orgHandle);
234 String repository = URI2RepositoryManager.getInstance().getRepository(orgHandle);
235 String handle = URI2RepositoryManager.getInstance().getHandle(orgHandle);
236 return createLink(repository, handle, matcher.group(3),matcher.group(5),matcher.group(7));
237 }
238 throw new LinkException("can't parse [ " + link + "]");
239 }
240
241
242
243
244
245
246 public static String toPattern(Link link) {
247 return "${link:{"
248 + "uuid:{" + link.getUUID() + "},"
249 + "repository:{" + link.getRepository() + "},"
250 + "handle:{" + link.getHandle() + "},"
251 + "nodeData:{" + StringUtils.defaultString(link.getNodeDataName()) + "},"
252 + "extension:{" + StringUtils.defaultString(link.getExtension()) + "}"
253 + "}}"
254 + (StringUtils.isNotEmpty(link.getAnchor())? "#" + link.getAnchor():"")
255 + (StringUtils.isNotEmpty(link.getParameters())? "?" + link.getParameters() : "");
256 }
257
258
259
260
261 public static Pattern UUID_PATTERN = Pattern.compile(
262 "\\$\\{link:\\{uuid:\\{([^\\}]*)\\},"
263 + "repository:\\{([^\\}]*)\\},"
264 + "(workspace:\\{[^\\}]*\\},)?"
265 + "(path|handle):\\{([^\\}]*)\\}"
266 + "(,nodeData:\\{([^\\}]*)\\},"
267 + "extension:\\{([^\\}]*)\\})?"
268 + "\\}\\}"
269 + "(#([^\\?\"]*))?"
270 + "(\\?([^\"]*))?");
271
272
273
274
275
276 public static final Pattern LINK_PATTERN = Pattern.compile(
277 "(/[^\\.\"#\\?]*)" +
278 "(\\.([\\w[^#\\?]]+))?" +
279 "(#([^\\?\"]*))?" +
280 "(\\?([^\"]*))?"
281 );
282 }