Coverage Summary for Class: JoinInfo (net.sf.persism)
Class |
Class, %
|
Method, %
|
Line, %
|
JoinInfo |
100%
(1/1)
|
100%
(16/16)
|
98.8%
(83/84)
|
1 package net.sf.persism;
2
3 import net.sf.persism.annotations.Join;
4
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collection;
8 import java.util.List;
9 import java.util.concurrent.CopyOnWriteArrayList;
10
11 final class JoinInfo {
12
13 static final List<JoinInfo> joinInfos = new CopyOnWriteArrayList<>();
14
15 private String[] parentPropertyNames;
16 private String[] childPropertyNames;
17 private List<PropertyInfo> parentProperties;
18 private List<PropertyInfo> childProperties;
19 private Class<?> parentClass;
20 private Class<?> childClass;
21 private final PropertyInfo joinProperty;
22 private final boolean caseSensitive;
23 private final boolean parentIsAQuery;
24 private boolean reversed = false;
25
26 private JoinInfo(JoinInfo other) {
27 parentPropertyNames = other.parentPropertyNames;
28 childPropertyNames = other.childPropertyNames;
29 parentProperties = other.parentProperties;
30 childProperties = other.childProperties;
31 parentClass = other.parentClass;
32 childClass = other.childClass;
33 joinProperty = other.joinProperty;
34 caseSensitive = other.caseSensitive;
35 parentIsAQuery = other.parentIsAQuery;
36 reversed = other.reversed;
37 }
38
39 // note parent may be a POJO or a list of POJOs
40 private JoinInfo(Join joinAnnotation, PropertyInfo joinProperty, Object parent, Class<?> parentClass) {
41 this.joinProperty = joinProperty;
42 parentPropertyNames = joinAnnotation.onProperties().split(",");
43 childPropertyNames = joinAnnotation.toProperties().split(",");
44 if (parentPropertyNames.length != childPropertyNames.length) {
45 throw new PersismException(Message.PropertyCountMismatchForJoin.message(parentClass, joinAnnotation.onProperties(), joinAnnotation.toProperties()));
46 }
47 Util.trimArray(parentPropertyNames);
48 Util.trimArray(childPropertyNames);
49
50 caseSensitive = joinAnnotation.caseSensitive();
51
52 childClass = joinAnnotation.to();
53 this.parentClass = parentClass;
54
55 parentIsAQuery = Collection.class.isAssignableFrom(parent.getClass());
56
57 parentProperties = new ArrayList<>(parentPropertyNames.length);
58 childProperties = new ArrayList<>(childPropertyNames.length);
59
60 for (int j = 0; j < parentPropertyNames.length; j++) {
61 String prop = parentPropertyNames[j];
62 var opt = MetaData.getPropertyInfo(parentClass).stream().filter(p -> p.propertyName.equalsIgnoreCase(prop)).findFirst();
63 if (opt.isPresent()) {
64 parentProperties.add(opt.get());
65 parentPropertyNames[j] = opt.get().propertyName; // ensure names match exact
66 } else {
67 throw new PersismException(Message.PropertyNotFoundForJoin.message(prop, parentClass));
68 }
69 }
70
71 for (int j = 0; j < childPropertyNames.length; j++) {
72 String prop = childPropertyNames[j];
73 var opt = MetaData.getPropertyInfo(childClass).stream().filter(p -> p.propertyName.equalsIgnoreCase(prop)).findFirst();
74 if (opt.isPresent()) {
75 childProperties.add(opt.get());
76 childPropertyNames[j] = opt.get().propertyName; // ensure names match exact
77 } else {
78 throw new PersismException(Message.PropertyNotFoundForJoin.message(prop, childClass));
79 }
80 }
81 }
82
83 public JoinInfo swapParentAndChild() {
84 JoinInfo info = new JoinInfo(this);
85
86 String[] tmpPropertyNames = info.parentPropertyNames;
87 info.parentPropertyNames = info.childPropertyNames;
88 info.childPropertyNames = tmpPropertyNames;
89
90 List<PropertyInfo> tmpProperties = info.parentProperties;
91 info.parentProperties = info.childProperties;
92 info.childProperties = tmpProperties;
93
94 Class<?> tmpClass = info.parentClass;
95 info.parentClass = info.childClass;
96 info.childClass = tmpClass;
97
98 info.reversed = true;
99 return info;
100 }
101
102 public static JoinInfo getInstance(Join joinAnnotation, PropertyInfo joinProperty, Object parent, Class<?> parentClass) {
103 // if (true) {
104 // return new JoinInfo(joinAnnotation, joinProperty, parent, parentClass);
105 // }
106 JoinInfo foundInfo = null;
107 for (JoinInfo joinInfo : joinInfos) {
108 if (joinInfo.joinProperty().equals(joinProperty) && joinInfo.parentClass().equals(parentClass)) {
109 if (Collection.class.isAssignableFrom(parent.getClass())) {
110 if (joinInfo.parentIsAQuery()) {
111 foundInfo = joinInfo;
112 break;
113 }
114 } else {
115 if (!joinInfo.parentIsAQuery()) {
116 foundInfo = joinInfo;
117 break;
118 }
119 }
120 }
121 }
122
123 if (foundInfo != null) {
124 return foundInfo;
125 } else {
126 JoinInfo joinInfo = new JoinInfo(joinAnnotation, joinProperty, parent, parentClass);
127 joinInfos.add(joinInfo);
128 return joinInfo;
129 }
130 }
131
132
133 public String[] parentPropertyNames() {
134 return parentPropertyNames;
135 }
136
137 public String[] childPropertyNames() {
138 return childPropertyNames;
139 }
140
141 public List<PropertyInfo> parentProperties() {
142 return parentProperties;
143 }
144
145 public List<PropertyInfo> childProperties() {
146 return childProperties;
147 }
148
149 public Class<?> parentClass() {
150 return parentClass;
151 }
152
153 public Class<?> childClass() {
154 return childClass;
155 }
156
157 public boolean caseSensitive() {
158 return caseSensitive;
159 }
160
161 public boolean parentIsAQuery() {
162 return parentIsAQuery;
163 }
164
165 public PropertyInfo joinProperty() {
166 return joinProperty;
167 }
168
169 public boolean reversed() {
170 return reversed;
171 }
172
173 @Override
174 public String toString() {
175 return "" +
176 "Parent property name(s)=" + Arrays.toString(parentPropertyNames) +
177 ", Child property name(s)=" + Arrays.toString(childPropertyNames) +
178 ", Parent class=" + parentClass.getSimpleName() +
179 ", Child class=" + childClass.getSimpleName() +
180 ", Join property name=" + joinProperty.propertyName +
181 ", Is parent a query?=" + parentIsAQuery +
182 ", Is reversed?=" + reversed +
183 '}';
184 }
185 }