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

openmrs / openmrs-core / 15205088843

23 May 2025 07:43AM UTC coverage: 65.083% (+0.01%) from 65.069%
15205088843

push

github

rkorytkowski
TRUNK-6300: Adding Windows test, cleaning up logs, adjusting variable name

2 of 2 new or added lines in 2 files covered. (100.0%)

336 existing lines in 18 files now uncovered.

23379 of 35922 relevant lines covered (65.08%)

0.65 hits per line

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

82.95
/api/src/main/java/org/openmrs/User.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;
11

12
import javax.persistence.Cacheable;
13
import javax.persistence.CollectionTable;
14
import javax.persistence.Column;
15
import javax.persistence.ElementCollection;
16
import javax.persistence.Entity;
17
import javax.persistence.GeneratedValue;
18
import javax.persistence.GenerationType;
19
import javax.persistence.Id;
20
import javax.persistence.JoinColumn;
21
import javax.persistence.JoinTable;
22
import javax.persistence.ManyToMany;
23
import javax.persistence.ManyToOne;
24
import javax.persistence.MapKeyColumn;
25
import javax.persistence.Table;
26
import javax.persistence.Transient;
27
import java.util.ArrayList;
28
import java.util.Collection;
29
import java.util.Collections;
30
import java.util.Date;
31
import java.util.HashMap;
32
import java.util.HashSet;
33
import java.util.List;
34
import java.util.Locale;
35
import java.util.Map;
36
import java.util.Set;
37

38
import org.apache.commons.lang3.StringUtils;
39
import org.hibernate.annotations.Cache;
40
import org.hibernate.annotations.CacheConcurrencyStrategy;
41
import org.hibernate.annotations.Cascade;
42
import org.hibernate.annotations.CascadeType;
43
import org.hibernate.annotations.GenericGenerator;
44
import org.hibernate.annotations.LazyCollection;
45
import org.hibernate.annotations.LazyCollectionOption;
46
import org.hibernate.annotations.Parameter;
47
import org.hibernate.envers.Audited;
48
import org.hibernate.envers.NotAudited;
49
import org.openmrs.api.context.Context;
50
import org.openmrs.util.LocaleUtility;
51
import org.openmrs.util.OpenmrsConstants;
52
import org.openmrs.util.OpenmrsUtil;
53
import org.openmrs.util.RoleConstants;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

57
/**
58
 * Defines a User Account in the system. This account belongs to a {@link Person} in the system,
59
 * although that person may have other user accounts. Users have login credentials
60
 * (username/password) and can have special user properties. User properties are just simple
61
 * key-value pairs for either quick info or display specific info that needs to be persisted (like
62
 * locale preferences, search options, etc)
63
 */
64

65
@Entity
66
@Table(name = "users")
67
@Cacheable
68
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
69
@Audited
70
public class User extends BaseOpenmrsObject implements java.io.Serializable, Attributable<User>, Auditable, Retireable {
71
        
72
        public static final long serialVersionUID = 2L ;
73
        
74
        private static final Logger log = LoggerFactory.getLogger(User.class);
1✔
75
        
76
        // Fields
77
        @Id
78
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "users_user_id_seq")
79
        @GenericGenerator(
80
                name = "users_user_id_seq",
81
                strategy = "native",
82
                parameters = @Parameter(name = "sequence", value = "users_user_id_seq")
83
        )
84
        @Column(name = "user_id")
85
        private Integer userId;
86

87
        @ManyToOne
88
        @JoinColumn(name = "person_id", nullable = false)
89
        @LazyCollection(LazyCollectionOption.FALSE)
90
        @Cascade(CascadeType.SAVE_UPDATE)
91
        private Person person;
92

93
        @Column(name = "system_id", nullable = false, length = 50)
94
        private String systemId;
95

96
        @Column(name = "username", length = 50)
97
        private String username;
98

99
        @Column(name = "email", length = 255, unique = true)
100
        private String email;
101

102
        @ManyToMany
103
        @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role"))
104
        @LazyCollection(LazyCollectionOption.FALSE)
105
        @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
106
        @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.EVICT })
107
        private Set<Role> roles;
108

