1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ch.esense.magnolia.module.googlesitemap.tags;
16
17 import info.magnolia.cms.beans.config.ServerConfiguration;
18 import info.magnolia.cms.core.Content;
19 import info.magnolia.cms.core.HierarchyManager;
20 import info.magnolia.cms.core.ItemType;
21 import info.magnolia.cms.i18n.I18nContentSupport;
22 import info.magnolia.cms.i18n.I18nContentSupportFactory;
23 import info.magnolia.cms.util.QueryUtil;
24 import info.magnolia.context.MgnlContext;
25 import info.magnolia.context.MgnlContext.VoidOp;
26 import info.magnolia.module.templating.MagnoliaTemplatingUtilities;
27
28 import java.io.IOException;
29 import java.text.SimpleDateFormat;
30 import java.util.ArrayList;
31 import java.util.Calendar;
32 import java.util.Collection;
33 import java.util.Iterator;
34 import java.util.Locale;
35
36 import javax.jcr.RepositoryException;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.jsp.JspException;
39 import javax.servlet.jsp.JspWriter;
40 import javax.servlet.jsp.tagext.TagSupport;
41
42 import org.apache.commons.lang.StringUtils;
43 import org.apache.commons.lang.exception.NestableRuntimeException;
44 import org.apache.log4j.Logger;
45
46
47
48
49
50
51
52 public class SitemapTag extends TagSupport {
53
54
55
56
57 public static final String DEFAULT_PRIORITY_NODEDATA = "googleSitemapPriority";
58
59
60
61
62 public static final String DEFAULT_CHANGEFREQ_NODEDATA = "googleSitemapChangefreq";
63
64
65
66
67 public static final String DEFAULT_HIDEINGOOGLESITEMAP_NODEDATA = "googleSitemapHide";
68
69
70
71
72 public static final String DEFAULT_HIDEINGOOGLESITEMAPCHILDREN_NODEDATA = "googleSitemapHideChildren";
73
74
75
76
77 public static final String DEFAULT_WORKSPACE = "website";
78
79
80
81
82 public static final String DEFAULT_MODE_VALUE = "xml";
83
84
85
86
87 private static final long serialVersionUID = 222L;
88
89 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
90
91 private static final Logger log = Logger.getLogger(SitemapTag.class);
92
93
94
95
96 private String startNode;
97
98
99
100
101 private String workspace;
102
103
104
105
106 private String hideInGoogleSitemap;
107
108
109
110
111 private String hideInGoogleSitemapChildren;
112
113
114
115
116 private String priority;
117
118
119
120
121 private String changefreq;
122
123
124
125
126 private int level;
127
128 final I18nContentSupport i18nSupport = I18nContentSupportFactory.getI18nSupport();
129
130
131
132
133
134
135
136 public void setWorkspace(String workspace) {
137 this.workspace = workspace;
138 }
139
140
141
142
143
144
145
146 public void setStartNode(String startNode) {
147 this.startNode = startNode;
148 }
149
150
151
152
153
154
155
156 public void setPriority(String priority) {
157 this.priority = priority;
158 }
159
160
161
162
163
164
165
166 public void setHideInGoogleSitemap(String hideInGoogleSitemap) {
167 this.hideInGoogleSitemap = hideInGoogleSitemap;
168 }
169
170
171
172
173
174
175
176 public void setHideInGoogleSitemapChildren(
177 String hideInGoogleSitemapChildren) {
178 this.hideInGoogleSitemapChildren = hideInGoogleSitemapChildren;
179 }
180
181
182
183
184
185
186
187 public void setChangefreq(String changefreq) {
188 this.changefreq = changefreq;
189 }
190
191
192
193
194 public int doEndTag() throws JspException {
195 Content activePage = MgnlContext.getAggregationState().getMainContent();
196 JspWriter out = this.pageContext.getOut();
197 final HierarchyManager hm = MgnlContext.getHierarchyManager("website");
198
199 Collection locales = new ArrayList();
200
201 if (i18nSupport.isEnabled()) {
202 locales = i18nSupport.getLocales();
203 }
204
205 final String defaultBaseUrl = ServerConfiguration.getInstance()
206 .getDefaultBaseUrl();
207
208 try {
209
210 if (this.workspace.equals("website"))
211 if (this.startNode == null) {
212 drawChildren(activePage.getAncestor(0), activePage, out,
213 level + 1, defaultBaseUrl, locales);
214 } else {
215 drawChildren(hm.getContent(this.startNode), activePage,
216 out, level + 1, defaultBaseUrl,
217 locales);
218 }
219 else if (this.workspace.equals("config")) {
220 final JspWriter o = out;
221 new VoidOp(){
222 public void doExec() {
223 final String xpath = "//virtualURIMapping//element(*,mgnl:contentNode)";
224 final Collection nodes = QueryUtil.query("config", xpath, "xpath", "mgnl:contentNode");
225 try {
226 drawVirtualURIMapping(nodes, o, defaultBaseUrl);
227 } catch (IOException e) {
228 e.printStackTrace();
229 } catch (RepositoryException e) {
230 e.printStackTrace();
231 }
232 }
233 };
234 }
235 }
236
237 catch (RepositoryException e) {
238
239 log.warn("RepositoryException caught while drawing navigation");
240 return EVAL_PAGE;
241 } catch (IOException e) {
242
243 throw new NestableRuntimeException(e);
244 }
245 return EVAL_PAGE;
246
247 }
248
249
250
251
252 public void release() {
253 this.startNode = null;
254 this.level = 1;
255 super.release();
256 }
257
258 private void drawVirtualURIMapping(Collection nodes, JspWriter out,
259 String defaultBaseUrl) throws IOException, RepositoryException {
260
261 if (nodes.size() == 0) {
262 return;
263 }
264
265 for (Iterator iter = nodes.iterator(); iter.hasNext();) {
266 Content node = (Content) iter.next();
267
268
269 double priority = 0.5;
270 if (node.hasNodeData(StringUtils.defaultString(this.priority,
271 DEFAULT_PRIORITY_NODEDATA))) {
272 priority = node.getNodeData(
273 StringUtils.defaultString(this.priority,
274 DEFAULT_PRIORITY_NODEDATA)).getDouble();
275 }
276
277
278 String changefreq = "weekly";
279 if (node.hasNodeData(StringUtils.defaultString(this.changefreq,
280 DEFAULT_CHANGEFREQ_NODEDATA))) {
281 changefreq = node.getNodeData(
282 StringUtils.defaultString(this.changefreq,
283 DEFAULT_CHANGEFREQ_NODEDATA)).getString();
284 }
285
286 if (!node.getNodeData(
287 StringUtils.defaultString(this.hideInGoogleSitemap,
288 DEFAULT_HIDEINGOOGLESITEMAP_NODEDATA)).getBoolean()) {
289 if (node.getMetaData().hasProperty("mgnl:lastmodified")) {
290 out.print("<url>");
291 out.print("<loc>");
292
293 out.print(defaultBaseUrl);
294
295 out.print(((HttpServletRequest) this.pageContext
296 .getRequest()).getContextPath());
297
298 out.print(node.getNodeData("fromURI").getString());
299
300 out.print("</loc>");
301 out.print("<lastmod>");
302 out.print(DATE_FORMAT.format(node.getMetaData().getModificationDate().getTime()));
303 out.print("</lastmod>");
304 out.print("<changefreq>");
305 out.print(changefreq);
306 out.print("</changefreq>");
307 out.print("<priority>");
308 out.print(Double.toString(priority));
309 out.print("</priority>");
310 out.print("</url>");
311 }
312 }
313 }
314 }
315
316
317
318
319 private void drawChildren(Content page, Content activePage, JspWriter out,
320 int level, String defaultBaseUrl, Collection locales)
321 throws IOException, RepositoryException {
322 Collection children = page.getChildren(ItemType.CONTENT);
323
324 if (children.size() == 0) {
325 return;
326 }
327
328
329 Iterator it = children.iterator();
330
331 it = children.iterator();
332
333 while (it.hasNext()) {
334 Content child = (Content) it.next();
335
336 if (!child.getNodeData(
337 StringUtils.defaultString(this.hideInGoogleSitemap,
338 DEFAULT_HIDEINGOOGLESITEMAP_NODEDATA)).getBoolean()) {
339
340 }
341
342
343 double priority = 0.5;
344 if (child.hasNodeData(StringUtils.defaultString(this.priority,
345 DEFAULT_PRIORITY_NODEDATA))) {
346 priority = child.getNodeData(
347 StringUtils.defaultString(this.priority,
348 DEFAULT_PRIORITY_NODEDATA)).getDouble();
349 }
350
351
352 String changefreq = "weekly";
353 if (child.hasNodeData(StringUtils.defaultString(this.changefreq,
354 DEFAULT_CHANGEFREQ_NODEDATA))) {
355 changefreq = child.getNodeData(
356 StringUtils.defaultString(this.changefreq,
357 DEFAULT_CHANGEFREQ_NODEDATA)).getString();
358 }
359
360 boolean showChildren = true;
361
362 if (child.getNodeData(
363 StringUtils.defaultString(this.hideInGoogleSitemap,
364 DEFAULT_HIDEINGOOGLESITEMAPCHILDREN_NODEDATA))
365 .getBoolean()) {
366 showChildren = false;
367 }
368
369 if (!child.getNodeData(
370 StringUtils.defaultString(this.hideInGoogleSitemap,
371 DEFAULT_HIDEINGOOGLESITEMAP_NODEDATA)).getBoolean()
372 && !child
373 .getNodeData(
374 StringUtils
375 .defaultString(
376 this.hideInGoogleSitemap,
377 DEFAULT_HIDEINGOOGLESITEMAPCHILDREN_NODEDATA))
378 .getBoolean()) {
379 if (locales.isEmpty()) {
380 out.print("<url>");
381 out.print("<loc>");
382
383 out.print(defaultBaseUrl);
384
385 out.print(((HttpServletRequest) this.pageContext
386 .getRequest()).getContextPath());
387
388 out.print(child.getHandle());
389 out.print(".html");
390 out.print("</loc>");
391 out.print("<lastmod>");
392 Calendar lastMod = child.getMetaData().getModificationDate();
393 out.print(DATE_FORMAT.format(lastMod != null ? lastMod.getTime(): child.getMetaData().getCreationDate().getTime()));
394 out.print("</lastmod>");
395 out.print("<changefreq>");
396 out.print(changefreq);
397 out.print("</changefreq>");
398 out.print("<priority>");
399 out.print(Double.toString(priority));
400 out.print("</priority>");
401 out.print("</url>");
402
403 } else {
404 Locale currentLocale = i18nSupport.getLocale();
405 for (Iterator iter = locales.iterator(); iter.hasNext();) {
406 Locale locale = (Locale) iter.next();
407 out.print("<url>");
408 out.print("<loc>");
409
410 out.print(defaultBaseUrl);
411
412 out.print(((HttpServletRequest) this.pageContext
413 .getRequest()).getContextPath());
414 i18nSupport.setLocale(locale);
415 out.print(MagnoliaTemplatingUtilities.getInstance().createLink(child));
416 out.print("</loc>");
417 out.print("<lastmod>");
418 Calendar lastMod = child.getMetaData().getModificationDate();
419 out.print(DATE_FORMAT.format(lastMod != null ? lastMod.getTime(): child.getMetaData().getCreationDate().getTime()));
420 out.print("</lastmod>");
421 out.print("<changefreq>");
422 out.print(changefreq);
423 out.print("</changefreq>");
424 out.print("<priority>");
425 out.print(Double.toString(priority));
426 out.print("</priority>");
427 out.print("</url>");
428 }
429
430 i18nSupport.setLocale(currentLocale);
431 }
432 }
433 if (showChildren) {
434 drawChildren(child, activePage, out, level + 1,
435 defaultBaseUrl, locales);
436 }
437 }
438 }
439 }