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