Search in sources :

Example 1 with Parameter

use of org.simpleflatmapper.reflect.Parameter in project SimpleFlatMapper by arnaudroger.

the class ConstantSourceMapperBuilder method constructorInjections.

@SuppressWarnings("unchecked")
private ConstructorInjections constructorInjections() {
    final Map<Parameter, BiFunction<? super S, ? super MappingContext<? super S>, ?>> injections = new HashMap<Parameter, BiFunction<? super S, ? super MappingContext<? super S>, ?>>();
    final List<FieldMapper<S, T>> fieldMappers = new ArrayList<FieldMapper<S, T>>();
    propertyMappingsBuilder.forEachConstructorProperties(new ForEachCallBack<PropertyMapping<T, ?, K, FieldMapperColumnDefinition<K>>>() {

        @SuppressWarnings("unchecked")
        @Override
        public void handle(PropertyMapping<T, ?, K, FieldMapperColumnDefinition<K>> propertyMapping) {
            if (!isTargetForMapperFieldMapper(propertyMapping)) {
                PropertyMeta<T, ?> pm = propertyMapping.getPropertyMeta();
                ConstructorPropertyMeta<T, ?> cProp = (ConstructorPropertyMeta<T, ?>) pm;
                Parameter parameter = cProp.getParameter();
                Getter<? super S, ?> getter = fieldMapperFactory.getGetterFromSource(propertyMapping.getColumnKey(), pm.getPropertyType(), propertyMapping.getColumnDefinition(), pm.getPropertyClassMetaSupplier());
                if (NullGetter.isNull(getter)) {
                    mapperConfig.mapperBuilderErrorHandler().accessorNotFound("Could not find getter for " + propertyMapping.getColumnKey() + " type " + propertyMapping.getPropertyMeta().getPropertyType() + " path " + propertyMapping.getPropertyMeta().getPath() + " See " + ErrorDoc.toUrl("FMMB_GETTER_NOT_FOUND"));
                } else {
                    injections.put(parameter, new BiFunctionGetter<S, MappingContext<? super S>, Object>(getter));
                }
                if (!NullSetter.isNull(cProp.getSetter())) {
                    fieldMappers.add(fieldMapperFactory.newFieldMapper(propertyMapping, mappingContextFactoryBuilder, mapperConfig.mapperBuilderErrorHandler()));
                }
            }
        }
    });
    for (PropertyPerOwner e : getSubPropertyPerOwner()) {
        if (e.owner.isConstructorProperty()) {
            final List<PropertyMapping<T, ?, K, FieldMapperColumnDefinition<K>>> properties = e.propertyMappings;
            final MappingContextFactoryBuilder currentBuilder = getMapperContextFactoryBuilder(e.owner, properties);
            final Mapper<S, ?> mapper;
            if (properties.size() == 1 && JoinUtils.isArrayElement(properties.get(0).getPropertyMeta())) {
                mapper = getterPropertyMapper(e.owner, properties.get(0));
            } else {
                mapper = subPropertyMapper(e.owner, properties, currentBuilder);
            }
            ConstructorPropertyMeta<T, ?> meta = (ConstructorPropertyMeta<T, ?>) e.owner;
            injections.put(meta.getParameter(), newMapperGetterAdapter(mapper, currentBuilder));
            fieldMappers.add(newMapperFieldMapper(properties, meta, mapper, currentBuilder));
        }
    }
    return new ConstructorInjections(injections, fieldMappers.toArray(new FieldMapper[0]));
}
Also used : FieldMapperColumnDefinition(org.simpleflatmapper.map.property.FieldMapperColumnDefinition) ConstantGetter(org.simpleflatmapper.reflect.getter.ConstantGetter) Getter(org.simpleflatmapper.reflect.Getter) NullGetter(org.simpleflatmapper.reflect.getter.NullGetter) BiFunctionGetter(org.simpleflatmapper.reflect.getter.BiFunctionGetter) MappingContextFactoryBuilder(org.simpleflatmapper.map.context.MappingContextFactoryBuilder) MappingContext(org.simpleflatmapper.map.MappingContext) ConstructorPropertyMeta(org.simpleflatmapper.reflect.meta.ConstructorPropertyMeta) SelfPropertyMeta(org.simpleflatmapper.reflect.meta.SelfPropertyMeta) PropertyMeta(org.simpleflatmapper.reflect.meta.PropertyMeta) SubPropertyMeta(org.simpleflatmapper.reflect.meta.SubPropertyMeta) BiFunction(org.simpleflatmapper.util.BiFunction) BiFunctionGetter(org.simpleflatmapper.reflect.getter.BiFunctionGetter) Parameter(org.simpleflatmapper.reflect.Parameter) MapperFieldMapper(org.simpleflatmapper.map.fieldmapper.MapperFieldMapper) FieldMapper(org.simpleflatmapper.map.FieldMapper) ConstructorPropertyMeta(org.simpleflatmapper.reflect.meta.ConstructorPropertyMeta)

