Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.apache.brooklyn.util.javalang; import java.util.Arrays; import java.util.Set; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.StringFunctions; import org.apache.brooklyn.util.text.Strings; import com.google.common.base.CaseFormat; import com.google.common.base.Function; import com.google.common.collect.Iterables; public class Enums { /** returns a function which given an enum, returns its <code>name()</code> function * @deprecated since 0.7.0 use {@link #nameFunction()} to avoid inner class */ @Deprecated public static Function<Enum<?>, String> enumValueNameFunction() { return new Function<Enum<?>, String>() { @Override public String apply(Enum<?> input) { return input.name(); } }; } private static final class EnumToNameFunction implements Function<Enum<?>, String> { @Override public String apply(Enum<?> input) { return input.name(); } } /** returns a function which given an enum, returns its <code>name()</code> function */ public static Function<Enum<?>, String> nameFunction() { return new EnumToNameFunction(); } private static final class EnumFromStringFunction<T extends Enum<?>> implements Function<String, T> { private final Class<T> type; public EnumFromStringFunction(Class<T> type) { this.type = type; } @Override public T apply(String input) { return valueOfIgnoreCase(type, input).orNull(); } } /** returns a function which given a string, produces an enum of the given type or null */ public static <T extends Enum<?>> Function<String, T> fromStringFunction(Class<T> type) { return new EnumFromStringFunction<T>(type); } @SuppressWarnings("unchecked") private static <T extends Enum<?>> T[] values(Class<T> type) { try { return (T[]) type.getMethod("values").invoke(null); } catch (Exception e) { throw Exceptions.propagate(e); } } /** as {@link #checkAllEnumeratedIgnoreCase(String, Enum[], String...)} using the same default strategy * that {@link #valueOfIgnoreCase(Class, String)} applies */ public static void checkAllEnumeratedIgnoreCase(Class<? extends Enum<?>> type, String... explicitValues) { checkAllEnumeratedIgnoreCase(JavaClassNames.simpleClassName(type), values(type), explicitValues); } /** checks that all accepted enum values are represented by the given set of explicit values */ public static void checkAllEnumeratedIgnoreCase(String contextMessage, Enum<?>[] enumValues, String... explicitValues) { MutableSet<String> explicitValuesSet = MutableSet .copyOf(Iterables.transform(Arrays.asList(explicitValues), StringFunctions.toLowerCase())); Set<Enum<?>> missingEnums = MutableSet.of(); for (Enum<?> e : enumValues) { if (explicitValuesSet.remove(e.name().toLowerCase())) continue; if (explicitValuesSet.remove(e.toString().toLowerCase())) continue; if (explicitValuesSet .remove(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, e.name()).toLowerCase())) continue; if (explicitValuesSet .remove(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.toString()).toLowerCase())) continue; if (explicitValuesSet .remove(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, e.toString()).toLowerCase())) continue; if (explicitValuesSet .remove(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.name()).toLowerCase())) continue; missingEnums.add(e); } if (!missingEnums.isEmpty() || !explicitValuesSet.isEmpty()) { throw new IllegalStateException("Not all options for " + contextMessage + " are enumerated; " + "leftover enums = " + missingEnums + "; " + "leftover values = " + explicitValuesSet); } } /** as {@link #valueOfIgnoreCase(String, Enum[], String)} for all values of the given enum and using the enum type as the message */ public static <T extends Enum<?>> Maybe<T> valueOfIgnoreCase(Class<T> type, String givenValue) { return valueOfIgnoreCase(JavaClassNames.simpleClassName(type), values(type), givenValue); } /** attempts to match the givenValue against the given enum values, first looking for exact matches (against name and toString), * then matching ignoring case, * then matching with {@link CaseFormat#UPPER_UNDERSCORE} converted to {@link CaseFormat#LOWER_CAMEL}, * then matching with {@link CaseFormat#LOWER_CAMEL} converted to {@link CaseFormat#UPPER_UNDERSCORE} * (including case insensitive matches for the final two) **/ public static <T extends Enum<?>> Maybe<T> valueOfIgnoreCase(String contextMessage, T[] enumValues, String givenValue) { if (givenValue == null) return Maybe.absent(new IllegalStateException("Value for " + contextMessage + " must not be null")); if (Strings.isBlank(givenValue)) return Maybe.absent(new IllegalStateException("Value for " + contextMessage + " must not be blank")); for (T v : enumValues) if (v.name().equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (v.toString().equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (v.name().equalsIgnoreCase(givenValue)) return Maybe.of(v); for (T v : enumValues) if (v.toString().equalsIgnoreCase(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, v.name()).equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, v.toString()).equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, v.name()).equalsIgnoreCase(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, v.toString()).equalsIgnoreCase(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, v.toString()).equalsIgnoreCase(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, v.name()).equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, v.toString()).equals(givenValue)) return Maybe.of(v); for (T v : enumValues) if (CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, v.name()).equalsIgnoreCase(givenValue)) return Maybe.of(v); return Maybe.absent(new IllegalStateException("Invalid value " + givenValue + " for " + contextMessage)); } }