109
        @ElementCollection
110
        @CollectionTable(name = "user_property", joinColumns = @JoinColumn(name = "user_id", nullable = false))
111
        @MapKeyColumn(name = "property", length = 255)
112
        @Column(name = "property_value", length = Integer.MAX_VALUE)
113
        @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.EVICT })
114
        @NotAudited
115
        private Map<String, String> userProperties;
116

117
        @Transient
1✔
118
        private List<Locale> proficientLocales = null;
119

120
        @Transient
1✔
121
        private String parsedProficientLocalesProperty = "";
122

123
        @ManyToOne
124
        @JoinColumn(name = "creator", nullable = false)
125
        private User creator;
126

127
        @Column(name = "date_created", nullable = false, length = 19)
128
        private Date dateCreated;
129

130
        @ManyToOne
131
        @JoinColumn(name = "changed_by")
132
        private User changedBy;
133

134
        @Column(name = "date_changed", length = 19)
135
        private Date dateChanged;
136

137
        @Column(name = "retired", nullable = false, length = 1)
138
        private boolean retired;
139

140
        @ManyToOne
141
        @JoinColumn(name = "retired_by")
142
        private User retiredBy;
143

144
        @Column(name = "date_retired", length = 19)
145
        private Date dateRetired;
146

147
        @Column(name = "retire_reason", length = 255)
148
        private String retireReason;
149
        
150
        // Constructors
151
        
152
        /** default constructor */
153
        public User() {
1✔
154
        }
1✔
155
        
156
        /** constructor with id */
157
        public User(Integer userId) {
1✔
158
                this.userId = userId;
1✔
159
        }
1✔
160
        
161
        /** constructor with person object */
162
        public User(Person person) {
1✔
163
                this.person = person;
1✔
164
        }
1✔
165
        
166
        /**
167
         * Return true if this user has all privileges
168
         * 
169
         * @return true/false if this user is defined as a super user
170
         */
171
        public boolean isSuperUser() {
172
                return containsRole(RoleConstants.SUPERUSER);
1✔
173
        }
174
        
175
        /**
176
         * This method shouldn't be used directly. Use org.openmrs.api.context.Context#hasPrivilege so that
177
         * anonymous/authenticated/proxy privileges are all included Return true if this user has the
178
         * specified privilege
179
         * 
180
         * @param privilege
181
         * @return true/false depending on whether user has specified privilege
182
         */
183
        public boolean hasPrivilege(String privilege) {
184
                
185
                // All authenticated users have the "" (empty) privilege
186
                if (StringUtils.isEmpty(privilege)) {
1✔
UNCOV
187
                        return true;
×
188
                }
189
                
190
                if (isSuperUser()) {
1✔
191
                        return true;
1✔
192
                }
193
                
194
                Set<Role> tmproles = getAllRoles();
1✔
195
                
196
                // loop over the roles and check each for the privilege
197
                for (Role tmprole : tmproles) {
1✔
198
                        if (tmprole.hasPrivilege(privilege)) {
1✔
199
                                return true;
1✔
200
                        }
201
                }
1✔
202
                
203
                return false;
1✔
204
        }
205
        
206
        /**
207
         * Check if this user has the given String role
208
         * 
209
         * @param r String name of a role to check
210
         * @return Returns true if this user has the specified role, false otherwise
211
         */
212
        public boolean hasRole(String r) {
213
                return hasRole(r, false);
1✔
214
        }
215
        
216
        /**
217
         * Checks if this user has the given String role
218
         * 
219
         * @param r String name of a role to check
220
         * @param ignoreSuperUser If this is false, then this method will always return true for a
221
         *            superuser.
222
         * @return Returns true if the user has the given role, or if ignoreSuperUser is false and the user
223
         *         is a superUser
224
         */
225
        public boolean hasRole(String r, boolean ignoreSuperUser) {
226
                if (!ignoreSuperUser && isSuperUser()) {
1✔
227
                        return true;
1✔
228
                }
229
                
230
                if (roles == null) {
1✔
UNCOV
231
                        return false;
×
232
                }
233
                
234
                Set<Role> tmproles = getAllRoles();
1✔
235
                
236
                log.debug("User # {} has roles: {}", userId, tmproles);
1✔
237
                
238
                return containsRole(r);
1✔
239
        }
