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; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.vividsolutions.jts.util.Assert; import org.fao.geonet.Constants; import org.fao.geonet.constants.Geonet; import org.fao.geonet.exceptions.TermNotFoundException; import org.fao.geonet.kernel.search.keyword.KeywordRelation; import org.fao.geonet.languages.IsoLanguagesMapper; import org.fao.geonet.utils.Log; import org.openrdf.model.GraphException; import org.openrdf.model.URI; import org.openrdf.sesame.config.AccessDeniedException; import org.openrdf.sesame.config.ConfigurationException; import org.openrdf.sesame.query.MalformedQueryException; import org.openrdf.sesame.query.QueryEvaluationException; import org.openrdf.sesame.query.QueryResultsTable; import org.openrdf.sesame.repository.local.LocalRepository; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.file.Path; import java.nio.file.attribute.FileTime; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * @author Jesse on 2/27/2015. */ public class AllThesaurus extends Thesaurus { public static final String FNAME = "allThesaurus"; public static final String SEPARATOR = "@@@"; static final String TYPE = "external"; static final String DNAME = "none"; public static final String ALL_THESAURUS_KEY = TYPE + "." + DNAME + "." + FNAME; static final String TITLE = "All Keywords"; private static final String URI_CODE_PREFIX = "http://org.fao.geonet.thesaurus.all/"; private final ThesaurusFinder thesaurusFinder; private final IsoLanguagesMapper isoLangMapper; private final String downloadUrl; private final String keywordUrl; public AllThesaurus(ThesaurusFinder thesaurusFinder, IsoLanguagesMapper isoLangMapper, String siteUrl) { this.thesaurusFinder = thesaurusFinder; this.isoLangMapper = isoLangMapper; this.downloadUrl = buildDownloadUrl(FNAME, TYPE, DNAME, siteUrl); this.keywordUrl = buildKeywordUrl(FNAME, TYPE, DNAME, siteUrl); } public static String buildKeywordUri(KeywordBean actualWord) { return buildKeywordUri(actualWord.getThesaurusKey(), actualWord.getUriCode()); } @VisibleForTesting static String buildKeywordUri(String thesaurusKey, String uri) { try { thesaurusKey = URLEncoder.encode(thesaurusKey, Constants.ENCODING); // uri = URLEncoder.encode(uri, Constants.ENCODING); return URI_CODE_PREFIX + thesaurusKey + SEPARATOR + uri; } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } @Override public String getKey() { return ALL_THESAURUS_KEY; } @Override public String getDname() { return DNAME; } @Override public String getFname() { return FNAME; } @Override public Path getFile() { throw new UnsupportedOperationException(); } @Override public String getType() { return TYPE; } @Override public String getTitle() { return TITLE; } @Override public String getDate() { return ""; } @Override public String getDownloadUrl() { return this.downloadUrl; } @Override public String getKeywordUrl() { return this.keywordUrl; } @Override public void retrieveThesaurusTitle() { // nothing to do } @Override public synchronized LocalRepository getRepository() { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus setRepository(LocalRepository repository) { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus initRepository() throws ConfigurationException, IOException { // do nothing return this; } @Override public synchronized QueryResultsTable performRequest(final String query) throws IOException, MalformedQueryException, QueryEvaluationException, AccessDeniedException { final Map<Thesaurus, QueryResultsTable> allResults = Maps.newIdentityHashMap(); onThesauri(null, new Function<Thesaurus, Void>() { @Nullable @Override public Void apply(@Nonnull Thesaurus input) { final QueryResultsTable queryResultsTable; try { queryResultsTable = input.performRequest(query); if (queryResultsTable.getRowCount() > 0) { allResults.put(input, queryResultsTable); } } catch (IOException | AccessDeniedException | QueryEvaluationException | MalformedQueryException e) { throw new RuntimeException(e); } return null; } }); return new AllQueryResultsTable(allResults); } @Override public boolean hasConceptScheme(String uri) { return false; } @Override public synchronized URI addElement(KeywordBean keyword) throws IOException, AccessDeniedException, GraphException { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus removeElement(KeywordBean keyword) throws MalformedQueryException, QueryEvaluationException, IOException, AccessDeniedException { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus removeElement(String namespace, String code) throws AccessDeniedException { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus removeElement(String uri) throws AccessDeniedException { throw new UnsupportedOperationException(); } @Override public synchronized URI updateElement(KeywordBean keyword, boolean replace) throws AccessDeniedException, IOException, MalformedQueryException, QueryEvaluationException, GraphException { throw new UnsupportedOperationException(); } @Override public synchronized boolean isFreeCode(final String namespace, final String code) throws AccessDeniedException { return onThesauri(true, new Function<Thesaurus, Boolean>() { @Nullable @Override public Boolean apply(Thesaurus thesaurus) { try { if (!thesaurus.isFreeCode(namespace, code)) { return false; } } catch (AccessDeniedException e) { // skip } return null; } }); } @Override public Thesaurus updateCode(KeywordBean bean, String newcode) throws AccessDeniedException, IOException { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus updateCode(String namespace, String oldcode, String newcode) throws AccessDeniedException, IOException { throw new UnsupportedOperationException(); } @Override public synchronized Thesaurus updateCodeByURI(String olduri, String newuri) throws AccessDeniedException, IOException { throw new UnsupportedOperationException(); } @Override public void addTitleElement(String thesaurusTitle) throws IOException, AccessDeniedException, GraphException { throw new UnsupportedOperationException(); } @Override public IsoLanguagesMapper getIsoLanguageMapper() { return isoLangMapper; } @Override public synchronized void addRelation(String subject, KeywordRelation related, String relatedSubject) throws AccessDeniedException, IOException, MalformedQueryException, QueryEvaluationException, GraphException { throw new UnsupportedOperationException(); } @Override public KeywordBean getKeyword(String uri, String... languages) { final DecomposedAllUri decomposedAllUri = new DecomposedAllUri(uri); final Thesaurus thesaurus = this.thesaurusFinder.getThesaurusByName(decomposedAllUri.thesaurusKey); final KeywordBean keyword = thesaurus.getKeyword(decomposedAllUri.keywordUri, languages); updateKeywordBeanThesaurusInfo(keyword); return keyword; } private KeywordBean updateKeywordBeanThesaurusInfo(KeywordBean keyword) { keyword.setUriCode(buildKeywordUri(keyword)); keyword.setThesaurusInfo(this); return keyword; } @Override public boolean hasKeyword(String uri) { final DecomposedAllUri decomposedAllUri = new DecomposedAllUri(uri); final Thesaurus thesaurus = this.thesaurusFinder.getThesaurusByName(decomposedAllUri.thesaurusKey); return thesaurus.hasKeyword(decomposedAllUri.keywordUri); } @Override public List<KeywordBean> getRelated(final String uri, final KeywordRelation request, final String... languages) { final DecomposedAllUri decomposedAllUri = new DecomposedAllUri(uri); final Thesaurus thesaurus = this.thesaurusFinder.getThesaurusByName(decomposedAllUri.thesaurusKey); return Lists.transform(thesaurus.getRelated(decomposedAllUri.keywordUri, request, languages), new Function<KeywordBean, KeywordBean>() { @Nullable @Override public KeywordBean apply(@Nullable KeywordBean keywordBean) { return updateKeywordBeanThesaurusInfo(keywordBean); } }); } @Override public boolean hasKeywordWithLabel(final String label, final String langCode) { return onThesauri(false, new Function<Thesaurus, Boolean>() { @Nullable @Override public Boolean apply(Thesaurus thesaurus) { if (thesaurus.hasKeywordWithLabel(label, langCode)) { return true; } return null; } }); } private <R> R onThesauri(R defaultVal, Function<Thesaurus, R> function) { for (Thesaurus thesaurus : this.thesaurusFinder.getThesauriMap().values()) { if (ALL_THESAURUS_KEY.equals(thesaurus.getKey())) { continue; } final R result = function.apply(thesaurus); if (result != null) { return result; } } return defaultVal; } @Override public KeywordBean getKeywordWithLabel(final String label, final String langCode) { KeywordBean result = onThesauri(null, new Function<Thesaurus, KeywordBean>() { @Nullable @Override public KeywordBean apply(@Nonnull Thesaurus thesaurus) { try { return updateKeywordBeanThesaurusInfo(thesaurus.getKeywordWithLabel(label, langCode)); } catch (TermNotFoundException e) { return null; } } }); if (result == null) { throw new TermNotFoundException(label); } return result; } @Override public synchronized void clear() throws IOException, AccessDeniedException { throw new UnsupportedOperationException(); } @Nonnull @Override public FileTime getLastModifiedTime() { long lastModified = -1; for (Thesaurus thesaurus : this.thesaurusFinder.getThesauriMap().values()) { if (thesaurus.getKey().equals(ALL_THESAURUS_KEY)) { continue; } long thesLastModified = thesaurus.getLastModifiedTime().toMillis(); if (thesLastModified > lastModified) { lastModified = thesLastModified; } } if (Log.isDebugEnabled(Geonet.THESAURUS)) { Log.debug(Geonet.THESAURUS, ALL_THESAURUS_KEY + " has lastModified of: " + lastModified); } return FileTime.fromMillis(lastModified); } @Override public String getDefaultNamespace() { try { final Iterator<Thesaurus> iterator = thesaurusFinder.getThesauriMap().values().iterator(); Thesaurus thesaurus = null; while (iterator.hasNext()) { thesaurus = iterator.next(); if (!AllThesaurus.ALL_THESAURUS_KEY.equals(thesaurus.getKey())) { break; } else { thesaurus = null; } } if (thesaurus != null) { return URI_CODE_PREFIX + URLEncoder.encode(thesaurus.getDefaultNamespace(), Constants.ENCODING); } else { return null; } } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public static final class DecomposedAllUri { private static final Pattern URI_DECOMPOSER = Pattern .compile(Pattern.quote(URI_CODE_PREFIX) + "(.+)" + SEPARATOR + "(.+)"); public final String thesaurusKey, keywordUri; public DecomposedAllUri(String allUri) { final Matcher matcher = URI_DECOMPOSER.matcher(allUri); Assert.isTrue(matcher.matches(), allUri + "is not an 'all' keyword"); try { thesaurusKey = URLDecoder.decode(matcher.group(1), Constants.ENCODING); keywordUri = URLDecoder.decode(matcher.group(2), Constants.ENCODING); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } @Override public String toString() { return "DecomposedAllUri{" + "thesaurusKey='" + thesaurusKey + '\'' + ", keywordUri='" + keywordUri + '\'' + '}'; } } }