From b0ea4aa5e0b6130432f80d60ae3a09f4594a08bf Mon Sep 17 00:00:00 2001 From: lidongy <1879087903@qq.com> Date: Tue, 28 Mar 2023 11:45:45 +0800 Subject: [PATCH 1/4] =?UTF-8?q?REPORT-90336=E3=80=90=E6=9D=A5=E6=BA=90?= =?UTF-8?q?=E5=86=85=E6=B5=8BBUG=E3=80=91=E5=B9=B3=E5=8F=B0=E5=B7=A6?= =?UTF-8?q?=E4=BE=A7=E7=9B=AE=E5=BD=95=E6=90=9C=E7=B4=A2=E5=BE=88=E6=85=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boot/internal/SessionFactoryBuilderImpl.java | 12 ++++++++++++ .../boot/internal/SessionFactoryOptionsImpl.java | 9 +++++++++ .../boot/internal/SessionFactoryOptionsState.java | 2 ++ .../spi/AbstractDelegatingSessionFactoryOptions.java | 5 +++++ .../hibernate/boot/spi/SessionFactoryOptions.java | 2 ++ .../third/org/hibernate/cfg/AvailableSettings.java | 11 +++++++++++ .../hql/internal/ast/QueryTranslatorImpl.java | 2 +- .../hql/internal/ast/tree/JavaConstantNode.java | 2 +- .../hql/internal/ast/util/LiteralProcessor.java | 2 +- .../hibernate/hql/internal/classic/WhereParser.java | 2 +- .../org/hibernate/internal/util/ReflectHelper.java | 12 +++++++++++- 11 files changed, 56 insertions(+), 5 deletions(-) diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java index 57a874a82..57a755ef9 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java @@ -483,6 +483,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement private Map querySubstitutions; private boolean strictJpaQueryLanguageCompliance; private boolean namedQueryStartupCheckingEnabled; + private boolean conventionalJavaConstants; private final boolean procedureParameterNullPassingEnabled; private final boolean collectionJoinSubqueryRewriteEnabled; @@ -600,6 +601,8 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement this.querySubstitutions = ConfigurationHelper.toMap( QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", configurationSettings ); this.strictJpaQueryLanguageCompliance = cfgService.getSetting( JPAQL_STRICT_COMPLIANCE, BOOLEAN, false ); this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true ); + this.conventionalJavaConstants = cfgService.getSetting( + CONVENTIONAL_JAVA_CONSTANTS, BOOLEAN, true ); this.procedureParameterNullPassingEnabled = cfgService.getSetting( PROCEDURE_NULL_PARAM_PASSING, BOOLEAN, false ); this.collectionJoinSubqueryRewriteEnabled = cfgService.getSetting( COLLECTION_JOIN_SUBQUERY, BOOLEAN, true ); @@ -851,6 +854,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement return namedQueryStartupCheckingEnabled; } + @Override + public boolean isConventionalJavaConstants() { + return conventionalJavaConstants; + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return procedureParameterNullPassingEnabled; @@ -1132,6 +1140,10 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement return options.isNamedQueryStartupCheckingEnabled(); } + @Override + public boolean isConventionalJavaConstants() { + return options.isConventionalJavaConstants(); + } @Override public boolean isProcedureParameterNullPassingEnabled() { return options.isProcedureParameterNullPassingEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java index ffaa7a149..f925b5cba 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsImpl.java @@ -88,6 +88,9 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { private final Map querySubstitutions; private final boolean strictJpaQueryLanguageCompliance; private final boolean namedQueryStartupCheckingEnabled; + + private final boolean conventionalJavaConstants; + private final boolean procedureParameterNullPassingEnabled; private final boolean collectionJoinSubqueryRewriteEnabled; @@ -160,6 +163,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { this.querySubstitutions = state.getQuerySubstitutions(); this.strictJpaQueryLanguageCompliance = state.isStrictJpaQueryLanguageCompliance(); this.namedQueryStartupCheckingEnabled = state.isNamedQueryStartupCheckingEnabled(); + this.conventionalJavaConstants = state.isConventionalJavaConstants(); this.procedureParameterNullPassingEnabled = state.isProcedureParameterNullPassingEnabled(); this.collectionJoinSubqueryRewriteEnabled = state.isCollectionJoinSubqueryRewriteEnabled(); @@ -339,6 +343,11 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions { return namedQueryStartupCheckingEnabled; } + @Override + public boolean isConventionalJavaConstants() { + return conventionalJavaConstants; + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return procedureParameterNullPassingEnabled; diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java index c73f94f8b..8835f3453 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/internal/SessionFactoryOptionsState.java @@ -98,6 +98,8 @@ public interface SessionFactoryOptionsState { boolean isNamedQueryStartupCheckingEnabled(); + boolean isConventionalJavaConstants(); + boolean isProcedureParameterNullPassingEnabled(); boolean isCollectionJoinSubqueryRewriteEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java index 3e8a7f603..97d723488 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java @@ -198,6 +198,11 @@ public abstract class AbstractDelegatingSessionFactoryOptions implements Session return delegate.isNamedQueryStartupCheckingEnabled(); } + @Override + public boolean isConventionalJavaConstants() { + return delegate.isConventionalJavaConstants(); + } + @Override public boolean isProcedureParameterNullPassingEnabled() { return delegate.isProcedureParameterNullPassingEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java index 7872aacb7..6c8972464 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/boot/spi/SessionFactoryOptions.java @@ -122,6 +122,8 @@ public interface SessionFactoryOptions { boolean isNamedQueryStartupCheckingEnabled(); + boolean isConventionalJavaConstants(); + boolean isSecondLevelCacheEnabled(); boolean isQueryCacheEnabled(); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java index 0ac6a9122..80541d2f1 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/cfg/AvailableSettings.java @@ -564,6 +564,17 @@ public interface AvailableSettings { */ String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check"; + /** + * Setting which indicates whether or not Java constant follow the Java Naming conventions. + *
+ * Default is {@code true}. Existing applications may want to disable this (set it {@code false}) if non-conventional Java constants are used. + * However, there is a significant performance overhead for using non-conventional Java constants since Hibernate cannot determine if aliases + * should be treated as Java constants or not. + * + * @since 5.2 + */ + String CONVENTIONAL_JAVA_CONSTANTS = "hibernate.query.conventional_java_constants"; + /** * The {@link com.fr.third.org.hibernate.exception.spi.SQLExceptionConverter} to use for converting SQLExceptions * to Hibernate's JDBCException hierarchy. The default is to use the configured diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java index e7968fcca..ab9c923a8 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java @@ -612,7 +612,7 @@ public class QueryTranslatorImpl implements FilterTranslator { } private void handleDotStructure(AST dotStructureRoot) { final String expression = ASTUtil.getPathText( dotStructureRoot ); - final Object constant = ReflectHelper.getConstantValue( expression, factory.getServiceRegistry().getService( ClassLoaderService.class ) ); + final Object constant = ReflectHelper.getConstantValue( expression, factory ); if ( constant != null ) { dotStructureRoot.setFirstChild( null ); dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT ); diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java index 2f77663fd..5a678968e 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/tree/JavaConstantNode.java @@ -39,7 +39,7 @@ public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, Ses // this method to get called twice. The first time with an empty string if ( StringHelper.isNotEmpty( s ) ) { constantExpression = s; - constantValue = ReflectHelper.getConstantValue( s, factory.getServiceRegistry().getService( ClassLoaderService.class ) ); + constantValue = ReflectHelper.getConstantValue( s, factory ); heuristicType = factory.getTypeResolver().heuristicType( constantValue.getClass().getName() ); super.setText( s ); } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java index c414c847f..6fb54838d 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/ast/util/LiteralProcessor.java @@ -107,7 +107,7 @@ public class LiteralProcessor implements HqlSqlTokenTypes { setSQLValue( node, text, discrim ); } else { - Object value = ReflectHelper.getConstantValue( text, walker.getSessionFactoryHelper().getFactory().getServiceRegistry().getService( ClassLoaderService.class ) ); + Object value = ReflectHelper.getConstantValue( text, walker.getSessionFactoryHelper().getFactory() ); if ( value == null ) { throw new InvalidPathException( "Invalid path: '" + text + "'" ); } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java index 618950829..7f22b82ee 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/hql/internal/classic/WhereParser.java @@ -419,7 +419,7 @@ public class WhereParser implements Parser { Object constant; if ( token.indexOf( '.' ) > -1 && - ( constant = ReflectHelper.getConstantValue( token, q.getFactory().getServiceRegistry().getService( ClassLoaderService.class ) ) ) != null + ( constant = ReflectHelper.getConstantValue( token, q.getFactory() ) ) != null ) { Type type; try { diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java index bb9d5aa3a..819fc0358 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/internal/util/ReflectHelper.java @@ -13,12 +13,14 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Locale; +import java.util.regex.Pattern; import com.fr.third.org.hibernate.AssertionFailure; import com.fr.third.org.hibernate.MappingException; import com.fr.third.org.hibernate.PropertyNotFoundException; import com.fr.third.org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import com.fr.third.org.hibernate.boot.registry.classloading.spi.ClassLoadingException; +import com.fr.third.org.hibernate.engine.spi.SessionFactoryImplementor; import com.fr.third.org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl; import com.fr.third.org.hibernate.property.access.spi.Getter; import com.fr.third.org.hibernate.type.PrimitiveType; @@ -32,6 +34,8 @@ import com.fr.third.org.hibernate.type.Type; */ @SuppressWarnings("unchecked") public final class ReflectHelper { + private static final Pattern JAVA_CONSTANT_PATTERN = Pattern.compile( + "[a-z\\d]+\\.([A-Z]+[a-z\\d]+)+\\$?([A-Z]{1}[a-z\\d]+)*\\.[A-Z_\\$]+", Pattern.UNICODE_CHARACTER_CLASS); public static final Class[] NO_PARAM_SIGNATURE = new Class[0]; public static final Object[] NO_PARAMS = new Object[0]; @@ -229,9 +233,15 @@ public final class ReflectHelper { return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess( clazz, name ).getGetter(); } - public static Object getConstantValue(String name, ClassLoaderService classLoaderService) { + public static Object getConstantValue(String name, SessionFactoryImplementor factory) { + boolean conventionalJavaConstants = factory.getSessionFactoryOptions().isConventionalJavaConstants(); Class clazz; try { + if ( conventionalJavaConstants && + !JAVA_CONSTANT_PATTERN.matcher( name ).find() ) { + return null; + } + ClassLoaderService classLoaderService = factory.getServiceRegistry().getService( ClassLoaderService.class ); clazz = classLoaderService.classForName( StringHelper.qualifier( name ) ); } catch ( Throwable t ) { From 9e2a9e6fa5be99a343ab17ff86f508c10c8464a6 Mon Sep 17 00:00:00 2001 From: Elijah- * Note that constructor annotations can never be inherited so this just determines - * between inclusion or non-inclusion. - */ - public abstract AnnotationInclusion getInclusionForConstructor(Class extends Annotation> annotationType); - - /** - * Method called to figure out how to handle instances of specified annotation - * type when used as field annotation. - *
- * Note that field annotations can never be inherited so this just determines - * between inclusion or non-inclusion. - */ - public abstract AnnotationInclusion getInclusionForField(Class extends Annotation> annotationType); - - /** - * Method called to figure out how to handle instances of specified annotation - * type when used as method annotation. - *
- * Note that method annotations can be inherited for member methods, but not for static - * methods; for static methods thereby this just determines between inclusion and - * non-inclusion. - */ - public abstract AnnotationInclusion getInclusionForMethod(Class extends Annotation> annotationType); - - /** - * Method called to figure out how to handle instances of specified annotation - * type when used as parameter annotation. - *
- * Note that parameter annotations can be inherited for member methods, but not for static
- * methods; for static methods thereby this just determines between inclusion and
- * non-inclusion.
- */
- public abstract AnnotationInclusion getInclusionForParameter(Class extends Annotation> annotationType);
-
- /**
- * Simple implementation that can be configured with default behavior
- * for unknown annotations, as well as explicit behaviors for
- * enumerated annotation types. Same default is used for both class and
- * member method annotations (constructor, field and static method
- * annotations are never inherited)
- */
- public static class StdConfiguration extends AnnotationConfiguration implements Serializable
- {
- protected final AnnotationInclusion _defaultInclusion;
-
- protected final HashMap
- * Usage is by sub-classing: here is one way to instantiate reference
- * to generic type
- * Note that instances are not thread-safe, as the expectation is that instances
- * will not be shared (unlike raw members or resolved types)
- */
-public class ResolvedTypeWithMembers
-{
- private final static ResolvedType[] NO_RESOLVED_TYPES = new ResolvedType[0];
-
- private final static ResolvedMethod[] NO_RESOLVED_METHODS = new ResolvedMethod[0];
- private final static ResolvedField[] NO_RESOLVED_FIELDS = new ResolvedField[0];
- private final static ResolvedConstructor[] NO_RESOLVED_CONSTRUCTORS = new ResolvedConstructor[0];
-
- /**
- * Default annotation configuration is to ignore all annotations types.
- */
- protected final static AnnotationConfiguration DEFAULT_ANNOTATION_CONFIG
- = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.DONT_INCLUDE);
-
- /**
- * Need to be able to resolve member types still
- */
- protected final TypeResolver _typeResolver;
-
- /**
- * Handler for resolving annotation information
- */
- protected final AnnotationHandler _annotationHandler;
-
- /**
- * Leaf of the type hierarchy, i.e. type from which this hierarchy
- * was generated.
- */
- protected final HierarchicType _mainType;
-
- /**
- * All types that hierarchy contains, in order of increasing precedence
- * (that is, later entries override members of earlier members)
- */
- protected final HierarchicType[] _types;
-
- /**
- * Filter to use for selecting fields to include
- */
- protected Filter
- * Note that resolver instances are stateful in that resolvers cache resolved
- * types for efficiency. Since this is internal state and not directly visible
- * to callers, access to state is fully synchronized so that access from
- * multiple threads is safe.
- */
-@SuppressWarnings("serial")
-public class TypeResolver implements Serializable
-{
- private final static ResolvedType[] NO_TYPES = new ResolvedType[0];
-
- /*
- /**********************************************************************
- /* Pre-created instances
- /**********************************************************************
- */
-
- /**
- * We will also need to return "unknown" type for cases where type variable binding
- * is not found ('raw' instances of generic types); easiest way is to
- * pre-create type for
- * Use of this method is discouraged (use if and only if you really know what you
- * are doing!); but if used, type bindings passed should come from {@link ResolvedType}
- * instance of declaring class (or interface).
- *
- * NOTE: order of arguments was reversed for 0.8, to avoid problems with
- * overload varargs method.
- */
- public ResolvedType resolve(TypeBindings typeBindings, Type jdkType)
- {
- return _fromAny(null, jdkType, typeBindings);
- }
-
- /**
- * Factory method for constructing sub-classing specified type; class specified
- * as sub-class must be compatible according to basic Java inheritance rules
- * (subtype must properly extend or implement specified supertype).
- *
- * A typical use case here is to refine a generic type; for example, given
- * that we have generic type like
- * Note that this method will fail if extension can not succeed; either because
- * this type is not extendable (sub-classable) -- which is true for primitive
- * and array types -- or because given class is not a subtype of this type.
- * To check whether subtyping could succeed, you can call
- * {@link ResolvedType#canCreateSubtypes()} to see if supertype can ever
- * be extended.
- *
- * @param supertype Type to subtype (extend)
- * @param subtype Type-erased sub-class or sub-interface
- *
- * @return Resolved subtype
- *
- * @throws IllegalArgumentException If this type can be extended in general, but not into specified sub-class
- * @throws UnsupportedOperationException If this type can not be sub-classed
- */
- public ResolvedType resolveSubtype(ResolvedType supertype, Class> subtype)
- throws IllegalArgumentException, UnsupportedOperationException
- {
- // first: if it's a recursive reference, find out referred-to type
- ResolvedType refType = supertype.getSelfReferencedType();
- if (refType != null) {
- supertype = refType;
- }
- // Then, trivial check for case where subtype is supertype...
- if (supertype.getErasedType() == subtype) {
- return supertype;
- }
-
- if (!supertype.canCreateSubtypes()) {
- throw new UnsupportedOperationException("Can not subtype primitive or array types (type "+supertype.getFullDescription()+")");
- }
- // In general, must be able to subtype as per JVM rules:
- Class> superclass = supertype.getErasedType();
- if (!superclass.isAssignableFrom(subtype)) {
- throw new IllegalArgumentException("Can not sub-class "+supertype.getBriefDescription()
- +" into "+subtype.getName());
- }
- // Ok, then, let us instantiate type with placeholders
- ResolvedType resolvedSubtype;
- int paramCount = subtype.getTypeParameters().length;
- TypePlaceHolder[] placeholders;
-
- if (paramCount == 0) { // no generics
- placeholders = null;
- resolvedSubtype = resolve(subtype);
- } else {
- placeholders = new TypePlaceHolder[paramCount];
- for (int i = 0; i < paramCount; ++i) {
- placeholders[i] = new TypePlaceHolder(i);
- }
- resolvedSubtype = resolve(subtype, placeholders);
- }
- ResolvedType rawSupertype = resolvedSubtype.findSupertype(superclass);
- if (rawSupertype == null) { // sanity check, should never occur
- throw new IllegalArgumentException("Internal error: unable to locate supertype ("+subtype.getName()+") for type "+supertype.getBriefDescription());
- }
- // Ok, then, let's find and verify type assignments
- _resolveTypePlaceholders(supertype, rawSupertype);
-
- // And then re-construct, if necessary
- if (paramCount == 0) { // if no type parameters, fine as is
- return resolvedSubtype;
- }
- // but with type parameters, need to reconstruct
- ResolvedType[] typeParams = new ResolvedType[paramCount];
- for (int i = 0; i < paramCount; ++i) {
- ResolvedType t = placeholders[i].actualType();
- /* Is it ok for it to be left unassigned? For now let's not
- * allow that
- */
- if (t == null) {
- throw new IllegalArgumentException("Failed to find type parameter #"+(i+1)+"/"
- +paramCount+" for "+subtype.getName());
- }
- typeParams[i] = t;
- }
- return resolve(subtype, typeParams);
- }
-
- /*
- /**********************************************************************
- /* Misc other methods
- /**********************************************************************
- */
-
- /**
- * Helper method that can be used to checked whether given resolved type
- * (with erased type of
- * Most commonly resolution starts with {@link com.fr.third.com.fasterxml.classmate.TypeResolver},
- * using its
- * Since set of primitive types is bounded, constructor is defined as protected,
- * and class final; that is, new primitive types are not to be constructed
- * by calling applications.
- */
-public final class ResolvedPrimitiveType extends ResolvedType
-{
- private final static ResolvedPrimitiveType VOID = new ResolvedPrimitiveType(Void.TYPE, 'V', "void");
-
- /**
- * Primitive types have single-character Signature, easy and efficient
- * to just store here
- */
- protected final String _signature;
-
- /**
- * Human-readable description should be simple as well
- */
- protected final String _description;
-
- /*
- /**********************************************************************
- /* Life cycle
- /**********************************************************************
- */
-
- protected ResolvedPrimitiveType(Class> erased, char sig, String desc)
- {
- super(erased, TypeBindings.emptyBindings());
- _signature = String.valueOf(sig);
- _description = desc;
- }
-
- public static List >(EGA<8Z+>?bQ+{7
z==EcM#w)|&8|~3JjGkqH;h;mQ>uYD!nU~IzEAZkKcX|M<@&r2K)rD}a(^dOM0ABR_
zw29WKVBm|1<(**sL|nlbList<Integer>
:
- *
- * GenericType type = new GenericType<List<Integer>>() { };
- *
- * which can be passed to methods that accept GenericReference
.
- */
-@SuppressWarnings("serial")
-public abstract class GenericTypejava.lang.Object
- * in type hierarchy
- */
- public MemberResolver(TypeResolver typeResolver)
- {
- _typeResolver = typeResolver;
- }
-
- /**
- * Configuration method for specifying whether members of java.lang.Object
- * are to be included in resolution; if false, no members from {@link java.lang.Object}
- * are to be included; if true, will be included.
- */
- public MemberResolver setIncludeLangObject(boolean state) {
- _cfgIncludeLangObject = state;
- return this;
- }
-
- public MemberResolver setFieldFilter(FilterT implements Comparable<T>
).
- * For all other types returns null but for self-references "real" type.
- * Separate accessor is provided to avoid accidental infinite loops.
- */
- public abstract ResolvedType getSelfReferencedType();
-
- /**
- * Method that can be used to access element type of array types; will return
- * null for non-array types, and non-null type for array types.
- */
- public abstract ResolvedType getArrayElementType();
-
- /**
- * Returns ordered list of interfaces (in declaration order) that this type
- * implements.
- *
- * @return List of interfaces this type implements, if any; empty list if none
- */
- public abstract Listjava.lang.Object
- */
- private final static ResolvedObjectType sJavaLangObject =
- ResolvedObjectType.create(Object.class, null, null, null);
-
- /**
- * Since number of primitive types is small, and they are frequently needed,
- * let's actually pre-create them for efficient reuse. Same goes for limited number
- * of other "standard" types...
- */
- protected final static HashMap
- * ResolvedType type = TypeResolver.resolve(List.class, Integer.class);
- *
- * which would be equivalent to
- *
- * ResolvedType type = TypeResolver.resolve(new GenericType<List<Integer>>() { });
- *
- * Note that you can mix different types of type parameters, whether already
- * resolved ({@link ResolvedType}), type-erased ({@link java.lang.Class}) or
- * generic type reference ({@link GenericType}).
- */
- public ResolvedType resolve(Type type, Type... typeParameters)
- {
- boolean noParams = (typeParameters == null || typeParameters.length == 0);
- TypeBindings bindings;
- Class> rawBase;
-
- if (type instanceof Class>) {
- bindings = TypeBindings.emptyBindings();
- if (noParams) {
- return _fromClass(null, (Class>) type, bindings);
- }
- rawBase = (Class>) type;
- } else if (type instanceof GenericType>) {
- bindings = TypeBindings.emptyBindings();
- if (noParams) {
- return _fromGenericType(null, (GenericType>) type, bindings);
- }
- ResolvedType rt = _fromAny(null, type, bindings);
- rawBase = rt.getErasedType();
- } else if (type instanceof ResolvedType) {
- ResolvedType rt = (ResolvedType) type;
- if (noParams) {
- return rt;
- }
- bindings = rt.getTypeBindings();
- rawBase = rt.getErasedType();
- } else {
- bindings = TypeBindings.emptyBindings();
- if (noParams) {
- return resolve(bindings, type);
- }
- // Quite convoluted... but necessary to find Class> underlying it all
- ResolvedType rt = _fromAny(null, type, bindings);
- rawBase = rt.getErasedType();
- }
-
- // Next: resolve type parameters
- int len = typeParameters.length;
- ResolvedType[] resolvedParams = new ResolvedType[len];
- for (int i = 0; i < len; ++i) {
- resolvedParams[i] = _fromAny(null, typeParameters[i], bindings);
- }
- return _fromClass(null, rawBase, TypeBindings.create(rawBase, resolvedParams));
- }
-
- /**
- * Factory method for constructing array type of given element type.
- */
- public ResolvedArrayType arrayType(Type elementType)
- {
- ResolvedType resolvedElementType = resolve(TypeBindings.emptyBindings(), elementType);
- // Arrays are cumbersome for some reason:
- Object emptyArray = Array.newInstance(resolvedElementType.getErasedType(), 0);
- // Should we try to use cache? It's bit tricky, so let's not bother yet
- return new ResolvedArrayType(emptyArray.getClass(), TypeBindings.emptyBindings(),
- resolvedElementType);
- }
-
- /**
- * Factory method for resolving specified Java {@link java.lang.reflect.Type}, given
- * {@link TypeBindings} needed to resolve any type variables.
- *List<Integer>
, but we want
- * a more specific implementation type like
- * class ArrayList
but with same parameterization (here just Integer
),
- * we could achieve it by:
- *
- * ResolvedType mapType = typeResolver.resolve(List.class, Integer.class);
- * ResolveType concreteMapType = typeResolver.resolveSubType(mapType, ArrayList.class);
- *
- * (in this case, it would have been simpler to resolve directly; but in some
- * cases we are handled supertype and want to refine it, in which case steps
- * would be the same but separated by other code)
- *java.lang.Object
) is a placeholder
- * for "self-reference"; these are nasty recursive ("self") types
- * needed with some interfaces
- */
- public static boolean isSelfReference(ResolvedType type)
- {
- return (type instanceof ResolvedRecursiveType);
- }
-
- /*
- /**********************************************************************
- /* Internal methods, second-level factory methods
- /**********************************************************************
- */
-
- private ResolvedType _fromAny(ClassStack context, Type mainType, TypeBindings typeBindings)
- {
- if (mainType instanceof Class>) {
- return _fromClass(context, (Class>) mainType, typeBindings);
- }
- if (mainType instanceof ResolvedType) {
- return (ResolvedType) mainType;
- }
- if (mainType instanceof ParameterizedType) {
- return _fromParamType(context, (ParameterizedType) mainType, typeBindings);
- }
- if (mainType instanceof GenericType>) {
- return _fromGenericType(context, (GenericType>) mainType, typeBindings);
- }
- if (mainType instanceof GenericArrayType) {
- return _fromArrayType(context, (GenericArrayType) mainType, typeBindings);
- }
- if (mainType instanceof TypeVariable>) {
- return _fromVariable(context, (TypeVariable>) mainType, typeBindings);
- }
- if (mainType instanceof WildcardType) {
- return _fromWildcard(context, (WildcardType) mainType, typeBindings);
- }
- // should never get here...
- throw new IllegalArgumentException("Unrecognized type class: "+mainType.getClass().getName());
- }
-
- private ResolvedType _fromClass(ClassStack context, Class> rawType, TypeBindings typeBindings)
- {
- // First: a primitive type perhaps?
- ResolvedType type = _primitiveTypes.get(new ClassKey(rawType));
- if (type != null) {
- return type;
- }
- // Second: recursive reference?
- if (context == null) {
- context = new ClassStack(rawType);
- } else {
- ClassStack prev = context.find(rawType);
- if (prev != null) {
- // Self-reference: needs special handling, then...
- ResolvedRecursiveType selfRef = new ResolvedRecursiveType(rawType, typeBindings);
- prev.addSelfReference(selfRef);
- return selfRef;
- }
- // no, can just add
- context = context.child(rawType);
- }
-
- // If not, already recently resolved?
- ResolvedType[] typeParameters = typeBindings.typeParameterArray();
- ResolvedTypeCache.Key key = _resolvedTypes.key(rawType, typeParameters);
-
- type = _resolvedTypes.find(key);
- if (type == null) {
- type = _constructType(context, rawType, typeBindings);
- _resolvedTypes.put(key, type);
- }
- context.resolveSelfReferences(type);
- return type;
- }
-
- /**
- * Factory method for resolving given generic type, defined by using sub-class
- * instance of {@link GenericType}
- */
- private ResolvedType _fromGenericType(ClassStack context, GenericType> generic, TypeBindings typeBindings)
- {
- /* To allow multiple levels of inheritance (just in case someone
- * wants to go to town with inheritance of GenericType),
- * we better resolve the whole thing; then dig out
- * type parameterization...
- */
- ResolvedType type = _fromClass(context, generic.getClass(), typeBindings);
- ResolvedType genType = type.findSupertype(GenericType.class);
- if (genType == null) { // sanity check; shouldn't occur
- throw new IllegalArgumentException("Unparameterized GenericType instance ("+generic.getClass().getName()+")");
- }
- TypeBindings b = genType.getTypeBindings();
- ResolvedType[] params = b.typeParameterArray();
- if (params.length == 0) {
- throw new IllegalArgumentException("Unparameterized GenericType instance ("+generic.getClass().getName()+")");
- }
- return params[0];
- }
-
- private ResolvedType _constructType(ClassStack context, Class> rawType, TypeBindings typeBindings)
- {
- // Ok: no easy shortcut, let's figure out type of type...
- if (rawType.isArray()) {
- ResolvedType elementType = _fromAny(context, rawType.getComponentType(), typeBindings);
- return new ResolvedArrayType(rawType, typeBindings, elementType);
- }
- // For other types super interfaces are needed...
- if (rawType.isInterface()) {
- return new ResolvedInterfaceType(rawType, typeBindings,
- _resolveSuperInterfaces(context, rawType, typeBindings));
-
- }
- return new ResolvedObjectType(rawType, typeBindings,
- _resolveSuperClass(context, rawType, typeBindings),
- _resolveSuperInterfaces(context, rawType, typeBindings));
- }
-
- private ResolvedType[] _resolveSuperInterfaces(ClassStack context, Class> rawType, TypeBindings typeBindings)
- {
- Type[] types = rawType.getGenericInterfaces();
- if (types == null || types.length == 0) {
- return NO_TYPES;
- }
- int len = types.length;
- ResolvedType[] resolved = new ResolvedType[len];
- for (int i = 0; i < len; ++i) {
- resolved[i] = _fromAny(context, types[i], typeBindings);
- }
- return resolved;
- }
-
- /**
- * NOTE: return type changed in 1.0.1 from {@link ResolvedObjectType} to
- * {@link ResolvedType}, since it was found that other types may
- * be returned...
- *
- * @return Usually a {@link ResolvedObjectType}, but possibly also
- * {@link ResolvedRecursiveType}
- */
- private ResolvedType _resolveSuperClass(ClassStack context, Class> rawType, TypeBindings typeBindings)
- {
- Type parent = rawType.getGenericSuperclass();
- if (parent == null) {
- return null;
- }
- return _fromAny(context, parent, typeBindings);
- }
-
- private ResolvedType _fromParamType(ClassStack context, ParameterizedType ptype, TypeBindings parentBindings)
- {
- /* First: what is the actual base type? One odd thing is that 'getRawType'
- * returns Type, not Class> as one might expect. But let's assume it is
- * always of type Class: if not, need to add more code to resolve it...
- */
- Class> rawType = (Class>) ptype.getRawType();
- Type[] params = ptype.getActualTypeArguments();
- int len = params.length;
- ResolvedType[] types = new ResolvedType[len];
-
- for (int i = 0; i < len; ++i) {
- types[i] = _fromAny(context, params[i], parentBindings);
- }
- // Ok: this gives us current bindings for this type:
- TypeBindings newBindings = TypeBindings.create(rawType, types);
- return _fromClass(context, rawType, newBindings);
- }
-
- private ResolvedType _fromArrayType(ClassStack context, GenericArrayType arrayType, TypeBindings typeBindings)
- {
- ResolvedType elementType = _fromAny(context, arrayType.getGenericComponentType(), typeBindings);
- // Figuring out raw class for generic array is actually bit tricky...
- Object emptyArray = Array.newInstance(elementType.getErasedType(), 0);
- return new ResolvedArrayType(emptyArray.getClass(), typeBindings, elementType);
- }
-
- private ResolvedType _fromWildcard(ClassStack context, WildcardType wildType, TypeBindings typeBindings)
- {
- /* Similar to challenges with TypeVariable, we may have multiple upper bounds.
- * But it is also possible that if upper bound defaults to Object, we might want to
- * consider lower bounds instead?
- * For now, we won't try anything more advanced; above is just for future reference.
- */
- return _fromAny(context, wildType.getUpperBounds()[0], typeBindings);
- }
-
- private ResolvedType _fromVariable(ClassStack context, TypeVariable> variable, TypeBindings typeBindings)
- {
- // ideally should find it via bindings:
- String name = variable.getName();
- ResolvedType type = typeBindings.findBoundType(name);
-
- if (type != null) {
- return type;
- }
-
- /* but if not, use bounds... note that approach here is simplistic; not taking
- * into account possible multiple bounds, nor consider upper bounds.
- */
- /* 02-Mar-2011, tatu: As per issue#4, need to avoid self-reference cycles here;
- * can be handled by (temporarily) adding binding:
- */
- if (typeBindings.hasUnbound(name)) {
- return sJavaLangObject;
- }
- typeBindings = typeBindings.withUnboundVariable(name);
-
- Type[] bounds = variable.getBounds();
- return _fromAny(context, bounds[0], typeBindings);
- }
-
- /*
- /**********************************************************************
- /* Internal methods, replacing and verifying type placeholders
- /**********************************************************************
- */
-
- /**
- * Method called to verify that types match; and if there are
- */
- private void _resolveTypePlaceholders(ResolvedType expectedType, ResolvedType actualType)
- throws IllegalArgumentException
- {
- Listresolve()
method, which returns a
- * {@link com.fr.third.com.fasterxml.classmate.ResolvedType} instance.
- * These type objects contain all necessary information about type itself;
- * but if type information on members (fields, methods, constructors, static
- * members) is needed, {@link com.fr.third.com.fasterxml.classmate.MemberResolver} can
- * resolve types for members: it takes {@link com.fr.third.com.fasterxml.classmate.ResolvedType}s.
- */
-package com.fr.third.com.fasterxml.classmate;
diff --git a/fine-classmate/src/main/java/com/fr/third/com/fasterxml/classmate/types/ResolvedArrayType.java b/fine-classmate/src/main/java/com/fr/third/com/fasterxml/classmate/types/ResolvedArrayType.java
deleted file mode 100644
index 099f9d2c3..000000000
--- a/fine-classmate/src/main/java/com/fr/third/com/fasterxml/classmate/types/ResolvedArrayType.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.fr.third.com.fasterxml.classmate.types;
-
-import java.util.*;
-
-import com.fr.third.com.fasterxml.classmate.ResolvedType;
-import com.fr.third.com.fasterxml.classmate.TypeBindings;
-
-public final class ResolvedArrayType extends ResolvedType
-{
- protected final ResolvedType _elementType;
-
- /*
- /**********************************************************************
- /* Life cycle
- /**********************************************************************
- */
-
- public ResolvedArrayType(Class> erased, TypeBindings bindings,
- ResolvedType elementType)
- {
- super(erased, bindings);
- _elementType = elementType;
- }
-
- @Override
- public boolean canCreateSubtypes() {
- return false;
- }
-
- /*
- /**********************************************************************
- /* Accessors for related types
- /**********************************************************************
- */
-
- @Override
- public ResolvedType getParentClass() { return null; }
-
- @Override
- public ResolvedType getSelfReferencedType() { return null; }
-
- @Override
- public List
#X;i1b5lCxH&d90S-xO_@1AT#+v3D2=V33?`3psuF|*
zqO7t3w(tfQ2GcbG3|h-FW5tA#Y^l@=1=rrs#64Z~>+o?5N6bomz7qG5xga>UHQw~7*2M^b3r-n7B@&XM^-4yvi
z9$>F5#AB-4pgU+{A)i0l795e`Q>#O=YPS}e3&W?9C}F&dCrsrspj7JNEXVGHmN1bH
z*Jgt=Z}pH9HzB|zbp!vh6P)v>qK65-D0y$wZf?+HwAu;=77t^uGm)MOa{w}mMasd-
z3*AL0lVSCjGG_w)aPVNULoW1A(||T7k+5Rc6C+iwreH0?EVCAB-P4tXSgF4n0sg22
zrNq;fh*+9GI{~^WDH^GdMgeK!x-NA=y#be5wQrTNr}jW3-H6jDK$n>}%&BTAPZMph
zXr3>1kgf3|L3YCg+;rSQM!s&gj9yOZjPgB!mCp5=`kNBj)WLUcU|Tp=Bn#~<$%+uW
zk7!CIP}!zm@KYdU*o6D~ZNDa>ntVbl5JX^0SqGl*Psv_+j^NG;sR%BR