Skip to content
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

Cleanup Types interface / add Type.ofClass(String) #513

Merged
merged 3 commits into from
Aug 11, 2021
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface AnnotationBuilder {
* @return a new {@code AnnotationBuilder}, never {@code null}
*/
static AnnotationBuilder of(Class<? extends Annotation> annotationType) {
return AnnotationBuilderFactoryResolver.get().create(annotationType);
return BuildServicesResolver.get().annotationBuilderFactory().create(annotationType);
}

/**
Expand All @@ -36,7 +36,7 @@ static AnnotationBuilder of(Class<? extends Annotation> annotationType) {
* @return a new {@code AnnotationBuilder}
*/
static AnnotationBuilder of(ClassInfo annotationType) {
return AnnotationBuilderFactoryResolver.get().create(annotationType);
return BuildServicesResolver.get().annotationBuilderFactory().create(annotationType);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package jakarta.enterprise.inject.build.compatible.spi;

import jakarta.enterprise.inject.spi.Prioritized;
import jakarta.enterprise.lang.model.declarations.ClassInfo;

import java.lang.annotation.Annotation;
Expand All @@ -9,7 +8,7 @@
* Service provider interface that supports creating {@link AnnotationBuilder}.
* Should not be called directly by users; the static methods on {@link AnnotationBuilder} are preferred.
*/
public interface AnnotationBuilderFactory extends Prioritized {
public interface AnnotationBuilderFactory {
/**
* Returns a new {@link AnnotationBuilder} for given annotation type.
*
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package jakarta.enterprise.inject.build.compatible.spi;

import jakarta.enterprise.inject.spi.Prioritized;

/**
* Service facade for various services needed by {@link BuildCompatibleExtension} implementations.
*/
public interface BuildServices extends Prioritized {
/**
* @return The {@link AnnotationBuilderFactory} instance, never {@code null}
*/
AnnotationBuilderFactory annotationBuilderFactory();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package jakarta.enterprise.inject.build.compatible.spi;

import java.util.Collections;
import java.util.Comparator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeSet;

final class BuildServicesResolver {
private static final Object lock = new Object();
private static volatile Set<BuildServices> discoveredBuildServices;
private static volatile BuildServices configuredBuildServices;

static BuildServices get() {
if (configuredBuildServices != null) {
return configuredBuildServices;
}

if (discoveredBuildServices == null) {
synchronized (lock) {
if (discoveredBuildServices == null) {
discoverFactories();
}
}
}

configuredBuildServices = discoveredBuildServices.iterator().next();

return configuredBuildServices;
}

private static void discoverFactories() {
Set<BuildServices> factories = new TreeSet<>(
Comparator.comparingInt(BuildServices::getPriority).reversed());

ServiceLoader<BuildServices> loader = SecurityActions.loadService(
BuildServices.class, BuildServicesResolver.class.getClassLoader());

if (!loader.iterator().hasNext()) {
throw new IllegalStateException("Unable to locate AnnotationBuilderFactory implementation");
}

try {
for (BuildServices buildServicies : loader) {
factories.add(buildServicies);
}
} catch (ServiceConfigurationError e) {
throw new IllegalStateException(e);
}

BuildServicesResolver.discoveredBuildServices = Collections.unmodifiableSet(factories);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package jakarta.enterprise.inject.build.compatible.spi;

import jakarta.enterprise.lang.model.declarations.ClassInfo;
import jakarta.enterprise.lang.model.types.ArrayType;
import jakarta.enterprise.lang.model.types.ClassType;
import jakarta.enterprise.lang.model.types.PrimitiveType;
import jakarta.enterprise.lang.model.types.Type;
import jakarta.enterprise.lang.model.types.VoidType;

// TODO move to jakarta.enterprise.lang.model.types? probably not, it doesn't model any part of Java language

/**
* A factory interface for creating instances of {@link Type}.
*/
public interface Types {

/**
* Returns a type from given class literal.
* Returns a type from the given class literal.
*
* For example:
* <ul>
* <li>{@code of(void.class)}: same as {@code ofVoid()}</li>
Expand All @@ -17,37 +26,87 @@ public interface Types {
* <li>{@code of(String[][].class)}: same as {@code ofArray(ofClass(... ClassInfo for String ...), 2)}</li>
* </ul>
*
* @param clazz class literal
* @param clazz class literal, must not be {@code null}
* @return {@link Type} object representing the given class literal
*/
Type of(Class<?> clazz);

Type ofVoid();
/**
* Returns a {@link ClassType type} for the given {@link Class#getName() binary class name}.
*
* <p>Note that only {@link ClassType} instances can be returned from this method, for primitives use {@link #ofPrimitive(PrimitiveType.PrimitiveKind)}.</p>
*
* @param name The binary class name, must not be {@code null}
* @return The {@link ClassType} or {@code null} if the type doesn't exist on the application classpath
*/
ClassType ofClass(String name);

Type ofPrimitive(PrimitiveType.PrimitiveKind kind);
/**
* @return An instance of {@link jakarta.enterprise.lang.model.types.VoidType}, never {@code null}
*/
VoidType ofVoid();

/**
* Returns a {@link PrimitiveType} for the given {@link jakarta.enterprise.lang.model.types.PrimitiveType.PrimitiveKind kind}.
* @param kind The kind, must not be {@code null}
* @return The {@link PrimitiveType}, never {@code null}
*/
PrimitiveType ofPrimitive(PrimitiveType.PrimitiveKind kind);

/**
* Returns a {@link Type} for the given {@link ClassInfo clazz}.
* @param clazz The {@link ClassInfo}, must not be {@code null}
* @return A {@link Type}, never {@code null}
*/
Type ofClass(ClassInfo clazz);

Type ofArray(Type componentType, int dimensions);
/**
* Returns an {@link ArrayType} for the given {@link Type componentType} and dimensions
* @param componentType The component {@link Type}, must not be {@code null}
* @param dimensions The dimensions
* @return The {@link ArrayType}, never {@code null}
*/
ArrayType ofArray(Type componentType, int dimensions);

/**
* Returns a parameterized {@link Type} for the given type and type arguments.
*
* @param parameterizedType The type to parametrize, must not be {@code null}
* @param typeArguments Zero or more type arguments
* @return A potentially parameterized type, never {@code null}
*/
Type parameterized(Class<?> parameterizedType, Class<?>... typeArguments);

/**
* Returns a parameterized {@link Type} for the given type and type arguments.
*
* @param parameterizedType The type to parametrize, must not be {@code null}
* @param typeArguments Zero or more type arguments
* @return A potentially parameterized type, never {@code null}
*/
Type parameterized(Class<?> parameterizedType, Type... typeArguments);

/**
* Returns a parameterized {@link Type} for the given type and type arguments.
*
* @param parameterizedType The type to parametrize, must not be {@code null}
* @param typeArguments Zero or more type arguments
* @return A potentially parameterized type, never {@code null}
*/
Type parameterized(Type parameterizedType, Type... typeArguments);

/**
* Equivalent of {@code ? extends upperBound}.
*
* @param upperBound upper bound type
* @param upperBound upper bound type, must not be {@code null}
* @return {@link Type} object representing a wildcard type with given upper bound
*/
Type wildcardWithUpperBound(Type upperBound);

/**
* Equivalent of {@code ? super lowerBound}.
*
* @param lowerBound lower bound type
* @param lowerBound lower bound type, must not be {@code null}
* @return {@link Type} object representing a wildcard type with given lower bound
*/
Type wildcardWithLowerBound(Type lowerBound);
Expand Down