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.ContentRepository;
45 import info.magnolia.cms.beans.config.URI2RepositoryManager;
46 import info.magnolia.cms.core.Content;
47 import info.magnolia.cms.core.HierarchyManager;
48 import info.magnolia.cms.core.NodeData;
49 import info.magnolia.cms.i18n.I18nContentSupportFactory;
50 import info.magnolia.context.MgnlContext;
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.getHierarchyManager().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 public static Link createLink(String uuid, String repository, String fallbackHandle, String nodeDataName, String extension, String anchor, String parameters) throws LinkException {
180 repository = StringUtils.defaultIfEmpty(repository, ContentRepository.WEBSITE);
181 Link link;
182 try {
183 link = createLink(repository, uuid);
184 } catch (LinkException e) {
185 try {
186 final Content node = MgnlContext.getHierarchyManager(repository).getContent(fallbackHandle);
187 link = createLink(node);
188 } catch (PathNotFoundException e1) {
189 log.warn("Can't find node with uuid " + uuid + " or handle " + fallbackHandle + " in repository " + repository);
190 link = new Link();
191 } catch (RepositoryException e1) {
192 throw new LinkException("Failed to create link with uuid " + uuid + " and repository " + repository + " and fallbackhandle " + fallbackHandle, e);
193 }
194 }
195 link.setFallbackHandle(fallbackHandle);
196 link.setNodeDataName(nodeDataName);
197 link.setExtension(extension);
198 link.setAnchor(anchor);
199 link.setParameters(parameters);
200
201 return link;
202 }
203
204
205
206
207
208
209 public static Link parseUUIDLink(String uuidLink) throws LinkException{
210 Matcher matcher = LinkFactory.UUID_PATTERN.matcher(uuidLink);
211 if(matcher.matches()){
212 return createLink(matcher.group(1), matcher.group(2), matcher.group(5), matcher.group(7), matcher.group(8), matcher.group(10), matcher.group(12));
213 }
214 else{
215 throw new LinkException("can't parse [ " + uuidLink + "]");
216 }
217 }
218
219
220
221
222
223
224 public static Link parseLink(String link) throws LinkException{
225
226 link = StringUtils.removeStart(link, MgnlContext.getContextPath());
227
228 Matcher matcher = LinkFactory.LINK_PATTERN.matcher(link);
229 if(matcher.matches()){
230 String orgHandle = matcher.group(1);
231 orgHandle = I18nContentSupportFactory.getI18nSupport().toRawURI(orgHandle);
232 String repository = URI2RepositoryManager.getInstance().getRepository(orgHandle);
233 String handle = URI2RepositoryManager.getInstance().getHandle(orgHandle);
234 return createLink(repository, handle, matcher.group(3),matcher.group(5),matcher.group(7));
235 }
236 else{
237 throw new LinkException("can't parse [ " + link + "]");
238 }
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 }