6200 |
08 Apr 21 |
nicklas |
1 |
package net.sf.basedb.reggie.plugins.cmd; |
6200 |
08 Apr 21 |
nicklas |
2 |
|
6200 |
08 Apr 21 |
nicklas |
3 |
import java.util.regex.Matcher; |
6200 |
08 Apr 21 |
nicklas |
4 |
import java.util.regex.Pattern; |
6200 |
08 Apr 21 |
nicklas |
5 |
|
6201 |
09 Apr 21 |
nicklas |
6 |
import net.sf.basedb.core.DbControl; |
6200 |
08 Apr 21 |
nicklas |
7 |
|
6201 |
09 Apr 21 |
nicklas |
8 |
|
6200 |
08 Apr 21 |
nicklas |
9 |
/** |
6200 |
08 Apr 21 |
nicklas |
Validator for string values that are expected to match a |
6200 |
08 Apr 21 |
nicklas |
specific patter. If the value matches it is returned unmodified |
6200 |
08 Apr 21 |
nicklas |
or using the replacement template. |
6200 |
08 Apr 21 |
nicklas |
13 |
|
6200 |
08 Apr 21 |
nicklas |
@since 4.32 |
6200 |
08 Apr 21 |
nicklas |
15 |
*/ |
6200 |
08 Apr 21 |
nicklas |
16 |
public class PatternValidator |
6200 |
08 Apr 21 |
nicklas |
17 |
implements ValueValidator<String, String> |
6200 |
08 Apr 21 |
nicklas |
18 |
{ |
6200 |
08 Apr 21 |
nicklas |
19 |
/** |
6510 |
03 Dec 21 |
nicklas |
A CMD ID is expected to be string with numbers and hyphen. We |
6510 |
03 Dec 21 |
nicklas |
add 'cmd:' prefix to the value. |
6200 |
08 Apr 21 |
nicklas |
22 |
*/ |
6201 |
09 Apr 21 |
nicklas |
23 |
public static final PatternValidator CMD_ID = new PatternValidator("[0-9]+[0-9\\-]+", "ID", "cmd:$0", null); |
6200 |
08 Apr 21 |
nicklas |
24 |
|
6201 |
09 Apr 21 |
nicklas |
25 |
/** |
6510 |
03 Dec 21 |
nicklas |
A CMD Protocol. We allow any text, but add 'cmd:' prefix. |
6510 |
03 Dec 21 |
nicklas |
27 |
*/ |
6710 |
27 Apr 22 |
nicklas |
28 |
public static final PatternValidator CMD_PROTOCOL = new PatternValidator(".+", "protocol", "cmd:$0", null); |
6510 |
03 Dec 21 |
nicklas |
29 |
|
6510 |
03 Dec 21 |
nicklas |
30 |
/** |
6510 |
03 Dec 21 |
nicklas |
A Clarity ID is expected to be string with numbers and letters. |
6510 |
03 Dec 21 |
nicklas |
32 |
*/ |
6710 |
27 Apr 22 |
nicklas |
33 |
public static final PatternValidator CLARITY_ID = new PatternValidator("[A-Z0-9]+", "Clarity ID", "cmd:$0", null); |
6710 |
27 Apr 22 |
nicklas |
34 |
|
6510 |
03 Dec 21 |
nicklas |
35 |
/** |
6709 |
27 Apr 22 |
nicklas |
A Specimen-ID is expected to be Clarity ID followed by a '-' and some letters. |
6709 |
27 Apr 22 |
nicklas |
@since 4.39 |
6709 |
27 Apr 22 |
nicklas |
38 |
*/ |
6709 |
27 Apr 22 |
nicklas |
39 |
public static final PatternValidator SPECIMEN_ID = new PatternValidator("[A-Z0-9]+(\\-[A-Za-z]+)?", "Specimen-ID", null, null); |
6709 |
27 Apr 22 |
nicklas |
40 |
|
6709 |
27 Apr 22 |
nicklas |
41 |
/** |
6201 |
09 Apr 21 |
nicklas |
A flow cell ID is uppercase letters and numbers. Typically |
6201 |
09 Apr 21 |
nicklas |
they are 9 characaters, but we allow between 6 and 12. |
6201 |
09 Apr 21 |
nicklas |
44 |
*/ |
6201 |
09 Apr 21 |
nicklas |
45 |
public static final PatternValidator FLOWCELL_ID = new PatternValidator("[A-Z0-9]{6,12}", "flow cell ID", null, "6-12 characters A-Z or 0-9"); |
6201 |
09 Apr 21 |
nicklas |
46 |
|
6201 |
09 Apr 21 |
nicklas |
47 |
/** |
6201 |
09 Apr 21 |
nicklas |
The flow cell position is "A" or "B". |
6201 |
09 Apr 21 |
nicklas |
49 |
*/ |
6201 |
09 Apr 21 |
nicklas |
50 |
public static final PatternValidator SEQUENCER_POSITION = new PatternValidator("A|B", "flow cell position", null, "A or B"); |
6201 |
09 Apr 21 |
nicklas |
51 |
|
6201 |
09 Apr 21 |
nicklas |
52 |
/** |
6201 |
09 Apr 21 |
nicklas |
Serial numbers are uppercase letters and numbers. Typically |
6201 |
09 Apr 21 |
nicklas |
5-10 characters but we allow between 2 and 20. |
6201 |
09 Apr 21 |
nicklas |
55 |
*/ |
6201 |
09 Apr 21 |
nicklas |
56 |
public static final PatternValidator SERIAL_NO = new PatternValidator("[A-Z0-9]{2,20}", "serial number", null, "2-20 characters A-Z or 0-9"); |
6203 |
09 Apr 21 |
nicklas |
57 |
|
6203 |
09 Apr 21 |
nicklas |
58 |
/** |
6203 |
09 Apr 21 |
nicklas |
At least four groups of [0-9]+[TBS]. |
6203 |
09 Apr 21 |
nicklas |
60 |
*/ |
6203 |
09 Apr 21 |
nicklas |
61 |
public static final PatternValidator READ_STRING = new PatternValidator("([0-9]+[TBS]){4,8}", "read string", null, "at least 4 groups of [0-9]+[TBS]"); |
6203 |
09 Apr 21 |
nicklas |
62 |
|
6209 |
13 Apr 21 |
nicklas |
63 |
/** |
6209 |
13 Apr 21 |
nicklas |
4 groups of digits with - separator. |
6209 |
13 Apr 21 |
nicklas |
65 |
*/ |
6209 |
13 Apr 21 |
nicklas |
66 |
public static final PatternValidator SEQUENCING_CYCLES = new PatternValidator("([0-9]+\\-){3}[0-9]+", "sequencing cycles", null, "4 groups of 0-9"); |
6201 |
09 Apr 21 |
nicklas |
67 |
|
6217 |
19 Apr 21 |
nicklas |
68 |
/** |
6217 |
19 Apr 21 |
nicklas |
PAD is uppercase letters and numbers or '-'. Typically 5-10 |
7286 |
15 Aug 23 |
nicklas |
characters but we allow between 4 and 50 and issue a warning if |
7286 |
15 Aug 23 |
nicklas |
longer 20. |
6217 |
19 Apr 21 |
nicklas |
72 |
*/ |
7286 |
15 Aug 23 |
nicklas |
73 |
public static final PatternValidator PAD = new PatternValidator("[A-Z0-9-]{4,50}", "PAD", null, "4-20/50 characters A-Z, 0-9 or '-'").warnIfLonger(20); |
6217 |
19 Apr 21 |
nicklas |
74 |
|
6221 |
23 Apr 21 |
nicklas |
75 |
/** |
6221 |
23 Apr 21 |
nicklas |
Filenames are allowed to have A-Z (upper and lower case), 0-9, '-', '_', and '.'. |
6221 |
23 Apr 21 |
nicklas |
77 |
*/ |
6221 |
23 Apr 21 |
nicklas |
78 |
public static final PatternValidator FILE_NAME = new PatternValidator("[a-zA-Z0-9_.-]+", "file name", null, "A-Z, 0-9, '-', '_' or '.'"); |
6221 |
23 Apr 21 |
nicklas |
79 |
|
6221 |
23 Apr 21 |
nicklas |
80 |
/** |
6221 |
23 Apr 21 |
nicklas |
MD5 validator. |
6221 |
23 Apr 21 |
nicklas |
82 |
*/ |
6221 |
23 Apr 21 |
nicklas |
83 |
public static final PatternValidator MD5 = new PatternValidator("[a-f0-9]{32}", "MD5", null, "32 characters, 0-9 or a-f"); |
6221 |
23 Apr 21 |
nicklas |
84 |
|
6200 |
08 Apr 21 |
nicklas |
85 |
private final Pattern pattern; |
6200 |
08 Apr 21 |
nicklas |
86 |
private final String subject; |
6200 |
08 Apr 21 |
nicklas |
87 |
private final String replacement; |
6201 |
09 Apr 21 |
nicklas |
88 |
private final String expected; |
6709 |
27 Apr 22 |
nicklas |
89 |
private final String prefix; |
6709 |
27 Apr 22 |
nicklas |
90 |
private final String suffix; |
7286 |
15 Aug 23 |
nicklas |
91 |
private final Integer warnIfLonger; |
6200 |
08 Apr 21 |
nicklas |
92 |
|
6201 |
09 Apr 21 |
nicklas |
93 |
public PatternValidator(String pattern, String subject, String replacement, String expected) |
6200 |
08 Apr 21 |
nicklas |
94 |
{ |
6200 |
08 Apr 21 |
nicklas |
95 |
this.pattern = Pattern.compile(pattern); |
6200 |
08 Apr 21 |
nicklas |
96 |
this.subject = subject; |
6200 |
08 Apr 21 |
nicklas |
97 |
this.replacement = replacement; |
6201 |
09 Apr 21 |
nicklas |
98 |
this.expected = expected; |
6709 |
27 Apr 22 |
nicklas |
99 |
this.prefix = null; |
6709 |
27 Apr 22 |
nicklas |
100 |
this.suffix = null; |
7286 |
15 Aug 23 |
nicklas |
101 |
this.warnIfLonger = null; |
6200 |
08 Apr 21 |
nicklas |
102 |
} |
6200 |
08 Apr 21 |
nicklas |
103 |
|
7286 |
15 Aug 23 |
nicklas |
104 |
private PatternValidator(PatternValidator parent, int warnIfLonger) |
7286 |
15 Aug 23 |
nicklas |
105 |
{ |
7286 |
15 Aug 23 |
nicklas |
106 |
this.pattern = parent.pattern; |
7286 |
15 Aug 23 |
nicklas |
107 |
this.subject = parent.subject; |
7286 |
15 Aug 23 |
nicklas |
108 |
this.replacement = parent.replacement; |
7286 |
15 Aug 23 |
nicklas |
109 |
this.expected = parent.expected; |
7286 |
15 Aug 23 |
nicklas |
110 |
this.prefix = null; |
7286 |
15 Aug 23 |
nicklas |
111 |
this.suffix = null; |
7286 |
15 Aug 23 |
nicklas |
112 |
this.warnIfLonger = warnIfLonger; |
7286 |
15 Aug 23 |
nicklas |
113 |
} |
7286 |
15 Aug 23 |
nicklas |
114 |
|
6709 |
27 Apr 22 |
nicklas |
115 |
private PatternValidator(PatternValidator parent, String prefix, String suffix) |
6709 |
27 Apr 22 |
nicklas |
116 |
{ |
6709 |
27 Apr 22 |
nicklas |
117 |
this.pattern = parent.pattern; |
6709 |
27 Apr 22 |
nicklas |
118 |
this.subject = parent.subject; |
6709 |
27 Apr 22 |
nicklas |
119 |
this.replacement = parent.replacement; |
6709 |
27 Apr 22 |
nicklas |
120 |
this.expected = parent.expected; |
6709 |
27 Apr 22 |
nicklas |
121 |
this.prefix = prefix; |
6709 |
27 Apr 22 |
nicklas |
122 |
this.suffix = suffix; |
7286 |
15 Aug 23 |
nicklas |
123 |
this.warnIfLonger = null; |
6709 |
27 Apr 22 |
nicklas |
124 |
} |
6709 |
27 Apr 22 |
nicklas |
125 |
|
6200 |
08 Apr 21 |
nicklas |
126 |
@Override |
6201 |
09 Apr 21 |
nicklas |
127 |
public String isValid(DbControl dc, String value, JsonSection section, String entryKey) |
6200 |
08 Apr 21 |
nicklas |
128 |
{ |
6221 |
23 Apr 21 |
nicklas |
129 |
if (value != null) |
6200 |
08 Apr 21 |
nicklas |
130 |
{ |
6221 |
23 Apr 21 |
nicklas |
131 |
Matcher m = pattern.matcher(value); |
6221 |
23 Apr 21 |
nicklas |
132 |
if (!m.matches()) |
6221 |
23 Apr 21 |
nicklas |
133 |
{ |
6221 |
23 Apr 21 |
nicklas |
134 |
section.addErrorMessage("Invalid "+subject+" in JSON: "+entryKey+"="+value+(expected!=null?" (expected " +expected+")":"")); |
6221 |
23 Apr 21 |
nicklas |
135 |
return null; |
6221 |
23 Apr 21 |
nicklas |
136 |
} |
6709 |
27 Apr 22 |
nicklas |
137 |
if (prefix != null && !value.startsWith(prefix)) |
6709 |
27 Apr 22 |
nicklas |
138 |
{ |
6709 |
27 Apr 22 |
nicklas |
139 |
section.addWarningMessage("Unexpected prefix: "+entryKey+"="+value+" (expected '"+prefix+"')"); |
6709 |
27 Apr 22 |
nicklas |
140 |
} |
6709 |
27 Apr 22 |
nicklas |
141 |
if (suffix != null && !value.endsWith(suffix)) |
6709 |
27 Apr 22 |
nicklas |
142 |
{ |
6709 |
27 Apr 22 |
nicklas |
143 |
section.addWarningMessage("Unexpected suffix: "+entryKey+"="+value+" (expected '"+suffix+"')"); |
6709 |
27 Apr 22 |
nicklas |
144 |
} |
7286 |
15 Aug 23 |
nicklas |
145 |
if (warnIfLonger != null && value.length() > warnIfLonger) |
7286 |
15 Aug 23 |
nicklas |
146 |
{ |
7286 |
15 Aug 23 |
nicklas |
147 |
section.addWarningMessage("Long "+subject+" in JSON: "+entryKey+"="+value+" (expected <= " +warnIfLonger+" characters)"); |
7286 |
15 Aug 23 |
nicklas |
148 |
} |
6221 |
23 Apr 21 |
nicklas |
149 |
if (replacement != null) value = m.replaceAll(replacement); |
6200 |
08 Apr 21 |
nicklas |
150 |
} |
6200 |
08 Apr 21 |
nicklas |
151 |
return value; |
6200 |
08 Apr 21 |
nicklas |
152 |
} |
6200 |
08 Apr 21 |
nicklas |
153 |
|
6200 |
08 Apr 21 |
nicklas |
154 |
@Override |
6200 |
08 Apr 21 |
nicklas |
155 |
public Class<String> getExpectedClass() |
6200 |
08 Apr 21 |
nicklas |
156 |
{ |
6200 |
08 Apr 21 |
nicklas |
157 |
return String.class; |
6200 |
08 Apr 21 |
nicklas |
158 |
} |
6709 |
27 Apr 22 |
nicklas |
159 |
|
6710 |
27 Apr 22 |
nicklas |
160 |
/** |
6993 |
20 Jan 23 |
nicklas |
A simple check if the given value matches the pattern. No errors |
6993 |
20 Jan 23 |
nicklas |
are reported. |
6993 |
20 Jan 23 |
nicklas |
163 |
*/ |
6993 |
20 Jan 23 |
nicklas |
164 |
public boolean matches(String value) |
6993 |
20 Jan 23 |
nicklas |
165 |
{ |
6993 |
20 Jan 23 |
nicklas |
166 |
return value != null && pattern.matcher(value).matches(); |
6993 |
20 Jan 23 |
nicklas |
167 |
} |
6993 |
20 Jan 23 |
nicklas |
168 |
|
6993 |
20 Jan 23 |
nicklas |
169 |
/** |
6710 |
27 Apr 22 |
nicklas |
Wrap this validator in a validator that also checks the if value |
6710 |
27 Apr 22 |
nicklas |
starts and/or ends with the given prefix and suffix. Warning-level |
6710 |
27 Apr 22 |
nicklas |
messages are created if the value doesn't match. Use null for the |
6710 |
27 Apr 22 |
nicklas |
prefix or suffix to skip the check. |
6710 |
27 Apr 22 |
nicklas |
@since 4.39 |
6710 |
27 Apr 22 |
nicklas |
175 |
*/ |
6709 |
27 Apr 22 |
nicklas |
176 |
public PatternValidator withPrefixSuffix(String prefix, String suffix) |
6709 |
27 Apr 22 |
nicklas |
177 |
{ |
6709 |
27 Apr 22 |
nicklas |
178 |
return new PatternValidator(this, prefix, suffix); |
6709 |
27 Apr 22 |
nicklas |
179 |
} |
7286 |
15 Aug 23 |
nicklas |
180 |
|
7286 |
15 Aug 23 |
nicklas |
181 |
/** |
7286 |
15 Aug 23 |
nicklas |
Wrap this validator in a validator that also checks the length of |
7286 |
15 Aug 23 |
nicklas |
the value and issues a warning if it is longer than the given |
7286 |
15 Aug 23 |
nicklas |
max length. |
7286 |
15 Aug 23 |
nicklas |
@since 4.48.5 |
7286 |
15 Aug 23 |
nicklas |
186 |
*/ |
7286 |
15 Aug 23 |
nicklas |
187 |
public PatternValidator warnIfLonger(int maxLength) |
7286 |
15 Aug 23 |
nicklas |
188 |
{ |
7286 |
15 Aug 23 |
nicklas |
189 |
return new PatternValidator(this, maxLength); |
7286 |
15 Aug 23 |
nicklas |
190 |
} |
6200 |
08 Apr 21 |
nicklas |
191 |
|
6200 |
08 Apr 21 |
nicklas |
192 |
} |