• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

link-intersystems / lis-commons / #291

05 Nov 2023 07:22PM UTC coverage: 90.072% (+0.04%) from 90.032%
#291

push

renelink
Code coverage and clean up. Breaking API change.

21 of 24 new or added lines in 5 files covered. (87.5%)

6 existing lines in 3 files now uncovered.

7712 of 8562 relevant lines covered (90.07%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.98
/lis-commons-beans/src/main/java/com/link_intersystems/beans/java/JavaBeanClass.java
1
/**
2
 * Copyright 2011 Link Intersystems GmbH <rene.link@link-intersystems.com>
3
 * <p>
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
 * <p>
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 * <p>
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
package com.link_intersystems.beans.java;
17

18
import com.link_intersystems.beans.*;
19

20
import java.beans.*;
21
import java.io.Serializable;
22
import java.lang.reflect.Method;
23
import java.util.List;
24

25
import static java.text.MessageFormat.format;
26
import static java.util.Arrays.stream;
27
import static java.util.Objects.requireNonNull;
28
import static java.util.stream.Collectors.toList;
29

30
/**
31
 * A {@link JavaBeanClass} provides features for handling common bean issues.
32
 *
33
 * @param <T> the type of the bean.
34
 * @author René Link
35
 * <a href="mailto:rene.link@link-intersystems.com">[rene.link@link-
36
 * intersystems.com]</a>
37
 * @since 1.2.0;
38
 */
39
public class JavaBeanClass<T> extends BeanClass<T> implements Serializable {
40

41
    private static final long serialVersionUID = -5446272789930350423L;
42

43
    private BeanInfo beanInfo;
44

45
    private transient JavaPropertyDescriptors propertyDescriptors;
46

47
    private transient List<JavaPropertyDesc> javaPropertyDescs;
48

49
    private transient PropertyDescList allProperties;
50

51
    private BeanEventTypeList beanEventTypes;
52

53
    JavaBeanClass(Class<T> beanType) throws BeanClassException {
54
        this(beanType, null);
1✔
55
    }
1✔
56

57
    JavaBeanClass(Class<T> beanType, Class<?> stopClass) throws BeanClassException {
58
        this(getBeanInfo(beanType, stopClass));
1✔
59
    }
1✔
60

61
    private static BeanInfo getBeanInfo(Class<?> beanType, Class<?> stopClass) {
62
        try {
63
            return Introspector.getBeanInfo(beanType, stopClass);
1✔
UNCOV
64
        } catch (IntrospectionException e) {
×
UNCOV
65
            String msg = format("Unable to create BeanClass for ''{0}''. Stop at ''{1}''", beanType, stopClass);
×
UNCOV
66
            throw new BeanClassException(msg, e);
×
67
        }
68
    }
69

70
    protected JavaBeanClass(BeanInfo beanInfo) throws BeanClassException {
1✔
71
        this.beanInfo = requireNonNull(beanInfo);
1✔
72
    }
1✔
73

74
    @Override
75
    public String getName() {
76
        return beanInfo.getBeanDescriptor().getName();
1✔
77
    }
78

79
    @SuppressWarnings("unchecked")
80
    @Override
81
    public Class<T> getType() {
82
        return (Class<T>) beanInfo.getBeanDescriptor().getBeanClass();
1✔
83
    }
84

85
    /**
86
     * @return a map whose keys are the property names of the properties that this
87
     * class defines according to the java bean specification. The values
88
     * are the corresponding {@link PropertyDescriptor}s. The returned Map
89
     * is unmodifiable.
90
     * @since 1.2.0;
91
     */
92
    public JavaPropertyDescriptors getJavaPropertyDescriptors() {
93
        if (propertyDescriptors == null) {
1✔
94
            propertyDescriptors = createJavaPropertyDescriptors();
1✔
95
        }
96
        return propertyDescriptors;
1✔
97
    }
98

99
    private JavaPropertyDescriptors createJavaPropertyDescriptors() throws IllegalStateException {
100
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
1✔
101
        return new JavaPropertyDescriptors(propertyDescriptors);
1✔
102
    }
103

104
    /**
105
     * Returns true if the method is a method to access a property (either get, is,
106
     * set). The equality is based on the method's signature. This means that even
107
     * property accessor methods in super classes will be recognized as property
108
     * accessor methods of this {@link JavaBeanClass}.
109
     *
110
     * @param method the method to test if it is a property accessor method of this
111
     *               class.
112
     * @return true if the given method is a property accessor method of this class.
113
     * @since 1.2.0;
114
     */
115
    public boolean isPropertyAccessor(Method method) {
116
        Class<?> declaringClass = method.getDeclaringClass();
1✔
117
        Class<T> beanType = getType();
1✔
118
        boolean isInHierarchy = declaringClass.isAssignableFrom(beanType);
1✔
119
        if (!isInHierarchy) {
1✔
UNCOV
120
            return false;
×
121
        }
122
        JavaPropertyDescriptors propertyDescriptors = getJavaPropertyDescriptors();
1✔
123

124
        return propertyDescriptors.stream()
1✔
125
                .anyMatch(pd -> PropertyDescriptor2AccessorsTransformer.INSTANCE.apply(pd).stream().anyMatch(method::equals));
1✔
126
    }
127

128
    @Override
129
    public BeanInstanceFactory<T> getBeanInstanceFactory() {
130
        return new JavaBeanInstanceFactory<>(this);
1✔
131
    }
132

133
    @Override
134
    public BeanEventTypeList getBeanEventTypes() {
135
        if (beanEventTypes == null) {
1✔
136
            beanEventTypes = createBeanEventTypes();
1✔
137
        }
138
        return beanEventTypes;
1✔
139
    }
140

141
    private BeanEventTypeList createBeanEventTypes() {
142
        EventSetDescriptor[] eventSetDescriptors = beanInfo.getEventSetDescriptors();
1✔
143
        List<JavaBeanEventType> beanEventTypes = stream(eventSetDescriptors)
1✔
144
                .map(this::newJavaBeanEventType)
1✔
145
                .collect(toList());
1✔
146
        return new BeanEventTypeList(beanEventTypes);
1✔
147
    }
148

149
    private JavaBeanEventType newJavaBeanEventType(EventSetDescriptor eventSetDescriptor) {
150
        return new JavaBeanEventType(this, eventSetDescriptor);
1✔
151
    }
152

153
    @Override
154
    public boolean isListenerSupported(Class<?> listenerClass) {
155
        BeanEventTypeList beanEvents = getBeanEventTypes();
1✔
156
        return beanEvents.stream().anyMatch(be -> be.isApplicable(listenerClass));
1✔
157
    }
158

159
    @Override
160
    public PropertyDescList getAllProperties() {
161
        if (this.allProperties == null) {
1✔
162
            this.allProperties = new PropertyDescList(getJavaPropertyDescs());
1✔
163
        }
164
        return allProperties;
1✔
165
    }
166

167

168
    List<JavaPropertyDesc> getJavaPropertyDescs() {
169
        if (javaPropertyDescs == null) {
1✔
170
            javaPropertyDescs = getJavaPropertyDescriptors().stream()
1✔
171
                    .map(this::toPropertyDesc)
1✔
172
                    .collect(toList());
1✔
173
        }
174
        return javaPropertyDescs;
1✔
175
    }
176

177
    JavaPropertyDesc getPropertyDescByMethod(Method method) {
178
        return getAllProperties().stream()
1✔
179
                .map(JavaPropertyDesc.class::cast)
1✔
180
                .filter(jpd -> jpd.hasMethod(method))
1✔
181
                .findFirst()
1✔
182
                .orElse(null);
1✔
183
    }
184

185
    private JavaPropertyDesc toPropertyDesc(PropertyDescriptor pd) {
186
        if (pd instanceof IndexedPropertyDescriptor) {
1✔
187
            return new JavaIndexedPropertyDesc((IndexedPropertyDescriptor) pd);
1✔
188
        } else {
189
            return new JavaPropertyDesc(pd);
1✔
190
        }
191
    }
192

193
    @Override
194
    public String toString() {
195
        return "JavaBeanClass{" +
1✔
196
                "name=" + getName() +
1✔
197
                ", type=" + getType().getName() +
1✔
198
                '}';
199
    }
200
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc