Skip to contentMethod: static {...}
1: /**
2: * Copyright (C) 2019 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jopa.model.metamodel;
14:
15: import cz.cvut.kbss.jopa.exception.InvalidFieldMappingException;
16: import cz.cvut.kbss.jopa.model.annotations.OWLAnnotationProperty;
17: import cz.cvut.kbss.jopa.model.annotations.OWLDataProperty;
18: import cz.cvut.kbss.jopa.utils.IdentifierTransformer;
19:
20: import java.lang.reflect.Field;
21: import java.lang.reflect.ParameterizedType;
22: import java.lang.reflect.Type;
23: import java.util.List;
24: import java.util.Map;
25: import java.util.Set;
26: import java.util.SortedSet;
27:
28: import static cz.cvut.kbss.jopa.utils.Constants.SUPPORTED_IDENTIFIER_TYPES;
29:
30: /**
31: * Verifies that a field's mapping metadata and declaration are valid.
32: */
33: class FieldMappingValidator {
34:
35: void validatePropertiesField(Field field) {
36: assert field != null;
37: if (!Map.class.isAssignableFrom(field.getType())) {
38: throw new InvalidFieldMappingException(
39: "Expected @Properties field to be a map, but it is a " + field.getType());
40: }
41: if (isRawType(field.getGenericType())) {
42: throw new InvalidFieldMappingException("@Properties field cannot be a raw map.");
43: }
44: final PropertiesParametersResolver parametersResolver = new PropertiesParametersResolver(field);
45: if (!isValidIdentifierType(parametersResolver.getKeyType())) {
46: throw new InvalidFieldMappingException(
47: "@Properties key type is not a valid identifier type. Expected one of " +
48: SUPPORTED_IDENTIFIER_TYPES);
49: }
50: validatePropertiesValueType(parametersResolver.getValueType());
51: }
52:
53: private static boolean isRawType(Type type) {
54: return !(type instanceof ParameterizedType);
55: }
56:
57: private static void validatePropertiesValueType(Type type) {
58: if (isRawType(type)) {
59: throw new InvalidFieldMappingException(
60: "Expected a java.util.Set as value parameter of the @Properties map, but got " + type);
61: }
62: if (!((ParameterizedType) type).getRawType().equals(Set.class)) {
63: throw new InvalidFieldMappingException(
64: "Expected a java.util.Set as value parameter of the @Properties map, but got " + type);
65: }
66: }
67:
68: void validateTypesField(Field field) {
69: if (!Set.class.isAssignableFrom(field.getType())) {
70: throw new InvalidFieldMappingException("Expected @Types field to be a set, but it is a " + field.getType());
71: }
72: if (isRawType(field.getGenericType())) {
73: throw new InvalidFieldMappingException("@Types field cannot be a raw set.");
74: }
75: final ParameterizedType typeSpec = (ParameterizedType) field.getGenericType();
76: if (!isValidIdentifierType(typeSpec.getActualTypeArguments()[0])) {
77: throw new InvalidFieldMappingException(
78: "@Types field value is not a valid identifier type. Expected one of " + SUPPORTED_IDENTIFIER_TYPES);
79: }
80: }
81:
82: void validateIdentifierType(Type type) {
83: if (!isValidIdentifierType(type)) {
84: throw new InvalidFieldMappingException(type + " is not a valid identifier type.");
85: }
86: }
87:
88: boolean isValidIdentifierType(Type type) {
89: return type instanceof Class && IdentifierTransformer.isValidIdentifierType((Class<?>) type);
90: }
91:
92: void validateAnnotationPropertyField(Field field, OWLAnnotationProperty config) {
93: assert field != null;
94: assert config != null;
95: validateLexicalFormField(field, config.lexicalForm());
96: validateSimpleLiteralField(field, config.simpleLiteral());
97: }
98:
99: void validateDataPropertyField(Field field, OWLDataProperty config) {
100: assert field != null;
101: assert config != null;
102: validateLexicalFormField(field, config.lexicalForm());
103: validateSimpleLiteralField(field, config.simpleLiteral());
104: }
105:
106: private static void validateLexicalFormField(Field field, boolean lexicalForm) {
107: if (lexicalForm && !String.class.isAssignableFrom(getLiteralFieldType(field))) {
108: throw new InvalidFieldMappingException("lexicalForm mapping can be used only on fields of type String.");
109: }
110: }
111:
112: private static void validateSimpleLiteralField(Field field, boolean simpleLiteral) {
113: if (simpleLiteral && !String.class.isAssignableFrom(getLiteralFieldType(field))) {
114: throw new InvalidFieldMappingException("simpleLiteral mapping can be used only on fields of type String.");
115: }
116: }
117:
118: private static Class<?> getLiteralFieldType(Field field) {
119: final Class<?> fieldType = field.getType();
120: if (List.class.isAssignableFrom(fieldType) || Set.class.isAssignableFrom(fieldType) ||
121: SortedSet.class.isAssignableFrom(fieldType)) {
122: final ParameterizedType typeSpec = (ParameterizedType) field.getGenericType();
123: assert typeSpec.getActualTypeArguments().length == 1;
124: return (Class<?>) typeSpec.getActualTypeArguments()[0];
125: }
126: return fieldType;
127: }
128: }