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.module.blossom.template;
35
36 import java.util.Collection;
37 import java.util.List;
38 import javax.jcr.RepositoryException;
39
40 import org.apache.commons.lang.StringUtils;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.beans.factory.InitializingBean;
44 import org.springframework.context.ApplicationEvent;
45 import org.springframework.context.ApplicationListener;
46
47 import info.magnolia.module.blossom.annotation.Area;
48 import info.magnolia.module.blossom.annotation.Template;
49 import info.magnolia.module.blossom.dialog.BlossomDialogDescription;
50 import info.magnolia.module.blossom.dialog.BlossomDialogRegistry;
51 import info.magnolia.module.blossom.dialog.DialogDescriptionBuilder;
52 import info.magnolia.module.blossom.dispatcher.BlossomDispatcher;
53 import info.magnolia.module.blossom.dispatcher.BlossomDispatcherAware;
54 import info.magnolia.module.blossom.dispatcher.BlossomDispatcherInitializedEvent;
55 import info.magnolia.module.blossom.support.AbstractUrlMappedHandlerPostProcessor;
56 import info.magnolia.objectfactory.Components;
57 import info.magnolia.rendering.template.AreaDefinition;
58 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
59
60
61
62
63
64
65 public class TemplateExporter extends AbstractUrlMappedHandlerPostProcessor implements InitializingBean, ApplicationListener, BlossomDispatcherAware {
66
67 private static final String TEMPLATE_DIALOG_PREFIX = "blossom-template-dialog:";
68 private static final String AREA_DIALOG_PREFIX = "blossom-area-dialog:";
69
70 private final Logger logger = LoggerFactory.getLogger(getClass());
71
72 private BlossomDispatcher dispatcher;
73 private TemplateDefinitionBuilder templateDefinitionBuilder;
74 private DialogDescriptionBuilder dialogDescriptionBuilder;
75
76 private DetectedHandlersMetaData detectedHandlers = new DetectedHandlersMetaData();
77
78 public void setTemplateDefinitionBuilder(TemplateDefinitionBuilder templateDefinitionBuilder) {
79 this.templateDefinitionBuilder = templateDefinitionBuilder;
80 }
81
82 public void setDialogDescriptionBuilder(DialogDescriptionBuilder dialogDescriptionBuilder) {
83 this.dialogDescriptionBuilder = dialogDescriptionBuilder;
84 }
85
86 @Override
87 public void setBlossomDispatcher(BlossomDispatcher dispatcher) {
88 this.dispatcher = dispatcher;
89 }
90
91 @Override
92 protected void postProcessHandler(Object handler, String handlerPath) {
93 if (handler.getClass().isAnnotationPresent(Area.class)) {
94 detectedHandlers.addArea(new HandlerMetaData(handler, handlerPath));
95 } else if (handler.getClass().isAnnotationPresent(Template.class)) {
96 detectedHandlers.addTemplate(new HandlerMetaData(handler, handlerPath));
97 }
98 }
99
100 @Override
101 public void onApplicationEvent(ApplicationEvent event) {
102 if (event instanceof BlossomDispatcherInitializedEvent && event.getSource() == dispatcher) {
103 exportTemplates();
104 }
105 }
106
107 protected void exportTemplates() {
108 for (HandlerMetaData template : detectedHandlers.getTemplates()) {
109
110 BlossomTemplateDefinition definition = templateDefinitionBuilder.buildTemplateDefinition(dispatcher, detectedHandlers, template);
111
112 Components.getComponent(TemplateDefinitionRegistry.class).register(new BlossomTemplateDefinitionProvider(definition));
113
114 if (StringUtils.isEmpty(definition.getDialog())) {
115 registerTemplateDialog(definition);
116 }
117
118 registerDialogFactories(definition);
119
120 registerAreaDialogs(definition.getAreas().values());
121 }
122
123
124 detectedHandlers = null;
125 }
126
127 protected void registerDialogFactories(BlossomTemplateDefinition templateDefinition) {
128
129 List<BlossomDialogDescription> dialogDescriptions = dialogDescriptionBuilder.buildDescriptions(templateDefinition.getHandler());
130 for (BlossomDialogDescription dialogDescription : dialogDescriptions) {
131 try {
132 Components.getComponent(BlossomDialogRegistry.class).addDialogDescription(dialogDescription);
133 } catch (RepositoryException e) {
134 logger.error("Unable to register dialog factory within template [" + dialogDescription.getFactoryMetaData().getFactoryMethod() + "] with handlerPath [" + templateDefinition.getHandlerPath() + "]", e);
135 }
136
137 if (logger.isDebugEnabled()) {
138 logger.debug("Registered dialog factory within template [" + templateDefinition.getId() + "] with id [" + dialogDescription.getId() + "]");
139 }
140 }
141 }
142
143 protected void registerTemplateDialog(BlossomTemplateDefinition templateDefinition) {
144
145 String templateId = templateDefinition.getId();
146
147 String dialogId = TEMPLATE_DIALOG_PREFIX + templateDefinition.getHandler().getClass().getName();
148
149 BlossomDialogDescription dialogDescription = dialogDescriptionBuilder.buildDescription(dialogId, templateDefinition.getTitle(), templateDefinition.getHandler());
150
151 if (dialogDescription.getFactoryMetaData().isEmpty()) {
152 return;
153 }
154
155 templateDefinition.setDialog(dialogId);
156
157 try {
158 Components.getComponent(BlossomDialogRegistry.class).addDialogDescription(dialogDescription);
159 } catch (RepositoryException e) {
160 logger.error("Failed to register dialog for template [" + templateId + "] with id [" + dialogId + "]", e);
161 return;
162 }
163
164 if (logger.isDebugEnabled()) {
165 logger.debug("Registered dialog for template [" + templateId + "] with id [" + dialogId + "]");
166 }
167 }
168
169 protected void registerAreaDialogs(Collection<AreaDefinition> areas) {
170 for (AreaDefinition areaDefinition : areas) {
171 if (StringUtils.isEmpty(areaDefinition.getDialog())) {
172 registerAreaDialog((BlossomAreaDefinition) areaDefinition);
173 }
174 registerAreaDialogs(areaDefinition.getAreas().values());
175 }
176 }
177
178 protected void registerAreaDialog(BlossomAreaDefinition areaDefinition) {
179
180 String areaName = areaDefinition.getName();
181
182 String dialogId = AREA_DIALOG_PREFIX + areaDefinition.getHandler().getClass().getName();
183
184 BlossomDialogDescription dialogDescription = dialogDescriptionBuilder.buildDescription(dialogId, areaDefinition.getTitle(), areaDefinition.getHandler());
185
186 if (dialogDescription.getFactoryMetaData().isEmpty()) {
187 return;
188 }
189
190 areaDefinition.setDialog(dialogId);
191
192 try {
193 Components.getComponent(BlossomDialogRegistry.class).addDialogDescription(dialogDescription);
194 } catch (RepositoryException e) {
195 logger.error("Failed to register dialog for area [" + areaName + "] with id [" + dialogId + "]", e);
196 return;
197 }
198
199 if (logger.isDebugEnabled()) {
200 logger.debug("Registered dialog for area [" + areaName + "] with id [" + dialogId + "]");
201 }
202 }
203
204 @Override
205 public void afterPropertiesSet() throws Exception {
206 if (templateDefinitionBuilder == null) {
207 templateDefinitionBuilder = new TemplateDefinitionBuilder();
208 }
209 if (dialogDescriptionBuilder == null) {
210 dialogDescriptionBuilder = new DialogDescriptionBuilder();
211 }
212 }
213 }