240
        
241
        /**
242
         * Checks if the user has a given role. Role name comparisons are not case sensitive.
243
         * 
244
         * @param roleName the name of the role to check
245
         * @return true if the user has the given role, else false
246
         * <strong>Should</strong> return true if the user has the given role
247
         * <strong>Should</strong> return false if the user does not have the given role
248
         * <strong>Should</strong> be case insensitive
249
         */
250
        public boolean containsRole(String roleName) {
251
                for (Role role : getAllRoles()) {
1✔
252
                        if (role.getRole().equalsIgnoreCase(roleName)) {
1✔
253
                                return true;
1✔
254
                        }
255
                }
1✔
256
                return false;
1✔
257
        }
258
        
259
        /**
260
         * Get <i>all</i> privileges this user has. This delves into all of the roles that a person has,
261
         * appending unique privileges
262
         * 
263
         * @return Collection of complete Privileges this user has
264
         */
265
        public Collection<Privilege> getPrivileges() {
266
                Set<Privilege> privileges = new HashSet<>();
1✔
267
                Set<Role> tmproles = getAllRoles();
1✔
268
                
269
                Role role;
270
                for (Role tmprole : tmproles) {
1✔
271
                        role = tmprole;
1✔
272
                        Collection<Privilege> privs = role.getPrivileges();
1✔
273
                        if (privs != null) {
1✔
274
                                privileges.addAll(privs);
1✔
275
                        }
276
                }
1✔
277
                
278
                return privileges;
1✔
279
        }
280
        
281
        // Property accessors
282
        
283
        /**
284
         * Returns all roles attributed to this user by expanding the role list to include the parents of
285
         * the assigned roles
286
         * 
287
         * @return all roles (inherited from parents and given) for this user
288
         */
289
        public Set<Role> getAllRoles() {
290
                // the user's immediate roles
291
                Set<Role> baseRoles = new HashSet<>();
1✔
292
                
293
                // the user's complete list of roles including
294
                // the parent roles of their immediate roles
295
                Set<Role> totalRoles = new HashSet<>();
1✔
296
                if (getRoles() != null) {
1✔
297
                        baseRoles.addAll(getRoles());
1✔
298
                        totalRoles.addAll(getRoles());
1✔
299
                }
300
                
301
                log.debug("User's base roles: {}", baseRoles);
1✔
302
                
303
                try {
304
                        for (Role r : baseRoles) {
1✔
305
                                totalRoles.addAll(r.getAllParentRoles());
1✔
306
                        }
1✔
307
                }
308
                catch (ClassCastException e) {
×
309
                        log.error("Error converting roles for user: " + this);
×
310
                        log.error("baseRoles.class: " + baseRoles.getClass().getName());
×
311
                        log.error("baseRoles: " + baseRoles.toString());
×
312
                        for (Role baseRole : baseRoles) {
×
UNCOV
313
                                log.error("baseRole: '" + baseRole + "'");
×
UNCOV
314
                        }
×
315
                }
1✔
316
                return totalRoles;
1✔
317
        }
318
        
319
        /**
320
         * @return Returns the roles.
321
         */
322
        public Set<Role> getRoles() {
323
                return roles;
1✔
324
        }
325
        
326
        /**
327
         * @param roles The roles to set.
328
         */
329
        public void setRoles(Set<Role> roles) {
UNCOV
330
                this.roles = roles;
×
UNCOV
331
        }
×
332
        
333
        /**
334
         * Add the given Role to the list of roles for this User
335
         * 
336
         * @param role
337
         * @return Returns this user with the given role attached
338
         */
339
        public User addRole(Role role) {
340
                if (roles == null) {
1✔
341
                        roles = new HashSet<>();
1✔
342
                }
343
                if (!roles.contains(role) && role != null) {
1✔
344
                        roles.add(role);
1✔
345
                }
346
                
347
                return this;
1✔
348
        }
349
        
350
        /**
351
         * Remove the given Role from the list of roles for this User
352
         * 
353
         * @param role
354
         * @return this user with the given role removed
355
         */