Example 2 with Parameter

use of org.simpleflatmapper.reflect.Parameter in project SimpleFlatMapper by arnaudroger.

the class CellSetterFactory method cellValueReaderFromFactory.

private <P> CellValueReader<P> cellValueReaderFromFactory(PropertyMeta<?, ?> pm, int index, CsvColumnDefinition columnDefinition, ParsingContextFactoryBuilder parsingContextFactoryBuilder) {
    Type propertyType = pm.getPropertyType();
    CellValueReader<P> reader = null;
    if (columnDefinition.hasCustomReaderFactory()) {
        CellValueReaderFactory factory = columnDefinition.getCustomCellValueReaderFactory();
        reader = factory.getReader(propertyType, index, columnDefinition, parsingContextFactoryBuilder);
    }
    if (reader == null) {
        reader = cellValueReaderFactory.getReader(propertyType, index, columnDefinition, parsingContextFactoryBuilder);
    }
    if (reader == null) {
        if (!pm.isSelf()) {
            final ClassMeta<?> classMeta = pm.getPropertyClassMeta();
            InstantiatorDefinition id = InstantiatorDefinitions.lookForCompatibleOneArgument(classMeta.getInstantiatorDefinitions(), COMPATIBILITY_SCORER);
            if (id != null) {
                final Parameter parameter = id.getParameters()[0];
                // look for constructor property matching name
                final PropertyMeta<?, Object> property = classMeta.newPropertyFinder(new Predicate<PropertyMeta<?, ?>>() {

                    @Override
                    public boolean test(PropertyMeta<?, ?> propertyMeta) {
                        return propertyMeta.isConstructorProperty() || propertyMeta.isSubProperty() && ((SubPropertyMeta) propertyMeta).getOwnerProperty().isConstructorProperty();
                    }
                }).findProperty(DefaultPropertyNameMatcher.exact(parameter.getName()), columnDefinition.properties());
                reader = cellValueReaderFromFactory(property, index, columnDefinition, parsingContextFactoryBuilder);
                if (reader != null) {
                    Instantiator<P, P> instantiator = classMeta.getReflectionService().getInstantiatorFactory().getOneArgIdentityInstantiator(id, classMeta.getReflectionService().builderIgnoresNullValues());
                    return new InstantiatorOnReader<P, P>(instantiator, reader);
                }
            }
        }
    }
    return reader;
}
Also used : Predicate(org.simpleflatmapper.util.Predicate) InstantiatorDefinition(org.simpleflatmapper.reflect.InstantiatorDefinition) Type(java.lang.reflect.Type) CellValueReaderFactory(org.simpleflatmapper.csv.CellValueReaderFactory) Parameter(org.simpleflatmapper.reflect.Parameter) SubPropertyMeta(org.simpleflatmapper.reflect.meta.SubPropertyMeta) PropertyMeta(org.simpleflatmapper.reflect.meta.PropertyMeta)

Example 3 with Parameter

use of org.simpleflatmapper.reflect.Parameter in project SimpleFlatMapper by arnaudroger.

the class AsmFactory method createBiInstantiator.

