Шустрый

Профиль
Группа: Участник
Сообщений: 73
Регистрация: 23.4.2008
Репутация: нет Всего: нет
|
Для генерации сайтмапа решил использовать sitemapgen4j. Все подключил, написал, вроде как работает. Но тесты не хотят выполняться. Пишет для обоих тестовых методов примено то же. при этом (я дебажил) при вызове метода generator.addUrl вызывается метод заглушки, а generator.write() - реальный метод. Строка 160 в последнем файле (SitemapGenerator) - это строка 145 в листинге. А (WebSitemapGenerator.java:14) - это объявление класса, сам он метод этот не переопределяет. Насколько я понимаю, суть в том, что при добавлении урлов вызывался метод заглушки и никакие урлы не добавлялиь. А потом для записи вызвался реальный метод и полез в NULL переменную. | Цитата | java.lang.NullPointerException at com.redfin.sitemapgenerator.SitemapGenerator.write(SitemapGenerator.java:160) at com.redfin.sitemapgenerator.WebSitemapGenerator.write(WebSitemapGenerator.java:14) at services.impl.SitemapServiceImpl.refreshSitemap(SitemapServiceImpl.java:66) at services.impl.SitemapServiceImplTest.testRefreshsitemapNoProduct(SitemapServiceImplTest.java:46) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
|
Код для генерации | Код | @Override public void refreshSitemap() throws MalformedURLException { LOGGER.info("Sitemap refreshing started");
generator.addUrl(applicationBaseUrl + "/");
List<Long> allPackSpecifications = packSpecificationService.getAllValidAndApprovedPackIds(); String actualProductPagePattern = applicationBaseUrl + PRODUCT_PAGE_PATTERN; for (Long packId : allPackSpecifications) { WebSitemapUrl packUrl = new WebSitemapUrl .Options(String.format(actualProductPagePattern, packId)) .changeFreq(ChangeFreq.WEEKLY) .build(); generator.addUrl(packUrl); }
generator.write(); generator.writeSitemapsWithIndex(); LOGGER.info("Sitemap refreshing finished successfully"); } |
Код теста | Код | public class SitemapServiceImplTest {
private static final int NUMBER_OF_PACKS = 10; private SitemapServiceImpl sitemapService;
private String baseUrl = "http://site.com";
@Mock private PackSpecificationServices packSpecificationServices; @Mock private WebSitemapGenerator webSitemapGenerator;
@Before public void setUp() throws MalformedURLException { MockitoAnnotations.initMocks(this);
sitemapService = new SitemapServiceImpl(baseUrl, packSpecificationServices); sitemapService.setWebSitemapGenerator(webSitemapGenerator); }
@Test public void testRefreshsitemapNoProduct() throws MalformedURLException { when(packSpecificationServices.getAllValidAndApprovedPackIds()).thenReturn(new ArrayList<Long>());
sitemapService.refreshSitemap();
verify(webSitemapGenerator).addUrl(anyString()); verify(webSitemapGenerator).write(); verify(webSitemapGenerator).writeSitemapsWithIndex(); }
@Test public void testRefreshsitemapSeveralProductExists() throws MalformedURLException { List<Long> ids = new ArrayList<Long>(NUMBER_OF_PACKS); for (int i = 0; i < NUMBER_OF_PACKS; i++) { ids.add(Long.valueOf(i)); } when(packSpecificationServices.getAllValidAndApprovedPackIds()).thenReturn(ids);
sitemapService.refreshSitemap();
verify(webSitemapGenerator, times(NUMBER_OF_PACKS + 1)).addUrl(anyString()); verify(webSitemapGenerator).write(); verify(webSitemapGenerator).writeSitemapsWithIndex(); } } |
код класса (из библиотеки) | Код | public class WebSitemapGenerator extends SitemapGenerator<WebSitemapUrl,WebSitemapGenerator> { WebSitemapGenerator(AbstractSitemapGeneratorOptions<?> options) { super(options, new Renderer()); } /** 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<WebSitemapGenerator> builder(URL baseUrl, File baseDir) { return new SitemapGeneratorBuilder<WebSitemapGenerator>(baseUrl, baseDir, WebSitemapGenerator.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 */ public static SitemapGeneratorBuilder<WebSitemapGenerator> builder(String baseUrl, File baseDir) throws MalformedURLException { return new SitemapGeneratorBuilder<WebSitemapGenerator>(baseUrl, baseDir, WebSitemapGenerator.class); }
/**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 WebSitemapGenerator(String baseUrl, File baseDir) throws MalformedURLException { this(new SitemapGeneratorOptions(new URL(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 WebSitemapGenerator(URL baseUrl, File baseDir) { this(new SitemapGeneratorOptions(baseUrl, baseDir)); }
private static class Renderer extends AbstractSitemapUrlRenderer<WebSitemapUrl> implements ISitemapUrlRenderer<WebSitemapUrl> {
public Class<WebSitemapUrl> getUrlClass() { return WebSitemapUrl.class; } public void render(WebSitemapUrl url, OutputStreamWriter out, W3CDateFormat dateFormat) throws IOException { super.render(url, out, dateFormat, null); }
public String getXmlNamespaces() { return null; }
} } |
полный код его суперкласса | Код | abstract class SitemapGenerator<U extends ISitemapUrl, THIS extends SitemapGenerator<U,THIS>> { /** 50000 URLs per sitemap maximum */ public static final int MAX_URLS_PER_SITEMAP = 50000; private final String baseUrl; private final File baseDir; private final String fileNamePrefix; private final String fileNameSuffix; private final boolean allowMultipleSitemaps; private final ArrayList<U> urls = new ArrayList<U>(); private final W3CDateFormat dateFormat; private final int maxUrls; private final boolean autoValidate; private final boolean gzip; private final ISitemapUrlRenderer<U> renderer; private int mapCount = 0; private boolean finished = false; private final ArrayList<File> outFiles = new ArrayList<File>(); public SitemapGenerator(AbstractSitemapGeneratorOptions<?> options, ISitemapUrlRenderer<U> renderer) { baseDir = options.baseDir; baseUrl = options.baseUrl; fileNamePrefix = options.fileNamePrefix; W3CDateFormat dateFormat = options.dateFormat; if (dateFormat == null) dateFormat = new W3CDateFormat(); this.dateFormat = dateFormat; allowMultipleSitemaps = options.allowMultipleSitemaps; maxUrls = options.maxUrls; autoValidate = options.autoValidate; gzip = options.gzip; this.renderer = renderer; fileNameSuffix = gzip ? ".xml.gz" : ".xml"; } /** Add one URL of the appropriate type to this sitemap. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or else write out one sitemap immediately. * @param url the URL to add to this sitemap * @return this */ public THIS addUrl(U url) { if (finished) throw new RuntimeException("Sitemap already printed; you must create a new generator to make more sitemaps"); UrlUtils.checkUrl(url.getUrl().toString(), baseUrl); if (urls.size() == maxUrls) { if (!allowMultipleSitemaps) throw new RuntimeException("More than " + maxUrls + " urls, but allowMultipleSitemaps is false. Enable allowMultipleSitemaps to split the sitemap into multiple files with a sitemap index."); if (mapCount == 0) mapCount++; writeSiteMap(); mapCount++; urls.clear(); } urls.add(url); return getThis(); } /** Add multiple URLs of the appropriate type to this sitemap, one at a time. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or write out one sitemap immediately. * @param urls the URLs to add to this sitemap * @return this */ public THIS addUrls(Iterable<? extends U> urls) { for (U url : urls) addUrl(url); return getThis(); } /** Add multiple URLs of the appropriate type to this sitemap, one at a time. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or write out one sitemap immediately. * @param urls the URLs to add to this sitemap * @return this */ public THIS addUrls(U... urls) { for (U url : urls) addUrl(url); return getThis(); } /** Add multiple URLs of the appropriate type to this sitemap, one at a time. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or write out one sitemap immediately. * @param urls the URLs to add to this sitemap * @return this * @throws MalformedURLException */ public THIS addUrls(String... urls) throws MalformedURLException { for (String url : urls) addUrl(url); return getThis(); } /** Add one URL of the appropriate type to this sitemap. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or else write out one sitemap immediately. * @param url the URL to add to this sitemap * @return this * @throws MalformedURLException */ public THIS addUrl(String url) throws MalformedURLException { U sitemapUrl; try { sitemapUrl = renderer.getUrlClass().getConstructor(String.class).newInstance(url); } catch (Exception e) { throw new RuntimeException(e); } return addUrl(sitemapUrl); } /** Add multiple URLs of the appropriate type to this sitemap, one at a time. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or write out one sitemap immediately. * @param urls the URLs to add to this sitemap * @return this */ public THIS addUrls(URL... urls) { for (URL url : urls) addUrl(url); return getThis(); } /** Add one URL of the appropriate type to this sitemap. * If we have reached the maximum number of URLs, we'll throw an exception if {@link #allowMultipleSitemaps} is false, * or write out one sitemap immediately. * @param url the URL to add to this sitemap * @return this */ public THIS addUrl(URL url) { U sitemapUrl; try { sitemapUrl = renderer.getUrlClass().getConstructor(URL.class).newInstance(url); } catch (Exception e) { throw new RuntimeException(e); } return addUrl(sitemapUrl); } @SuppressWarnings("unchecked") THIS getThis() { return (THIS)this; } /** Write out remaining URLs; this method can only be called once. This is necessary so we can keep an accurate count for {@link #writeSitemapsWithIndex()}. * * @return a list of files we wrote out to disk */ 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"); writeSiteMap(); finished = true; return outFiles; } /** After you've called {@link #write()}, call this to generate a sitemap index of all sitemaps you generated. * */ public void writeSitemapsWithIndex() { if (!finished) throw new RuntimeException("Sitemaps not generated yet; call write() first"); File outFile = new File(baseDir, "sitemap_index.xml"); SitemapIndexGenerator sig; try { sig = new SitemapIndexGenerator.Options(baseUrl, outFile).dateFormat(dateFormat).autoValidate(autoValidate).build(); } catch (MalformedURLException e) { throw new RuntimeException("bug", e); } sig.addUrls(fileNamePrefix, fileNameSuffix, mapCount).write(); } private void writeSiteMap() { if (urls.size() == 0) return; String fileNamePrefix; if (mapCount > 0) { fileNamePrefix = this.fileNamePrefix + mapCount; } else { fileNamePrefix = this.fileNamePrefix; } File outFile = new File(baseDir, fileNamePrefix+fileNameSuffix); outFiles.add(outFile); try { OutputStreamWriter out; if (gzip) { FileOutputStream fileStream = new FileOutputStream(outFile); GZIPOutputStream gzipStream = new GZIPOutputStream(fileStream); out = new OutputStreamWriter(gzipStream); } else { out = new FileWriter(outFile); } writeSiteMap(out); if (autoValidate) SitemapValidator.validateWebSitemap(outFile); } catch (IOException e) { throw new RuntimeException("Problem writing sitemap file " + outFile, e); } catch (SAXException e) { throw new RuntimeException("Sitemap file failed to validate (bug?)", e); } } private void writeSiteMap(OutputStreamWriter out) throws IOException { out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); out.write("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" "); if (renderer.getXmlNamespaces() != null) { out.write(renderer.getXmlNamespaces()); out.write(' '); } out.write(">\n"); for (U url : urls) { renderer.render(url, out, dateFormat); } out.write("</urlset>"); out.close(); } } |
|