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.registry;
35
36 import info.magnolia.cms.core.MgnlNodeType;
37 import info.magnolia.jcr.util.MetaDataUtil;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.objectfactory.Components;
40 import info.magnolia.registry.RegistryMap;
41 import info.magnolia.registry.RegistrationException;
42 import info.magnolia.rendering.template.TemplateDefinition;
43 import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment;
44
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Collections;
48 import java.util.Set;
49
50 import javax.inject.Inject;
51 import javax.inject.Singleton;
52 import javax.jcr.Node;
53 import javax.jcr.RepositoryException;
54
55 import org.apache.commons.lang.StringUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64
65 @Singleton
66 public class TemplateDefinitionRegistry {
67
68 private static final Logger log = LoggerFactory.getLogger(TemplateDefinitionRegistry.class);
69
70 private static final String DELETED_PAGE_TEMPLATE = "adminInterface:mgnlDeleted";
71
72 private final RegistryMap<String, TemplateDefinitionProvider> registry = new RegistryMap<String, TemplateDefinitionProvider>() {
73
74 @Override
75 protected String keyFromValue(TemplateDefinitionProvider provider) {
76 return provider.getId();
77 }
78 };
79 private TemplateAvailability templateAvailability;
80
81 @Inject
82 public TemplateDefinitionRegistry(TemplateAvailability templateAvailability) {
83 this.templateAvailability = templateAvailability;
84 }
85
86 public TemplateDefinition getTemplateDefinition(String id) throws RegistrationException {
87
88 TemplateDefinitionProvider templateDefinitionProvider;
89 try {
90 templateDefinitionProvider = registry.getRequired(id);
91 } catch (RegistrationException e) {
92 throw new RegistrationException("No template definition registered for id: " + id, e);
93 }
94
95 return templateDefinitionProvider.getTemplateDefinition();
96 }
97
98
99
100
101 public Collection<TemplateDefinition> getTemplateDefinitions() {
102 final Collection<TemplateDefinition> templateDefinitions = new ArrayList<TemplateDefinition>();
103 for (TemplateDefinitionProvider provider : registry.values()) {
104 try {
105 final TemplateDefinition templateDefinition = provider.getTemplateDefinition();
106 if (templateDefinition == null) {
107 log.error("Provider's TemplateDefinition is null: " + provider);
108 } else {
109 templateDefinitions.add(templateDefinition);
110 }
111 } catch (RegistrationException e) {
112 log.error("Failed to read template definition from " + provider + ".", e);
113 }
114 }
115 return templateDefinitions;
116 }
117
118 public void register(TemplateDefinitionProvider provider) {
119 registry.put(provider);
120 }
121
122 public void unregister(String id) {
123 registry.remove(id);
124 }
125
126 public Set<String> unregisterAndRegister(Collection<String> registeredIds, Collection<TemplateDefinitionProvider> providers) {
127 return registry.removeAndPutAll(registeredIds, providers);
128 }
129
130 public Collection<TemplateDefinition> getAvailableTemplates(Node content) {
131
132 try {
133 if (content != null && NodeUtil.hasMixin(content, MgnlNodeType.MIX_DELETED)) {
134 return Collections.singleton(getTemplateDefinition(DELETED_PAGE_TEMPLATE));
135 }
136 } catch (RepositoryException e) {
137 log.error("Failed to check node for deletion status.", e);
138 } catch (RegistrationException e) {
139 log.error("Deleted content template is not correctly registered.", e);
140 }
141
142 final ArrayList<TemplateDefinition> availableTemplateDefinitions = new ArrayList<TemplateDefinition>();
143 final Collection<TemplateDefinition> templateDefinitions = getTemplateDefinitions();
144 for (TemplateDefinition templateDefinition : templateDefinitions) {
145 if (isAvailable(templateDefinition, content)) {
146 availableTemplateDefinitions.add(templateDefinition);
147 }
148 }
149 return availableTemplateDefinitions;
150 }
151
152 protected boolean isAvailable(TemplateDefinition templateDefinition, Node content) {
153 if (templateDefinition.getId().equals(DELETED_PAGE_TEMPLATE)) {
154 return false;
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169 public TemplateDefinition getDefaultTemplate(Node content) {
170
171
172 TemplateDefinition parentTemplate = null;
173 try {
174 parentTemplate = getTemplateDefinition(content.getParent());
175 } catch (RepositoryException e) {
176 log.error("Failed to determine template assigned to parent of node: " + NodeUtil.getNodePathIfPossible(content), e);
177 }
178
179 if (parentTemplate != null && templateAvailability.isAvailable(content, parentTemplate)) {
180 return parentTemplate;
181 }
182
183
184 Collection<TemplateDefinition> templates = getAvailableTemplates(content);
185 if (templates.isEmpty()) {
186 return null;
187 }
188
189 return templates.iterator().next();
190 }
191
192 private TemplateDefinition getTemplateDefinition(Node node) throws RepositoryException {
193 String templateId = MetaDataUtil.getTemplate(node);
194 if (StringUtils.isEmpty(templateId)) {
195 return null;
196 }
197 try {
198
199 TemplateDefinitionAssignment templateDefinitionAssignment = Components.getComponent(TemplateDefinitionAssignment.class);
200 return templateDefinitionAssignment.getAssignedTemplateDefinition(node);
201 } catch (RegistrationException e) {
202 return null;
203 }
204 }
205 }