@SuppressWarnings("unchecked")
public <S1, S2, T> BiInstantiator<S1, S2, T> createBiInstantiator(final Class<?> s1, final Class<?> s2, final InstantiatorDefinition instantiatorDefinition, final Map<Parameter, BiFunction<? super S1, ? super S2, ?>> injections, boolean builderIgnoresNullValues) throws Exception {
    BiInstantiatorKey instantiatorKey = new BiInstantiatorKey(instantiatorDefinition, injections, s1, s2);
    Class<? extends BiInstantiator<?, ?, ?>> instantiator = biInstantiatorCache.get(instantiatorKey);
    Instantiator builderInstantiator = null;
    if (instantiator == null) {
        final String className = generateClassNameForBiInstantiator(instantiatorKey);
        final byte[] bytes;
        if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) {
            bytes = BiInstantiatorBuilder.createInstantiator(className, s1, s2, (ExecutableInstantiatorDefinition) instantiatorDefinition, injections);
        } else {
            builderInstantiator = createInstantiator(Void.class, ((BuilderInstantiatorDefinition) instantiatorDefinition).getBuilderInstantiator(), new HashMap<Parameter, Getter<? super Void, ?>>(), builderIgnoresNullValues);
            bytes = BiInstantiatorBuilder.createInstantiator(className, s1, s2, builderInstantiator, (BuilderInstantiatorDefinition) instantiatorDefinition, injections, builderIgnoresNullValues);
        }
        instantiator = (Class<? extends BiInstantiator<?, ?, ?>>) createClass(className, bytes, instantiatorKey.getDeclaringClass().getClassLoader());
        biInstantiatorCache.put(instantiatorKey, instantiator);
    }
    Map<String, BiFunction<? super S1, ? super S2, ?>> factoryPerName = new HashMap<String, BiFunction<? super S1, ? super S2, ?>>();
    for (Entry<Parameter, BiFunction<? super S1, ? super S2, ?>> e : injections.entrySet()) {
        factoryPerName.put(e.getKey().getName(), e.getValue());
    }
    if (instantiatorDefinition instanceof ExecutableInstantiatorDefinition) {
        return (BiInstantiator<S1, S2, T>) instantiator.getConstructor(Map.class).newInstance(factoryPerName);
    } else {
        return (BiInstantiator<S1, S2, T>) instantiator.getConstructor(Map.class, Instantiator.class).newInstance(factoryPerName, builderInstantiator);
    }
}
Also used : ExecutableInstantiatorDefinition(org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Instantiator(org.simpleflatmapper.reflect.Instantiator) BiInstantiator(org.simpleflatmapper.reflect.BiInstantiator) BuilderInstantiatorDefinition(org.simpleflatmapper.reflect.BuilderInstantiatorDefinition) BiFunction(org.simpleflatmapper.util.BiFunction) Parameter(org.simpleflatmapper.reflect.Parameter) BiInstantiator(org.simpleflatmapper.reflect.BiInstantiator)

Example 4 with Parameter

use of org.simpleflatmapper.reflect.Parameter in project SimpleFlatMapper by arnaudroger.

the class AsmInstantiatorDefinitionFactory method extractDefinitions.

public static List<InstantiatorDefinition> extractDefinitions(final Type target) throws IOException {
    final List<InstantiatorDefinition> constructors = new ArrayList<InstantiatorDefinition>();
    final Class<?> targetClass = TypeHelper.toClass(target);
    ClassLoader cl = targetClass.getClassLoader();
    if (cl == null) {
        cl = ClassLoader.getSystemClassLoader();
    }
    final String fileName = targetClass.getName().replace('.', '/') + ".class";
    final InputStream is = cl.getResourceAsStream(fileName);
    try {
        if (is == null) {
            throw new IOException("Cannot find file " + fileName + " in " + cl);
        }
        ClassReader classReader = new ClassReader(is);
        classReader.accept(new ClassVisitor(Opcodes.ASM5) {

            List<String> genericTypeNames;

            @Override
            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
                if (signature != null) {
                    genericTypeNames = AsmUtils.extractGenericTypeNames(signature);
                } else {
                    genericTypeNames = Collections.emptyList();
                }
                super.visit(version, access, name, signature, superName, interfaces);
            }

            @Override
            public MethodVisitor visitMethod(int access, final String methodName, String desc, String signature, String[] exceptions) {
                final boolean isConstructor = "<init>".equals(methodName);
                if ((Opcodes.ACC_PUBLIC & access) == Opcodes.ACC_PUBLIC && (isConstructor || ((Opcodes.ACC_STATIC & access) == Opcodes.ACC_STATIC && !desc.endsWith("V")))) {
                    final List<String> descTypes = AsmUtils.extractTypeNamesFromSignature(desc);
                    final List<String> genericTypes;
                    final List<String> names = new ArrayList<String>();
                    if (signature != null) {
                        genericTypes = AsmUtils.extractTypeNamesFromSignature(signature);
                    } else {
                        genericTypes = descTypes;
                    }
                    if (!isConstructor) {
                        if (descTypes.size() > 0) {
                            try {
                                final Type genericType = AsmUtils.toGenericType(descTypes.get(descTypes.size() - 1), genericTypeNames, target);
                                if (!targetClass.isAssignableFrom(TypeHelper.toClass(genericType))) {
                                    return null;
                                }
                            } catch (ClassNotFoundException e) {
                                return null;
                            }
                        } else
                            return null;
                    }
                    return new MethodVisitor(Opcodes.ASM5) {

                        Label firstLabel;

                        Label lastLabel;

                        @Override
                        public void visitLabel(Label label) {
                            if (firstLabel == null) {
                                firstLabel = label;
                            }
                            lastLabel = label;
                        }

                        @Override
                        public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                            if (start.equals(firstLabel) && end.equals(lastLabel) && !"this".equals(name)) {
                                names.add(name);
                            }
                        }

                        @Override
                        public void visitEnd() {
                            try {
                                final List<Parameter> parameters = new ArrayList<Parameter>();
                                int l = descTypes.size() - (isConstructor ? 0 : 1);
                                for (int i = 0; i < l; i++) {
                                    String name = "arg" + i;
                                    if (i < names.size()) {
                                        name = names.get(i);
                                    }
                                    parameters.add(createParameter(i, name, descTypes.get(i), genericTypes.get(i)));
                                }
                                final Member executable;
                                if (isConstructor) {
                                    executable = targetClass.getDeclaredConstructor(toTypeArray(parameters));
                                } else {
                                    executable = targetClass.getDeclaredMethod(methodName, toTypeArray(parameters));
                                }
                                constructors.add(new ExecutableInstantiatorDefinition(executable, parameters.toArray(new Parameter[0])));
                            } catch (Exception e) {
                                ErrorHelper.rethrow(e);
                            }
                        }

                        private Class<?>[] toTypeArray(List<Parameter> parameters) {
                            Class<?>[] types = new Class<?>[parameters.size()];
                            for (int i = 0; i < types.length; i++) {
                                types[i] = parameters.get(i).getType();
                            }
                            return types;
                        }

                        private Parameter createParameter(int index, String name, String desc, String signature) {
                            try {
                                Type basicType = AsmUtils.toGenericType(desc, genericTypeNames, target);
                                Type genericType = basicType;
                                if (signature != null) {
                                    Type type = AsmUtils.toGenericType(signature, genericTypeNames, target);
                                    if (type != null) {
                                        genericType = type;
                                    }
                                }
                                return new Parameter(index, name, TypeHelper.toClass(basicType), genericType);
                            } catch (ClassNotFoundException e) {
                                throw new Error("Unexpected error " + e, e);
                            }
                        }
                    };
                } else {
                    return null;
                }
            }
        }, 0);
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (Exception e) {
            }
        }
    }
    return constructors;
}
Also used : ExecutableInstantiatorDefinition(org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition) ArrayList(java.util.ArrayList) Label(org.simpleflatmapper.ow2asm.Label) ClassVisitor(org.simpleflatmapper.ow2asm.ClassVisitor) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor) ExecutableInstantiatorDefinition(org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition) InstantiatorDefinition(org.simpleflatmapper.reflect.InstantiatorDefinition) ArrayList(java.util.ArrayList) List(java.util.List) Member(java.lang.reflect.Member) InputStream(java.io.InputStream) IOException(java.io.IOException) IOException(java.io.IOException) Type(java.lang.reflect.Type) ClassReader(org.simpleflatmapper.ow2asm.ClassReader) Parameter(org.simpleflatmapper.reflect.Parameter)

