Coverage Report - org.yaml.snakeyaml.introspector.PropertyUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
PropertyUtils
100%
58/58
98%
51/52
4.75
PropertyUtils$1
100%
1/1
N/A
4.75
 
 1  
 /**
 2  
  * Copyright (c) 2008-2011, http://www.snakeyaml.org
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.yaml.snakeyaml.introspector;
 18  
 
 19  
 import java.beans.IntrospectionException;
 20  
 import java.beans.Introspector;
 21  
 import java.beans.PropertyDescriptor;
 22  
 import java.lang.reflect.Field;
 23  
 import java.lang.reflect.Method;
 24  
 import java.lang.reflect.Modifier;
 25  
 import java.util.Collection;
 26  
 import java.util.HashMap;
 27  
 import java.util.LinkedHashMap;
 28  
 import java.util.Map;
 29  
 import java.util.Set;
 30  
 import java.util.TreeSet;
 31  
 
 32  
 import org.yaml.snakeyaml.error.YAMLException;
 33  
 
 34  3964
 public class PropertyUtils {
 35  
 
 36  3964
     private final Map<Class<?>, Map<String, Property>> propertiesCache = new HashMap<Class<?>, Map<String, Property>>();
 37  3964
     private final Map<Class<?>, Set<Property>> readableProperties = new HashMap<Class<?>, Set<Property>>();
 38  3964
     private BeanAccess beanAccess = BeanAccess.DEFAULT;
 39  3964
     private boolean allowReadOnlyProperties = false;
 40  
 
 41  
     protected Map<String, Property> getPropertiesMap(Class<?> type, BeanAccess bAccess)
 42  
             throws IntrospectionException {
 43  14839
         if (propertiesCache.containsKey(type)) {
 44  2320
             return propertiesCache.get(type);
 45  
         }
 46  
 
 47  12519
         Map<String, Property> properties = new LinkedHashMap<String, Property>();
 48  12519
         boolean inaccessableFieldsExist = false;
 49  12519
         switch (bAccess) {
 50  
         case FIELD:
 51  87
             for (Class<?> c = type; c != null; c = c.getSuperclass()) {
 52  119
                 for (Field field : c.getDeclaredFields()) {
 53  61
                     int modifiers = field.getModifiers();
 54  61
                     if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)
 55  
                             && !properties.containsKey(field.getName())) {
 56  55
                         properties.put(field.getName(), new FieldProperty(field));
 57  
                     }
 58  
                 }
 59  
             }
 60  29
             break;
 61  
         default:
 62  
             // add JavaBean properties
 63  
             for (PropertyDescriptor property : Introspector.getBeanInfo(type)
 64  26233
                     .getPropertyDescriptors()) {
 65  13743
                 Method readMethod = property.getReadMethod();
 66  13743
                 if (readMethod == null || !readMethod.getName().equals("getClass")) {
 67  1253
                     properties.put(property.getName(), new MethodProperty(property));
 68  
                 }
 69  
             }
 70  
 
 71  
             // add public fields
 72  37523
             for (Class<?> c = type; c != null; c = c.getSuperclass()) {
 73  83464
                 for (Field field : c.getDeclaredFields()) {
 74  58431
                     int modifiers = field.getModifiers();
 75  58431
                     if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {
 76  58409
                         if (Modifier.isPublic(modifiers)) {
 77  57143
                             properties.put(field.getName(), new FieldProperty(field));
 78  
                         } else {
 79  1266
                             inaccessableFieldsExist = true;
 80  
                         }
 81  
                     }
 82  
                 }
 83  
             }
 84  
             break;
 85  
         }
 86  12519
         if (properties.isEmpty() && inaccessableFieldsExist) {
 87  4
             throw new YAMLException("No JavaBean properties found in " + type.getName());
 88  
         }
 89  12515
         propertiesCache.put(type, properties);
 90  12515
         return properties;
 91  
     }
 92  
 
 93  
     public Set<Property> getProperties(Class<? extends Object> type) throws IntrospectionException {
 94  41387
         return getProperties(type, beanAccess);
 95  
     }
 96  
 
 97  
     public Set<Property> getProperties(Class<? extends Object> type, BeanAccess bAccess)
 98  
             throws IntrospectionException {
 99  41387
         if (readableProperties.containsKey(type)) {
 100  29116
             return readableProperties.get(type);
 101  
         }
 102  12271
         Set<Property> properties = createPropertySet(type, bAccess);
 103  12267
         readableProperties.put(type, properties);
 104  12267
         return properties;
 105  
     }
 106  
 
 107  
     protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess)
 108  
             throws IntrospectionException {
 109  12270
         Set<Property> properties = new TreeSet<Property>();
 110  12270
         Collection<Property> props = getPropertiesMap(type, bAccess).values();
 111  12266
         for (Property property : props) {
 112  57695
             if (property.isReadable() && (allowReadOnlyProperties || property.isWritable())) {
 113  57680
                 properties.add(property);
 114  
             }
 115  
         }
 116  12266
         return properties;
 117  
     }
 118  
 
 119  
     public Property getProperty(Class<? extends Object> type, String name)
 120  
             throws IntrospectionException {
 121  2568
         return getProperty(type, name, beanAccess);
 122  
     }
 123  
 
 124  
     public Property getProperty(Class<? extends Object> type, String name, BeanAccess bAccess)
 125  
             throws IntrospectionException {
 126  2568
         Map<String, Property> properties = getPropertiesMap(type, bAccess);
 127  2568
         Property property = properties.get(name);
 128  2568
         if (property == null || !property.isWritable()) {
 129  12
             throw new YAMLException("Unable to find property '" + name + "' on class: "
 130  
                     + type.getName());
 131  
         }
 132  2556
         return property;
 133  
     }
 134  
 
 135  
     public void setBeanAccess(BeanAccess beanAccess) {
 136  45
         if (this.beanAccess != beanAccess) {
 137  20
             this.beanAccess = beanAccess;
 138  20
             propertiesCache.clear();
 139  20
             readableProperties.clear();
 140  
         }
 141  45
     }
 142  
 
 143  
     public void setAllowReadOnlyProperties(boolean allowReadOnlyProperties) {
 144  3963
         if (this.allowReadOnlyProperties != allowReadOnlyProperties) {
 145  12
             this.allowReadOnlyProperties = allowReadOnlyProperties;
 146  12
             readableProperties.clear();
 147  
         }
 148  3963
     }
 149  
 }