io.devbench.uibuilder.data.common.parse.annotation.IdAnnotationParser Maven / Gradle / Ivy
/*
*
* Copyright © 2018 Webvalto Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.devbench.uibuilder.data.common.parse.annotation;
import io.devbench.uibuilder.core.controllerbean.uiproperty.PropertyConverters;
import io.devbench.uibuilder.core.utils.reflection.ClassMetadata;
import io.devbench.uibuilder.core.utils.reflection.PropertyMetadata;
import javax.persistence.Id;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class IdAnnotationParser {
private static final Map, Set> CACHE = new ConcurrentHashMap<>();
public static Set getIdPropertyPathsFromClass(Class> clazz) {
CACHE.putIfAbsent(clazz, collectIdPaths(clazz));
return CACHE.get(clazz);
}
private static Set collectIdPaths(Class> clazz) {
Set idSet = getIdFieldsPropertyMetadataStream(clazz)
.flatMap(field -> getIdPropertyPathsRecursively(field, new ArrayList<>()))
.collect(Collectors.toSet());
if (idSet.isEmpty()) {
throw new EntityIdNotFoundException("The class [" + clazz + "] does not contain any field annotated with the @Id annotation.");
}
return idSet;
}
private static Stream extends PropertyMetadata>> getIdFieldsPropertyMetadataStream(Class> clazz) {
return ClassMetadata
.ofClass(clazz)
.getProperties()
.stream()
.filter(property -> property.isAnnotationPresent(Id.class));
}
private static Stream getIdPropertyPathsRecursively(PropertyMetadata> field, List> alreadyVisitedProperties) {
if (PropertyConverters.IMPLICIT_CONVERTERS.containsKey(field.getType())) {
return Stream.of(calculatePropertyPath(copyListWith(alreadyVisitedProperties, field)));
} else {
if (alreadyVisitedProperties.contains(field)) {
throw new IllegalIdPropertyPathRecursionException(alreadyVisitedProperties);
}
List> visitedPropertiesWithCurrentOne = copyListWith(alreadyVisitedProperties, field);
return
getIdFieldsPropertyMetadataStream(field.getType())
.flatMap(it -> getIdPropertyPathsRecursively(it, visitedPropertiesWithCurrentOne));
}
}
private static List> copyListWith(List> alreadyVisitedProperties, PropertyMetadata> field) {
List> copiedList = new ArrayList<>(alreadyVisitedProperties);
copiedList.add(field);
return copiedList;
}
private static String calculatePropertyPath(List> visitedProperties) {
return visitedProperties
.stream()
.map(PropertyMetadata::getName)
.collect(Collectors.joining("."));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy