Commit 77da8689 authored by Noel's avatar Noel
Browse files

Añade generador para web con múltiples idiomas

Solo se ha tenido en cuenta los casos en los que se crea un dominio por idioma.
Cuando se trata de un idioma por defecto se elimina el dominio.

Ej: English - https://en.ejemplo.com
    Spanish (default) - https://ejemplo.com
parent c4a85bf8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@
          </execution>
        </executions>
      </plugin>
      <plugin>
      <!-- plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-gpg-plugin</artifactId>
        <version>1.5</version>
@@ -101,7 +101,7 @@
            </goals>
          </execution>
        </executions>
      </plugin>
      </plugin-->
      <plugin>
        <groupId>org.sonatype.plugins</groupId>
        <artifactId>nexus-staging-maven-plugin</artifactId>
+191 −0
Original line number Diff line number Diff line
package com.redfin.sitemapgenerator;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import com.redfin.sitemapgenerator.MultipleLangSitemapUrl.Options;

/**
 * Builds a image sitemap for Multilanguage website. To configure options, use
 * {@link #builder(URL, File)}
 * 
 * @author Noel Alonso
 */
public class MultipleLangSitemapGenerator
		extends SitemapGenerator<MultipleLangSitemapUrl, MultipleLangSitemapGenerator> {

	MultipleLangSitemapGenerator(AbstractSitemapGeneratorOptions<?> options) {
		super(options, new Renderer());
	}

	/**
	 * Configures the generator with a base URL and directory to write the
	 * sitemap files.
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 * @param baseDir
	 *            Sitemap files will be generated in this directory as either
	 *            "sitemap.xml" or "sitemap1.xml" "sitemap2.xml" and so on.
	 * @throws MalformedURLException
	 */
	public MultipleLangSitemapGenerator(String baseUrl, File baseDir) throws MalformedURLException {
		this(new SitemapGeneratorOptions(baseUrl, baseDir));
	}

	/**
	 * Configures the generator with a base URL and directory to write the
	 * sitemap files.
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 * @param baseDir
	 *            Sitemap files will be generated in this directory as either
	 *            "sitemap.xml" or "sitemap1.xml" "sitemap2.xml" and so on.
	 */
	public MultipleLangSitemapGenerator(URL baseUrl, File baseDir) {
		this(new SitemapGeneratorOptions(baseUrl, baseDir));
	}

	/**
	 * Configures the generator with a base URL and a null directory. The object
	 * constructed is not intended to be used to write to files. Rather, it is
	 * intended to be used to obtain XML-formatted strings that represent
	 * sitemaps.
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 */
	public MultipleLangSitemapGenerator(String baseUrl) throws MalformedURLException {
		this(new SitemapGeneratorOptions(new URL(baseUrl)));
	}

	/**
	 * Configures the generator with a base URL and a null directory. The object
	 * constructed is not intended to be used to write to files. Rather, it is
	 * intended to be used to obtain XML-formatted strings that represent
	 * sitemaps.
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 */
	public MultipleLangSitemapGenerator(URL baseUrl) {
		this(new SitemapGeneratorOptions(baseUrl));
	}

	/**
	 * Configures a builder so you can specify sitemap generator options
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 * @param baseDir
	 *            Sitemap files will be generated in this directory as either
	 *            "sitemap.xml" or "sitemap1.xml" "sitemap2.xml" and so on.
	 * @return a builder; call .build() on it to make a sitemap generator
	 */
	public static SitemapGeneratorBuilder<MultipleLangSitemapGenerator> builder(URL baseUrl, File baseDir) {
		return new SitemapGeneratorBuilder<MultipleLangSitemapGenerator>(baseUrl, baseDir,
				MultipleLangSitemapGenerator.class);
	}

	/**
	 * Configures a builder so you can specify sitemap generator options
	 * 
	 * @param baseUrl
	 *            All URLs in the generated sitemap(s) should appear under this
	 *            base URL
	 * @param baseDir
	 *            Sitemap files will be generated in this directory as either
	 *            "sitemap.xml" or "sitemap1.xml" "sitemap2.xml" and so on.
	 * @return a builder; call .build() on it to make a sitemap generator
	 * @throws MalformedURLException
	 */
	public static SitemapGeneratorBuilder<MultipleLangSitemapGenerator> builder(String baseUrl, File baseDir)
			throws MalformedURLException {
		return new SitemapGeneratorBuilder<MultipleLangSitemapGenerator>(baseUrl, baseDir,
				MultipleLangSitemapGenerator.class);
	}

	private static class Renderer extends AbstractSitemapUrlRenderer<MultipleLangSitemapUrl>
			implements ISitemapUrlRenderer<MultipleLangSitemapUrl> {

		public Class<MultipleLangSitemapUrl> getUrlClass() {
			return MultipleLangSitemapUrl.class;
		}

		public String getXmlNamespaces() {
			return "\n  xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"";
		}

		public void render(MultipleLangSitemapUrl url, StringBuilder sb, W3CDateFormat dateFormat) {

			List<String> langs = url.getLangs();

			URL originalUrl = url.getUrl();

			for (String langForUrl : langs) {
				//new config for each URL
				url = newUrl(url, originalUrl, langForUrl);
				
				StringBuilder tagSb = new StringBuilder();

				for (String langForTag : langs) {
					addAlternate(tagSb, langForTag, getUrlByLang(originalUrl, langForTag, url.getDefaultLang()));
				}
				super.render(url, sb, dateFormat, tagSb.toString());
			}
		}

		/*
		 * Add lang tags
		 */

		private void addAlternate(StringBuilder tagSb, String lang, String url) {
			tagSb.append("    <xhtml:link\n");
			tagSb.append("      rel=\"alternate\"\n");
			tagSb.append("      hreflang=\"" + lang + "\"\n");
			tagSb.append("      href=\"" + url + "\"\n");
			tagSb.append("    />\n");
		}

	}
	
	/*
	 * Copy config for add new url tag with other language
	 * */
	public static MultipleLangSitemapUrl newUrl(MultipleLangSitemapUrl url, URL originalUrl, String lang) {
		
		try {
			String newUrl = getUrlByLang(originalUrl, lang, url.getDefaultLang());
			return new Options(newUrl, url.getLangs(), url.getDefaultLang())
				.changeFreq(url.getChangeFreq())
				// .priority(url.getPriority()) //TODO: fail when priority is null
				.lastMod(url.getLastMod())
				.build();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return url;
	}
	
	/*
	 * Create url depend on lang and defaultLang 
	 */

	public static String getUrlByLang(URL url, String lang, String defaultLang) {

		if (lang.equals(defaultLang)) {
			return url.toString();
		}

		// TODO: support others language url format. This case is a different language per domain
		return url.toString().replaceAll("//", "//" + lang + ".");
	}
}
+71 −0
Original line number Diff line number Diff line
package com.redfin.sitemapgenerator;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/** One configurable Multilanguage URL.  To configure, use {@link Options}
 * 
 * @author Noel Alonso
 * @see Options
 */
public class MultipleLangSitemapUrl extends WebSitemapUrl {

	//Languages allow 
	private List<String> langs = new ArrayList<String>();
	
	// Default lang
	private String defaultLang;
	
	/** Options to configure langs URLs */
	public static class Options extends AbstractSitemapUrlOptions<MultipleLangSitemapUrl, Options> {
		
		private List<String> langs;
		
		private String defaultLang;
		
		public Options(String url, List<String> langs, String defaultLang) throws MalformedURLException {
			super(new URL(url), MultipleLangSitemapUrl.class);
			this.langs = langs;
			this.defaultLang = defaultLang;
		}
		
		public Options langs(List<String> langs) {
			this.langs = langs;
			return this;
		}
		
		public Options defaultLang(String defaultLang) {
			this.defaultLang = defaultLang;
			return this;
		}
	}

	/** Specifies a landing page URL, together with an image url 
	 *  
	 * @param url the landing page URL
	 * @param imageUrl the URL of the image
	 * @throws MalformedURLException 
	 */
	public MultipleLangSitemapUrl(String url, List<String> langs, String defaultLang) throws MalformedURLException {
		this(new Options(url,langs,defaultLang));
	}
  
	/** Configures the url with options */
	public MultipleLangSitemapUrl(Options options) {
		super(options);
		langs = options.langs;
		defaultLang = options.defaultLang;
	}
	
	
	/** Retrieves the {@link Options#langs}*/
	public List<String> getLangs() {
		return langs;
	}
	
	public String getDefaultLang() {
		return defaultLang;
	}
}
+123 −0
Original line number Diff line number Diff line
package com.redfin.sitemapgenerator;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import com.redfin.sitemapgenerator.MultipleLangSitemapUrl.Options;

import junit.framework.TestCase;

public class MultipleLangSitemapUrlTest extends TestCase {
	
	private static final String HOST = "https://example.com",
			URL = "https://example.com/inner-terms-and-conditions";
	File dir;
	
	List<String> langs = Arrays.asList("es", "en");
	
	String defaultLang = "es";
	
	MultipleLangSitemapGenerator wsg;
	
	public void setUp() throws Exception {
		dir = File.createTempFile(MultipleLangSitemapUrlTest.class.getSimpleName(), "");
		dir.delete();
		dir.mkdir();
		dir.deleteOnExit();
	}
	
	public void tearDown() {
		wsg = null;
		for (File file : dir.listFiles()) {
			file.deleteOnExit();
			file.delete();
		}
		dir.delete();
		dir = null;
	}
	
	public void testSimpleUrl() throws Exception {
		wsg = new MultipleLangSitemapGenerator(HOST, dir);
		MultipleLangSitemapUrl url = new MultipleLangSitemapUrl(URL, langs, defaultLang);
		wsg.addUrl(url);
		String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
			"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" \n"+
			"  xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" >\n" + 
			"  <url>\n" + 
			"    <loc>https://example.com/inner-terms-and-conditions</loc>\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"es\"\n" +
	        "      href=\"https://example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"en\"\n" +
	        "      href=\"https://en.example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"  </url>\n" +
			"  <url>\n" + 
			"    <loc>https://en.example.com/inner-terms-and-conditions</loc>\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"es\"\n" +
	        "      href=\"https://example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"en\"\n" +
	        "      href=\"https://en.example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"  </url>\n" +
			"</urlset>";
		
		String sitemap = writeSingleSiteMap(wsg);
		assertEquals(expected, sitemap);
	}

	public void testOptions() throws Exception {
		wsg = MultipleLangSitemapGenerator.builder(HOST, dir).build();
		MultipleLangSitemapUrl url = new Options(URL, langs, defaultLang).build();
		wsg.addUrl(url);
		String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
			"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" \n"+
			"  xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" >\n" + 
			"  <url>\n" + 
			"    <loc>https://example.com/inner-terms-and-conditions</loc>\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"es\"\n" +
	        "      href=\"https://example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"en\"\n" +
	        "      href=\"https://en.example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"  </url>\n" +
			"  <url>\n" + 
			"    <loc>https://en.example.com/inner-terms-and-conditions</loc>\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"es\"\n" +
	        "      href=\"https://example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"    <xhtml:link\n" + 
	        "      rel=\"alternate\"\n" +
	        "      hreflang=\"en\"\n" +
	        "      href=\"https://en.example.com/inner-terms-and-conditions\"\n" + 
			"    />\n" + 
			"  </url>\n" +
			"</urlset>";
		String sitemap = writeSingleSiteMap(wsg);
		assertEquals(expected, sitemap);
	}
	
	private String writeSingleSiteMap(MultipleLangSitemapGenerator wsg) {
		List<File> files = wsg.write();
		assertEquals("Too many files: " + files.toString(), 1, files.size());
		assertEquals("Sitemap misnamed", "sitemap.xml", files.get(0).getName());
		return TestUtil.slurpFileAndDelete(files.get(0));
	}
}