io.micronaut.data.model.runtime.RuntimePersistentEntity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of micronaut-data-model Show documentation
Show all versions of micronaut-data-model Show documentation
Data Repository Support for Micronaut
/*
* Copyright 2017-2020 original authors
*
* 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
*
* https://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.micronaut.data.model.runtime;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.beans.BeanIntrospection;
import io.micronaut.core.beans.BeanProperty;
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.data.annotation.Id;
import io.micronaut.data.annotation.Relation;
import io.micronaut.data.annotation.Transient;
import io.micronaut.data.annotation.Version;
import io.micronaut.data.exceptions.MappingException;
import io.micronaut.data.model.*;
import io.micronaut.data.model.runtime.convert.AttributeConverter;
import java.util.*;
import java.util.stream.Collectors;
/**
* Runtime implementation of {@link PersistentEntity} that uses pre-computed {@link io.micronaut.core.annotation.Introspected} bean data and is completely stateless.
*
* @author graemerocher
* @since 1.0
* @param The type
*/
public class RuntimePersistentEntity extends AbstractPersistentEntity implements PersistentEntity {
private final BeanIntrospection introspection;
private final RuntimePersistentProperty[] identity;
// Subset of all introspections properties with the same order as in BeanIntrospection with nulls if excluded.
private final RuntimePersistentProperty[] allPersistentProperties;
private final RuntimePersistentProperty[] persistentProperties;
private final RuntimePersistentProperty[] constructorArguments;
private final String aliasName;
private final RuntimePersistentProperty version;
private Boolean hasAutoPopulatedProperties;
private List allPersistentPropertiesNames;
private List> persistentPropertiesValues;
private EnumSet cascadedTypes;
/**
* Default constructor.
* @param type The type
*/
public RuntimePersistentEntity(@NonNull Class type) {
this(BeanIntrospection.getIntrospection(type));
}
/**
* Default constructor.
* @param introspection The introspection
*/
public RuntimePersistentEntity(@NonNull BeanIntrospection introspection) {
super(introspection);
ArgumentUtils.requireNonNull("introspection", introspection);
this.introspection = introspection;
Argument>[] constructorArguments = introspection.getConstructorArguments();
Set constructorArgumentNames = Arrays.stream(constructorArguments).map(Argument::getName).collect(Collectors.toSet());
RuntimePersistentProperty version = null;
List> ids = new LinkedList<>();
Collection> beanProperties = introspection.getBeanProperties();
this.allPersistentProperties = new RuntimePersistentProperty[beanProperties.size()];
this.persistentProperties = new RuntimePersistentProperty[beanProperties.size()];
for (BeanProperty bp : beanProperties) {
if (bp.hasStereotype(Transient.class)) {
continue;
}
int propertyIndex = introspection.propertyIndexOf(bp.getName());
if (bp.hasStereotype(Id.class)) {
RuntimePersistentProperty id;
if (isEmbedded(bp)) {
id = new RuntimeEmbedded<>(this, bp, constructorArgumentNames.contains(bp.getName()));
} else {
id = new RuntimePersistentProperty<>(this, bp, constructorArgumentNames.contains(bp.getName()));
}
ids.add(id);
allPersistentProperties[propertyIndex] = id;
} else if (bp.hasStereotype(Version.class)) {
version = new RuntimePersistentProperty<>(this, bp, constructorArgumentNames.contains(bp.getName()));
allPersistentProperties[propertyIndex] = version;
} else {
RuntimePersistentProperty prop;
if (bp.hasAnnotation(Relation.class)) {
if (isEmbedded(bp)) {
prop = new RuntimeEmbedded<>(this, bp, constructorArgumentNames.contains(bp.getName()));
} else {
prop = new RuntimeAssociation<>(this, bp, constructorArgumentNames.contains(bp.getName()));
}
} else {
prop = new RuntimePersistentProperty<>(this, bp, constructorArgumentNames.contains(bp.getName()));
}
allPersistentProperties[propertyIndex] = prop;
persistentProperties[propertyIndex] = prop;
}
}
this.identity = ids.toArray(new RuntimePersistentProperty[0]);
this.version = version;
this.constructorArguments = new RuntimePersistentProperty[constructorArguments.length];
for (int i = 0; i < constructorArguments.length; i++) {
Argument> constructorArgument = constructorArguments[i];
String argumentName = constructorArgument.getName();
RuntimePersistentProperty prop = getPropertyByName(argumentName);
if (prop == null) {
throw new MappingException("Constructor argument [" + argumentName + "] for type [" + getName() + "] must have an associated getter");
}
this.constructorArguments[i] = prop;
}
this.aliasName = super.getAliasName();
}
private static EnumSet cascades(RuntimePersistentEntity> persistentEntity) {
EnumSet cascades = EnumSet.noneOf(Relation.Cascade.class);
for (RuntimeAssociation> association : persistentEntity.getAssociations()) {
cascades.addAll(cascades(association));
}
cascades.remove(Relation.Cascade.NONE);
if (cascades.remove(Relation.Cascade.ALL)) {
EnumSet all = EnumSet.allOf(Relation.Cascade.class);
all.remove(Relation.Cascade.ALL);
all.remove(Relation.Cascade.NONE);
return all;
}
return cascades;
}
private static EnumSet cascades(RuntimeAssociation> association) {
if (association.getKind() == Relation.Kind.EMBEDDED) {
return cascades(association.getAssociatedEntity());
}
return association.getCascadeTypes();
}
/**
* Resolves a converter instance.
* @param converterClass The converter class
* @return converter instance
*/
@NonNull
protected AttributeConverter
© 2015 - 2025 Weber Informatics LLC | Privacy Policy