Skip to content

#78 - Investigate alternative approach to AnnotationUsage using Annotation interface subclassing #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion buildSrc/src/main/groovy/release-process.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ def releasePreparationTask = tasks.register( "releasePreparation" ) {
dependsOn tasks.named( "compile" )

doFirst {
logger.lifecycle "Release version : {}", releaseVersion
logger.lifecycle "Release version : {}", releaseVersion
logger.lifecycle "Development version : {}", developmentVersion
logger.lifecycle " - same version? : {}", releaseVersion == developmentVersion

logger.lifecycle "Switching to branch {}", gitBranch
executeGitCommand('checkout', gitBranch)
Expand All @@ -61,6 +62,7 @@ def changeToReleaseVersionTask = tasks.register( "changeToReleaseVersion" ) {
dependsOn releasePreparationTask
onlyIf {
releasePreparationTask.get().didWork
&& releaseVersion != developmentVersion
}

doFirst {
Expand Down Expand Up @@ -105,6 +107,7 @@ tasks.register( "prepareForRelease" ) {
def tagReleaseTask = tasks.register( "tagRelease" ) {
onlyIf {
changeToReleaseVersionTask.get().didWork
&& releaseVersion != developmentVersion
}

doLast {
Expand All @@ -119,6 +122,11 @@ def changeToDevelopmentVersionTask = tasks.register( 'changeToDevelopmentVersion

dependsOn tagReleaseTask

onlyIf {
changeToReleaseVersionTask.get().didWork
&& releaseVersion != developmentVersion
}

doFirst {
logger.lifecycle( "Updating version-file to development-version : `${developmentVersion}`" )
updateVersionFile( developmentVersion )
Expand All @@ -134,6 +142,11 @@ def changeToDevelopmentVersionTask = tasks.register( 'changeToDevelopmentVersion
def pushToGitTask = tasks.register( 'pushToGit' ) {
dependsOn changeToDevelopmentVersionTask

onlyIf {
changeToReleaseVersionTask.get().didWork
&& releaseVersion != developmentVersion
}

doLast {
def gitRemote = determineGitRemote( project )
logger.lifecycle "Pushing branch and tag to Git : {}", gitRemote
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/hibernate/models/UnhandledMethodException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models;

/**
* Generally indicates an attempt to call an unknown/unhandled method on an annotation
* {@linkplain org.hibernate.models.internal.AnnotationProxy proxy}.
*
* @author Steve Ebersole
*/
public class UnhandledMethodException extends ModelsException {
public UnhandledMethodException(String message) {
super( message );
}

public UnhandledMethodException(String message, Throwable cause) {
super( message, cause );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models.internal;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.EnumSet;

import org.hibernate.models.IllegalCastException;
import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails;
import org.hibernate.models.spi.RecordComponentDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;

/**
* Base support for {@link AnnotationDescriptor} implementations
*
* @author Steve Ebersole
*/
public abstract class AbstractAnnotationDescriptor<A extends Annotation>
extends AbstractAnnotationTarget
implements AnnotationDescriptor<A> {
private final Class<A> annotationType;
private final EnumSet<Kind> allowableTargets;

private final boolean inherited;
private final AnnotationDescriptor<?> repeatableContainer;

public AbstractAnnotationDescriptor(
Class<A> annotationType,
EnumSet<Kind> allowableTargets,
boolean inherited,
AnnotationDescriptor<?> repeatableContainer) {
this.annotationType = annotationType;
this.allowableTargets = allowableTargets;
this.inherited = inherited;
this.repeatableContainer = repeatableContainer;
}

@Override
public Class<A> getAnnotationType() {
return annotationType;
}

@Override
public String getName() {
return annotationType.getName();
}

@Override
public EnumSet<Kind> getAllowableTargets() {
return allowableTargets;
}

@Override
public boolean isInherited() {
return inherited;
}

@Override
public AnnotationDescriptor<?> getRepeatableContainer() {
return repeatableContainer;
}

@Override
public Collection<? extends Annotation> getDirectAnnotationUsages() {
return getUsageMap().values();
}

@Override
public <X extends Annotation> X[] getRepeatedAnnotationUsages(
AnnotationDescriptor<X> type,
SourceModelBuildingContext modelContext) {
return AnnotationUsageHelper.getRepeatedUsages( type, getUsageMap(), modelContext );
}

@Override
public <X extends Annotation> X[] getRepeatedAnnotationUsages(Class<X> type, SourceModelBuildingContext modelContext) {
return getRepeatedAnnotationUsages( modelContext.getAnnotationDescriptorRegistry().getDescriptor( type ), modelContext );
}

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

@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" );
}

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

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

@Override
public RecordComponentDetails asRecordComponentDetails() {
throw new IllegalCastException( "AnnotationDescriptor cannot be cast to RecordComponentDetails" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models.internal;

/**
* @author Steve Ebersole
*/
public abstract class AbstractAnnotationTarget implements AnnotationTargetSupport {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
*/
package org.hibernate.models.internal;

import java.lang.annotation.Annotation;
import java.util.Locale;

import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.internal.jdk.JdkPassThruConverter;
import org.hibernate.models.internal.jdk.JdkPassThruExtractor;
import org.hibernate.models.spi.AttributeDescriptor;
import org.hibernate.models.spi.JdkValueConverter;
import org.hibernate.models.spi.JdkValueExtractor;
import org.hibernate.models.spi.RenderingCollector;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.ValueTypeDescriptor;
import org.hibernate.models.spi.ValueWrapper;

/**
* Base support for {@linkplain AttributeDescriptor} implementations
Expand All @@ -23,33 +26,28 @@
public abstract class AbstractTypeDescriptor<V> implements ValueTypeDescriptor<V> {
@Override
public AttributeDescriptor<V> createAttributeDescriptor(
AnnotationDescriptor<?> annotationDescriptor,
Class<? extends Annotation> annotationType,
String attributeName) {
return new AttributeDescriptorImpl<>( annotationDescriptor.getAnnotationType(), attributeName, this );
return new AttributeDescriptorImpl<>( annotationType, attributeName, this );
}

@Override
public V createValue(
AttributeDescriptor<?> attributeDescriptor,
SourceModelBuildingContext context) {
final Object defaultValue = attributeDescriptor.getAttributeMethod().getDefaultValue();
if ( defaultValue == null ) {
// a non-defaulted attribute, just return null for the baseline
return null;
}
public JdkValueConverter<V> createJdkValueConverter(SourceModelBuildingContext modelContext) {
return JdkPassThruConverter.passThruConverter();
}

//noinspection unchecked
final ValueWrapper<V, Object> valueWrapper = (ValueWrapper<V, Object>) createJdkWrapper( context );
return valueWrapper.wrap( defaultValue, context );
@Override
public JdkValueExtractor<V> createJdkValueExtractor(SourceModelBuildingContext modelContext) {
return JdkPassThruExtractor.passThruExtractor();
}

@Override
public void render(RenderingCollector collector, String name, Object attributeValue) {
public void render(RenderingCollector collector, String name, Object attributeValue, SourceModelBuildingContext modelContext) {
collector.addLine( "%s = %s", name, attributeValue );
}

@Override
public void render(RenderingCollector collector, Object attributeValue) {
public void render(RenderingCollector collector, Object attributeValue, SourceModelBuildingContext modelContext) {
collector.addLine( "%s", attributeValue );
}

Expand All @@ -58,7 +56,7 @@ public String toString() {
return String.format(
Locale.ROOT,
"AttributeTypeDescriptor(%s)",
getWrappedValueType().getName()
getValueType().getName()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models.internal;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.models.spi.AttributeDescriptor;
import org.hibernate.models.spi.ValueTypeDescriptor;

/**
* @author Steve Ebersole
*/
public class AnnotationDescriptorBuilding {

public static <A extends Annotation> List<AttributeDescriptor<?>> extractAttributeDescriptors(Class<A> annotationType) {
final Method[] methods = annotationType.getDeclaredMethods();
final List<AttributeDescriptor<?>> attributeDescriptors = new ArrayList<>( methods.length );
for ( Method method : methods ) {
attributeDescriptors.add( createAttributeDescriptor( annotationType, method ) );
}
return attributeDescriptors;
}

private static <X, A extends Annotation> AttributeDescriptor<X> createAttributeDescriptor(
Class<A> annotationType,
Method method) {
//noinspection unchecked
final Class<X> attributeType = (Class<X>) method.getReturnType();

final ValueTypeDescriptor<X> typeDescriptor = TypeDescriptors.resolveTypeDescriptor( attributeType );
return typeDescriptor.createAttributeDescriptor( annotationType, method.getName() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@

import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.util.Collections;
import java.util.HashMap;

import org.hibernate.models.internal.jdk.AnnotationDescriptorImpl;
import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.AnnotationDescriptorRegistry;

Expand Down Expand Up @@ -70,7 +67,7 @@ private <A extends Annotation> AnnotationDescriptor<A> buildAdHocAnnotationDescr
containerDescriptor = null;
}

final AnnotationDescriptorImpl<A> descriptor = new AnnotationDescriptorImpl<>(
final StandardAnnotationDescriptor<A> descriptor = new StandardAnnotationDescriptor<>(
javaType,
containerDescriptor,
modelBuildingContext
Expand Down
Loading
Loading