/** * Copyright 2012-2013 Maciej Jaworski, Mariusz Kapcia, Paweł Kędzia, Mateusz Kubuszok * * <p>Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at</p> * * <p>http://www.apache.org/licenses/LICENSE-2.0</p> * * <p>Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.</p> */ package com.autoupdater.client.utils.enums; import static com.google.common.base.Throwables.propagate; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; /** * Contains methods useful in work with Enums objects. */ public class Enums { /** * Obtains enum by its toString() value. * * @param klass * Enum klass * @param message * message returned by Enums toString() - should be unique * @return Enum instance */ public static <E extends Enum<E>> E parseMessage(Class<E> klass, String message) { try { E[] values = (E[]) klass.getDeclaredMethod("values").invoke(null); for (E value : values) if (message.equals(value.toString())) return value; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { // should never happen since all enum E got method (E[] values()) } return null; } /** * Obtains Enum instance by value of one of its fields. * * @param klass * Enum class * @param fieldName * field's name * @param value * field's value unique to some Enum * @return Enum instance * @throws NoSuchFieldException * thrown if field with such name doesn't exist */ public static <E extends Enum<E>> E parseField(Class<E> klass, String fieldName, Object value) throws NoSuchFieldException { if (value == null || fieldName == null) throw new NullPointerException(); Field messageField = klass.getDeclaredField(fieldName); boolean accessible = messageField.isAccessible(); messageField.setAccessible(true); EParsingStrategy parsingStrategy = EParsingStrategy.resolve(value); try { E[] eValues = (E[]) klass.getDeclaredMethod("values").invoke(null); for (E eValue : eValues) if (value.equals(parsingStrategy.getFieldObtainer().obtain(messageField, eValue))) return eValue; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { // should never happen since all enum E got method (E[] values()) propagate(e); } finally { messageField.setAccessible(accessible); } return null; } /** * Interface used for obtaining contents from Enums. */ private interface IFieldObtainer { Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException; } /** * Used for finding right IFieldObtainer for required field. */ private enum EParsingStrategy { BOOLEAN(Boolean.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getBoolean(source); } }), BYTE(Byte.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getByte(source); } }), CHAR(Character.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getChar(source); } }), INTEGER(Integer.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getInt(source); } }), SHORT(Short.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getShort(source); } }), LONG(Long.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getLong(source); } }), FLOAT(Float.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getFloat(source); } }), DOUBLE(Double.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.getDouble(source); } }), GENERIC(Object.class, new IFieldObtainer() { @Override public Object obtain(Field field, Object source) throws IllegalArgumentException, IllegalAccessException { return field.get(source); } }); private final Class<?> klass; private final IFieldObtainer fieldObtainer; private EParsingStrategy(Class<?> klass, IFieldObtainer fieldObtainer) { this.klass = klass; this.fieldObtainer = fieldObtainer; } /** * Returns IFieldObtainer. * * @return IFieldObtainer */ public IFieldObtainer getFieldObtainer() { return fieldObtainer; } /** * Resolves IFieldObtainer for given object. * * @param source * object for which IFieldObtainer is sought * @return right parsing strategy */ public static EParsingStrategy resolve(Object source) { for (EParsingStrategy value : EParsingStrategy.values()) if (value.klass.isInstance(source)) return value; return null; } } }