001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.gbif.common.parsers; 015 016import org.gbif.api.vocabulary.License; 017import org.gbif.common.parsers.core.EnumParser; 018import org.gbif.common.parsers.core.ParseResult; 019 020import java.net.URI; 021import java.util.regex.Pattern; 022 023import javax.annotation.Nullable; 024 025import org.apache.commons.lang3.StringUtils; 026 027/** 028 * Singleton implementation of the dictionary that uses the file /dictionaries/parse/license.txt to lookup a 029 * License by its URI or its acronym/title, e.g. a lookup by "CC-BY 4.0" returns License.CC_BY_4_0. 030 * </br> 031 * The dictionary file must enforce the <a href="http://www.gbif.org/terms/licences">GBIF Licensing Policy</a>. 032 * Non-CC licenses that GBIF considers equal to one of its three supported CC licenses (CC0 1.0, CC-BY 4.0 and CC-BY-NC 033 * 4.0) can be added to this file. 034 * </br> 035 * Note a lookup by license acronym/title without a version number defaults to the latest version of that license, 036 * e.g. a lookup by "CC-BY" returns License.CC_BY_4_0. 037 */ 038public class LicenseParser extends EnumParser<License> { 039 040 private static final String COMMENT_MARKER = "#"; 041 private static final String LICENSE_FILEPATH = "/dictionaries/parse/license.tsv"; 042 //allows us to remove the protocol part for http:// and https:// 043 private static final Pattern REMOVE_HTTP_PATTERN = Pattern.compile("^https?:\\/\\/", Pattern.CASE_INSENSITIVE); 044 private static LicenseParser singletonObject = null; 045 046 private LicenseParser() { 047 super(License.class, true); 048 // also make sure we have all enum values and their parameters title and url mapped 049 for (License l : License.values()) { 050 add(l.name(), l); 051 add(l.getLicenseTitle(), l); 052 add(l.getLicenseUrl(), l); 053 } 054 // use dict file last 055 init(LicenseParser.class.getResourceAsStream(LICENSE_FILEPATH), COMMENT_MARKER); 056 } 057 058 @Override 059 protected String normalize(String value) { 060 if(value == null){ 061 return null; 062 } 063 return super.normalize(REMOVE_HTTP_PATTERN.matcher(value).replaceAll("")); 064 } 065 066 public static LicenseParser getInstance() { 067 synchronized (ContinentParser.class) { 068 if (singletonObject == null) { 069 singletonObject = new LicenseParser(); 070 } 071 } 072 return singletonObject; 073 } 074 075 /** 076 * Parse license supplied in two parts: URI and title. First parse URI. Only if no URI supplied, parse title. 077 * supplied. 078 * 079 * @param uri optional license URI 080 * @param title optional license title 081 * 082 * @return License corresponding to license URI or title, License.UNSPECIFIED if both URI and title not supplied, 083 * otherwise defaults to License.UNSUPPORTED 084 */ 085 public License parseUriThenTitle(@Nullable URI uri, @Nullable String title) { 086 if (uri == null && StringUtils.isEmpty(title)) { 087 return License.UNSPECIFIED; 088 } 089 090 if (uri != null) { 091 ParseResult<License> result = singletonObject.parse(uri.toString()); 092 if (result.isSuccessful()) { 093 return result.getPayload(); 094 } 095 } 096 097 if (StringUtils.isNotEmpty(title)) { 098 ParseResult<License> result = singletonObject.parse(title); 099 if (result.isSuccessful()) { 100 return result.getPayload(); 101 } 102 } 103 104 return License.UNSUPPORTED; 105 } 106}