package com.ajah.sitemap; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import com.ajah.lang.ConfigException; import com.ajah.util.date.DateUtils; /** * A writer that generates the actual sitemap files. * * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a * href="mailto:code@efsavage.com">code@efsavage.com</a>. * */ public class SiteMapWriter { private static Node toElement(final Document doc, final SiteMap siteMap) { final Element siteMapElement = doc.createElement("sitemap"); final Element siteMapLocElement = doc.createElement("loc"); siteMapLocElement.setTextContent(siteMap.getLocationRoot() + "/" + siteMap.getFilename()); siteMapElement.appendChild(siteMapLocElement); // Element siteMapLastModElement = doc.createElement("lastmod"); // siteMapLastModElement.setTextContent(DateUtils.W3C_FORMAT.format(new // Date())); // siteMapElement.appendChild(siteMapLastModElement); return siteMapElement; } private static Node toElement(final Document doc, final SiteMapUrl siteMapUrl) { final Element siteMapElement = doc.createElement("url"); final Element siteMapLocElement = doc.createElement("loc"); siteMapLocElement.setTextContent(siteMapUrl.getLoc()); siteMapElement.appendChild(siteMapLocElement); if (siteMapUrl.getLastMod() != null) { final Element siteMapLastModElement = doc.createElement("lastmod"); siteMapLastModElement.setTextContent(DateUtils.W3C_FORMAT.format(siteMapUrl.getLastMod())); siteMapElement.appendChild(siteMapLastModElement); } if (siteMapUrl.getPriority() != null) { final Element siteMapLastModElement = doc.createElement("priority"); siteMapLastModElement.setTextContent(String.valueOf(siteMapUrl.getPriority())); siteMapElement.appendChild(siteMapLastModElement); } if (siteMapUrl.getChangeFrequency() != null) { final Element siteMapLastModElement = doc.createElement("lastmod"); siteMapLastModElement.setTextContent(DateUtils.W3C_FORMAT.format(siteMapUrl.getChangeFrequency().name().toLowerCase())); siteMapElement.appendChild(siteMapLastModElement); } return siteMapElement; } /** * Writes a sitemap. * * @param siteMap * The sitemap to write. * @throws TransformerException * If the XML document could not be constructed. */ public static void write(final SiteMap siteMap) throws TransformerException { final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder; try { docBuilder = docFactory.newDocumentBuilder(); } catch (final ParserConfigurationException e) { // This never really happens in a normal JVM throw new ConfigException(e); } // root elements final Document doc = docBuilder.newDocument(); final Element rootElement = doc.createElementNS("http://www.sitemaps.org/schemas/sitemap/0.9", "urlset"); doc.appendChild(rootElement); for (final SiteMapUrl siteMapUrl : siteMap.getSiteMapUrls()) { rootElement.appendChild(toElement(doc, siteMapUrl)); } // write the content into xml file final TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer; try { transformer = transformerFactory.newTransformer(); } catch (final TransformerConfigurationException e) { // This never really happens in a normal JVM throw new ConfigException(e); } transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); final DOMSource source = new DOMSource(doc); final StreamResult result = new StreamResult(new File(siteMap.getFilename())); transformer.transform(source, result); System.out.println("File saved!"); } /** * Write an index and all of its children. * * @param index * The index to write. * @throws TransformerException * If the XML document could not be constructed. */ public static void write(final SiteMapIndex index) throws TransformerException { final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder; try { docBuilder = docFactory.newDocumentBuilder(); } catch (final ParserConfigurationException e) { // This never really happens in a normal JVM throw new ConfigException(e); } // root elements final Document doc = docBuilder.newDocument(); final Element rootElement = doc.createElementNS("http://www.sitemaps.org/schemas/sitemap/0.9", "sitemapindex"); doc.appendChild(rootElement); for (final SiteMap siteMap : index.getSiteMaps()) { rootElement.appendChild(toElement(doc, siteMap)); write(siteMap); } final TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer; try { transformer = transformerFactory.newTransformer(); } catch (final TransformerConfigurationException e) { // This never really happens in a normal JVM throw new ConfigException(e); } transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); final DOMSource source = new DOMSource(doc); final StreamResult result = new StreamResult(new File("sitemap.xml")); transformer.transform(source, result); System.out.println("File saved!"); } }