001/*
002 * Licensed to the author under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package de.cuioss.test.generator.internal.net.java.quickcheck.generator.support;
018
019import java.lang.reflect.Method;
020import java.util.HashMap;
021import java.util.Map;
022
023import de.cuioss.test.generator.internal.net.java.quickcheck.Generator;
024import de.cuioss.test.generator.internal.net.java.quickcheck.ObjectGenerator;
025
026/**
027 * {@link ObjectGenerator} implementation that can generate object graphs with
028 * default primitive value generators.
029 */
030public class ObjectDefaultMappingGenerator<T> extends ObjectGeneratorImpl<T> {
031
032    private static final Map<Class<?>, Generator<?>> RETURN_TYPE_TO_GENERATOR = new HashMap<>();
033
034    static {
035        map(new IntegerGenerator(), Integer.class, int.class);
036        map(new StringGenerator(), String.class);
037        map(new LongGenerator(), Long.class, long.class);
038        map(new DoubleGenerator(), Double.class, double.class, Number.class);
039        map(new ByteGenerator(), byte.class, Byte.class);
040    }
041
042    public ObjectDefaultMappingGenerator(Class<T> objectType) {
043        super(objectType);
044        mapMethodsToGenerators();
045    }
046
047    private static void map(Generator<?> generator, Class<?>... classes) {
048        for (Class<?> c : classes) {
049            RETURN_TYPE_TO_GENERATOR.put(c, generator);
050        }
051    }
052
053    private void mapMethodsToGenerators() {
054        for (Method method : definition.getType().getMethods()) {
055            Class<?> returnType = method.getReturnType();
056            Generator<?> generator = RETURN_TYPE_TO_GENERATOR.get(returnType);
057            if (generator == null && returnType.isInterface()) {
058                generator = buildGenerator(returnType);
059            }
060            definition.defineMapping(method, generator);
061        }
062    }
063
064    private <R> ObjectDefaultMappingGenerator<R> buildGenerator(Class<R> returnType) {
065        return new ObjectDefaultMappingGenerator<>(returnType);
066    }
067}