Skip to content

Commit

Permalink
#59 - Add safe cast methods
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed Apr 12, 2024
1 parent 7492b52 commit 3cf203b
Show file tree
Hide file tree
Showing 25 changed files with 573 additions and 249 deletions.
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ dependencies {
annotationProcessor libs.logging
annotationProcessor libs.loggingAnnotations

testImplementation jakartaLibs.jpa
testImplementation testLibs.junit5Api
testImplementation testLibs.assertjCore
testImplementation platform( libs.hibernatePlatform )
testImplementation libs.hibernateCore

testRuntimeOnly testLibs.junit5Engine
testRuntimeOnly testLibs.log4j
Expand Down
13 changes: 2 additions & 11 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ dependencyResolutionManagement {
def classmateVersion = version "classmate", "1.5.1"
library( "classmate", "com.fasterxml", "classmate" ).versionRef( classmateVersion )

def hcannVersion = version "hcann", "6.0.6.Final"
library( "hcann", "org.hibernate.common", "hibernate-commons-annotations" ).versionRef( hcannVersion )

def hibernateVersion = version "hibernateOrm", "7.0.0-SNAPSHOT"
library( "hibernatePlatform", "org.hibernate.orm", "hibernate-platform" ).versionRef( hibernateVersion )
// withoutVersion assuming that the platform is applied
library( "hibernateCore", "org.hibernate.orm", "hibernate-core" ).withoutVersion()
library( "hibernateTesting", "org.hibernate.orm", "hibernate-testing" ).withoutVersion()

def jacksonVersion = version "jackson", "2.14.1"
library( "jackson", "com.fasterxml.jackson.core", "jackson-databind" ).versionRef( jacksonVersion )
library( "jacksonXml", "com.fasterxml.jackson.dataformat", "jackson-dataformat-xml" ).versionRef( jacksonVersion )
Expand All @@ -71,8 +62,8 @@ dependencyResolutionManagement {
library( "loggingProcessor", "org.jboss.logging", "jboss-logging-processor" ).versionRef( jbossLoggingToolVersion )
}
jakartaLibs {
// withoutVersion to pick up the version used with Hibernate ORM (libs.hibernatePlatform)
library( "jpa", "jakarta.persistence", "jakarta.persistence-api" ).withoutVersion()
def jpaVersion = version "jpa", "3.2.0-B02"
library( "jpa", "jakarta.persistence", "jakarta.persistence-api" ).versionRef( jpaVersion )

def injectVersion = version "inject", "2.0.1"
def jaxbApiVersion = version "jaxbApi", "4.0.0"
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/org/hibernate/models/IllegalCastException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models;

/**
* @author Steve Ebersole
*/
public class IllegalCastException extends ModelsException {
public IllegalCastException(String message) {
super( message );
}

public IllegalCastException(String message, Throwable cause) {
super( message, cause );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails;
import org.hibernate.models.spi.MutableAnnotationTarget;
import org.hibernate.models.spi.MutableClassDetails;

/**
* @author Steve Ebersole
*/
public interface ClassDetailsSupport extends MutableClassDetails, AnnotationTargetSupport, MutableAnnotationTarget {
public interface ClassDetailsSupport extends MutableClassDetails, AnnotationTargetSupport {

@Override
default void forEachField(IndexedConsumer<FieldDetails> consumer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
import java.util.EnumSet;
import java.util.List;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.internal.AnnotationHelper;
import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.AttributeDescriptor;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;

import static org.hibernate.models.internal.jdk.JdkBuilders.extractAttributeDescriptors;
Expand Down Expand Up @@ -81,4 +84,14 @@ public List<AttributeDescriptor<?>> getAttributes() {
public String getName() {
return annotationType.getName();
}

@Override
public MutableClassDetails asClassDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to ClassDetails" );
}

@Override
public MutableMemberDetails asMemberDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to MemberDetails" );
}
}
32 changes: 32 additions & 0 deletions src/main/java/org/hibernate/models/spi/AnnotationDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;
import java.util.function.Consumer;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.UnknownAnnotationAttributeException;
import org.hibernate.models.internal.dynamic.DynamicAnnotationUsage;

Expand Down Expand Up @@ -128,4 +129,35 @@ default MutableAnnotationUsage<A> createUsage(

return usage;
}

@Override
default <X extends Annotation> AnnotationDescriptor<X> asAnnotationDescriptor() {
//noinspection unchecked
return (AnnotationDescriptor<X>) this;
}

@Override
default ClassDetails asClassDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to a ClassDetails" );
}

@Override
default MemberDetails asMemberDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to a MemberDetails" );
}

@Override
default FieldDetails asFieldDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to a FieldDetails" );
}

@Override
default MethodDetails asMethodDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to a MethodDetails" );
}

@Override
default RecordComponentDetails asRecordComponentDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to a RecordComponentDetails" );
}
}
43 changes: 43 additions & 0 deletions src/main/java/org/hibernate/models/spi/AnnotationTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.function.Consumer;

import org.hibernate.models.AnnotationAccessException;
import org.hibernate.models.IllegalCastException;

