• 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

75.78
/api/src/main/java/org/openmrs/Location.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 org.hibernate.annotations.BatchSize;
13
import org.hibernate.annotations.Cache;
14
import org.hibernate.annotations.CacheConcurrencyStrategy;
15
import org.hibernate.envers.Audited;
16
import org.openmrs.annotation.Independent;
17
import org.openmrs.api.APIException;
18
import org.openmrs.api.context.Context;
19

20
import javax.persistence.AttributeOverride;
21
import javax.persistence.Cacheable;
22
import javax.persistence.CascadeType;
23
import javax.persistence.Column;
24
import javax.persistence.Entity;
25
import javax.persistence.FetchType;
26
import javax.persistence.GeneratedValue;
27
import javax.persistence.GenerationType;
28
import javax.persistence.Id;
29
import javax.persistence.JoinColumn;
30
import javax.persistence.JoinTable;
31
import javax.persistence.ManyToMany;
32
import javax.persistence.ManyToOne;
33
import javax.persistence.OneToMany;
34
import javax.persistence.OrderBy;
35
import javax.persistence.Table;
36
import java.util.Collections;
37
import java.util.HashSet;
38
import java.util.List;
39
import java.util.Set;
40

41
/**
42
 * A Location is a physical place, such as a hospital, a room, a clinic, or a district. Locations
43
 * support a single hierarchy, such that each location may have one parent location. A
44
 * non-geographical grouping of locations, such as "All Community Health Centers" is not a location,
45
 * and should be modeled using {@link LocationTag}s.
46
 * Note: Prior to version 1.9 this class extended BaseMetadata
47
 */
