001/* 002 * Copyright 2020 Global Biodiversity Information Facility (GBIF) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.gbif.api.util; 017 018import org.gbif.api.vocabulary.ContactType; 019import org.gbif.api.vocabulary.EndpointType; 020import org.gbif.api.vocabulary.IdentifierType; 021import org.gbif.api.vocabulary.TechnicalInstallationType; 022 023import java.util.Optional; 024 025import org.apache.commons.lang3.StringUtils; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028 029public final class VocabularyUtils { 030 031 private static final Logger LOG = LoggerFactory.getLogger(VocabularyUtils.class); 032 033 public static ContactType parseContactType(String type) { 034 return lookupEnum(type, ContactType.class); 035 } 036 037 public static EndpointType parseEndpointType(String type) { 038 return lookupEnum(type, EndpointType.class); 039 } 040 041 public static IdentifierType parseIdentifierType(String type) { 042 return lookupEnum(type, IdentifierType.class); 043 } 044 045 @Deprecated 046 public static TechnicalInstallationType parseTechnicalInstallationType(String type) { 047 return lookupEnum(type, TechnicalInstallationType.class); 048 } 049 050 /** 051 * Generic method to lookup an enumeration value for a given string based on the name of the enum member. 052 * The lookup is case insensitive and ignore whitespaces, underscores and dashes. 053 * 054 * @param name the enum members name to lookup 055 * @param vocab the enumeration class 056 * @return the matching enum member or null if {@code name} is null or empty (see http://dev.gbif.org/issues/browse/POR-2858) 057 * @throws IllegalArgumentException if the name cannot be parsed into a known name 058 */ 059 public static <T extends Enum<?>> T lookupEnum(String name, Class<T> vocab) { 060 if (StringUtils.isEmpty(name)) { 061 return null; 062 } 063 final String normedType = name.toUpperCase().replaceAll("[. _-]", ""); 064 T[] values = vocab.getEnumConstants(); 065 if (values != null) { 066 for (T val : values) { 067 final String normedVal = val.name().toUpperCase().replaceAll("[. _-]", ""); 068 if (normedType.equals(normedVal)) { 069 return val; 070 } 071 } 072 } 073 throw new IllegalArgumentException("Cannot parse " + name + " into a known " + vocab.getSimpleName()); 074 } 075 076 /** 077 * Same as {@link #lookupEnum(String, Class)} } without IllegalArgumentException. 078 * On failure, this method will return Optional.empty(). 079 * 080 * @return instance of Optional, never null. 081 */ 082 public static <T extends Enum<?>> Optional<T> lookup(String name, Class<T> vocab) { 083 T result = null; 084 // this try/catch in needed until we replace all calls to lookupEnum() in favor of this method 085 try { 086 result = lookupEnum(name, vocab); 087 } catch (IllegalArgumentException iaEx) {/*ignore*/} 088 return Optional.ofNullable(result); 089 } 090 091 /** 092 * Looks up an enumeration by class name. One can get the classname using the likes of: 093 * <p/> 094 * 095 * <pre> 096 * {@code 097 * Country.class.getName() 098 * } 099 * </pre> 100 * 101 * @param fullyQualifiedClassName Which should name the enumeration (e.g. org.gbif.api.vocabulary.Country) 102 * @return The enumeration or null if {@code fullyQualifiedClassName} is null or empty (see http://dev.gbif.org/issues/browse/POR-2858) 103 * @throws IllegalArgumentException if {@code fullyQualifiedClassName} class cannot be located 104 */ 105 @SuppressWarnings("unchecked") 106 public static Class<? extends Enum<?>> lookupVocabulary(String fullyQualifiedClassName) { 107 if (StringUtils.isNotEmpty(fullyQualifiedClassName)) { 108 try { 109 Class<?> cl = Class.forName(fullyQualifiedClassName); 110 if (Enum.class.isAssignableFrom(cl)) { 111 return (Class<? extends Enum<?>>) cl; 112 } 113 } catch (Exception e) { 114 throw new IllegalArgumentException("Unable to lookup the vocabulary: " + fullyQualifiedClassName, e); 115 } 116 } 117 return null; 118 } 119 120 /** 121 * A static utils class. 122 */ 123 private VocabularyUtils() { 124 } 125 126}