356
        public User removeRole(Role role) {
357
                if (roles != null) {
1✔
358
                        roles.remove(role);
1✔
359
                }
360
                
361
                return this;
1✔
362
        }
363
        
364
        /**
365
         * @see org.openmrs.Attributable#findPossibleValues(java.lang.String)
366
         */
367
        @Override
368
        @Deprecated
369
        public List<User> findPossibleValues(String searchText) {
370
                try {
371
                        return Context.getUserService().getUsersByName(searchText, "", false);
×
372
                }
UNCOV
373
                catch (Exception e) {
×
UNCOV
374
                        return Collections.emptyList();
×
375
                }
376
        }
377
        
378
        /**
379
         * @see org.openmrs.Attributable#getPossibleValues()
380
         */
381
        @Override
382
        @Deprecated
383
        public List<User> getPossibleValues() {
384
                try {
385
                        return Context.getUserService().getAllUsers();
×
386
                }
UNCOV
387
                catch (Exception e) {
×
UNCOV
388
                        return Collections.emptyList();
×
389
                }
390
        }
391
        
392
        /**
393
         * @see org.openmrs.Attributable#hydrate(java.lang.String)
394
         */
395
        @Override
396
        public User hydrate(String userId) {
397
                try {
398
                        return Context.getUserService().getUser(Integer.valueOf(userId));
1✔
399
                }
UNCOV
400
                catch (Exception e) {
×
UNCOV
401
                        return new User();
×
402
                }
403
        }
404
        
405
        /**
406
         * @see org.openmrs.Attributable#serialize()
407
         */
408
        @Override
409
        public String serialize() {
UNCOV
410
                if (getUserId() != null) {
×
411
                        return "" + getUserId();
×
412
                } else {
UNCOV
413
                        return "";
×
414
                }
415
        }
416
        
417
        /**
418
         * @see org.openmrs.Attributable#getDisplayString()
419
         */
420
        @Override
421
        public String getDisplayString() {
422
                String returnString = "";
1✔
423
                if (getPersonName() != null) {
1✔
424
                        returnString += getPersonName().getFullName() + " ";
1✔
425
                }
426
                
427
                returnString += "(" + getUsername() + ")";
1✔
428
                return returnString;
1✔
429
                
430
        }
431
        
432
        /**
433
         * @return Returns the systemId.
434
         */
435
        public String getSystemId() {
436
                return systemId;
1✔
437
        }
438
        
439
        /**
440
         * @param systemId The systemId to set.
441
         */
442
        public void setSystemId(String systemId) {
443
                this.systemId = systemId;
1✔
444
        }
1✔
445
        
446
        /**
447
         * @return Returns the userId.
448
         */
449
        public Integer getUserId() {
450
                return userId;
1✔
451
        }
452
        
453
        /**
454
         * @param userId The userId to set.
455
         */
456
        public void setUserId(Integer userId) {
457
                this.userId = userId;
1✔
458
        }
1✔
459
        
460
        /**
461
         * @return the person
462
         * @since 1.6
463
         */
464
        public Person getPerson() {
465
                return person;
1✔
466
        }
467
        
468
        /**
469
         * @return the person, creating a new object if person is null
470
         */
471
        private Person getPersonMaybeCreate() {
472
                if (person == null) {
1✔
UNCOV
473
                        person = new Person();
×
474
                }
475
                return person;
1✔
476
        }
477
        
478
        /**
479
         * @param person the person to set
480
         * @since 1.6
481
         */
482
        public void setPerson(Person person) {
483
                this.person = person;
1✔
484
        }
1✔
485
        
486
        /**
487
         * @return Returns the username.
488
         */
489
        public String getUsername() {
490
                return username;
1✔
491
        }
492
        
493
        /**
494
         * @param username The username to set.
495
         */
496
        public void setUsername(String username) {
497
                this.username = username;
1✔
498
        }
1✔
499
        
500
        /**
501
         * @since 2.2
502
         * @return Returns the email.
503
         */
504
        public String getEmail() {
505
                return email;
1✔
506
        }
507
        
