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