Commit e10e166b authored by Joseph Beard's avatar Joseph Beard Committed by dfabulich
Browse files

Write empty sitemap and index files (#23)

* Allow SitemapGenerators to write an empty sitemap.

* Allow SitemapIndexGenerators to write an empty sitemap index.
parent 6e9832be
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ abstract class AbstractSitemapGeneratorOptions<THIS extends AbstractSitemapGener
	File baseDir;
	URL baseUrl;
	String fileNamePrefix = "sitemap";
	boolean allowEmptySitemap = false;
	boolean allowMultipleSitemaps = true;
	String suffixStringPattern; // this will store some type of string pattern suitable per needs.
	W3CDateFormat dateFormat;
@@ -38,6 +39,17 @@ abstract class AbstractSitemapGeneratorOptions<THIS extends AbstractSitemapGener
		return getThis();
	}

	/**
	 * Permit writing a sitemap that contains no URLs.
	 *
	 * @param allowEmpty {@code true} if an empty sitemap is permissible
	 * @return this instance, for chaining
	 */
	public THIS allowEmptySitemap(boolean allowEmpty) {
		this.allowEmptySitemap = allowEmpty;
		return getThis();
	}

	/** When more than the maximum number of URLs are passed in, should we split into multiple sitemaps automatically, or just throw an exception? */
	public THIS allowMultipleSitemaps(boolean allowMultipleSitemaps) {
		this.allowMultipleSitemaps = allowMultipleSitemaps;
+4 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ abstract class SitemapGenerator<U extends ISitemapUrl, THIS extends SitemapGener
	private final File baseDir;
	private final String fileNamePrefix;
	private final String fileNameSuffix;
	private final boolean allowEmptySitemap;
	private final boolean allowMultipleSitemaps;
	private final ArrayList<U> urls = new ArrayList<U>();
	private final W3CDateFormat dateFormat;
@@ -40,6 +41,7 @@ abstract class SitemapGenerator<U extends ISitemapUrl, THIS extends SitemapGener
		W3CDateFormat dateFormat = options.dateFormat;
		if (dateFormat == null) dateFormat = new W3CDateFormat();
		this.dateFormat = dateFormat;
		allowEmptySitemap = options.allowEmptySitemap;
		allowMultipleSitemaps = options.allowMultipleSitemaps;
		maxUrls = options.maxUrls;
		autoValidate = options.autoValidate;
@@ -165,7 +167,7 @@ abstract class SitemapGenerator<U extends ISitemapUrl, THIS extends SitemapGener
	 */
	public List<File> write() {
		if (finished) throw new RuntimeException("Sitemap already printed; you must create a new generator to make more sitemaps");
		if (urls.size() == 0 && mapCount == 0) throw new RuntimeException("No URLs added, sitemap would be empty; you must add some URLs with addUrls");
		if (!allowEmptySitemap && urls.isEmpty() && mapCount == 0) throw new RuntimeException("No URLs added, sitemap would be empty; you must add some URLs with addUrls");
		writeSiteMap();
		finished = true;
		return outFiles;
@@ -221,7 +223,7 @@ abstract class SitemapGenerator<U extends ISitemapUrl, THIS extends SitemapGener
		if (baseDir == null) {
			throw new NullPointerException("To write to files, baseDir must not be null");
		}
		if (urls.size() == 0) return;
		if (urls.isEmpty() && (mapCount > 0 || !allowEmptySitemap)) return;
		String fileNamePrefix;
		if (mapCount > 0) {
			fileNamePrefix = this.fileNamePrefix + mapCount;
+16 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import org.xml.sax.SAXException;
public class SitemapIndexGenerator {
	private final URL baseUrl;	
	private final File outFile;
	private final boolean allowEmptyIndex;
	private final ArrayList<SitemapIndexUrl> urls = new ArrayList<SitemapIndexUrl>();
	private final int maxUrls;
	private final W3CDateFormat dateFormat;
@@ -32,6 +33,7 @@ public class SitemapIndexGenerator {
		private URL baseUrl;
		private File outFile;
		private W3CDateFormat dateFormat = null;
		private boolean allowEmptyIndex = false;
		private int maxUrls = MAX_SITEMAPS_PER_INDEX;
		private Date defaultLastMod = new Date();
		private boolean autoValidate = false;
@@ -59,6 +61,18 @@ public class SitemapIndexGenerator {
			this.dateFormat = dateFormat;
			return this;
		}

		/**
		 * Permit writing an index that contains no URLs.
		 *
		 * @param allowEmptyIndex {@code true} if an empty index is permissible
		 * @return this instance, for chaining
		 */
		public Options allowEmptyIndex(boolean allowEmptyIndex) {
			this.allowEmptyIndex = allowEmptyIndex;
			return this;
		}

		/**
		 * The maximum number of sitemaps to allow per sitemap index; the default is the
		 * maximum allowed (1,000), but you can decrease it if you wish (for testing)
@@ -116,6 +130,7 @@ public class SitemapIndexGenerator {
	private SitemapIndexGenerator(Options options) {
		this.baseUrl = options.baseUrl;		
		this.outFile = options.outFile;
		this.allowEmptyIndex = options.allowEmptyIndex;
		this.maxUrls = options.maxUrls;
		W3CDateFormat dateFormat = options.dateFormat;
		if (dateFormat == null) dateFormat = new W3CDateFormat();
@@ -206,7 +221,7 @@ public class SitemapIndexGenerator {
	
	/** Writes out the sitemap index */
	public void write() {
		if (urls.size() == 0) throw new RuntimeException("No URLs added, sitemap index would be empty; you must add some URLs with addUrls");
		if (!allowEmptyIndex && urls.isEmpty()) throw new RuntimeException("No URLs added, sitemap index would be empty; you must add some URLs with addUrls");
		try {
			// TODO gzip? is that legal for a sitemap index?
			FileWriter out = new FileWriter(outFile);
+18 −0
Original line number Diff line number Diff line
@@ -348,6 +348,24 @@ public class SitemapGeneratorTest extends TestCase {
		assertEquals("Second string didn't match", SITEMAP_PLUS_ONE, siteMapsAsStrings.get(1));
	}

	public void testWriteEmptySitemap() throws Exception {
		wsg = WebSitemapGenerator.builder("http://www.example.com", dir).allowEmptySitemap(true).build();
		String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
				"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" >\n" +
				"</urlset>";
		String sitemap = writeSingleSiteMap(wsg);
		assertEquals(expected, sitemap);
	}

	public void testMaxUrlsAllowingEmptyDoesNotWriteExtraSitemap() throws Exception {
		wsg = WebSitemapGenerator.builder("http://www.example.com", dir).allowEmptySitemap(true).maxUrls(10).build();
		for (int i = 0; i < 10; i++) {
			wsg.addUrl("http://www.example.com/"+i);
		}
		String sitemap = writeSingleSiteMap(wsg);
		assertEquals(SITEMAP1, sitemap);
	}
	
	private String writeSingleSiteMap(WebSitemapGenerator wsg) {
		List<File> files = wsg.write();
		assertEquals("Too many files: " + files.toString(), 1, files.size());
+10 −0
Original line number Diff line number Diff line
@@ -87,6 +87,16 @@ public class SitemapIndexGeneratorTest extends TestCase {
		} catch (RuntimeException e) {}
	}

	public void testNoUrlsEmptyIndexAllowed() throws Exception {
		sig = new SitemapIndexGenerator.Options(EXAMPLE, outFile).allowEmptyIndex(true).build();
		sig.write();
		String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
				"<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n" +
				"</sitemapindex>";
		String actual = TestUtil.slurpFileAndDelete(outFile);
		assertEquals(expected, actual);
	}
	
	public void testMaxUrls() throws Exception {
		sig = new SitemapIndexGenerator.Options(EXAMPLE, outFile).autoValidate(true)
			.maxUrls(10).defaultLastMod(new Date(0)).dateFormat(ZULU).build();