/*
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2014 Adobe
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.adobe.acs.commons.wcm.impl;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletException;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.PropertiesUtil;
import com.day.cq.commons.Externalizer;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageFilter;
import com.day.cq.wcm.api.PageManager;
@Component(metatype = true, label = "ACS AEM Commons - Site Map Servlet", description = "Site Map Servlet",
configurationFactory = true)
@Service
@SuppressWarnings("serial")
@Properties({ @Property(name = "sling.servlet.resourceTypes", unbounded = PropertyUnbounded.ARRAY,
label = "Sling Resource Type", description = "Sling Resource Type for the Home Page component or components."),
@Property(name = "sling.servlet.selectors", value = "sitemap", propertyPrivate = true),
@Property(name = "sling.servlet.extensions", value = "xml", propertyPrivate = true),
@Property(name = "sling.servlet.methods", value = "GET", propertyPrivate = true) })
public final class SiteMapServlet extends SlingSafeMethodsServlet {
private static final String DEFAULT_EXTERNALIZER_DOMAIN = "publish";
@Property(value = DEFAULT_EXTERNALIZER_DOMAIN, label = "Externalizer Domain",
description = "Must correspond to a configuration of the Externalizer component.")
private static final String PROP_EXTERNALIZER_DOMAIN = "externalizer.domain";
private static final String NS = "http://www.sitemaps.org/schemas/sitemap/0.9";
@Reference
private Externalizer externalizer;
private String externalizerDomain;
@Activate
protected void activate(Map<String, Object> properties) {
this.externalizerDomain = PropertiesUtil.toString(properties.get(PROP_EXTERNALIZER_DOMAIN),
DEFAULT_EXTERNALIZER_DOMAIN);
}
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
response.setContentType(request.getResponseContentType());
ResourceResolver resourceResolver = request.getResourceResolver();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page page = pageManager.getContainingPage(request.getResource());
XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
try {
XMLStreamWriter stream = outputFactory.createXMLStreamWriter(response.getWriter());
stream.writeStartDocument("1.0");
stream.writeStartElement("", "urlset", NS);
stream.writeNamespace("", NS);
// first do the current page
write(page, stream, resourceResolver);
for (Iterator<Page> children = page.listChildren(new PageFilter(), true); children.hasNext();) {
write(children.next(), stream, resourceResolver);
}
stream.writeEndElement();
stream.writeEndDocument();
} catch (XMLStreamException e) {
throw new IOException(e);
}
}
private void write(Page page, XMLStreamWriter stream, ResourceResolver resolver) throws XMLStreamException {
stream.writeStartElement(NS, "url");
stream.writeStartElement(NS, "loc");
String loc = externalizer.externalLink(resolver, externalizerDomain,
String.format("%s.html", page.getPath()));
stream.writeCharacters(loc);
stream.writeEndElement();
stream.writeEndElement();
}
}