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.templating.functions;
35
36 import info.magnolia.cms.beans.config.ServerConfiguration;
37 import info.magnolia.cms.core.MgnlNodeType;
38 import info.magnolia.cms.core.NodeData;
39 import info.magnolia.cms.i18n.I18nContentSupportFactory;
40 import info.magnolia.cms.util.ContentUtil;
41 import info.magnolia.cms.util.SiblingsHelper;
42 import info.magnolia.context.MgnlContext;
43 import info.magnolia.exception.RuntimeRepositoryException;
44 import info.magnolia.jcr.util.ContentMap;
45 import info.magnolia.jcr.util.NodeUtil;
46 import info.magnolia.jcr.util.PropertyUtil;
47 import info.magnolia.jcr.util.SessionUtil;
48 import info.magnolia.jcr.wrapper.HTMLEscapingNodeWrapper;
49 import info.magnolia.jcr.wrapper.InheritanceNodeWrapper;
50 import info.magnolia.link.LinkUtil;
51 import info.magnolia.objectfactory.Components;
52 import info.magnolia.repository.RepositoryConstants;
53
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.List;
57
58 import javax.jcr.Node;
59 import javax.jcr.PathNotFoundException;
60 import javax.jcr.Property;
61 import javax.jcr.PropertyType;
62 import javax.jcr.RepositoryException;
63
64 import org.apache.commons.lang.StringUtils;
65
66
67
68
69
70
71 public class TemplatingFunctions {
72
73 public Node asJCRNode(ContentMap contentMap) {
74 return contentMap == null ? null : contentMap.getJCRNode();
75 }
76
77 public ContentMap asContentMap(Node content) {
78 return content == null ? null : new ContentMap(content);
79 }
80
81 public List<Node> children(Node content) throws RepositoryException {
82 return content == null ? null : asNodeList(NodeUtil.getNodes(content, NodeUtil.EXCLUDE_META_DATA_FILTER));
83 }
84
85 public List<Node> children(Node content, String nodeTypeName) throws RepositoryException {
86 return content == null ? null : asNodeList(NodeUtil.getNodes(content, nodeTypeName));
87 }
88
89 public List<ContentMap> children(ContentMap content) throws RepositoryException {
90 return content == null ? null : asContentMapList(NodeUtil.getNodes(asJCRNode(content), NodeUtil.EXCLUDE_META_DATA_FILTER));
91 }
92
93 public List<ContentMap> children(ContentMap content, String nodeTypeName) throws RepositoryException {
94 return content == null ? null : asContentMapList(NodeUtil.getNodes(asJCRNode(content), nodeTypeName));
95 }
96
97 public ContentMap root(ContentMap contentMap) throws RepositoryException {
98 return contentMap == null ? null : asContentMap(this.root(contentMap.getJCRNode()));
99 }
100
101 public ContentMap root(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
102 return contentMap == null ? null : asContentMap(this.root(contentMap.getJCRNode(), nodeTypeName));
103 }
104
105 public Node root(Node content) throws RepositoryException {
106 return this.root(content, null);
107 }
108
109 public Node root(Node content, String nodeTypeName) throws RepositoryException {
110 if (content == null) {
111 return null;
112 }
113 if (nodeTypeName == null) {
114 return (Node) content.getAncestor(0);
115 }
116 if (isRoot(content) && content.isNodeType(nodeTypeName)) {
117 return content;
118 }
119
120 Node parentNode = this.parent(content, nodeTypeName);
121 while (parent(parentNode, nodeTypeName) != null) {
122 parentNode = this.parent(parentNode, nodeTypeName);
123 }
124 return parentNode;
125 }
126
127 public ContentMap parent(ContentMap contentMap) throws RepositoryException {
128 return contentMap == null ? null : asContentMap(this.parent(contentMap.getJCRNode()));
129 }
130
131 public ContentMap parent(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
132 return contentMap == null ? null : asContentMap(this.parent(contentMap.getJCRNode(), nodeTypeName));
133 }
134
135 public Node parent(Node content) throws RepositoryException {
136 return this.parent(content, null);
137 }
138
139 public Node parent(Node content, String nodeTypeName) throws RepositoryException {
140 if (content == null) {
141 return null;
142 }
143 if (isRoot(content)) {
144 return null;
145 }
146 if (nodeTypeName == null) {
147 return content.getParent();
148 }
149 Node parent = content.getParent();
150 while (!parent.isNodeType(nodeTypeName)) {
151 if (isRoot(parent)) {
152 return null;
153 }
154 parent = parent.getParent();
155 }
156 return parent;
157 }
158
159
160
161
162
163
164
165
166
167 public ContentMap page(ContentMap content) throws RepositoryException {
168 return content == null ? null : asContentMap(page(content.getJCRNode()));
169 }
170
171
172
173
174
175
176
177
178
179 public Node page(Node content) throws RepositoryException {
180 if (content == null) {
181 return null;
182 }
183 if (content.isNodeType(MgnlNodeType.NT_PAGE)) {
184 return content;
185 }
186 return parent(content, MgnlNodeType.NT_PAGE);
187 }
188
189 public List<ContentMap> ancestors(ContentMap contentMap) throws RepositoryException {
190 return ancestors(contentMap, null);
191 }
192
193 public List<ContentMap> ancestors(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
194 List<Node> ancestorsAsNodes = this.ancestors(contentMap.getJCRNode(), nodeTypeName);
195 return asContentMapList(ancestorsAsNodes);
196 }
197
198 public List<Node> ancestors(Node content) throws RepositoryException {
199 return content == null ? null : this.ancestors(content, null);
200 }
201
202 public List<Node> ancestors(Node content, String nodeTypeName) throws RepositoryException {
203 if (content == null) {
204 return null;
205 }
206 List<Node> ancestors = new ArrayList<Node>();
207 int depth = content.getDepth();
208 for (int i = 1; i < depth; ++i) {
209 Node possibleAncestor = (Node) content.getAncestor(i);
210 if (nodeTypeName == null) {
211 ancestors.add(possibleAncestor);
212 } else {
213 if (possibleAncestor.isNodeType(nodeTypeName)) {
214 ancestors.add(possibleAncestor);
215 }
216 }
217 }
218 return ancestors;
219 }
220
221 public Node inherit(Node content) throws RepositoryException {
222 return inherit(content,null);
223 }
224
225 public Node inherit(Node content, String relPath) throws RepositoryException {
226 if (content == null) {
227 return null;
228 }
229 InheritanceNodeWrapper inheritedNode = new InheritanceNodeWrapper(content);
230
231 if (StringUtils.isBlank(relPath)) {
232 return inheritedNode;
233 }
234
235 try {
236 Node subNode = inheritedNode.getNode(relPath);
237 return NodeUtil.unwrap(subNode);
238 } catch (PathNotFoundException e) {
239
240 }
241 return null;
242 }
243
244 public ContentMap inherit(ContentMap content) throws RepositoryException {
245 return inherit(content, null);
246 }
247
248 public ContentMap inherit(ContentMap content, String relPath) throws RepositoryException {
249 if (content == null) {
250 return null;
251 }
252 Node node = inherit(content.getJCRNode(), relPath);
253 return node == null ? null : new ContentMap(node);
254 }
255
256
257 public Property inheritProperty(Node content, String relPath) throws RepositoryException {
258 if (content == null) {
259 return null;
260 }
261 if (StringUtils.isBlank(relPath)) {
262 throw new IllegalArgumentException("relative path cannot be null or empty");
263 }
264 InheritanceNodeWrapper inheritedNode = new InheritanceNodeWrapper(content);
265 try {
266 return inheritedNode.getProperty(relPath);
267
268 } catch (PathNotFoundException e) {
269
270 } catch (RepositoryException e) {
271
272 }
273
274 return null;
275 }
276
277 public Property inheritProperty(ContentMap content, String relPath) throws RepositoryException {
278 if (content == null) {
279 return null;
280 }
281 return inheritProperty(content.getJCRNode(), relPath);
282 }
283
284 public List<Node> inheritList(Node content, String relPath) throws RepositoryException {
285 if (content == null) {
286 return null;
287 }
288 if (StringUtils.isBlank(relPath)) {
289 throw new IllegalArgumentException("relative path cannot be null or empty");
290 }
291 InheritanceNodeWrapper inheritedNode = new InheritanceNodeWrapper(content);
292 Node subNode = inheritedNode.getNode(relPath);
293 return children(subNode);
294 }
295
296 public List<ContentMap> inheritList(ContentMap content, String relPath) throws RepositoryException {
297 if (content == null) {
298 return null;
299 }
300 if (StringUtils.isBlank(relPath)) {
301 throw new IllegalArgumentException("relative path cannot be null or empty");
302 }
303 InheritanceNodeWrapper inheritedNode = new InheritanceNodeWrapper(asJCRNode(content));
304 Node subNode = inheritedNode.getNode(relPath);
305 return children(new ContentMap(subNode));
306
307 }
308
309 public boolean isInherited(Node content) {
310 if (content instanceof InheritanceNodeWrapper) {
311 return ((InheritanceNodeWrapper) content).isInherited();
312 }
313 return false;
314 }
315
316 public boolean isInherited(ContentMap content) {
317 return isInherited(asJCRNode(content));
318 }
319
320 public boolean isFromCurrentPage(Node content) {
321 return !isInherited(content);
322 }
323
324 public boolean isFromCurrentPage(ContentMap content) {
325 return isFromCurrentPage(asJCRNode(content));
326 }
327
328
329
330
331 public String link(String workspace, String nodeIdentifier) {
332 try {
333 return LinkUtil.createLink(workspace, nodeIdentifier);
334 } catch (RepositoryException e) {
335 return null;
336 }
337 }
338
339
340
341
342
343 public String link(Property property) {
344 try {
345 Node parentNode = null;
346 String propertyName = null;
347 if (property.getType() == PropertyType.BINARY) {
348 parentNode = property.getParent().getParent();
349 propertyName = property.getParent().getName();
350 } else {
351 parentNode = property.getParent();
352 propertyName = property.getName();
353 }
354 NodeData equivNodeData = ContentUtil.asContent(parentNode).getNodeData(propertyName);
355 return LinkUtil.createLink(equivNodeData);
356 } catch (Exception e) {
357 return null;
358 }
359 }
360
361
362
363 public String link(Node content) {
364 return content == null ? null : LinkUtil.createLink(ContentUtil.asContent(content));
365 }
366
367 public String link(ContentMap contentMap) throws RepositoryException {
368 return contentMap == null ? null : this.link(asJCRNode(contentMap));
369 }
370
371
372
373
374
375 public String language(){
376 return I18nContentSupportFactory.getI18nSupport().getLocale().toString();
377 }
378
379
380
381
382
383
384
385
386 public String externalLink(Node content, String linkPropertyName) {
387 String externalLink = PropertyUtil.getString(content, linkPropertyName);
388 if (StringUtils.isBlank(externalLink)) {
389 return StringUtils.EMPTY;
390 }
391 if (!hasProtocol(externalLink)) {
392 externalLink = "http://" + externalLink;
393 }
394 return externalLink;
395 }
396
397
398
399
400
401
402
403
404
405 public String externalLink(ContentMap content, String linkPropertyName) {
406 return externalLink(asJCRNode(content), linkPropertyName);
407 }
408
409
410
411
412
413
414
415
416
417
418 public String externalLinkTitle(Node content, String linkPropertyName, String linkTitlePropertyName) {
419 String linkTitle = PropertyUtil.getString(content, linkTitlePropertyName);
420 if (StringUtils.isNotEmpty(linkTitle)) {
421 return linkTitle;
422 }
423 return externalLink(content, linkPropertyName);
424 }
425
426
427
428
429
430
431
432
433
434
435 public String externalLinkTitle(ContentMap content, String linkPropertyName, String linkTitlePropertyName) {
436 return externalLinkTitle(asJCRNode(content), linkPropertyName, linkTitlePropertyName);
437 }
438
439 public boolean isEditMode() {
440
441 return isAuthorInstance() && !isPreviewMode();
442 }
443
444 public boolean isPreviewMode() {
445 return MgnlContext.getAggregationState().isPreviewMode();
446 }
447
448 public boolean isAuthorInstance() {
449 return Components.getComponent(ServerConfiguration.class).isAdmin();
450 }
451
452 public boolean isPublicInstance() {
453 return !isAuthorInstance();
454 }
455
456
457
458
459
460 public String createHtmlAttribute(String name, String value) {
461 value = StringUtils.trim(value);
462 if (StringUtils.isNotEmpty(value)) {
463 return new StringBuffer().append(name).append("=\"").append(value).append("\"").toString();
464 }
465 return StringUtils.EMPTY;
466 }
467
468
469
470
471 public SiblingsHelper siblings(Node node) throws RepositoryException {
472 return SiblingsHelper.of(ContentUtil.asContent(node));
473 }
474
475 public SiblingsHelper siblings(ContentMap node) throws RepositoryException {
476 return siblings(asJCRNode(node));
477 }
478
479
480
481
482
483 public Node content(String path){
484 return content(RepositoryConstants.WEBSITE, path);
485 }
486
487
488
489
490
491 public Node content(String repository, String path){
492 return SessionUtil.getNode(repository, path);
493 }
494
495 public List<ContentMap> asContentMapList(Collection<Node> nodeList) {
496 if (nodeList != null) {
497 List<ContentMap> contentMapList = new ArrayList<ContentMap>();
498 for (Node node : nodeList) {
499 contentMapList.add(asContentMap(node));
500 }
501 return contentMapList;
502 }
503 return null;
504 }
505
506 public List<Node> asNodeList(Collection<ContentMap> contentMapList) {
507 if (contentMapList != null) {
508 List<Node> nodeList = new ArrayList<Node>();
509 for (ContentMap node : contentMapList) {
510 nodeList.add(node.getJCRNode());
511 }
512 return nodeList;
513 }
514 return null;
515 }
516
517
518 protected List<Node> asNodeList(Iterable<Node> nodes) {
519 List<Node> childList = new ArrayList<Node>();
520 for (Node child : nodes) {
521 childList.add(child);
522 }
523 return childList;
524 }
525
526
527 protected List<ContentMap> asContentMapList(Iterable<Node> nodes) {
528 List<ContentMap> childList = new ArrayList<ContentMap>();
529 for (Node child : nodes) {
530 childList.add(new ContentMap(child));
531 }
532 return childList;
533 }
534
535
536
537
538
539
540
541 private boolean hasProtocol(String link) {
542 return link != null && link.contains("://");
543 }
544
545
546
547
548
549
550
551 private boolean isRoot(Node content) throws RepositoryException {
552 return content.getDepth() == 0;
553 }
554
555
556
557
558 public ContentMap decode(ContentMap content){
559 return asContentMap(decode(content.getJCRNode()));
560 }
561
562
563
564
565 public Node decode(Node content){
566 if (content instanceof HTMLEscapingNodeWrapper) {
567 try {
568 return ((HTMLEscapingNodeWrapper) content).getWrappedNode();
569 } catch (RepositoryException e) {
570 throw new RuntimeRepositoryException(e);
571 }
572 }
573 return content;
574 }
575
576
577
578
579 public Node encode(Node content){
580 return content != null ? new HTMLEscapingNodeWrapper(content, true) : null;
581 }
582
583
584 }