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.beans.config.URI2RepositoryManager;
38 import info.magnolia.cms.core.AggregationState;
39 import info.magnolia.cms.core.NodeData;
40 import info.magnolia.cms.core.Path;
41 import info.magnolia.cms.i18n.I18nContentSupport;
42 import info.magnolia.cms.util.ContentUtil;
43 import info.magnolia.cms.util.PathUtil;
44 import info.magnolia.cms.util.QueryUtil;
45 import info.magnolia.cms.util.SiblingsHelper;
46 import info.magnolia.context.MgnlContext;
47 import info.magnolia.jcr.inheritance.InheritanceNodeWrapper;
48 import info.magnolia.jcr.util.ContentMap;
49 import info.magnolia.jcr.util.MetaDataUtil;
50 import info.magnolia.jcr.util.NodeTypes;
51 import info.magnolia.jcr.util.NodeUtil;
52 import info.magnolia.jcr.util.PropertyUtil;
53 import info.magnolia.jcr.util.SessionUtil;
54 import info.magnolia.jcr.wrapper.HTMLEscapingNodeWrapper;
55 import info.magnolia.jcr.wrapper.I18nNodeWrapper;
56 import info.magnolia.link.LinkUtil;
57 import info.magnolia.objectfactory.Components;
58 import info.magnolia.objectfactory.guice.GuiceUtils;
59 import info.magnolia.rendering.template.configured.ConfiguredInheritance;
60 import info.magnolia.rendering.template.type.DefaultTemplateTypes;
61 import info.magnolia.rendering.template.type.TemplateTypeHelper;
62 import info.magnolia.repository.RepositoryConstants;
63 import info.magnolia.templating.inheritance.DefaultInheritanceContentDecorator;
64 import info.magnolia.util.EscapeUtil;
65
66 import java.net.URI;
67 import java.net.URISyntaxException;
68 import java.util.ArrayList;
69 import java.util.Arrays;
70 import java.util.Calendar;
71 import java.util.Collection;
72 import java.util.Collections;
73 import java.util.LinkedHashMap;
74 import java.util.List;
75 import java.util.Locale;
76 import java.util.Map;
77 import java.util.Set;
78
79 import javax.inject.Inject;
80 import javax.inject.Provider;
81 import javax.jcr.Node;
82 import javax.jcr.PathNotFoundException;
83 import javax.jcr.Property;
84 import javax.jcr.PropertyType;
85 import javax.jcr.RepositoryException;
86
87 import org.apache.commons.io.FileUtils;
88 import org.apache.commons.lang3.StringUtils;
89 import org.apache.jackrabbit.util.ISO8601;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
92
93
94
95
96 public class TemplatingFunctions {
97
98 private static final Logger log = LoggerFactory.getLogger(TemplatingFunctions.class);
99
100 private final Provider<AggregationState> aggregationStateProvider;
101 private final TemplateTypeHelper templateTypeHelper;
102 private final Provider<I18nContentSupport> i18nContentSupport;
103
104 @Inject
105 public TemplatingFunctions(Provider<AggregationState> aggregationStateProvider, TemplateTypeHelper templateTypeFunctions, Provider<I18nContentSupport> i18nContentSupport) {
106 this.aggregationStateProvider = aggregationStateProvider;
107 this.templateTypeHelper = templateTypeFunctions;
108 this.i18nContentSupport = i18nContentSupport;
109 }
110
111
112
113
114 @Deprecated
115 public TemplatingFunctions(Provider<AggregationState> aggregationStateProvider, TemplateTypeHelper templateTypeFunctions) {
116 this(aggregationStateProvider, templateTypeFunctions, GuiceUtils.providerForInstance(Components.getComponent(I18nContentSupport.class)));
117 }
118
119
120
121
122 @Deprecated
123 public TemplatingFunctions(Provider<AggregationState> aggregationStateProvider) {
124 this(aggregationStateProvider, Components.getComponent(TemplateTypeHelper.class), GuiceUtils.providerForInstance(Components.getComponent(I18nContentSupport.class)));
125 }
126
127
128
129
130
131 public Node asJCRNode(ContentMap contentMap) {
132 return contentMap == null ? null : contentMap.getJCRNode();
133 }
134
135
136
137
138
139 public ContentMap asContentMap(Node content) {
140 return content == null ? null : new ContentMap(content);
141 }
142
143
144
145
146 public List<Node> children(Node content) throws RepositoryException {
147 return content == null ? null : asNodeList(NodeUtil.getNodes(content, NodeUtil.EXCLUDE_META_DATA_FILTER));
148 }
149
150
151
152
153 public List<Node> children(Node content, String nodeTypeName) throws RepositoryException {
154 return content == null ? null : asNodeList(NodeUtil.getNodes(content, nodeTypeName));
155 }
156
157
158
159
160 public List<ContentMap> children(ContentMap content) throws RepositoryException {
161 return content == null ? null : asContentMapList(NodeUtil.getNodes(asJCRNode(content), NodeUtil.EXCLUDE_META_DATA_FILTER));
162 }
163
164
165
166
167 public List<ContentMap> children(ContentMap content, String nodeTypeName) throws RepositoryException {
168 return content == null ? null : asContentMapList(NodeUtil.getNodes(asJCRNode(content), nodeTypeName));
169 }
170
171
172
173
174 public ContentMap root(ContentMap contentMap) throws RepositoryException {
175 return contentMap == null ? null : asContentMap(this.root(contentMap.getJCRNode()));
176 }
177
178
179
180
181 public ContentMap root(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
182 return contentMap == null ? null : asContentMap(this.root(contentMap.getJCRNode(), nodeTypeName));
183 }
184
185
186
187
188 public Node root(Node content) throws RepositoryException {
189 return this.root(content, null);
190 }
191
192
193
194
195 public Node root(Node content, String nodeTypeName) throws RepositoryException {
196 if (content == null) {
197 return null;
198 }
199 if (nodeTypeName == null) {
200 return (Node) content.getAncestor(0);
201 }
202 if (isRoot(content) && content.isNodeType(nodeTypeName)) {
203 return content;
204 }
205
206 Node parentNode = this.parent(content, nodeTypeName);
207 while (parent(parentNode, nodeTypeName) != null) {
208 parentNode = this.parent(parentNode, nodeTypeName);
209 }
210 return parentNode;
211 }
212
213
214
215
216 public ContentMap parent(ContentMap contentMap) throws RepositoryException {
217 return contentMap == null ? null : asContentMap(this.parent(contentMap.getJCRNode()));
218 }
219
220
221
222
223 public ContentMap parent(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
224 return contentMap == null ? null : asContentMap(this.parent(contentMap.getJCRNode(), nodeTypeName));
225 }
226
227
228
229
230 public Node parent(Node content) throws RepositoryException {
231 return this.parent(content, null);
232 }
233
234
235
236
237
238 public Node parent(Node content, String nodeTypeName) throws RepositoryException {
239 if (content == null) {
240 return null;
241 }
242 if (isRoot(content)) {
243 return null;
244 }
245 if (nodeTypeName == null) {
246 return content.getParent();
247 }
248 Node parent = content.getParent();
249 while (!parent.isNodeType(nodeTypeName)) {
250 if (isRoot(parent)) {
251 return null;
252 }
253 parent = parent.getParent();
254 }
255 return parent;
256 }
257
258
259
260
261
262
263
264
265 public ContentMap page(ContentMap content) throws RepositoryException {
266 return content == null ? null : asContentMap(page(content.getJCRNode()));
267 }
268
269
270
271
272
273
274
275
276 public Node page(Node content) throws RepositoryException {
277 if (content == null) {
278 return null;
279 }
280 if (content.isNodeType(NodeTypes.Page.NAME)) {
281 return content;
282 }
283 return parent(content, NodeTypes.Page.NAME);
284 }
285
286
287
288
289 public List<ContentMap> ancestors(ContentMap contentMap) throws RepositoryException {
290 return ancestors(contentMap, null);
291 }
292
293
294
295
296 public List<ContentMap> ancestors(ContentMap contentMap, String nodeTypeName) throws RepositoryException {
297 List<Node> ancestorsAsNodes = this.ancestors(contentMap.getJCRNode(), nodeTypeName);
298 return asContentMapList(ancestorsAsNodes);
299 }
300
301
302
303
304
305 public List<Node> ancestors(Node content) throws RepositoryException {
306 return content == null ? null : this.ancestors(content, null);
307 }
308
309
310
311
312
313 public List<Node> ancestors(Node content, String nodeTypeName) throws RepositoryException {
314 if (content == null) {
315 return null;
316 }
317 List<Node> ancestors = new ArrayList<Node>();
318 int depth = content.getDepth();
319 for (int i = 1; i < depth; ++i) {
320 Node possibleAncestor = (Node) content.getAncestor(i);
321 if (nodeTypeName == null) {
322 ancestors.add(possibleAncestor);
323 } else {
324 if (possibleAncestor.isNodeType(nodeTypeName)) {
325 ancestors.add(possibleAncestor);
326 }
327 }
328 }
329 return ancestors;
330 }
331
332
333
334
335
336
337
338
339
340 public Node inherit(Node content) throws RepositoryException {
341 return inherit(content, null);
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355 public Node inherit(Node content, String relPath) throws RepositoryException {
356 return inherit(content, relPath, StringUtils.EMPTY, ConfiguredInheritance.COMPONENTS_FILTERED, ConfiguredInheritance.PROPERTIES_ALL);
357 }
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 public Node inherit(Node content, String relPath, String nodeTypes, String nodeInheritance, String propertyInheritance) throws RepositoryException {
391 if (content == null) {
392 return null;
393 }
394
395 ConfiguredInheritance configuredInheritance = new ConfiguredInheritance();
396 if (StringUtils.isNotEmpty(nodeTypes)) {
397 configuredInheritance.setNodeTypes(Arrays.asList(StringUtils.split(nodeTypes, ",")));
398 }
399 if (StringUtils.isNotEmpty(nodeInheritance)) {
400 configuredInheritance.setComponents(nodeInheritance);
401 }
402 if (StringUtils.isNotEmpty(propertyInheritance)) {
403 configuredInheritance.setProperties(propertyInheritance);
404 }
405
406 Node inheritedNode = wrapForInheritance(content, configuredInheritance);
407
408 if (StringUtils.isBlank(relPath)) {
409 return inheritedNode;
410 }
411
412 try {
413 Node subNode = inheritedNode.getNode(relPath);
414 return NodeUtil.unwrap(subNode);
415 } catch (PathNotFoundException e) {
416
417 }
418 return null;
419 }
420
421
422
423
424 public ContentMap inherit(ContentMap content) throws RepositoryException {
425 return inherit(content, null);
426 }
427
428
429
430
431 public ContentMap inherit(ContentMap content, String relPath) throws RepositoryException {
432 if (content == null) {
433 return null;
434 }
435 Node node = inherit(content.getJCRNode(), relPath);
436 return node == null ? null : new ContentMap(node);
437 }
438
439
440
441
442 public ContentMap inherit(ContentMap content, String relPath, String nodeTypes, String nodeInheritance, String propertyInheritance) throws RepositoryException {
443 if (content == null) {
444 return null;
445 }
446 Node node = inherit(content.getJCRNode(), relPath, nodeTypes, nodeInheritance, propertyInheritance);
447 return node == null ? null : new ContentMap(node);
448 }
449
450
451
452
453
454
455
456
457 public Property inheritProperty(Node content, String relPath) throws RepositoryException {
458 if (content == null) {
459 return null;
460 }
461 if (StringUtils.isBlank(relPath)) {
462 throw new IllegalArgumentException("relative path cannot be null or empty");
463 }
464 try {
465 Node inheritedNode = wrapForInheritance(content, new ConfiguredInheritance());
466 return inheritedNode.getProperty(relPath);
467
468 } catch (PathNotFoundException e) {
469
470 } catch (RepositoryException e) {
471
472 }
473
474 return null;
475 }
476
477
478
479
480 public Property inheritProperty(ContentMap content, String relPath) throws RepositoryException {
481 if (content == null) {
482 return null;
483 }
484 return inheritProperty(content.getJCRNode(), relPath);
485 }
486
487
488
489
490 public List<Node> inheritList(Node content, String relPath) throws RepositoryException {
491 if (content == null) {
492 return null;
493 }
494 if (StringUtils.isBlank(relPath)) {
495 throw new IllegalArgumentException("Relative path cannot be null or empty");
496 }
497 Node inheritedNode = wrapForInheritance(content, new ConfiguredInheritance());
498 Node subNode = inheritedNode.getNode(relPath);
499 return children(subNode);
500 }
501
502
503
504
505 public List<ContentMap> inheritList(ContentMap content, String relPath) throws RepositoryException {
506 if (content == null) {
507 return null;
508 }
509 if (StringUtils.isBlank(relPath)) {
510 throw new IllegalArgumentException("Relative path cannot be null or empty");
511 }
512 Node node = asJCRNode(content);
513 Node inheritedNode = wrapForInheritance(node, new ConfiguredInheritance());
514 Node subNode = inheritedNode.getNode(relPath);
515 return children(new ContentMap(subNode));
516 }
517
518
519
520
521 public boolean isInherited(Node content) {
522 if (content instanceof InheritanceNodeWrapper) {
523 return ((InheritanceNodeWrapper) content).isInherited();
524 }
525 return false;
526 }
527
528
529
530
531 public boolean isInherited(ContentMap content) {
532 return isInherited(asJCRNode(content));
533 }
534
535
536
537
538
539 public boolean isFromCurrentPage(Node content) {
540 return !isInherited(content);
541 }
542
543
544
545
546 public boolean isFromCurrentPage(ContentMap content) {
547 return isFromCurrentPage(asJCRNode(content));
548 }
549
550
551
552
553
554 public String link(String workspace, String nodeIdentifier) {
555 try {
556 return LinkUtil.createLink(workspace, nodeIdentifier);
557 } catch (RepositoryException e) {
558 return null;
559 }
560 }
561
562
563
564
565
566
567
568
569 @Deprecated
570 public String link(Property property) {
571 try {
572 Node parentNode = null;
573 String propertyName = null;
574 if (property.getType() == PropertyType.BINARY) {
575 parentNode = property.getParent().getParent();
576 propertyName = property.getParent().getName();
577 } else {
578 parentNode = property.getParent();
579 propertyName = property.getName();
580 }
581 NodeData equivNodeData = ContentUtil.asContent(parentNode).getNodeData(propertyName);
582 return LinkUtil.createLink(equivNodeData);
583 } catch (Exception e) {
584 return null;
585 }
586 }
587
588
589
590
591
592 public String link(Node content) {
593 return content == null ? null : LinkUtil.createLink(content);
594 }
595
596
597
598
599 public String link(ContentMap contentMap) throws RepositoryException {
600 return contentMap == null ? null : this.link(asJCRNode(contentMap));
601 }
602
603 public String linkPrefix(Node content) {
604 if (!MgnlContext.isWebContext()) {
605 return MgnlContext.getContextPath();
606 }
607 String fullLinkToPage = link(content);
608 String pagePath = Components.getComponent(URI2RepositoryManager.class).getURI(LinkUtil.createLinkInstance(content));
609 int ndx = fullLinkToPage.length();
610 for (int cnt = StringUtils.countMatches(pagePath, "/"); cnt > 0; cnt--) {
611 ndx = fullLinkToPage.lastIndexOf('/', ndx - 1);
612 }
613 String linkPrefix = fullLinkToPage.substring(0, ndx);
614 return linkPrefix;
615 }
616
617
618
619
620 public String linkPrefix(ContentMap content) {
621 return linkPrefix(asJCRNode(content));
622 }
623
624
625
626
627
628
629 @Deprecated
630 public String getQueryStringAndFragment(String url) {
631 return queryStringAndFragment(url);
632 }
633
634
635
636
637 public String queryStringAndFragment(String url) {
638 String result = StringUtils.EMPTY;
639 try {
640 URI uri = new URI(url);
641 String query = uri.getQuery();
642 String fragment = uri.getFragment();
643
644 if (StringUtils.isNotEmpty(query)) {
645 result += "?" + query;
646 }
647 if (StringUtils.isNotEmpty(fragment)) {
648 result += "#" + fragment;
649 }
650 } catch (URISyntaxException e) {
651 log.warn("URL cannot be parsed. {0}, {1}", url, e.getMessage());
652 return StringUtils.EMPTY;
653 }
654 return result;
655 }
656
657
658
659
660
661
662 public String language() {
663 return i18nContentSupport.get().getLocale().toString();
664 }
665
666
667
668
669
670
671
672
673
674 public String externalLink(Node content, String linkPropertyName) {
675 String externalLink = PropertyUtil.getString(content, linkPropertyName);
676 if (StringUtils.isBlank(externalLink)) {
677 return StringUtils.EMPTY;
678 }
679
680 if (!hasProtocol(externalLink) && !externalLink.startsWith("#")) {
681 externalLink = "http://" + externalLink;
682 }
683 return EscapeUtil.escapeXss(externalLink);
684 }
685
686
687
688
689
690
691
692
693
694 public String externalLink(ContentMap content, String linkPropertyName) {
695 return externalLink(asJCRNode(content), linkPropertyName);
696 }
697
698
699
700
701
702
703
704
705
706
707 public String externalLinkTitle(Node content, String linkPropertyName, String linkTitlePropertyName) {
708 String linkTitle = PropertyUtil.getString(content, linkTitlePropertyName);
709 if (StringUtils.isNotEmpty(linkTitle)) {
710 return linkTitle;
711 }
712 return externalLink(content, linkPropertyName);
713 }
714
715
716
717
718
719
720
721
722
723
724 public String externalLinkTitle(ContentMap content, String linkPropertyName, String linkTitlePropertyName) {
725 return externalLinkTitle(asJCRNode(content), linkPropertyName, linkTitlePropertyName);
726 }
727
728
729
730
731
732
733 public boolean isEditMode() {
734
735 return isAuthorInstance() && !isPreviewMode();
736 }
737
738
739
740
741 public boolean isPreviewMode() {
742 return this.aggregationStateProvider.get().isPreviewMode();
743 }
744
745
746
747
748 public boolean isAuthorInstance() {
749 return Components.getComponent(ServerConfiguration.class).isAdmin();
750 }
751
752
753
754
755 public boolean isPublicInstance() {
756 return !isAuthorInstance();
757 }
758
759
760
761
762
763 public String createHtmlAttribute(String name, String value) {
764 value = StringUtils.trim(value);
765 if (StringUtils.isNotEmpty(value)) {
766 return new StringBuffer().append(name).append("=\"").append(value).append("\"").toString();
767 }
768 return StringUtils.EMPTY;
769 }
770
771
772
773
774 public SiblingsHelper siblings(Node node) throws RepositoryException {
775 return SiblingsHelper.of(ContentUtil.asContent(node));
776 }
777
778 public SiblingsHelper siblings(ContentMap node) throws RepositoryException {
779 return siblings(asJCRNode(node));
780 }
781
782
783
784
785
786
787 @Deprecated
788 public Node content(String path) {
789 return content(RepositoryConstants.WEBSITE, path);
790 }
791
792
793
794
795
796
797 @Deprecated
798 public Node content(String repository, String path) {
799 return SessionUtil.getNode(repository, path);
800 }
801
802
803
804
805
806
807 @Deprecated
808 public Node contentByIdentifier(String id) {
809 return contentByIdentifier(RepositoryConstants.WEBSITE, id);
810 }
811
812
813
814
815
816
817 @Deprecated
818 public Node contentByIdentifier(String repository, String id) {
819 return SessionUtil.getNodeByIdentifier(repository, id);
820 }
821
822
823
824
825 public ContentMap contentByPath(String path) {
826 return contentByPath(path, RepositoryConstants.WEBSITE);
827 }
828
829
830
831
832 public ContentMap contentByPath(String path, String workspace) {
833 return asContentMap(nodeByPath(path, workspace));
834 }
835
836
837
838
839 public ContentMap contentById(String id) {
840 return contentById(id, RepositoryConstants.WEBSITE);
841 }
842
843
844
845
846 public ContentMap contentById(String id, String workspace) {
847 return asContentMap(nodeById(id, workspace));
848 }
849
850
851
852
853 public Node nodeByPath(String path) {
854 return nodeByPath(path, RepositoryConstants.WEBSITE);
855 }
856
857
858
859
860 public Node nodeByPath(String path, String workspace) {
861 try {
862 String pathToNode = new URI(path).getPath();
863 return SessionUtil.getNode(workspace, pathToNode);
864 } catch (URISyntaxException e) {
865 log.warn("Path cannot be parsed. {0}, {1}", path, e.getMessage());
866 return null;
867 }
868 }
869
870
871
872
873 public Node nodeById(String id) {
874 return nodeById(id, RepositoryConstants.WEBSITE);
875 }
876
877
878
879
880 public Node nodeById(String id, String workspace) {
881 return SessionUtil.getNodeByIdentifier(workspace, id);
882 }
883
884
885
886
887
888
889
890
891
892
893 public Node contentByReference(Node content, String idPropertyName, String referencedWorkspace) throws RepositoryException {
894 if (content.hasProperty(idPropertyName)) {
895 final String identifier = PropertyUtil.getString(content, idPropertyName);
896 final Node node = NodeUtil.getNodeByIdentifier(referencedWorkspace, identifier);
897 return encode(wrapForI18n(node));
898 }
899 return null;
900 }
901
902
903
904
905 public ContentMap contentByReference(ContentMap content, String idPropertyName, String referencedWorkspace) throws RepositoryException {
906 Node node = asJCRNode(content);
907 return asContentMap(contentByReference(node, idPropertyName, referencedWorkspace));
908 }
909
910
911
912
913
914 public List<ContentMap> asContentMapList(Collection<Node> nodeList) {
915 if (nodeList != null) {
916 List<ContentMap> contentMapList = new ArrayList<ContentMap>();
917 for (Node node : nodeList) {
918 contentMapList.add(asContentMap(node));
919 }
920 return contentMapList;
921 }
922 return null;
923 }
924
925
926
927
928
929 public List<Node> asNodeList(Collection<ContentMap> contentMapList) {
930 if (contentMapList != null) {
931 List<Node> nodeList = new ArrayList<Node>();
932 for (ContentMap node : contentMapList) {
933 nodeList.add(node.getJCRNode());
934 }
935 return nodeList;
936 }
937 return null;
938 }
939
940
941 protected List<Node> asNodeList(Iterable<Node> nodes) {
942 List<Node> childList = new ArrayList<Node>();
943 for (Node child : nodes) {
944 childList.add(child);
945 }
946 return childList;
947 }
948
949
950 protected List<ContentMap> asContentMapList(Iterable<Node> nodes) {
951 List<ContentMap> childList = new ArrayList<ContentMap>();
952 for (Node child : nodes) {
953 childList.add(new ContentMap(child));
954 }
955 return childList;
956 }
957
958
959
960
961
962
963
964 private boolean hasProtocol(String link) {
965 return link != null && link.contains("://");
966 }
967
968
969
970
971
972
973
974 private boolean isRoot(Node content) throws RepositoryException {
975 return content.getDepth() == 0;
976 }
977
978
979
980
981 public ContentMap decode(ContentMap content) {
982 return asContentMap(decode(content.getJCRNode()));
983 }
984
985
986
987
988 public Node decode(Node content) {
989 return NodeUtil.deepUnwrap(content, HTMLEscapingNodeWrapper.class);
990 }
991
992
993
994
995 public ContentMap encode(ContentMap content) {
996 return content != null ? new ContentMap(new HTMLEscapingNodeWrapper(content.getJCRNode(), true)) : null;
997 }
998
999
1000
1001
1002 public Node encode(Node content) {
1003 return content != null ? new HTMLEscapingNodeWrapper(content, true) : null;
1004 }
1005
1006
1007
1008
1009 public Node wrapForI18n(Node content) {
1010 return content != null ? new I18nNodeWrapper(content) : null;
1011 }
1012
1013
1014
1015
1016
1017 private Node wrapForInheritance(Node destination, ConfiguredInheritance configuredInheritance) throws RepositoryException {
1018 configuredInheritance.setEnabled(true);
1019 return new DefaultInheritanceContentDecorator(destination, configuredInheritance).wrapNode(destination);
1020 }
1021
1022
1023
1024
1025 public String metaData(Node content, String property) {
1026
1027 Object returnValue;
1028 try {
1029 if (property.equals(NodeTypes.Created.CREATED)) {
1030 returnValue = NodeTypes.Created.getCreated(content);
1031 } else if (property.equals(NodeTypes.Created.CREATED_BY)) {
1032 returnValue = NodeTypes.Created.getCreatedBy(content);
1033 } else if (property.equals(NodeTypes.LastModified.LAST_MODIFIED)) {
1034 returnValue = NodeTypes.LastModified.getLastModified(content);
1035 } else if (property.equals(NodeTypes.LastModified.LAST_MODIFIED_BY)) {
1036 returnValue = NodeTypes.LastModified.getLastModifiedBy(content);
1037 } else if (property.equals(NodeTypes.Renderable.TEMPLATE)) {
1038 returnValue = NodeTypes.Renderable.getTemplate(content);
1039 } else if (property.equals(NodeTypes.Activatable.LAST_ACTIVATED)) {
1040 returnValue = NodeTypes.Activatable.getLastActivated(content);
1041 } else if (property.equals(NodeTypes.Activatable.LAST_ACTIVATED_BY)) {
1042 returnValue = NodeTypes.Activatable.getLastActivatedBy(content);
1043 } else if (property.equals(NodeTypes.Activatable.ACTIVATION_STATUS)) {
1044 returnValue = NodeTypes.Activatable.getActivationStatus(content);
1045 } else if (property.equals(NodeTypes.Deleted.DELETED)) {
1046 returnValue = NodeTypes.Deleted.getDeleted(content);
1047 } else if (property.equals(NodeTypes.Deleted.DELETED_BY)) {
1048 returnValue = NodeTypes.Deleted.getDeletedBy(content);
1049 } else if (property.equals(NodeTypes.Deleted.COMMENT)) {
1050
1051 returnValue = NodeTypes.Deleted.getComment(content);
1052 } else {
1053
1054
1055
1056 returnValue = MetaDataUtil.getMetaData(content).getStringProperty(property);
1057
1058
1059 log.warn("Deprecated constant [{}] used to query for meta data property on node [{}]", property, NodeUtil.getPathIfPossible(content));
1060 }
1061 } catch (RepositoryException e) {
1062 return "";
1063 }
1064
1065 return returnValue instanceof Calendar ? ISO8601.format((Calendar) returnValue) : returnValue.toString();
1066 }
1067
1068
1069
1070
1071 public String metaData(ContentMap content, String property) {
1072 return metaData(content.getJCRNode(), property);
1073 }
1074
1075
1076
1077
1078
1079
1080
1081 @Deprecated
1082 public Collection<Node> search(String workspace, String statement, String language, String returnItemType) {
1083 try {
1084 return NodeUtil.getCollectionFromNodeIterator(QueryUtil.search(workspace, statement, language, returnItemType));
1085 } catch (Exception e) {
1086 log.error(e.getMessage(), e);
1087 }
1088 return null;
1089 }
1090
1091
1092
1093
1094
1095
1096
1097
1098 @Deprecated
1099 public Collection<Node> simpleSearch(String workspace, String statement, String returnItemType, String startPath) {
1100 if (StringUtils.isEmpty(statement)) {
1101 log.error("Cannot search with empty statement.");
1102 return null;
1103 }
1104 String query = QueryUtil.buildQuery(statement, startPath);
1105 try {
1106 return NodeUtil.getCollectionFromNodeIterator(QueryUtil.search(workspace, query, "JCR-SQL2", returnItemType));
1107 } catch (Exception e) {
1108 log.error(e.getMessage(), e);
1109 }
1110 return null;
1111 }
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122 public Node siteRoot(Node content) {
1123 return this.siteRoot(content, DefaultTemplateTypes.SITE_ROOT);
1124 }
1125
1126
1127
1128
1129 public ContentMap siteRoot(ContentMap content) {
1130 return this.siteRoot(content, DefaultTemplateTypes.SITE_ROOT);
1131 }
1132
1133
1134
1135
1136 public ContentMap siteRoot(ContentMap content, String siteRootTemplateType) {
1137 return asContentMap(siteRoot(content.getJCRNode(), siteRootTemplateType));
1138 }
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150 public Node siteRoot(Node content, String siteRootTemplateType) {
1151 if (siteRootTemplateType == null) {
1152 siteRootTemplateType = DefaultTemplateTypes.SITE_ROOT;
1153 }
1154 try {
1155 final Node page = page(content);
1156 final Node root = parentWithTemplateType(page, siteRootTemplateType);
1157 return (root == null) ? (Node) page.getAncestor(0) : root;
1158 } catch (RepositoryException e) {
1159 throw new RuntimeException("Can't access site root.", e);
1160 }
1161 }
1162
1163
1164
1165
1166
1167
1168
1169 public String templateType(Node pageNode) {
1170 return templateTypeHelper.getTemplateTypeOrDefault(pageNode);
1171 }
1172
1173
1174
1175
1176 public String templateType(ContentMap page) {
1177 return templateType(asJCRNode(page));
1178 }
1179
1180
1181
1182
1183
1184
1185
1186 public String templateSubtype(Node pageNode) {
1187 return templateTypeHelper.getTemplateSubtypeOrDefault(pageNode);
1188 }
1189
1190
1191
1192
1193 public String templateSubtype(ContentMap page) {
1194 return templateSubtype(asJCRNode(page));
1195 }
1196
1197
1198
1199
1200 public boolean hasTemplateOfType(Node pageNode, String templateType) {
1201 return templateTypeHelper.hasTemplateOfType(pageNode, templateType);
1202 }
1203
1204
1205
1206
1207 public boolean hasTemplateOfType(ContentMap page, String templateType) {
1208 return hasTemplateOfType(asJCRNode(page), templateType);
1209 }
1210
1211
1212
1213
1214 public Node parentWithTemplateType(Node pageNode, String templateType) throws RepositoryException {
1215 return templateTypeHelper.findParentWithTemplateType(pageNode, templateType);
1216 }
1217
1218
1219
1220
1221 public ContentMap parentWithTemplateType(ContentMap page, String templateType) throws RepositoryException {
1222 return asContentMap(parentWithTemplateType(asJCRNode(page), templateType));
1223 }
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 public List<Node> contentListByTemplateType(Node searchRoot, String templateType, String templateSubtype, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
1236 return templateTypeHelper.getContentListByTemplateType(searchRoot, templateType, templateSubtype, maxResultSize, andClause, orderByClause);
1237 }
1238
1239
1240
1241
1242 public List<ContentMap> contentListByTemplateType(ContentMap searchRoot, String templateType, String templateSubtype, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
1243 return asContentMapList(contentListByTemplateType(asJCRNode(searchRoot), templateType, templateSubtype, maxResultSize, andClause, orderByClause));
1244 }
1245
1246
1247
1248
1249 public List<Node> contentListByTemplateType(Node siteRoot, String templateType, String templateSubtype) throws RepositoryException {
1250 return contentListByTemplateType(siteRoot, templateType, templateSubtype, Integer.MAX_VALUE, null, null);
1251 }
1252
1253
1254
1255
1256 public List<ContentMap> contentListByTemplateType(ContentMap siteRoot, String templateType, String templateSubtype) throws RepositoryException {
1257 return asContentMapList(contentListByTemplateType(asJCRNode(siteRoot), templateType, templateSubtype, Integer.MAX_VALUE, null, null));
1258 }
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 public List<Node> contentListByTemplateIds(Node searchRoot, Set<String> templateIds, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
1270 return templateTypeHelper.getContentListByTemplateIds(searchRoot, templateIds, maxResultSize, andClause, orderByClause);
1271 }
1272
1273
1274
1275
1276 public List<ContentMap> contentListByTemplateIds(ContentMap searchRoot, Set<String> templateIds, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
1277 return asContentMapList(contentListByTemplateIds(asJCRNode(searchRoot), templateIds, maxResultSize, andClause, orderByClause));
1278 }
1279
1280
1281
1282
1283 public List<Node> contentListByTemplateId(Node searchRoot, String templateId) throws RepositoryException {
1284 return contentListByTemplateIds(searchRoot, Collections.singleton(templateId), Integer.MAX_VALUE, null, null);
1285 }
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296 public List<Node> contentListByTemplateId(Node searchRoot, String templateId, int maxResultSize, String andClause, String orderByClause) throws RepositoryException {
1297 return contentListByTemplateIds(searchRoot, Collections.singleton(templateId), maxResultSize, andClause, orderByClause);
1298 }
1299
1300
1301
1302
1303 public String abbreviateString(String stringToAbbreviate, int length, String suffix) {
1304 if (stringToAbbreviate == null) {
1305 return null;
1306 }
1307
1308 if (stringToAbbreviate.length() > length) {
1309 final int lengthMinusSuffix = length - suffix.length();
1310 String abbreviatedString = StringUtils.left(stringToAbbreviate, lengthMinusSuffix);
1311
1312
1313 String firstCharAfterCut = stringToAbbreviate.substring(lengthMinusSuffix, lengthMinusSuffix + 1);
1314 if (!" ".equals(firstCharAfterCut)) {
1315 abbreviatedString = StringUtils.substringBeforeLast(abbreviatedString, " ");
1316 }
1317
1318 return abbreviatedString + suffix;
1319 }
1320
1321 return stringToAbbreviate;
1322 }
1323
1324
1325
1326
1327 public String abbreviateString(String stringToAbbreviate, int length) {
1328 return abbreviateString(stringToAbbreviate, length, " ...");
1329 }
1330
1331
1332
1333
1334 public String fileExtension(String fileName) {
1335 return PathUtil.getExtension(fileName);
1336 }
1337
1338
1339
1340
1341
1342
1343 public String readableFileSize(long sizeBytes) {
1344 return FileUtils.byteCountToDisplaySize(sizeBytes);
1345 }
1346
1347
1348
1349
1350 public boolean isCurrentLocale(String language) {
1351 return StringUtils.equals(aggregationStateProvider.get().getLocale().toString(), language);
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 public Map<String, String> localizedLinks() throws RepositoryException {
1363 final Node currentNode = aggregationStateProvider.get().getCurrentContentNode();
1364 final Node pageNode = page(currentNode);
1365
1366 final String pageIdentifier = pageNode.getIdentifier();
1367 final Collection<Locale> locales = i18nContentSupport.get().getLocales();
1368 if (i18nContentSupport.get().isEnabled() && locales.size() > 1) {
1369 final Map<String, String> map = new LinkedHashMap<>();
1370 for (Locale locale : locales) {
1371 final String uri = createURI(pageIdentifier, locale);
1372
1373
1374 final String label = locale.toString();
1375 map.put(label, uri);
1376 }
1377 return map;
1378 }
1379
1380 return Collections.emptyMap();
1381 }
1382
1383
1384
1385
1386
1387
1388 private String createURI(final String identifier, final Locale locale) {
1389
1390
1391 final Locale currentLocale = i18nContentSupport.get().getLocale();
1392 String uri = null;
1393
1394 try {
1395 aggregationStateProvider.get().setLocale(locale);
1396 uri = LinkUtil.createAbsoluteLink(RepositoryConstants.WEBSITE, identifier);
1397 } catch (RepositoryException e) {
1398 log.error("Error creating a localized link to node with identifier {} for locale {}", identifier, locale.toString());
1399 } finally {
1400
1401 aggregationStateProvider.get().setLocale(currentLocale);
1402 }
1403
1404 final String selector = aggregationStateProvider.get().getSelector();
1405 if (StringUtils.isNotBlank(selector)) {
1406 final String defaultExtension = Components.getComponent(ServerConfiguration.class).getDefaultExtension();
1407 if (StringUtils.isNotBlank(defaultExtension)) {
1408 uri = StringUtils.substringBeforeLast(uri, "." + defaultExtension) + Path.SELECTOR_DELIMITER + selector + Path.SELECTOR_DELIMITER + "." + defaultExtension;
1409 } else {
1410 uri = uri + Path.SELECTOR_DELIMITER + selector + Path.SELECTOR_DELIMITER;
1411 }
1412 }
1413
1414 return uri;
1415 }
1416
1417 }