Coverage Report - org.apache.johnzon.mapper.access.MethodAccessMode
 
Classes in this File Line Coverage Branch Coverage Complexity
MethodAccessMode
87 %
27/31
80 %
24/30
2,625
MethodAccessMode$MethodDecoratedType
100 %
6/6
100 %
2/2
2,625
MethodAccessMode$MethodGetterAsWriter
81 %
9/11
50 %
2/4
2,625
MethodAccessMode$MethodReader
71 %
5/7
N/A
2,625
MethodAccessMode$MethodWriter
77 %
7/9
N/A
2,625
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements. See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership. The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License. You may obtain a copy of the License at
 9  
  *
 10  
  * http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied. See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.johnzon.mapper.access;
 20  
 
 21  
 import org.apache.johnzon.mapper.JohnzonProperty;
 22  
 import org.apache.johnzon.mapper.MapperException;
 23  
 
 24  
 import java.beans.IntrospectionException;
 25  
 import java.beans.Introspector;
 26  
 import java.beans.PropertyDescriptor;
 27  
 import java.lang.annotation.Annotation;
 28  
 import java.lang.reflect.Method;
 29  
 import java.lang.reflect.Type;
 30  
 import java.util.Collection;
 31  
 import java.util.HashMap;
 32  
 import java.util.Map;
 33  
 
 34  
 public class MethodAccessMode implements AccessMode {
 35  
     private final boolean supportGetterAsWritter;
 36  
 
 37  64
     public MethodAccessMode(final boolean supportGetterAsWritter) {
 38  64
         this.supportGetterAsWritter = supportGetterAsWritter;
 39  64
     }
 40  
 
 41  
     @Override
 42  
     public Map<String, Reader> findReaders(final Class<?> clazz) {
 43  47
         final Map<String, Reader> readers = new HashMap<String, Reader>();
 44  47
         final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
 45  275
         for (final PropertyDescriptor descriptor : propertyDescriptors) {
 46  228
             final Method readMethod = descriptor.getReadMethod();
 47  228
             if (readMethod != null && readMethod.getDeclaringClass() != Object.class) {
 48  180
                 if (isIgnored(descriptor.getName())) {
 49  0
                     continue;
 50  
                 }
 51  180
                 readers.put(extractKey(descriptor), new MethodReader(readMethod));
 52  
             }
 53  
         }
 54  47
         return readers;
 55  
     }
 56  
 
 57  
     @Override
 58  
     public Map<String, Writer> findWriters(final Class<?> clazz) {
 59  47
         final Map<String, Writer> writers = new HashMap<String, Writer>();
 60  47
         final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
 61  275
         for (final PropertyDescriptor descriptor : propertyDescriptors) {
 62  228
             if (descriptor.getPropertyType() == Class.class || isIgnored(descriptor.getName())) {
 63  0
                 continue;
 64  
             }
 65  181
             final Method writeMethod = descriptor.getWriteMethod();
 66  181
             if (writeMethod != null) {
 67  173
                 writers.put(extractKey(descriptor), new MethodWriter(writeMethod));
 68  8
             } else if (supportGetterAsWritter
 69  
                     && Collection.class.isAssignableFrom(descriptor.getPropertyType())
 70  
                     && descriptor.getReadMethod() != null) {
 71  1
                 writers.put(extractKey(descriptor), new MethodGetterAsWriter(descriptor.getReadMethod()));
 72  
             }
 73  
         }
 74  47
         return writers;
 75  
     }
 76  
 
 77  
     private String extractKey(final PropertyDescriptor f) {
 78  354
         final JohnzonProperty property = f.getReadMethod() == null ? null : f.getReadMethod().getAnnotation(JohnzonProperty.class);
 79  354
         return property != null ? property.value() : f.getName();
 80  
     }
 81  
 
 82  
     protected boolean isIgnored(final String name) {
 83  361
         return name.equals("metaClass") || name.contains("$");
 84  
     }
 85  
 
 86  
     private PropertyDescriptor[] getPropertyDescriptors(final Class<?> clazz) {
 87  
         final PropertyDescriptor[] propertyDescriptors;
 88  
         try {
 89  94
             propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
 90  0
         } catch (final IntrospectionException e) {
 91  0
             throw new IllegalStateException(e);
 92  94
         }
 93  94
         return propertyDescriptors;
 94  
     }
 95  
 
 96  
     protected static abstract class MethodDecoratedType implements DecoratedType {
 97  
         protected final Method method;
 98  
 
 99  354
         public MethodDecoratedType(final Method method) {
 100  354
             this.method = method;
 101  354
             if (!method.isAccessible()) {
 102  101
                 method.setAccessible(true);
 103  
             }
 104  354
         }
 105  
 
 106  
         @Override
 107  
         public <T extends Annotation> T getAnnotation(final Class<T> clazz) {
 108  712
             return method.getAnnotation(clazz);
 109  
         }
 110  
     }
 111  
 
 112  348
     public static class MethodWriter extends MethodDecoratedType implements Writer {
 113  
         public MethodWriter(final Method method) {
 114  173
             super(method);
 115  173
         }
 116  
 
 117  
         @Override
 118  
         public Type getType() {
 119  173
             return method.getGenericParameterTypes()[0];
 120  
         }
 121  
 
 122  
         @Override
 123  
         public void write(final Object instance, final Object value) {
 124  
             try {
 125  129
                 method.invoke(instance, value);
 126  0
             } catch (final Exception e) {
 127  0
                 throw new MapperException(e);
 128  129
             }
 129  129
         }
 130  
     }
 131  
 
 132  364
     public static class MethodReader extends MethodDecoratedType implements Reader {
 133  
         public MethodReader(final Method method) {
 134  181
             super(method);
 135  181
         }
 136  
 
 137  
         @Override
 138  
         public Type getType() {
 139  541
             return method.getGenericReturnType();
 140  
         }
 141  
 
 142  
         @Override
 143  
         public Object read(final Object instance) {
 144  
             try {
 145  157
                 return method.invoke(instance);
 146  0
             } catch (final Exception e) {
 147  0
                 throw new MapperException(e);
 148  
             }
 149  
         }
 150  
     }
 151  
 
 152  
     private class MethodGetterAsWriter extends MethodReader implements Writer {
 153  1
         public MethodGetterAsWriter(final Method readMethod) {
 154  1
             super(readMethod);
 155  1
         }
 156  
 
 157  
         @Override
 158  
         public void write(final Object instance, final Object value) {
 159  1
             if (value != null) {
 160  
                 try {
 161  1
                     final Collection<?> collection = Collection.class.cast(method.invoke(instance));
 162  1
                     if (collection != null) {
 163  1
                         collection.addAll(Collection.class.cast(value));
 164  
                     }
 165  0
                 } catch (final Exception e) {
 166  0
                     throw new MapperException(e);
 167  1
                 }
 168  
             }
 169  1
         }
 170  
     }
 171  
 }