508
        /**
509
         * @since 2.2
510
         * @param email The email to set.
511
         */
512
        public void setEmail(String email) {
513
                this.email = email;
1✔
514
        }
1✔
515
        
516
        @Override
517
        public String toString() {
518
                return StringUtils.isNotBlank(username) ? username : systemId;
1✔
519
        }
520
        
521
        /**
522
         * @return Returns the userProperties.
523
         */
524
        public Map<String, String> getUserProperties() {
525
                if (userProperties == null) {
1✔
526
                        userProperties = new HashMap<>();
1✔
527
                }
528
                return userProperties;
1✔
529
        }
530
        
531
        /**
532
         * @param userProperties A Map&lt;String,String&gt; of the properties to set.
533
         */
534
        public void setUserProperties(Map<String, String> userProperties) {
535
                this.userProperties = userProperties;
1✔
536
        }
1✔
537
        
538
        /**
539
         * Convenience method. Adds the given property to the user's properties
540
         */
541
        public void setUserProperty(String prop, String value) {
542
                getUserProperties().put(prop, value);
1✔
543
        }
1✔
544
        
545
        /**
546
         * Convenience method. Removes the given property from the user's properties
547
         */
548
        public void removeUserProperty(String prop) {
549
                if (getUserProperties() != null && userProperties.containsKey(prop)) {
1✔
550
                        userProperties.remove(prop);
1✔
551
                }
552
        }
1✔
553
        
554
        /**
555
         * Get prop property from this user's properties. If prop is not found in properties, return empty
556
         * string
557
         * 
558
         * @param prop
559
         * @return property value
560
         */
561
        public String getUserProperty(String prop) {
562
                if (getUserProperties() != null && userProperties.containsKey(prop)) {
1✔
563
                        return userProperties.get(prop);
1✔
564
                }
565
                
566
                return "";
1✔
567
        }
568
        
569
        /**
570
         * Get prop property from this user's properties. If prop is not found in properties, return
571
         * <code>defaultValue</code>
572
         * 
573
         * @param prop
574
         * @param defaultValue
575
         * @return property value
576
         * @see #getUserProperty(java.lang.String)
577
         */
578
        public String getUserProperty(String prop, String defaultValue) {
579
                if (getUserProperties() != null && userProperties.containsKey(prop)) {
1✔
580
                        return userProperties.get(prop);
1✔
581
                }
582
                
583
                return defaultValue;
1✔
584
        }
585
        
586
        /**
587
         * @see Person#addName(PersonName)
588
         */
589
        public void addName(PersonName name) {
590
                getPersonMaybeCreate().addName(name);
1✔
591
        }
1✔
592
        
593
        /**
594
         * @see Person#getPersonName()
595
         */
596
        public PersonName getPersonName() {
597
                return getPerson() == null ? null : getPerson().getPersonName();
1✔
598
        }
599
        
600
        /**
601
         * Get givenName on the Person this user account belongs to
602
         * 
603
         * @see Person#getGivenName()
604
         */
605
        public String getGivenName() {
606
                return getPerson() == null ? null : getPerson().getGivenName();
1✔
607
        }
608
        
609
        /**
610
         * Get familyName on the Person this user account belongs to
611
         * 
612
         * @see Person#getFamilyName()
613
         */
614
        public String getFamilyName() {
UNCOV
615
                return getPerson() == null ? null : getPerson().getFamilyName();
×
616
        }
617
        
618
        /**
619
         * @see org.openmrs.Person#getNames()
620
         */
621
        public Set<PersonName> getNames() {
622
                return person.getNames();
1✔
623
        }
624
        
625
        /**
626
         * Returns a list of Locales for which the User is considered proficient.
627
         * 
628
         * @return List of the User's proficient locales
629
         */
