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
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, ContentRepository.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 else{
219 throw new LinkException("can't parse [ " + uuidLink + "]");
220 }
221 }
222
223
224
225
226
227
228 public static Link parseLink(String link) throws LinkException{
229
230 link = StringUtils.removeStart(link, MgnlContext.getContextPath());
231
232 Matcher matcher = LinkFactory.LINK_PATTERN.matcher(link);
233 if(matcher.matches()){
234 String orgHandle = matcher.group(1);
235 orgHandle = I18nContentSupportFactory.getI18nSupport().toRawURI(orgHandle);
236 String repository = URI2RepositoryManager.getInstance().getRepository(orgHandle);
237 String handle = URI2RepositoryManager.getInstance().getHandle(orgHandle);
238 return createLink(repository, handle, matcher.group(3),matcher.group(5),matcher.group(7));
239 }
240 else{
241 throw new LinkException("can't parse [ " + link + "]");
242 }
243 }
244
245
246
247
248
249
250 public static String toPattern(Link link) {
251 return "${link:{"
252 + "uuid:{" + link.getUUID() + "},"
253 + "repository:{" + link.getRepository() + "},"
254 + "handle:{" + link.getHandle() + "},"
255 + "nodeData:{" + StringUtils.defaultString(link.getNodeDataName()) + "},"
256 + "extension:{" + StringUtils.defaultString(link.getExtension()) + "}"
257 + "}}"
258 + (StringUtils.isNotEmpty(link.getAnchor())? "#" + link.getAnchor():"")
259 + (StringUtils.isNotEmpty(link.getParameters())? "?" + link.getParameters() : "");
260 }
261
262
263
264
265 public static Pattern UUID_PATTERN = Pattern.compile(
266 "\\$\\{link:\\{uuid:\\{([^\\}]*)\\},"
267 + "repository:\\{([^\\}]*)\\},"
268 + "(workspace:\\{[^\\}]*\\},)?"
269 + "(path|handle):\\{([^\\}]*)\\}"
270 + "(,nodeData:\\{([^\\}]*)\\},"
271 + "extension:\\{([^\\}]*)\\})?"
272 + "\\}\\}"
273 + "(#([^\\?\"]*))?"
274 + "(\\?([^\"]*))?");
275
276
277
278
279
280 public static final Pattern LINK_PATTERN = Pattern.compile(
281 "(/[^\\.\"#\\?]*)" +
282 "(\\.([\\w[^#\\?]]+))?" +
283 "(#([^\\?\"]*))?" +
284 "(\\?([^\"]*))?"
285 );
286 }