/**
* Abstract for something where an annotation can be {@linkplain AnnotationUsage used}.
Expand Down Expand Up @@ -283,6 +284,48 @@ default <T, A extends Annotation> T fromAnnotations(
return null;
}

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is an {@linkplain Kind#ANNOTATION annotation}.
*
* @throws IllegalCastException If the target is not an annotation
*/
<A extends Annotation> AnnotationDescriptor<A> asAnnotationDescriptor();

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is a {@linkplain Kind#CLASS class}.
*
* @throws IllegalCastException If the target is not a class
*/
ClassDetails asClassDetails();

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is a {@linkplain Kind#FIELD field}, {@linkplain Kind#METHOD method} or {@linkplain Kind#RECORD_COMPONENT record component}.
*
* @throws IllegalCastException If the target is not a member
*/
MemberDetails asMemberDetails();

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is a {@linkplain Kind#FIELD field}.
*
* @throws IllegalCastException If the target is not a field
*/
FieldDetails asFieldDetails();

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is a {@linkplain Kind#METHOD method}.
*
* @throws IllegalCastException If the target is not a method
*/
MethodDetails asMethodDetails();

/**
* Safe cast method for cases when the {@linkplain #getKind() target} is a {@linkplain Kind#RECORD_COMPONENT record component}.
*
* @throws IllegalCastException If the target is not a record component
*/
RecordComponentDetails asRecordComponentDetails();

/**
* Subset of {@linkplain ElementType annotation targets} supported for mapping annotations
*/
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/org/hibernate/models/spi/ClassDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
*/
package org.hibernate.models.spi;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.function.Predicate;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.internal.SimpleClassDetails;
import org.hibernate.models.internal.util.IndexedConsumer;

Expand Down Expand Up @@ -238,4 +240,34 @@ default RecordComponentDetails findRecordComponentByName(String name) {
* Know what you are doing before calling this method
*/
<X> Class<X> toJavaClass();

@Override
default ClassDetails asClassDetails() {
return this;
}

@Override
default <A extends Annotation> AnnotationDescriptor<A> asAnnotationDescriptor() {
throw new IllegalCastException( "ClassDetails cannot be cast to AnnotationDescriptor" );
}

@Override
default MemberDetails asMemberDetails() {
throw new IllegalCastException( "ClassDetails cannot be cast to MemberDescriptor" );
}

@Override
default FieldDetails asFieldDetails() {
throw new IllegalCastException( "ClassDetails cannot be cast to FieldDetails" );
}

@Override
default MethodDetails asMethodDetails() {
throw new IllegalCastException( "ClassDetails cannot be cast to MethodDetails" );
}

@Override
default RecordComponentDetails asRecordComponentDetails() {
throw new IllegalCastException( "ClassDetails cannot be cast to RecordComponentDetails" );
}
}
16 changes: 16 additions & 0 deletions src/main/java/org/hibernate/models/spi/FieldDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.models.spi;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.internal.ModifierUtils;

/**
Expand All @@ -28,4 +29,19 @@ default String resolveAttributeName() {
default boolean isPersistable() {
return ModifierUtils.hasPersistableFieldModifiers( getModifiers() );
}

@Override
default FieldDetails asFieldDetails() {
return this;
}

@Override
default MethodDetails asMethodDetails() {
throw new IllegalCastException( "FieldDetails cannot be cast to MethodDetails" );
}

@Override
default RecordComponentDetails asRecordComponentDetails() {
throw new IllegalCastException( "FieldDetails cannot be cast to RecordComponentDetails" );
}
}
18 changes: 18 additions & 0 deletions src/main/java/org/hibernate/models/spi/MemberDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
*/
package org.hibernate.models.spi;

import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.util.Collection;
import java.util.Map;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.internal.CollectionElementSwitch;
import org.hibernate.models.internal.MapKeySwitch;
import org.hibernate.models.internal.MapValueSwitch;
Expand Down Expand Up @@ -262,6 +264,22 @@ default ClassBasedTypeDetails resolveRelativeClassType(TypeVariableScope contain
return TypeDetailsHelper.resolveRelativeClassType( getType(), container );
}


@Override
default MemberDetails asMemberDetails() {
return this;
}

@Override
default <A extends Annotation> AnnotationDescriptor<A> asAnnotationDescriptor() {
throw new IllegalCastException( "MemberDetails cannot be cast to an AnnotationDescriptor" );
}

@Override
default ClassDetails asClassDetails() {
throw new IllegalCastException( "MemberDetails cannot be cast to a ClassDetails" );
}

enum Visibility {
PUBLIC,
PROTECTED,
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/hibernate/models/spi/MethodDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.beans.Introspector;
import java.util.List;

import org.hibernate.models.IllegalCastException;

import static org.hibernate.models.internal.ModifierUtils.hasPersistableMethodModifiers;

/**
Expand Down Expand Up @@ -53,4 +55,19 @@ else if ( methodName.startsWith( "get" ) ) {

return null;
}

@Override
default FieldDetails asFieldDetails() {
throw new IllegalCastException( "MethodDetails cannot be cast to FieldDetails" );
}

@Override
default MethodDetails asMethodDetails() {
return this;
}

@Override
default RecordComponentDetails asRecordComponentDetails() {
throw new IllegalCastException( "MethodDetails cannot be cast to RecordComponentDetails" );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@ default <A extends Annotation> MutableAnnotationUsage<A> applyAnnotationUsage(
addAnnotationUsage( usage );
return usage;
}

@Override
MutableClassDetails asClassDetails();

@Override
MutableMemberDetails asMemberDetails();
}
Loading

0 comments on commit 3cf203b

Please sign in to comment.