630
        public List<Locale> getProficientLocales() {
631
                String proficientLocalesProperty = getUserProperty(OpenmrsConstants.USER_PROPERTY_PROFICIENT_LOCALES);
1✔
632
                
633
                if ((proficientLocales == null)
1✔
UNCOV
634
                        || (!OpenmrsUtil.nullSafeEquals(parsedProficientLocalesProperty, proficientLocalesProperty))) {
×
635
                        parsedProficientLocalesProperty = proficientLocalesProperty;
1✔
636
                        proficientLocales = new ArrayList<>();
1✔
637
                        if (proficientLocalesProperty != null) {
1✔
638
                                String[] proficientLocalesArray = proficientLocalesProperty.split(",");
1✔
639
                                for (String proficientLocaleSpec : proficientLocalesArray) {
1✔
640
                                        if (proficientLocaleSpec.length() > 0) {
1✔
641
                                                Locale proficientLocale = LocaleUtility.fromSpecification(proficientLocaleSpec);
1✔
642
                                                if (!proficientLocales.contains(proficientLocale)) {
1✔
643
                                                        proficientLocales.add(proficientLocale);
1✔
644
                                                        if (StringUtils.isNotEmpty(proficientLocale.getCountry())) {
1✔
645
                                                                // add the language also
646
                                                                Locale languageOnlyLocale = LocaleUtility.fromSpecification(proficientLocale.getLanguage());
1✔
647
                                                                if (!proficientLocales.contains(languageOnlyLocale)) {
1✔
648
                                                                        proficientLocales.add(LocaleUtility.fromSpecification(proficientLocale.getLanguage()));
1✔
649
                                                                }
650
                                                        }
651
                                                }
652
                                        }
653
                                }
654
                        }
655
                }
656
                
657
                // return a copy so that the list isn't changed by other processes
658
                return new ArrayList<>(proficientLocales);
1✔
659
        }
660
        
661
        /**
662
         * @since 1.5
663
         * @see org.openmrs.OpenmrsObject#getId()
664
         */
665
        @Override
666
        public Integer getId() {
667
                return getUserId();
1✔
668
        }
669
        
670
        /**
671
         * @since 1.5
672
         * @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
673
         */
674
        @Override
675
        public void setId(Integer id) {
UNCOV
676
                setUserId(id);
×
UNCOV
677
        }
×
678
        
679
        @Override
680
        public User getCreator() {
681
                return creator;
1✔
682
        }
683

684
        @Override
685
        public void setCreator(User creator) {
UNCOV
686
                this.creator = creator;
×
UNCOV
687
        }
×
688
        
689
    @Override
690
        public Date getDateCreated() {
691
                return dateCreated;
1✔
692
        }
693

694
        @Override
695
        public void setDateCreated(Date dateCreated) {
696
                this.dateCreated = dateCreated;
1✔
697
        }
1✔
698

699
        @Override
700
        public User getChangedBy() {
UNCOV
701
                return changedBy;
×
702
        }
703

704
        @Override
705
        public void setChangedBy(User changedBy) {
706
                this.changedBy = changedBy;
1✔
707
        }
1✔
708

709
        @Override
710
        public Date getDateChanged() {
711
                return dateChanged;
1✔
712
        }
713

714
        @Override
715
        public void setDateChanged(Date dateChanged) {
716
                this.dateChanged = dateChanged;
1✔
717
        }
1✔
718

719
        @Override
720
        public Boolean isRetired() {
721
                return retired;
1✔
722
        }
723
        
724
    @Override
725
        public Boolean getRetired() {
726
                return retired;
1✔
727
        }
728

729
        @Override
730
        public void setRetired(Boolean retired) {
731
                this.retired = retired;
1✔
732
        }
1✔
733

734
        @Override
735
        public User getRetiredBy() {
736
                return retiredBy;
1✔
737
        }
738

739
        @Override
740
        public void setRetiredBy(User retiredBy) {
741
                this.retiredBy = retiredBy;
1✔
742
        }
1✔
743

744
        @Override
745
        public Date getDateRetired() {
746
                return dateRetired;
1✔
747
        }
748

749
        @Override
750
        public void setDateRetired(Date dateRetired) {
751
                this.dateRetired = dateRetired;
1✔
752
        }
1✔
753

754
        @Override
755
        public String getRetireReason() {
756
                return retireReason;
1✔
757
        }
758

759
        @Override
760
        public void setRetireReason(String retireReason) {
761
                this.retireReason = retireReason;
1✔
762
        }
1✔
763
}
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