Package com.google.caliper.util

Source Code of com.google.caliper.util.Parsers$InvokingParser

/*
* Copyright (C) 2011 Google Inc.
*
* 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
*
* 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 com.google.caliper.util;

import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Primitives;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.List;

public class Parsers {
  public static final Parser<String> IDENTITY = new Parser<String>() {
    @Override public String parse(CharSequence in) {
      return in.toString();
    }
  };

  private static final List<String> CONVERSION_METHOD_NAMES =
      ImmutableList.of("fromString", "decode", "valueOf");

  /**
   * Parser that tries, in this order:
   * <ul>
   * <li>ResultType.fromString(String)
   * <li>ResultType.decode(String)
   * <li>ResultType.valueOf(String)
   * <li>new ResultType(String)
   * </ul>
   */
  public static <T> Parser<T> conventionalParser(Class<T> resultType)
      throws NoSuchMethodException {
    if (resultType == String.class) {
      @SuppressWarnings("unchecked") // T == String
      Parser<T> identity = (Parser<T>) IDENTITY;
      return identity;
    }

    final Class<T> wrappedResultType = Primitives.wrap(resultType);

    for (String methodName : CONVERSION_METHOD_NAMES) {
      try {
        final Method method = wrappedResultType.getDeclaredMethod(methodName, String.class);

        if (Util.isStatic(method) && wrappedResultType.isAssignableFrom(method.getReturnType())) {
          method.setAccessible(true); // to permit inner enums, etc.
          return new InvokingParser<T>() {
            @Override protected T invoke(String input) throws Exception {
              return wrappedResultType.cast(method.invoke(null, input));
            }
          };
        }
      } catch (Exception tryAgain) {
      }
    }

    final Constructor<T> constr = wrappedResultType.getDeclaredConstructor(String.class);
    constr.setAccessible(true);
    return new InvokingParser<T>() {
      @Override protected T invoke(String input) throws Exception {
        return wrappedResultType.cast(constr.newInstance(input));
      }
    };
  }

  abstract static class InvokingParser<T> implements Parser<T> {
    @Override public T parse(CharSequence input) throws ParseException {
      try {
        return invoke(input.toString());
      } catch (InvocationTargetException e) {
        Throwable cause = e.getCause();
        String desc = firstNonNull(cause.getMessage(), cause.getClass().getSimpleName());
        throw newParseException(desc, cause);
      } catch (Exception e) {
        throw newParseException("Unknown parsing problem", e);
      }
    }

    protected abstract T invoke(String input) throws Exception;
  }

  public static ParseException newParseException(String message, Throwable cause) {
    ParseException pe = newParseException(message);
    pe.initCause(cause);
    return pe;
  }

  public static ParseException newParseException(String message) {
    return new ParseException(message, 0);
  }

  private static <T> T firstNonNull(T first, T second) {
    return (first != null) ? first : second;
  }
}
TOP

Related Classes of com.google.caliper.util.Parsers$InvokingParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.