-
Notifications
You must be signed in to change notification settings - Fork 86
/
DateTimeIntervalValidationVTwo.java
242 lines (205 loc) · 10.5 KB
/
DateTimeIntervalValidationVTwo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jena.datatypes.xsd.XSDDateTime;
import org.apache.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
/*
* Assumption for date time interval validation: Only one start field/end field/and precision.
* We are currently not accepting multiple values for start time, end time, or precision.
*/
public class DateTimeIntervalValidationVTwo implements N3ValidatorVTwo {
private static Log log = LogFactory.getLog(DateTimeIntervalValidationVTwo.class);
private String startFieldName;
private String endFieldName;
private String templateName;
private String startValueName;
private String endValueName;
private String startPrecisionName;
private String endPrecisionName;
public DateTimeIntervalValidationVTwo(String startFieldName, String endFieldName){
this.startFieldName = startFieldName;
this.endFieldName = endFieldName;
startValueName = startFieldName + "-value";
endValueName = endFieldName + "-value";
startPrecisionName = startFieldName + "-precision";
endPrecisionName = endFieldName + "-precision";
}
public DateTimeIntervalValidationVTwo(String startFieldName, String endFieldName, String template){
this.templateName = template;
this.startFieldName = startFieldName;
this.endFieldName = endFieldName;
startValueName = startFieldName + "-value";
endValueName = endFieldName + "-value";
startPrecisionName = startFieldName + "-precision";
endPrecisionName = endFieldName + "-precision";
}
public Map<String, String> validate(EditConfigurationVTwo editConfig,
MultiValueEditSubmission editSub) {
Map<String, List<Literal>> existingLiterals = editConfig.getLiteralsInScope();
List<Literal> existingStartYear = existingLiterals.get(startValueName);
List<Literal> existingEndYear = existingLiterals.get(endValueName);
Map<String, List<Literal>> literalsFromForm = editSub.getLiteralsFromForm();
List<Literal> formStartYear = literalsFromForm.get(startValueName);
List<Literal> formEndYear = literalsFromForm.get(endValueName);
VitroVocabulary.Precision startPrecision = getPrecision(startPrecisionName, editConfig, editSub);
VitroVocabulary.Precision endPrecision = getPrecision(endPrecisionName, editConfig, editSub);
Map<String, String> errors = new HashMap<String, String>();
// NIHVIVO-2541 Commented out to allow end date with no start date
// if( formStartYear == null && formEndYear != null ){
// errors.put(startFieldName, "If there is an end date, there should be a start date");
// return errors;
// }
// We need to ensure that the user has entered a start year or end year -- tlw72
if ( templateName != null && templateName.equals("dateTimeIntervalForm.ftl")) {
if ( literalListIsNull(formStartYear) && literalListIsNull(formEndYear) ) {
errors.put(startFieldName, "Date/time intervals must begin with a year. Please enter a start year, an end year or both.");
return errors;
}
}
//Assuming form start year and form end year are working in conjunction with multiple values
int index;
if (!literalListIsNull(formStartYear) && !literalListIsNull(formEndYear)) {
int numberStartYears = formStartYear.size();
int numberEndYears = formEndYear.size();
if(numberStartYears > 1 && numberEndYears > 1) {
errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
return errors;
}
if(numberStartYears > 0 && numberEndYears > 0) {
errors.putAll(checkDateLiterals(formStartYear.get(0), formEndYear.get(0), startPrecision, endPrecision));
}
} else if (!literalListIsNull(formStartYear) && !literalListIsNull(existingEndYear)) {
int numberStartYears = formStartYear.size();
int numberEndYears = existingEndYear.size();
if(numberStartYears > 1 && numberEndYears > 1) {
errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
return errors;
}
if(numberStartYears > 0 && numberEndYears > 0) {
errors.putAll(checkDateLiterals(formStartYear.get(0), existingEndYear.get(0), startPrecision, endPrecision));
}
} else if (!literalListIsNull(existingStartYear) && !literalListIsNull(formEndYear)) {
int numberStartYears = existingStartYear.size();
int numberEndYears = formEndYear.size();
if(numberStartYears > 1 && numberEndYears > 1) {
errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
return errors;
}
if(numberStartYears > 0 && numberEndYears > 0) {
errors.putAll(checkDateLiterals(existingStartYear.get(0), formEndYear.get(0), startPrecision, endPrecision));
}
} else if (!literalListIsNull(existingStartYear) && !literalListIsNull(existingEndYear)) {
int numberStartYears = existingStartYear.size();
int numberEndYears = existingEndYear.size();
if(numberStartYears > 1 && numberEndYears > 1) {
errors.put(startFieldName, "DateTimeIntervalValidationVTwo does not support multiple start years or end years");
return errors;
}
if(numberStartYears > 0 && numberEndYears > 0) {
errors.putAll(checkDateLiterals(existingStartYear.get(0), existingEndYear.get(0), startPrecision, endPrecision));
}
}
if (errors.size() != 0)
return errors;
else
return null;
}
private Precision getPrecision(String precisionVarName,
EditConfigurationVTwo editConfig, MultiValueEditSubmission editSub) {
if( editSub != null
&& editSub.getUrisFromForm() != null
&& editSub.getUrisFromForm().containsKey(precisionVarName)){
List<String> precisionStr = editSub.getUrisFromForm().get(precisionVarName);
//TODO: Check if we need to handle multiple precision strings and what to do then
//Currently checks first precision str and then returns response
if(precisionStr.size() > 0) {
String precisionString = precisionStr.get(0);
VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
if( precision == null )
log.debug("cannot convert " + precisionStr + " to a precision");
else
return precision;
} else {
log.error("No precision strings returned");
}
}else if( editConfig != null
&& editConfig.getUrisInScope() != null
&& editConfig.getUrisInScope().containsKey(precisionVarName)){
List<String> precisionStr = editConfig.getUrisInScope().get(precisionVarName);
//TODO: Check if we need to handle multiple precision strings and what to do then
//Currently checks first precision str and then returns response
if(precisionStr.size() > 0) {
String precisionString = precisionStr.get(0);
VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
if( precision == null )
log.warn("cannot convert " + precisionString + " to a precision");
else
return precision;
} else {
log.error("No precision strings returned");
}
}
//this is what is returned if a precision was not found in the config or submission
return null;
}
private Map<String, String> checkDateLiterals(
Literal startLit, Literal endLit,
VitroVocabulary.Precision startPrecision, VitroVocabulary.Precision endPrecision) {
Map<String, String> errors = new HashMap<String, String>();
if( endPrecision == null ){
//there is no end date, nothing to check
return errors;
}
try{
XSDDateTime startDate = (XSDDateTime)startLit.getValue();
XSDDateTime endDate = (XSDDateTime)endLit.getValue();
if( startDate != null && endDate!= null ){
Calendar startCal = startDate.asCalendar();
Calendar endCal = endDate.asCalendar();
if( endCal != null ){
if (startCal.after(endCal)) {
if( startPrecision == VitroVocabulary.Precision.YEAR
&& endPrecision == VitroVocabulary.Precision.YEAR ){
errors.putAll( checkYears(startCal,endCal));
}else{
errors.put(startFieldName, "Start must be before end");
errors.put(endFieldName, "End must be after start");
}
}
}
}
}catch(ClassCastException cce){
errors.put(startFieldName, "could not format start or end date");
errors.put(endFieldName, "could not format start or end date");
log.debug("could not format dates " + cce);
}
return errors;
}
private Map<? extends String, ? extends String> checkYears(
Calendar startCal, Calendar endCal) {
Map<String, String> errors = new HashMap<String, String>();
if( ! (endCal.get(Calendar.YEAR) >= startCal.get(Calendar.YEAR) )){
errors.put(startFieldName, "Start must be before end");
errors.put(endFieldName, "End must be after start");
}
return errors;
}
//MEthod that checks whether list of literals is null or contains only null
private boolean literalListIsNull(List<Literal> literalList) {
if(literalList == null)
return true;
boolean allNulls = true;
for(Literal l: literalList) {
if(l != null)
allNulls = false;
}
return allNulls;
}
}