Java tutorial
/* * Copyright (C) 2001-2016 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, * Rome - Italy. email: geonetwork@osgeo.org */ package org.fao.geonet.kernel.search; import jeeves.server.context.ServiceContext; import org.apache.commons.io.IOUtils; import org.fao.geonet.AbstractCoreIntegrationTest; import org.fao.geonet.constants.Geonet; import org.fao.geonet.constants.Params; import org.fao.geonet.domain.MetadataType; import org.fao.geonet.domain.ReservedGroup; import org.fao.geonet.domain.Setting; import org.fao.geonet.kernel.setting.SettingInfo; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.repository.SettingRepository; import org.fao.geonet.repository.Updater; import org.jdom.JDOMException; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import javax.annotation.Nonnull; import static org.fao.geonet.kernel.setting.SettingInfo.SearchRequestLanguage.ONLY_DOC_LOCALE; import static org.fao.geonet.kernel.setting.SettingInfo.SearchRequestLanguage.ONLY_LOCALE; import static org.fao.geonet.kernel.setting.SettingInfo.SearchRequestLanguage.ONLY_UI_LOCALE; import static org.fao.geonet.kernel.setting.SettingInfo.SearchRequestLanguage.PREFER_LOCALE; import static org.fao.geonet.kernel.setting.SettingInfo.SearchRequestLanguage.PREFER_UI_LOCALE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Test the order of search results with regards to language settings. * <p/> * Created by Jesse on 1/27/14. */ public abstract class AbstractLanguageSearchOrderIntegrationTest extends AbstractCoreIntegrationTest { public static List<String> METADATA_TO_IMPORT = new ArrayList<String>(10); protected MetaSearcher _luceneSearcher; protected ServiceContext _serviceContext; protected String _abstractSearchTerm; @Autowired private SettingRepository _settingRepository; @Autowired private SearchManager _searchManager; @BeforeClass public static synchronized void bareMetadataXml() throws IOException, JDOMException { if (METADATA_TO_IMPORT.isEmpty()) { final URL url = AbstractLanguageSearchOrderIntegrationTest.class .getResource("templated-name-lang.iso19139.xml"); final String xmlString = IOUtils.toString(url, "UTF-8"); METADATA_TO_IMPORT.add(loadMetadata("eng", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#DE\">zz</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("ita", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#DE\">yy</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("ita", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#DE\">xx</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("eng", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">A ENG EN and FR is " + "FR</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#EN\">A ENG EN and FR is " + "EN</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("eng", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">E2 ENG EN and FR is " + "FR</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#EN\">Z2 ENG EN and FR is " + "EN</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("eng", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">G eng is " + "fr</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("eng", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">e eng en and fr is " + "fr</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#EN\">e eng en and fr is " + "en</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("fre", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\"> fra is " + "fr</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("fre", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">A FRA EN and FR is " + "FR</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#EN\">A FRA EN and FR is " + "EN</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); METADATA_TO_IMPORT.add(loadMetadata("fre", "<gmd:PT_FreeText>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#FR\">Z3 FRA EN and FR is " + "FR</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "<gmd:textGroup><gmd:LocalisedCharacterString locale=\"#EN\">E3 FRA EN and FR is " + "EN</gmd:LocalisedCharacterString></gmd:textGroup>\n" + "</gmd:PT_FreeText>", xmlString)); } } private static String loadMetadata(String lang, String title, String xmlString) throws IOException, JDOMException { final String updatedXmlString = xmlString.replace("{lang}", lang).replace("{title}", title); return updatedXmlString; } public void importMetadata(String searchTerm) throws Exception { this._serviceContext = createServiceContext(); loginAsAdmin(_serviceContext); _abstractSearchTerm = searchTerm; for (String element : METADATA_TO_IMPORT) { byte[] bytes = element.replace("{uuid}", "" + _abstractSearchTerm).getBytes("UTF-8"); importMetadataXML(_serviceContext, "uuid:" + System.currentTimeMillis(), new ByteArrayInputStream(bytes), MetadataType.METADATA, ReservedGroup.intranet.getId(), Params.GENERATE_UUID); } this._luceneSearcher = _searchManager.newSearcher(SearcherType.LUCENE, Geonet.File.SEARCH_LUCENE); } protected abstract String[] doSearch(String lang) throws Exception; @After public void tearDownResources() throws Exception { if (this._luceneSearcher != null) { this._luceneSearcher.close(); } } @Test public void freTitleSearch_RequestLangNotSorted_AllLanguagesAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(PREFER_LOCALE, false, false); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A ENG EN and FR is FR", "A FRA EN and FR is FR", "E2 ENG EN and FR is FR", "e eng en and fr is fr", " fra is fr", "G eng is fr", "xx", "yy", "Z3 FRA EN and FR is FR", "zz" }, titles); } @Test public void engTitleSearch_RequestLangNotSorted_AllLanguagesAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(PREFER_LOCALE, false, false); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void freTitleSearch_RequestLangNotSorted_OnlyResultsInSearchLanguageAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(ONLY_DOC_LOCALE, false, false); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A FRA EN and FR is FR", " fra is fr", "Z3 FRA EN and FR is FR" }, titles); } @Test public void engTitleSearch_RequestLangNotSorted_OnlyResultsInSearchLanguageAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(ONLY_DOC_LOCALE, false, false); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "e eng en and fr is en", "G eng is fr", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void freTitleSearch_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(ONLY_LOCALE, false, false); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A FRA EN and FR is FR", " fra is fr", "Z3 FRA EN and FR is FR" }, titles); } @Test public void engTitleSearch_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(ONLY_LOCALE, false, false); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void freAutoDetect_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed() throws Exception { importMetadata("comment allez-vous aujourd'hui"); setSearchSettings(ONLY_LOCALE, false, true); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A FRA EN and FR is FR", " fra is fr", "Z3 FRA EN and FR is FR" }, titles); } @Test public void engAutoDetect_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed() throws Exception { importMetadata("it is a very nice day"); setSearchSettings(ONLY_LOCALE, false, true); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void freAutoDetect_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed_UseDisplayLanguageAsPreferredLanguage() throws Exception { importMetadata("comment allez-vous aujourd'hui"); setSearchSettings(ONLY_UI_LOCALE, false, true); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void engAutoDetect_RequestLangNotSorted_OnlyResultsContainingDataInSearchLanguageAllowed_UseDisplayLanguageAsPreferredLanguage() throws Exception { importMetadata("it is a very nice day"); setSearchSettings(ONLY_UI_LOCALE, false, true); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A FRA EN and FR is FR", " fra is fr", "Z3 FRA EN and FR is FR" }, titles); } @Test public void freAutoDetect_RequestLangNotSorted_AllLanguagesAllowed_UseDisplayLanguageAsPreferredLanguage() throws Exception { importMetadata("comment allez-vous aujourd'hui"); setSearchSettings(PREFER_UI_LOCALE, false, true); String[] titles = doSearch("eng"); assertArrayEquals(new String[] { "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz" }, titles); } @Test public void engAutoDetect_RequestLangNotSorted_AllLanguagesAllowed_UseDisplayLanguageAsPreferredLanguage() throws Exception { importMetadata("it is a very nice day"); setSearchSettings(PREFER_UI_LOCALE, false, true); String[] titles = doSearch("fre"); assertArrayEquals(new String[] { "A ENG EN and FR is FR", "A FRA EN and FR is FR", "E2 ENG EN and FR is FR", "e eng en and fr is fr", " fra is fr", "G eng is fr", "xx", "yy", "Z3 FRA EN and FR is FR", "zz" }, titles); } @Test public void freTitleSearch_RequestLangSorted_AllLanguagesAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(PREFER_LOCALE, true, false); String[] titles = doSearch("fre"); assertContainsOnly(titles, "A ENG EN and FR is FR", "A FRA EN and FR is FR", "e eng en and fr is fr", " fra is fr", "E2 ENG EN and FR is FR", "G eng is fr", "xx", "yy", "Z3 FRA EN and FR is FR", "zz"); assertContainsInOrderOnly(titles, 0, 3, "A FRA EN and FR is FR", " fra is fr", "Z3 FRA EN and FR is FR"); assertContainsInOrder(titles, 3, titles.length, "A ENG EN and FR is FR", "e eng en and fr is fr", "G eng is fr", "zz"); assertContainsInOrder(titles, 3, titles.length, "xx", "yy"); } @Test public void engTitleSearch_RequestLangSorted_AllLanguagesAllowed() throws Exception { importMetadata("" + System.currentTimeMillis()); setSearchSettings(PREFER_LOCALE, true, false); String[] titles = doSearch("eng"); assertContainsOnly(titles, "A ENG EN and FR is EN", "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", "e eng en and fr is en", " fra is fr", "G eng is fr", "xx", "yy", "Z2 ENG EN and FR is EN", "zz"); assertContainsInOrderOnly(titles, 0, 5, "A ENG EN and FR is EN", "e eng en and fr is en", "G eng is fr", "Z2 ENG EN and FR is EN", "zz"); assertContainsInOrder(titles, 5, titles.length, "A FRA EN and FR is EN", "E3 FRA EN and FR is EN", " fra is fr"); assertContainsInOrder(titles, 5, titles.length, "xx", "yy"); } protected void assertContainsInOrder(String[] titles, int start, int end, String... expectedValues) { final List<String> list = Arrays.asList(titles).subList(start, end); int lastIndex = -1; for (String expectedValue : expectedValues) { int index = list.indexOf(expectedValue); assertTrue(index != -1); assertTrue(index > lastIndex); lastIndex = index; } } private void assertContainsInOrderOnly(String[] titles, int start, int end, String... expectedValues) { assertArrayEquals(expectedValues, Arrays.asList(titles).subList(start, end).toArray()); } private void assertContainsOnly(String[] titles, String... expectedValues) { assertEquals(expectedValues.length, titles.length); final List<String> titlesList = Arrays.asList(titles); final List<String> expectedList = Arrays.asList(expectedValues); HashSet extras = new HashSet(titlesList); extras.removeAll(expectedList); HashSet missing = new HashSet(expectedList); missing.removeAll(titlesList); if (!extras.isEmpty() || !missing.isEmpty()) { throw new AssertionError("Following strings should not be in results: " + extras + "\nFollowing strings should have been in" + " results: " + missing); } } private void setSearchSettings(final SettingInfo.SearchRequestLanguage searchSetting, final Boolean sorted, final Boolean autoDetectSearchLanguage) { _settingRepository.update(Settings.SYSTEM_REQUESTED_LANGUAGE_ONLY, new Updater<Setting>() { @Override public void apply(@Nonnull Setting entity) { entity.setValue(searchSetting.databaseValue); } }); _settingRepository.update(Settings.SYSTEM_REQUESTED_LANGUAGE_SORTED, new Updater<Setting>() { @Override public void apply(@Nonnull Setting entity) { entity.setValue(sorted.toString()); } }); _settingRepository.update(Settings.SYSTEM_AUTODETECT_ENABLE, new Updater<Setting>() { @Override public void apply(@Nonnull Setting entity) { entity.setValue(autoDetectSearchLanguage.toString()); } }); } }