Example 5 with Parameter

use of org.simpleflatmapper.reflect.Parameter in project SimpleFlatMapper by arnaudroger.

the class BiInstantiatorBuilder method appendNewInstance.

private static <S1, S2> void appendNewInstance(Class<?> s1, Class<?> s2, ExecutableInstantiatorDefinition instantiatorDefinition, List<InjectionPoint> injectionPoints, ClassWriter cw, String targetType, String s1Type, String s2Type, String classType, Parameter[] parameters) throws NoSuchMethodException {
    MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "(" + AsmUtils.toTargetTypeDeclaration(s1Type) + AsmUtils.toTargetTypeDeclaration(s2Type) + ")" + AsmUtils.toTargetTypeDeclaration(targetType), null, new String[] { "java/lang/Exception" });
    mv.visitCode();
    mv.visitTypeInsn(NEW, targetType);
    mv.visitInsn(DUP);
    StringBuilder sb = new StringBuilder();
    for (Parameter p : parameters) {
        InjectionPoint function = findFunctionCalls(p, injectionPoints);
        sb.append(AsmUtils.toTargetTypeDeclaration(p.getType()));
        if (function == null) {
            newInstanceNullFunction(mv, p);
        } else {
            invokeBiFunction(function, classType, s1, s2, mv, null, false);
        }
    }
    Member exec = instantiatorDefinition.getExecutable();
    if (exec instanceof Constructor) {
        mv.visitMethodInsn(INVOKESPECIAL, targetType, "<init>", "(" + sb.toString() + ")V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, AsmUtils.toAsmType(((Method) exec).getDeclaringClass()), exec.getName(), AsmUtils.toSignature((Method) exec), false);
    }
    mv.visitInsn(ARETURN);
    mv.visitMaxs(3, 2);
    mv.visitEnd();
}
Also used : Constructor(java.lang.reflect.Constructor) Parameter(org.simpleflatmapper.reflect.Parameter) Method(java.lang.reflect.Method) Member(java.lang.reflect.Member) MethodVisitor(org.simpleflatmapper.ow2asm.MethodVisitor)

