org.hibernate.cfg.annotations.reflection.internal.PropertyMappingElementCollector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core-jakarta Show documentation
Show all versions of hibernate-core-jakarta Show documentation
Hibernate O/RM implementation of the Jakarta Persistence specification
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.cfg.annotations.reflection.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import org.hibernate.boot.jaxb.mapping.spi.AttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributes;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasic;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollection;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbedded;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedId;
import org.hibernate.boot.jaxb.mapping.spi.JaxbId;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToMany;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOne;
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToMany;
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOne;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostLoad;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostPersist;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostRemove;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostUpdate;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPrePersist;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPreRemove;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPreUpdate;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransient;
import org.hibernate.boot.jaxb.mapping.spi.JaxbVersion;
import org.hibernate.boot.jaxb.mapping.spi.LifecycleCallback;
import org.hibernate.boot.jaxb.mapping.spi.LifecycleCallbackContainer;
import org.hibernate.boot.jaxb.mapping.spi.PersistentAttribute;
/**
* Reproduces what we used to do with a {@code List} in {@link JPAXMLOverriddenAnnotationReader},
* with the following constraints:
*
* - Preserve type safety
* - Only create lists if we actually have elements (most lists should be empty in most cases)
*
*/
public final class PropertyMappingElementCollector {
public static final Function PERSISTENT_ATTRIBUTE_NAME = PersistentAttribute::getName;
public static final Function JAXB_TRANSIENT_NAME = JaxbTransient::getName;
static final Function LIFECYCLE_CALLBACK_NAME = LifecycleCallback::getMethodName;
private final String propertyName;
private List id;
private List embeddedId;
private List basic;
private List version;
private List manyToOne;
private List oneToMany;
private List oneToOne;
private List manyToMany;
private List elementCollection;
private List embedded;
private List _transient;
private List prePersist;
private List postPersist;
private List preRemove;
private List postRemove;
private List preUpdate;
private List postUpdate;
private List postLoad;
public PropertyMappingElementCollector(String propertyName) {
this.propertyName = propertyName;
}
public boolean isEmpty() {
return allNullOrEmpty( id, embeddedId, basic, version, manyToOne, oneToMany, oneToOne, manyToMany,
elementCollection, embedded, _transient,
prePersist, postPersist, preRemove, postRemove, preUpdate, postUpdate, postLoad );
}
private boolean allNullOrEmpty(List... lists) {
for ( List list : lists ) {
if ( list != null && !list.isEmpty() ) {
return false;
}
}
return true;
}
private List defaultToEmpty(List list) {
return list == null ? Collections.emptyList() : list;
}
public void collectPersistentAttributesIfMatching(AttributesContainer container) {
if ( container instanceof JaxbAttributes ) {
JaxbAttributes jaxbAttributes = (JaxbAttributes) container;
id = collectIfMatching( id, jaxbAttributes.getId(), PERSISTENT_ATTRIBUTE_NAME );
embeddedId = collectIfMatching( embeddedId, jaxbAttributes.getEmbeddedId(), PERSISTENT_ATTRIBUTE_NAME );
version = collectIfMatching( version, jaxbAttributes.getVersion(), PERSISTENT_ATTRIBUTE_NAME );
}
basic = collectIfMatching( basic, container.getBasic(), PERSISTENT_ATTRIBUTE_NAME );
manyToOne = collectIfMatching( manyToOne, container.getManyToOne(), PERSISTENT_ATTRIBUTE_NAME );
oneToMany = collectIfMatching( oneToMany, container.getOneToMany(), PERSISTENT_ATTRIBUTE_NAME );
oneToOne = collectIfMatching( oneToOne, container.getOneToOne(), PERSISTENT_ATTRIBUTE_NAME );
manyToMany = collectIfMatching( manyToMany, container.getManyToMany(), PERSISTENT_ATTRIBUTE_NAME );
elementCollection = collectIfMatching( elementCollection, container.getElementCollection(), PERSISTENT_ATTRIBUTE_NAME );
embedded = collectIfMatching( embedded, container.getEmbedded(), PERSISTENT_ATTRIBUTE_NAME );
_transient = collectIfMatching( _transient, container.getTransient(), JAXB_TRANSIENT_NAME );
}
public void collectLifecycleCallbacksIfMatching(LifecycleCallbackContainer container) {
prePersist = collectIfMatching( prePersist, container.getPrePersist(), LIFECYCLE_CALLBACK_NAME );
postPersist = collectIfMatching( postPersist, container.getPostPersist(), LIFECYCLE_CALLBACK_NAME );
preRemove = collectIfMatching( preRemove, container.getPreRemove(), LIFECYCLE_CALLBACK_NAME );
postRemove = collectIfMatching( postRemove, container.getPostRemove(), LIFECYCLE_CALLBACK_NAME );
preUpdate = collectIfMatching( preUpdate, container.getPreUpdate(), LIFECYCLE_CALLBACK_NAME );
postUpdate = collectIfMatching( postUpdate, container.getPostUpdate(), LIFECYCLE_CALLBACK_NAME );
postLoad = collectIfMatching( postLoad, container.getPostLoad(), LIFECYCLE_CALLBACK_NAME );
}
private List collectIfMatching(List collected, List candidates,
Function nameGetter) {
List result = collected;
for ( T candidate : candidates ) {
result = collectIfMatching( result, candidate, nameGetter );
}
return result;
}
private List collectIfMatching(List collected, T candidate, Function nameGetter) {
List result = collected;
if ( candidate != null && propertyName.equals( nameGetter.apply( candidate ) ) ) {
if ( result == null ) {
result = new ArrayList<>();
}
result.add( candidate );
}
return result;
}
public List getId() {
return defaultToEmpty( id );
}
public List getEmbeddedId() {
return defaultToEmpty( embeddedId );
}
public List getBasic() {
return defaultToEmpty( basic );
}
public List getVersion() {
return defaultToEmpty( version );
}
public List getManyToOne() {
return defaultToEmpty( manyToOne );
}
public List getOneToMany() {
return defaultToEmpty( oneToMany );
}
public List getOneToOne() {
return defaultToEmpty( oneToOne );
}
public List getManyToMany() {
return defaultToEmpty( manyToMany );
}
public List getElementCollection() {
return defaultToEmpty( elementCollection );
}
public List getEmbedded() {
return defaultToEmpty( embedded );
}
public List getTransient() {
return defaultToEmpty( _transient );
}
public List getPrePersist() {
return defaultToEmpty( prePersist );
}
public List getPostPersist() {
return defaultToEmpty( postPersist );
}
public List getPreRemove() {
return defaultToEmpty( preRemove );
}
public List getPostRemove() {
return defaultToEmpty( postRemove );
}
public List getPreUpdate() {
return defaultToEmpty( preUpdate );
}
public List getPostUpdate() {
return defaultToEmpty( postUpdate );
}
public List getPostLoad() {
return defaultToEmpty( postLoad );
}
}