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

openmrs / openmrs-core / 10584527061

27 Aug 2024 07:22PM CUT coverage: 64.727% (-0.003%) from 64.73%
10584527061

push

github

web-flow
maven(deps): bump org.apache.maven.plugins:maven-javadoc-plugin (#4732)

Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.8.0 to 3.10.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.8.0...maven-javadoc-plugin-3.10.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

22958 of 35469 relevant lines covered (64.73%)

0.65 hits per line

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

85.29
/api/src/main/java/org/openmrs/util/HandlerUtil.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.util;
11

12
import java.util.ArrayList;
13
import java.util.Comparator;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.WeakHashMap;
17

18
import org.openmrs.annotation.Handler;
19
import org.openmrs.api.APIException;
20
import org.openmrs.api.context.Context;
21
import org.slf4j.Logger;
22
import org.slf4j.LoggerFactory;
23
import org.springframework.context.ApplicationListener;
24
import org.springframework.context.event.ContextRefreshedEvent;
25
import org.springframework.stereotype.Component;
26

27
/**
28
 * Utility class that provides useful methods for working with classes that are annotated with the
29
 * {@link Handler} annotation
30
 * 
31
 * @since 1.5
32
 */
33
@Component
34
public class HandlerUtil implements ApplicationListener<ContextRefreshedEvent> {
1✔
35
        
36
        private static final Logger log = LoggerFactory.getLogger(HandlerUtil.class);
1✔
37
        
38
        private static volatile Map<Key, List<?>> cachedHandlers = new WeakHashMap<>();
1✔
39
        
40
        private static class Key {
41
                
42
                public final Class<?> handlerType;
43
                
44
                public final Class<?> type;
45
                
46
                public Key(Class<?> handlerType, Class<?> type) {
1✔
47
                        this.handlerType = handlerType;
1✔
48
                        this.type = type;
1✔
49
                }
1✔
50
                
51
                @Override
52
                public int hashCode() {
53
                        final int prime = 31;
1✔
54
                        int result = 1;
1✔
55
                        result = prime * result + ((handlerType == null) ? 0 : handlerType.hashCode());
1✔
56
                        result = prime * result + ((type == null) ? 0 : type.hashCode());
1✔
57
                        return result;
1✔
58
                }
59
                
60
                @Override
61
                public boolean equals(Object obj) {
62
                        if (this == obj) {
1✔
63
                                return true;
×
64
                        }
65
                        if (obj == null) {
1✔
66
                                return false;
×
67
                        }
68
                        if (getClass() != obj.getClass()) {
1✔
69
                                return false;
×
70
                        }
71
                        Key other = (Key) obj;
1✔
72
                        if (handlerType == null) {
1✔
73
                                if (other.handlerType != null) {
×
74
                                        return false;
×
75
                                }
76
                        } else if (!handlerType.equals(other.handlerType)) {
1✔
77
                                return false;
×
78
                        }
79
                        if (type == null) {
1✔
80
                                return other.type == null;
×
81
                        } else {
82
                                return type.equals(other.type);
1✔
83
                        }
84
                }
85
                
86
        }
87
        
88
        public static void clearCachedHandlers() {
89
                cachedHandlers = new WeakHashMap<>();
1✔
90
        }
1✔
91
        
92
        /**
93
         * Retrieves a List of all registered components from the Context that are of the passed
94
         * handlerType and one or more of the following is true:
95
         * <ul>
96
         * <li>The handlerType is annotated as a {@link Handler} that supports the passed type</li>
97
         * <li>The passed type is null - this effectively returns all components of the passed
98
         * handlerType</li>
99
         * </ul>
100
         * The returned handlers are ordered in the list based upon the order property.
101
         * 
102
         * @param handlerType Indicates the type of class to return
103
         * @param type Indicates the type that the given handlerType must support (or null for any)
104
         * @return a List of all matching Handlers for the given parameters, ordered by Handler#order
105
         * <strong>Should</strong> return a list of all classes that can handle the passed type
106
         * <strong>Should</strong> return classes registered in a module
107
         * <strong>Should</strong> return an empty list if no classes can handle the passed type
108
         */
109
        public static <H, T> List<H> getHandlersForType(Class<H> handlerType, Class<T> type) {
110
                List<?> list = cachedHandlers.get(new Key(handlerType, type));
1✔
111
                if (list != null) {
1✔
112
                        return (List<H>) list;
1✔
113
                }
114
                
115
                List<H> handlers = new ArrayList<>();
1✔
116
                
117
                // First get all registered components of the passed class
118
                log.debug("Getting handlers of type " + handlerType + (type == null ? "" : " for class " + type.getName()));
1✔
119
                for (H handler : Context.getRegisteredComponents(handlerType)) {
1✔
120
                        Handler handlerAnnotation = handler.getClass().getAnnotation(Handler.class);
1✔
121
                        // Only consider those that have been annotated as Handlers
122
                        if (handlerAnnotation != null) {
1✔
123
                                // If no type is passed in return all handlers
124
                                if (type == null) {
1✔
125
                                        log.debug("Found handler " + handler.getClass());
1✔
126
                                        handlers.add(handler);
1✔
127
                                }
128
                                // Otherwise, return all handlers that support the passed type
129
                                else {
130
                                        for (int i = 0; i < handlerAnnotation.supports().length; i++) {
1✔
131
                                                Class<?> clazz = handlerAnnotation.supports()[i];
1✔
132
                                                if (clazz.isAssignableFrom(type)) {
1✔
133
                                                        log.debug("Found handler: " + handler.getClass());
1✔
134
                                                        handlers.add(handler);
1✔
135
                                                }
136
                                        }
137
                                }
138
                        }
139
                }
1✔
140
                
141
                // Return the list of handlers based on the order specified in the Handler annotation
142
                handlers.sort(Comparator.comparing(o -> getOrderOfHandler(o.getClass())));
1✔
143
                
144
                Map<Key, List<?>> newCachedHandlers = new WeakHashMap<>(cachedHandlers);
1✔
145
                newCachedHandlers.put(new Key(handlerType, type), handlers);
1✔
146
                cachedHandlers = newCachedHandlers;
1✔
147
                
148
                return handlers;
1✔
149
        }
150
        
151
        /**
152
         * Retrieves the preferred Handler for a given handlerType and type. A <em>preferred</em>
153
         * handler is the Handler that has the lowest defined <em>order</em> attribute in it's
154
         * annotation. If multiple Handlers are found for the passed parameters at the lowest specified
155
         * order, then an APIException is thrown.
156
         * 
157
         * @param handlerType the class that is an annotated {@link Handler} to retrieve
158
         * @param type the class that the annotated {@link Handler} must support
159
         * @return the class of the passed handlerType with the lowest configured order
160
         * <strong>Should</strong> return the preferred handler for the passed handlerType and type
161
         * <strong>Should</strong> throw a APIException if no handler is found
162
         * <strong>Should</strong> throw a APIException if multiple preferred handlers are found
163
         * <strong>Should</strong> should return patient validator for patient
164
         * <strong>Should</strong> should return person validator for person
165
         */
166
        public static <H, T> H getPreferredHandler(Class<H> handlerType, Class<T> type) {
167
                
168
                if (handlerType == null || type == null) {
1✔
169
                        throw new IllegalArgumentException("You must specify both a handlerType and a type");
×
170
                }
171
                List<H> handlers = getHandlersForType(handlerType, type);
1✔
172
                if (handlers == null || handlers.isEmpty()) {
1✔
173
                        throw new APIException("handler.type.not.found", new Object[] { handlerType, type });
1✔
174
                }
175
                
176
                if (handlers.size() > 1) {
1✔
177
                        int order1 = getOrderOfHandler(handlers.get(0).getClass());
1✔
178
                        int order2 = getOrderOfHandler(handlers.get(1).getClass());
1✔
179
                        if (order1 == order2) {
1✔
180
                                throw new APIException("handler.type.multiple", new Object[] { handlerType, type });
×
181
                        }
182
                }
183
                
184
                return handlers.get(0);
1✔
185
        }
186
        
187
        /**
188
         * Utility method to return the order attribute of the {@link Handler} annotation on the passed
189
         * class. If the passed class does not have a {@link Handler} annotation, a RuntimeException is
190
         * thrown
191
         * 
192
         * @param handlerClass
193
         * @return the order attribute value
194
         */
195
        public static Integer getOrderOfHandler(Class<?> handlerClass) {
196
                Handler annotation = handlerClass.getAnnotation(Handler.class);
1✔
197
                if (annotation == null) {
1✔
198
                        throw new APIException("class.not.annotated.as.handler", new Object[] { handlerClass });
×
199
                }
200
                return annotation.order();
1✔
201
        }
202
        
203
        @Override
204
        public void onApplicationEvent(ContextRefreshedEvent event) {
205
                clearCachedHandlers();
1✔
206
        }
1✔
207
}
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

© 2025 Coveralls, Inc