-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #516 from entur/improve/id-validation
Improve/id validation
- Loading branch information
Showing
12 changed files
with
903 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
src/main/java/org/entur/lamassu/model/id/DefaultIdValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* | ||
* | ||
* * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by | ||
* * the European Commission - subsequent versions of the EUPL (the "Licence"); | ||
* * You may not use this work except in compliance with the Licence. | ||
* * You may obtain a copy of the Licence at: | ||
* * | ||
* * https://joinup.ec.europa.eu/software/page/eupl | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the Licence is distributed on an "AS IS" basis, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the Licence for the specific language governing permissions and | ||
* * limitations under the Licence. | ||
* | ||
*/ | ||
|
||
package org.entur.lamassu.model.id; | ||
|
||
import java.util.List; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class DefaultIdValidator implements IdValidator { | ||
|
||
public static final char ID_SEPARATOR_CHAR = ':'; | ||
public static final int ID_CODESPACE_LENGTH = 3; | ||
public static final int ID_MINIMUM_LENGTH = 6; | ||
|
||
protected static final DefaultIdValidator instance = new DefaultIdValidator(); | ||
private static final Logger log = LoggerFactory.getLogger(DefaultIdValidator.class); | ||
|
||
public static DefaultIdValidator getInstance() { | ||
return instance; | ||
} | ||
|
||
public boolean validate(CharSequence string, int offset, int length) { | ||
// minimum size is XXX:X:X | ||
if (length < ID_MINIMUM_LENGTH) { | ||
return false; | ||
} | ||
if (string.charAt(offset + ID_CODESPACE_LENGTH) != ':') { | ||
return false; | ||
} | ||
int nextSeparatorIndex = getNextSeparatorIndex( | ||
string, | ||
ID_CODESPACE_LENGTH + 1, | ||
length | ||
); | ||
if (nextSeparatorIndex == -1) { | ||
return false; | ||
} | ||
return ( | ||
validateCodespace(string, 0, ID_CODESPACE_LENGTH) && | ||
validateType(string, ID_CODESPACE_LENGTH + 1, nextSeparatorIndex) && | ||
validateValue(string, nextSeparatorIndex + 1, string.length()) | ||
); | ||
} | ||
|
||
protected static int getNextSeparatorIndex( | ||
CharSequence string, | ||
int startIndex, | ||
int endIndex | ||
) { | ||
for (int i = startIndex; i < endIndex; i++) { | ||
if (string.charAt(i) == ID_SEPARATOR_CHAR) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
public boolean validateCodespace(CharSequence codespace, int startIndex, int endIndex) { | ||
// length 3 | ||
// A-Z | ||
if (endIndex - startIndex == ID_CODESPACE_LENGTH) { | ||
for (int i = startIndex; i < endIndex; i++) { | ||
char c = codespace.charAt(i); | ||
if (c < 'A' || c > 'Z') { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
public boolean validateType(CharSequence type, int startIndex, int endIndex) { | ||
// not empty string | ||
// A-Z | ||
// a-z | ||
if (endIndex > startIndex) { | ||
for (int i = startIndex; i < endIndex; i++) { | ||
char c = type.charAt(i); | ||
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
public boolean validateValue(CharSequence value, int startIndex, int endIndex) { | ||
if (endIndex > startIndex) { | ||
for (int i = startIndex; i < endIndex; i++) { | ||
char c = value.charAt(i); | ||
if (!isValueCharacter(c)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
protected static boolean isValueCharacter(char c) { | ||
return c >= 0x21 && c <= 0x7E; // Not in the ASCII printable range | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* | ||
* | ||
* * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by | ||
* * the European Commission - subsequent versions of the EUPL (the "Licence"); | ||
* * You may not use this work except in compliance with the Licence. | ||
* * You may obtain a copy of the Licence at: | ||
* * | ||
* * https://joinup.ec.europa.eu/software/page/eupl | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the Licence is distributed on an "AS IS" basis, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the Licence for the specific language governing permissions and | ||
* * limitations under the Licence. | ||
* | ||
*/ | ||
|
||
package org.entur.lamassu.model.id; | ||
|
||
public class IdBuilder { | ||
|
||
public static IdBuilder newInstance() { | ||
return new IdBuilder(); | ||
} | ||
|
||
protected static final String ID_SEPARATOR_CHAR = ":"; | ||
|
||
private static final IdValidator defaultValidator = DefaultIdValidator.getInstance(); | ||
|
||
private final IdValidator validator; | ||
|
||
protected String codespace; | ||
protected String type; | ||
protected String value; | ||
|
||
public IdBuilder() { | ||
this(defaultValidator); | ||
} | ||
|
||
public IdBuilder(IdValidator validator) { | ||
this.validator = validator; | ||
} | ||
|
||
public IdBuilder withCodespace(String codespace) { | ||
this.codespace = codespace; | ||
return this; | ||
} | ||
|
||
public IdBuilder withType(String type) { | ||
this.type = type; | ||
return this; | ||
} | ||
|
||
public IdBuilder withValue(String value) { | ||
this.value = value; | ||
|
||
return this; | ||
} | ||
|
||
public String build() { | ||
if (codespace == null || !validator.validateCodespace(codespace)) { | ||
throw new IllegalStateException( | ||
"Expected codespace (size 3 with characters A-Z), found " + codespace | ||
); | ||
} | ||
if (type == null || !validator.validateType(type)) { | ||
throw new IllegalStateException( | ||
"Expected type (nonempty with characters A-Z), found " + type | ||
); | ||
} | ||
if (value == null || !validator.validateValue(value)) { | ||
throw new IllegalStateException( | ||
"Expected value (ASCII printable character), found " + value | ||
); | ||
} | ||
return String.join(ID_SEPARATOR_CHAR, codespace, type, value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* | ||
* | ||
* * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by | ||
* * the European Commission - subsequent versions of the EUPL (the "Licence"); | ||
* * You may not use this work except in compliance with the Licence. | ||
* * You may obtain a copy of the Licence at: | ||
* * | ||
* * https://joinup.ec.europa.eu/software/page/eupl | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the Licence is distributed on an "AS IS" basis, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the Licence for the specific language governing permissions and | ||
* * limitations under the Licence. | ||
* | ||
*/ | ||
|
||
package org.entur.lamassu.model.id; | ||
|
||
public interface IdValidator { | ||
default boolean validate(CharSequence id) { | ||
return validate(id, 0, id.length()); | ||
} | ||
|
||
boolean validate(CharSequence id, int offset, int length); | ||
|
||
default boolean validateCodespace(CharSequence codespace) { | ||
return validateCodespace(codespace, 0, codespace.length()); | ||
} | ||
|
||
boolean validateCodespace(CharSequence codespace, int offset, int length); | ||
|
||
default boolean validateType(CharSequence type) { | ||
return validateType(type, 0, type.length()); | ||
} | ||
|
||
boolean validateType(CharSequence type, int offset, int length); | ||
|
||
default boolean validateValue(CharSequence value) { | ||
return validateValue(value, 0, value.length()); | ||
} | ||
|
||
boolean validateValue(CharSequence value, int offset, int length); | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/org/entur/lamassu/model/id/predicate/IdCodespacePredicate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* | ||
* | ||
* * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by | ||
* * the European Commission - subsequent versions of the EUPL (the "Licence"); | ||
* * You may not use this work except in compliance with the Licence. | ||
* * You may obtain a copy of the Licence at: | ||
* * | ||
* * https://joinup.ec.europa.eu/software/page/eupl | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the Licence is distributed on an "AS IS" basis, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the Licence for the specific language governing permissions and | ||
* * limitations under the Licence. | ||
* | ||
*/ | ||
|
||
package org.entur.lamassu.model.id.predicate; | ||
|
||
import org.entur.lamassu.model.id.DefaultIdValidator; | ||
|
||
public class IdCodespacePredicate implements IdPredicate { | ||
|
||
private final char[] prefix; | ||
|
||
public IdCodespacePredicate(CharSequence codespace) { | ||
prefix = | ||
new char[] { | ||
codespace.charAt(0), | ||
codespace.charAt(1), | ||
codespace.charAt(2), | ||
DefaultIdValidator.ID_SEPARATOR_CHAR, | ||
}; | ||
} | ||
|
||
public boolean test(CharSequence t) { | ||
return ( | ||
t.length() > 4 && | ||
t.charAt(0) == prefix[0] && | ||
t.charAt(1) == prefix[1] && | ||
t.charAt(2) == prefix[2] && | ||
t.charAt(3) == prefix[3] | ||
); | ||
} | ||
} |
Oops, something went wrong.