48
@Entity
49
@Table(name = "location")
50
@Cacheable
51
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
52
@AttributeOverride(name = "attributes", column = @Column(name = "location_id"))
53
@Audited
54
public class Location extends BaseCustomizableMetadata<LocationAttribute> implements java.io.Serializable, Attributable<Location>, Address {
55
        
56
        public static final long serialVersionUID = 455634L;
57
        
58
        public static final int LOCATION_UNKNOWN = 1;
59
        
60
        // Fields
61
        @Id
62
        @Column(name = "location_id")
63
        @GeneratedValue(strategy = GenerationType.IDENTITY)
64
        private Integer locationId;
65
        
66
        @ManyToOne
67
        @JoinColumn(name = "location_type_concept_id")
68
        private Concept type;
69
        
70
        @Column(name = "address1")
71
        private String address1;
72
        
73
        @Column(name = "address2")
74
        private String address2;
75
        
76
        @Column(name = "city_village")
77
        private String cityVillage;
78
        
79
        @Column(name = "state_province")
80
        private String stateProvince;
81
        
82
        @Column(name = "country", length = 50)
83
        private String country;
84
        
85
        @Column(name = "postal_code", length = 50)
86
        private String postalCode;
87
        
88
        @Column(name = "latitude", length = 50)
89
        private String latitude;
90
        
91
        @Column(name = "longitude", length = 50)
92
        private String longitude;
93
        
94
        @Column(name = "county_district")
95
        private String countyDistrict;
96
        
97
        @Column(name = "address3")
98
        private String address3;
99
        
100
        @Column(name = "address4")
101
        private String address4;
102
        
103
        @Column(name = "address6")
104
        private String address6;
105
        
106
        @Column(name = "address5")
107
        private String address5;
108
        
109
        @Column(name = "address7")
110
        private String address7;
111
        
112
        @Column(name = "address8")
113
        private String address8;
114
        
115
        @Column(name = "address9")
116
        private String address9;
117
        
118
        @Column(name = "address10")
119
        private String address10;
120
        
121
        @Column(name = "address11")
122
        private String address11;
123
        
124
        @Column(name = "address12")
125
        private String address12;
126
        
127
        @Column(name = "address13")
128
        private String address13;
129
        
130
        @Column(name = "address14")
131
        private String address14;
132
        
133
        @Column(name = "address15")
134
        private String address15;
135

136
        @ManyToOne
137
        @JoinColumn(name = "parent_location")
138
        private Location parentLocation;
139
        
140
        @OneToMany(mappedBy = "parentLocation", cascade = CascadeType.ALL, orphanRemoval = true)
141
        @BatchSize(size = 100)
142
        @OrderBy("name")
143
        private Set<Location> childLocations;
144
        
145
        @ManyToMany(fetch = FetchType.LAZY)
146
        @JoinTable(
147
                name = "location_tag_map",
148
                joinColumns = @JoinColumn(name = "location_id"),
149
                inverseJoinColumns = @JoinColumn(name = "location_tag_id"))
150
        @Independent
151
        private Set<LocationTag> tags;
152
        
153
        // Constructors
154
        
155
        /** default constructor */
156
        public Location() {
1✔
157
        }
1✔
158
        
159
        /** constructor with id */
160
        public Location(Integer locationId) {
1✔
161
                this.locationId = locationId;
1✔
162
        }
1✔
163
        
164
        // Property accessors
165
        
166
        /**
167
         * @return Returns the address1.
168
         */
169
        @Override
170
        public String getAddress1() {
171
                return address1;
1✔
172
        }
173
        
174
        /**
175
         * @param address1 The address1 to set.
176
         */
177
        @Override
178
        public void setAddress1(String address1) {
179
                this.address1 = address1;
1✔
180
        }
1✔
181
        
182
        /**
183
         * @return Returns the address2.
184
         */
185
        @Override
186
        public String getAddress2() {
187
                return address2;
1✔
188
        }
189
        
190
        /**
191
         * @param address2 The address2 to set.
192
         */
193
        @Override
194
        public void setAddress2(String address2) {
195
                this.address2 = address2;
1✔
196
        }
1✔
197
        
198
        /**
199
         * @return Returns the cityVillage.
200
         */
201
        @Override
202
        public String getCityVillage() {
203
                return cityVillage;
1✔
204
        }
205
        
206
        /**
207
         * @param cityVillage The cityVillage to set.
208
         */
209
        @Override
210
        public void setCityVillage(String cityVillage) {
211
                this.cityVillage = cityVillage;
1✔
212
        }
1✔
213
        
214
        /**
215
         * @return Returns the country.
216
         */
217
        @Override
218
        public String getCountry() {
219
                return country;
1✔
220
        }
221
        
222
        /**
223
         * @param country The country to set.
224
         */
225
        @Override
226
        public void setCountry(String country) {
227
                this.country = country;
1✔
228
        }
1✔
229
        
230
        /**
231
         * @return Returns the latitude.
232
         */
233
        @Override
234
        public String getLatitude() {
235
                return latitude;
1✔
236
        }
237
        
238
        /**
239
         * @param latitude The latitude to set.
240
         */
241
        @Override
242
        public void setLatitude(String latitude) {
243
                this.latitude = latitude;
1✔
244
        }
1✔
245
        
246
        /**
247
         * @return Returns the locationId.
248
         */
249
        public Integer getLocationId() {
250
                return locationId;
1✔
251
        }
252
        
253
        /**
254
         * @param locationId The locationId to set.
255
         */
256
        public void setLocationId(Integer locationId) {
UNCOV
257
                this.locationId = locationId;
×
UNCOV
258
        }
×
259
        
260
        /**
261
         * @return Returns the longitude.
262
         */
263
        @Override
264
        public String getLongitude() {
265
                return longitude;
1✔
266
        }
267
        
268
        /**
269
         * @param longitude The longitude to set.
270
         */
271
        @Override
272
        public void setLongitude(String longitude) {
273
                this.longitude = longitude;
1✔
274
        }
1✔
275
        
276
        /**
277
         * @return Returns the postalCode.
278
         */
279
        @Override
280
        public String getPostalCode() {
281
                return postalCode;
1✔
282
        }
283
        
284
        /**
285
         * @param postalCode The postalCode to set.
286
         */
287
        @Override
288
        public void setPostalCode(String postalCode) {
289
                this.postalCode = postalCode;
1✔
290
        }
1✔
291
        
292
        /**
293
         * @return Returns the stateProvince.
294
         */
295
        @Override
296
        public String getStateProvince() {
297
                return stateProvince;
1✔
298
        }
299
        
300
        /**
301
         * @param stateProvince The stateProvince to set.
302
         */
303
        @Override
304
        public void setStateProvince(String stateProvince) {
305
                this.stateProvince = stateProvince;
1✔
306
        }
1✔
307
        
308
        @Override
309
        public String toString() {
310
                if (getName() != null) {
1✔
311
                        return getName();
1✔
312
                }
313
                if (getId() != null) {
1✔
UNCOV
314
                        return getId().toString();
×
315
                }
316
                return "";
1✔
317
        }
318
        
319
        /**
320
         * @return Returns the countyDistrict.
321
         */
322
        @Override
323
        public String getCountyDistrict() {
324
                return countyDistrict;
1✔
325
        }
326
        
327
        /**
328
         * @param countyDistrict The countyDistrict to set.
329
         */
330
        @Override
331
        public void setCountyDistrict(String countyDistrict) {
332
                this.countyDistrict = countyDistrict;
1✔
333
        }
1✔
334

335
        /**
336
         * @return Returns the code indicating the type of location this is
337
         * @since 2.5.0
338
         */
339
        public Concept getType() {
340
                return type;
1✔
341
        }
342
        
343
        /**
344
         * @param type The Concept for the type of location this is
345
         * @since 2.5.0
346
         */
347
        public void setType(Concept type) {
348
                this.type = type;
1✔
349
        }
1✔
350
        
351
        /**
352
         * @see org.openmrs.Attributable#findPossibleValues(java.lang.String)
353
         */
354
        @Override
355
        @Deprecated
356
        public List<Location> findPossibleValues(String searchText) {
357
                try {
358
                        return Context.getLocationService().getLocations(searchText);
×
359
                }
UNCOV
360
                catch (Exception e) {
×
UNCOV
361
                        return Collections.emptyList();
×
362
                }
363
        }
364
        
365
        /**
366
         * @see org.openmrs.Attributable#getPossibleValues()
367
         */
368
        @Override
369
        @Deprecated
370
        public List<Location> getPossibleValues() {
371
                try {
372
                        return Context.getLocationService().getAllLocations();
×
373
                }
UNCOV
374
                catch (Exception e) {
×
UNCOV
375
                        return Collections.emptyList();
×
376
                }
377
        }
378
        
379
        /**
380
         * @see org.openmrs.Attributable#hydrate(java.lang.String)
381
         */
382
        @Override
383
        public Location hydrate(String locationId) {
384
                try {
385
                        return Context.getLocationService().getLocation(Integer.valueOf(locationId));
×
386
                }
UNCOV
387
                catch (Exception e) {
×
UNCOV
388
                        return new Location();
×
389
                }
390
        }
391
        
392
        /**
393
         * @see org.openmrs.Attributable#serialize()
394
         */
395
        @Override
396
        public String serialize() {
UNCOV
397
                if (getLocationId() != null) {
×
398
                        return "" + getLocationId();
×
399
                } else {
UNCOV
400
                        return "";
×
401
                }
402
        }
403
        
404
        /**
405
         * @see org.openmrs.Attributable#getDisplayString()
406
         */
407
        @Override
408
        public String getDisplayString() {
UNCOV
409
                return getName();
×
410
        }
411
        
412
        /**
413
         * @return Returns the parentLocation.
414
         * @since 1.5
415
         */
416
        public Location getParentLocation() {
417
                return parentLocation;
1✔
418
        }
419
        
420
        /**
421
         * @param parentLocationId The parentLocation to set.
422
         * @since 1.5
423
         */
424
        public void setParentLocation(Location parentLocationId) {
425
                this.parentLocation = parentLocationId;
1✔
426
        }
1✔
427
        
428
        /**
429
         * @return Returns the childLocations.
430
         * @since 1.5
431
         */
432
        public Set<Location> getChildLocations() {
433
                return childLocations;
1✔
434
        }
435
        
436
        /**
437
         * Returns all childLocations where child.locationId = this.locationId.
438
         *
439
         * @param includeRetired specifies whether or not to include voided childLocations
440
         * @return Returns a Set&lt;Location&gt; of all the childLocations.
441
         * @since 1.5
442
         * <strong>Should</strong> return a set of locations
443
         */
444
        public Set<Location> getChildLocations(boolean includeRetired) {
445
                Set<Location> ret = new HashSet<>();
×
446
                if (includeRetired) {
×
447
                        ret = getChildLocations();
×
448
                } else if (getChildLocations() != null) {
×
449
                        for (Location l : getChildLocations()) {
×
UNCOV
450
                                if (!l.getRetired()) {
×
451
                                        ret.add(l);
×
452
                                }
453
                        }
×
454
                }
UNCOV
455
                return ret;
×
456
        }
457
        
458
        /**
459
         * Returns the descendant locations.
460
         *
461
         * @param includeRetired specifies whether or not to include voided childLocations
462
         * @return Returns a Set&lt;Location&gt; of the descendant location.
463
         * @since 1.10
464
         */
465
        public Set<Location> getDescendantLocations(boolean includeRetired) {
466
                Set<Location> result = new HashSet<>();
1✔
467
                
468
                for (Location childLocation : getChildLocations()) {
1✔
469
                        if (!childLocation.getRetired() || includeRetired) {
1✔
470
                                result.add(childLocation);
1✔
471
                                result.addAll(childLocation.getDescendantLocations(includeRetired));
1✔
472
                        }
473
                }
1✔
474
                return result;
1✔
475
        }
476
        
477
        /**
478
         * @param childLocations The childLocations to set.
479
         * @since 1.5
480
         */
481
        public void setChildLocations(Set<Location> childLocations) {
482
                this.childLocations = childLocations;
1✔
483
        }
1✔
484
        
485
        /**
486
         * @param child The child location to add.
487
         * @since 1.5
488
         * <strong>Should</strong> return null given null parameter
489
         * <strong>Should</strong> throw APIException given same object as child
490
         * <strong>Should</strong> throw APIException if child already in hierarchy
491
         */
492
        public void addChildLocation(Location child) {
493
                if (child == null) {
1✔
UNCOV
494
                        return;
×
495
                }
496
                
497
                if (getChildLocations() == null) {
1✔
498
                        childLocations = new HashSet<>();
1✔
499
                }
500
                
501
                if (child.equals(this)) {
1✔
UNCOV
502
                        throw new APIException("Location.cannot.be.its.own.child", (Object[]) null);
×
503
                }
504
                
505
                // Traverse all the way up (down?) to the root, then check whether the child is already
506
                // anywhere in the tree
507
                Location root = this;
1✔
508
                while (root.getParentLocation() != null) {
1✔
509
                        root = root.getParentLocation();
1✔
510
                }
511
                
512
                if (isInHierarchy(child, root)) {
1✔
UNCOV
513
                        throw new APIException("Location.hierarchy.loop", new Object[] { child, this });
×
514
                }
515
                
516
                child.setParentLocation(this);
1✔
517
                childLocations.add(child);
1✔
518
        }
1✔
519
        
520
        /**
521
         * Checks whether 'location' is a member of the tree starting at 'root'.
522
         *
523
         * @param location The location to be tested.
524
         * @param root Location node from which to start the testing (down in the hierarchy).
525
         * @since 1.5
526
         * <strong>Should</strong> return false given any null parameter
527
         * <strong>Should</strong> return true given same object in both parameters
528
         * <strong>Should</strong> return true given location that is already somewhere in hierarchy
529
         * <strong>Should</strong> return false given location that is not in hierarchy
530
         * <strong>Should</strong> should find location in hierarchy
531
         */
532
        public static Boolean isInHierarchy(Location location, Location root) {
533
                if (root == null) {
1✔
UNCOV
534
                        return false;
×
535
                }
536
                while (true) {
537
                        if (location == null) {
1✔
538
                                return false;
1✔
539
                        } else if (root.equals(location)) {
1✔
540
                                return true;
1✔
541
                        }
542
                        location = location.getParentLocation();
1✔
543
                }
544
        }
545
        
546
        /**
547
         * @param child The child location to remove.
548
         * @since 1.5
549
         */
550
        public void removeChildLocation(Location child) {
551
                if (getChildLocations() != null) {
1✔
552
                        childLocations.remove(child);
1✔
553
                }
554
        }
1✔
555
        
556
        /**
557
         * @return Returns the tags which have been attached to this Location.
558
         * @since 1.5
559
         */
560
        public Set<LocationTag> getTags() {
561
                return tags;
1✔
562
        }
563
        
564
        /**
565
         * Set the tags which are attached to this Location.
566
         *
567
         * @param tags The tags to set.
568
         * @since 1.5
569
         */
570
        public void setTags(Set<LocationTag> tags) {
UNCOV
571
                this.tags = tags;
×
UNCOV
572
        }
×
573
        
574
        /**
575
         * Attaches a tag to the Location.
576
         *
577
         * @param tag The tag to add.
578
         * @since 1.5
579
         */
580
        public void addTag(LocationTag tag) {
581
                if (getTags() == null) {
1✔
582
                        tags = new HashSet<>();
1✔
583
                }
584
                if (tag != null && !tags.contains(tag)) {
1✔
585
                        tags.add(tag);
1✔
586
                }
587
        }
1✔
588
        
589
        /**
590
         * Remove the tag from the Location.
591
         *
592
         * @param tag The tag to remove.
593
         * @since 1.5
594
         */
595
        public void removeTag(LocationTag tag) {
596
                if (getTags() != null) {
1✔
597
                        tags.remove(tag);
1✔
598
                }
599
        }
1✔
600
        
601
        /**
602
         * Checks whether the Location has a particular tag.
603
         *
604
         * @param tagToFind the string of the tag for which to check
605
         * @return true if the tags include the specified tag, false otherwise
606
         * @since 1.5
607
         * <strong>Should</strong> not fail given null parameter
608
         * <strong>Should</strong> return false given empty string parameter
609
         */
610
        public Boolean hasTag(String tagToFind) {
611
                if (tagToFind != null && getTags() != null) {
×
612
                        for (LocationTag locTag : getTags()) {
×
UNCOV
613
                                if (locTag.getName().equals(tagToFind)) {
×
614
                                        return true;
×
615
                                }
UNCOV
616
                        }
×
617
                }
618
                
UNCOV
619
                return false;
×
620
        }
621
        
622
        /**
623
         * @since 1.8
624
         * @return the address3
625
         */
626
        @Override
627
        public String getAddress3() {
628
                return address3;
1✔
629
        }
630
        
631
        /**
632
         * @since 1.8
633
         * @param address3 the address3 to set
634
         */
635
        @Override
636
        public void setAddress3(String address3) {
637
                this.address3 = address3;
1✔
638
        }
1✔
639
        
640
        /**
641
         * @since 1.8
642
         * @return the address4
643
         */
644
        @Override
645
        public String getAddress4() {
646
                return address4;
1✔
647
        }
648
        
649
        /**
650
         * @since 1.8
651
         * @param address4 the address4 to set
652
         */
653
        @Override
654
        public void setAddress4(String address4) {
655
                this.address4 = address4;
1✔
656
        }
1✔
657
        
658
        /**
659
         * @since 1.8
660
         * @return the address6
661
         */
662
        @Override
663
        public String getAddress6() {
664
                return address6;
1✔
665
        }
666
        
667
        /**
668
         * @since 1.8
669
         * @param address6 the address6 to set
670
         */
671
        @Override
672
        public void setAddress6(String address6) {
673
                this.address6 = address6;
1✔
674
        }
1✔
675
        
676
        /**
677
         * @since 1.8
678
         * @return the address5
679
         */
680
        @Override
681
        public String getAddress5() {
682
                return address5;
1✔
683
        }
684
        
685
        /**
686
         * @since 1.8
687
         * @param address5 the address5 to set
688
         */
689
        @Override
690
        public void setAddress5(String address5) {
691
                this.address5 = address5;
1✔
692
        }
1✔
693
        
694
        /**
695
         * @since 1.5
696
         * @see org.openmrs.OpenmrsObject#getId()
697
         */
698
        @Override
699
        public Integer getId() {
700
                
701
                return getLocationId();
1✔
702
        }
703
        
704
        /**
705
         * @since 1.5
706
         * @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
707
         */
708
        @Override
709
        public void setId(Integer id) {
710
                setLocationId(id);
×
711
                
UNCOV
712
        }
×
713

714
        /**
715
         * {@inheritDoc}
716
         */
717
        @Override
718
        public String getAddress7() {
719
                return address7;
1✔
720
        }
721

722
        /**
723
         * {@inheritDoc}
724
         */
725
        @Override
726
        public void setAddress7(String address7) {
727
                this.address7 = address7;
1✔
728
        }
1✔
729

730
        /**
731
         * {@inheritDoc}
732
         */
733
        @Override
734
        public String getAddress8() {
735
                return address8;
1✔
736
        }
737

738
        /**
739
         * {@inheritDoc}
740
         */
741
        @Override
742
        public void setAddress8(String address8) {
743
                this.address8 = address8;
1✔
744
        }
1✔
745

746
        /**
747
         * {@inheritDoc}
748
         */
749
        @Override
750
        public String getAddress9() {
751
                return address9;
1✔
752
        }
753

754
        /**
755
         * {@inheritDoc}
756
         */
757
        @Override
758
        public void setAddress9(String address9) {
759
                this.address9 = address9;
1✔
760
        }
1✔
761

762
        /**
763
         * {@inheritDoc}
764
         */
765
        @Override
766
        public String getAddress10() {
767
                return address10;
1✔
768
        }
769

770
        /**
771
         * {@inheritDoc}
772
         */
773
        @Override
774
        public void setAddress10(String address10) {
775
                this.address10 = address10;
1✔
776
        }
1✔
777

778
        /**
779
         * {@inheritDoc}
780
         */
781
        @Override
782
        public String getAddress11() {
783
                return address11;
1✔
784
        }
785

786
        /**
787
         * {@inheritDoc}
788
         */
789
        @Override
790
        public void setAddress11(String address11) {
791
                this.address11 = address11;
1✔
792
        }
1✔
793

794
        /**
795
         * {@inheritDoc}
796
         */
797
        @Override
798
        public String getAddress12() {
799
                return address12;
1✔
800
        }
801

802
        /**
803
         * {@inheritDoc}
804
         */
805
        @Override
806
        public void setAddress12(String address12) {
807
                this.address12 = address12;
1✔
808
        }
1✔
809

810
        /**
811
         * {@inheritDoc}
812
         */
813
        @Override
814
        public String getAddress13() {
815
                return address13;
1✔
816
        }
817

818
        /**
819
         * {@inheritDoc}
820
         */
821
        @Override
822
        public void setAddress13(String address13) {
823
                this.address13 = address13;
1✔
824
        }
1✔
825

826
        /**
827
         * {@inheritDoc}
828
         */
829
        @Override
830
        public String getAddress14() {
831
                return address14;
1✔
832
        }
833

834
        /**
835
         * {@inheritDoc}
836
         */
837
        @Override
838
        public void setAddress14(String address14) {
839
                this.address14 = address14;
1✔
840
        }
1✔
841

842
        /**
843
         * {@inheritDoc}
844
         */
845
        @Override
846
        public String getAddress15() {
847
                return address15;
1✔
848
        }
849

850
        /**
851
         * {@inheritDoc}
852
         */
853
        @Override
854
        public void setAddress15(String address15) {
855
                this.address15 = address15;
1✔
856
        }
1✔
857
}
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