/* * Copyright 2016 Samppa Saarela * * 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 org.javersion.object.mapping; import static java.lang.Integer.MAX_VALUE; import java.util.Map; import javax.annotation.Nonnull; import org.javersion.reflect.ElementDescriptor; import org.javersion.reflect.MethodDescriptor; import org.javersion.reflect.ParameterDescriptor; import org.javersion.reflect.StaticExecutable; import org.javersion.reflect.TypeDescriptor; import org.javersion.util.Check; public interface MappingResolver { @Nonnull Result<MethodDescriptor> delegateValue(MethodDescriptor method); @Nonnull <T extends StaticExecutable & ElementDescriptor> Result<StaticExecutable> creator(T methodOrConstructor); @Nonnull Result<String> alias(TypeDescriptor type); @Nonnull Result<Map<TypeDescriptor,String>> subclasses(TypeDescriptor type); @Nonnull Result<String> name(ParameterDescriptor parameter); final class Result<T> { public static <T> Result<T> of(T value) { return new Result<>(Check.notNull(value, "value"), 0); } @SuppressWarnings("unchecked") public static <T> Result<T> notFound() { return (Result<T>) NOT_FOUND; } public final T value; private final int priority; private Result(T value, int priority) { this.value = value; this.priority = priority; } public boolean isPreset() { return value != null; } public boolean isAbsent() { return value == null; } Result<T> withPriority(int priority) { return new Result<>(value, priority); } @SuppressWarnings("unchecked") private static Result NOT_FOUND = new Result(null, MAX_VALUE); } static <T> Result<T> higherOf(Result<T> result1, Result<T> result2) { return higherOf(result1, result2, null); } static <T> Result<T> higherOf(Result<T> result1, Result<T> result2, String samePriorityErrorMessage) { if (result1.isAbsent()) { return result2; } if (result2.isAbsent()) { return result1; } if (samePriorityErrorMessage != null && result1.priority == result2.priority) { throw new IllegalArgumentException(samePriorityErrorMessage); } return result1.priority < result2.priority ? result1 : result2; } }