##### 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;4.75
PropertyUtils$1 |
100% | 1/1
N/A | N/A
| 4.75;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 |  |
     }