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.rendering.template.assignment;
35
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import javax.inject.Inject;
41 import javax.inject.Singleton;
42 import javax.jcr.Node;
43 import javax.jcr.RepositoryException;
44 import javax.jcr.Session;
45
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 import info.magnolia.cms.i18n.Messages;
50 import info.magnolia.cms.i18n.MessagesManager;
51 import info.magnolia.cms.security.PermissionUtil;
52 import info.magnolia.context.MgnlContext;
53 import info.magnolia.jcr.util.NodeTypes;
54 import info.magnolia.jcr.util.NodeUtil;
55 import info.magnolia.registry.RegistrationException;
56 import info.magnolia.rendering.template.TemplateAvailability;
57 import info.magnolia.rendering.template.TemplateDefinition;
58 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
59
60
61
62
63
64 @Singleton
65 public class MetaDataBasedTemplateDefinitionAssignment implements TemplateDefinitionAssignment {
66
67 private static final String DELETED_PAGE_TEMPLATE = "adminInterface:mgnlDeleted";
68
69 private static final Logger log = LoggerFactory.getLogger(MetaDataBasedTemplateDefinitionAssignment.class);
70
71 private TemplateDefinitionRegistry templateDefinitionRegistry;
72
73 @Inject
74 public MetaDataBasedTemplateDefinitionAssignment(TemplateDefinitionRegistry templateDefinitionRegistry) {
75 this.templateDefinitionRegistry = templateDefinitionRegistry;
76 }
77
78 @Override
79 public String getAssignedTemplate(Node content) throws RepositoryException {
80 return NodeTypes.Renderable.getTemplate(content);
81 }
82
83 @Override
84 public TemplateDefinition getAssignedTemplateDefinition(Node content) throws RegistrationException {
85 final String templateId;
86 try {
87 templateId = getAssignedTemplate(content);
88 } catch (RepositoryException e) {
89 throw new RegistrationException("Could not determine assigned template", e);
90 }
91 if (templateId == null) {
92 throw new RegistrationException("No template definition assigned");
93 }
94 return templateDefinitionRegistry.getTemplateDefinition(templateId);
95 }
96
97
98
99
100 @Override
101 public TemplateDefinition getDefaultTemplate(Node content) {
102
103
104 TemplateDefinition parentTemplate = null;
105 try {
106 parentTemplate = getAssignedTemplateDefinition(content.getParent());
107 } catch (RepositoryException e) {
108 log.error("Failed to determine template assigned to parent of node: " + NodeUtil.getNodePathIfPossible(content), e);
109 } catch (RegistrationException e) {
110
111 }
112
113 if (parentTemplate != null && isAvailable(content, parentTemplate)) {
114 return parentTemplate;
115 }
116
117
118 Collection<TemplateDefinition> templates = getAvailableTemplates(content);
119 if (templates.isEmpty()) {
120 return null;
121 }
122
123 return templates.iterator().next();
124 }
125
126 @Override
127 public Collection<TemplateDefinition> getAvailableTemplates(Node content) {
128
129 try {
130 if (content != null && NodeUtil.hasMixin(content, NodeTypes.Deleted.NAME)) {
131 return Collections.singleton(templateDefinitionRegistry.getTemplateDefinition(DELETED_PAGE_TEMPLATE));
132 }
133 } catch (RepositoryException e) {
134 log.error("Failed to check node for deletion status.", e);
135 } catch (RegistrationException e) {
136 log.error("Deleted content template is not correctly registered.", e);
137 }
138
139 final ArrayList<TemplateDefinition> availableTemplateDefinitions = new ArrayList<TemplateDefinition>();
140 final Collection<TemplateDefinition> templateDefinitions = templateDefinitionRegistry.getTemplateDefinitions();
141 for (TemplateDefinition templateDefinition : templateDefinitions) {
142 if (isTemplateAvailable(content, templateDefinition)) {
143 availableTemplateDefinitions.add(templateDefinition);
144 }
145 }
146
147 Collections.sort(availableTemplateDefinitions, new Comparator<TemplateDefinition>() {
148
149 @Override
150 public int compare(TemplateDefinition lhs, TemplateDefinition rhs) {
151 return getI18nTitle(lhs).compareTo(getI18nTitle(rhs));
152 }
153
154 private String getI18nTitle(TemplateDefinition templateDefinition) {
155 Messages messages = MessagesManager.getMessages(templateDefinition.getI18nBasename());
156 return messages.getWithDefault(templateDefinition.getTitle(), templateDefinition.getTitle());
157 }
158 });
159
160 return availableTemplateDefinitions;
161 }
162
163 protected boolean isTemplateAvailable(Node content, TemplateDefinition templateDefinition) {
164 return hasReadAccess(content) &&
165 isVisible(templateDefinition) &&
166 isAvailable(content, templateDefinition);
167 }
168
169 protected boolean isVisible(TemplateDefinition templateDefinition) {
170 return templateDefinition.getVisible() == null || templateDefinition.getVisible();
171 }
172
173 protected boolean isAvailable(Node content, TemplateDefinition templateDefinition) {
174 TemplateAvailability templateAvailability = templateDefinition.getTemplateAvailability();
175 return templateAvailability == null || templateAvailability.isAvailable(content, templateDefinition);
176 }
177
178 protected boolean hasReadAccess(Node content) {
179 try {
180
181
182 return PermissionUtil.isGranted(
183 MgnlContext.getJCRSession(content.getSession().getWorkspace().getName()),
184 content.getPath(),
185 Session.ACTION_READ);
186 } catch (RepositoryException e) {
187 return false;
188 }
189 }
190 }