Aggregations

Parameter (org.simpleflatmapper.reflect.Parameter)37 Test (org.junit.Test)20 ExecutableInstantiatorDefinition (org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition)20 InstantiatorDefinition (org.simpleflatmapper.reflect.InstantiatorDefinition)17 HashMap (java.util.HashMap)16 BiFunction (org.simpleflatmapper.util.BiFunction)16 BuilderInstantiatorDefinition (org.simpleflatmapper.reflect.BuilderInstantiatorDefinition)10 InstantiatorFactory (org.simpleflatmapper.reflect.InstantiatorFactory)10 ConstantBiFunction (org.simpleflatmapper.util.ConstantBiFunction)9 Getter (org.simpleflatmapper.reflect.Getter)6 ConstantGetter (org.simpleflatmapper.reflect.getter.ConstantGetter)6 BuilderBiInstantiator (org.simpleflatmapper.reflect.impl.BuilderBiInstantiator)6 MethodVisitor (org.simpleflatmapper.ow2asm.MethodVisitor)5 Method (java.lang.reflect.Method)4 Type (java.lang.reflect.Type)4 AsmFactory (org.simpleflatmapper.reflect.asm.AsmFactory)4 DbFinalPrimitiveObject (org.simpleflatmapper.test.beans.DbFinalPrimitiveObject)4 InputStream (java.io.InputStream)3 Member (java.lang.reflect.Member)3 Constructor (java.lang.reflect.Constructor)2