Skip to content
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 @@ -24,34 +24,79 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation used to mark fields that represent configuration properties.
* This annotation provides metadata about how the configuration property
* should be handled, including its source, type, default value, and whether it's read-only.
*
* @since 4.0.0
*/
@Experimental
@Documented
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface Config {

/**
* Specifies the source of the configuration property, which determines when and where the property
* will be read from or set for consumption in the Maven build lifecycle.
*
* The source indicates whether the property is:
* - Set by Maven itself at startup (SYSTEM_PROPERTIES)
* - Configured by users through external means like CLI options (USER_PROPERTIES)
* - Defined in the project's POM file (MODEL)
*
* @return the source of the configuration property, defaults to USER_PROPERTIES
* @see Source for detailed information about each source type and when it's used
*/
Source source() default Source.USER_PROPERTIES;

/**
* Specifies the type of the configuration property.
*
* @return the fully qualified class name of the property type, defaults to "java.lang.String"
*/
String type() default "java.lang.String";

/**
* Specifies the default value of the configuration property.
*
* @return the default value as a string, defaults to empty string
*/
String defaultValue() default "";

/**
* Specifies whether the configuration property is read-only.
*
* @return true if the property is read-only, false otherwise
*/
boolean readOnly() default false;

/**
* Property source.
* Property source, which determines when and where the property will be read from or set for consumption.
* The source indicates the timing of property evaluation in the Maven build lifecycle and the location
* where the property value is defined.
*/
enum Source {
/**
* Maven system properties.
* Maven system properties. These properties are evaluated very early during the boot process,
* typically set by Maven itself and flagged as readOnly=true. System properties are initialized
* before the build starts and are available throughout the entire Maven execution. They are used
* for core Maven functionality that needs to be established at startup.
*/
SYSTEM_PROPERTIES,
/**
* Maven user properties.
* Maven user properties. These are properties that users configure through various means such as
* maven.properties files, maven.config files, command line parameters (-D flags), settings.xml,
* or environment variables. They are evaluated during the build process and represent the primary
* way for users to customize Maven's behavior at runtime.
*/
USER_PROPERTIES,
/**
* Project properties.
* Project model properties. These properties are defined in the project's POM file (pom.xml) and
* are read from the project model during the build. They represent build-time configuration that
* is specific to the project and is stored with the project definition itself rather than in
* external configuration.
*/
MODEL
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,69 @@
import java.util.Objects;
import java.util.Set;

/**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but I wonder if we should have a different name here to avoid confusion with Java enums, which these aren't

* Utility class for creating extensible enum implementations.
* This class provides factory methods for creating instances of extensible enums
* such as Language, PathScope, and ProjectScope.
*
* @since 4.0.0
*/
abstract class ExtensibleEnums {

/**
* Creates a new Language instance with the specified ID.
*
* @param id the identifier for the language
* @return a new Language instance
*/
static Language language(String id) {
return new DefaultLanguage(id);
}

/**
* Creates a new PathScope instance with the specified ID, project scope, and dependency scopes.
*
* @param id the identifier for the path scope
* @param projectScope the project scope associated with this path scope
* @param dependencyScopes the dependency scopes associated with this path scope
* @return a new PathScope instance
*/
static PathScope pathScope(String id, ProjectScope projectScope, DependencyScope... dependencyScopes) {
return new DefaultPathScope(id, projectScope, dependencyScopes);
}

/**
* Creates a new ProjectScope instance with the specified ID.
*
* @param id the identifier for the project scope
* @return a new ProjectScope instance
*/
static ProjectScope projectScope(String id) {
return new DefaultProjectScope(id);
}

/**
* Base implementation of the ExtensibleEnum interface.
* Provides common functionality for all extensible enum implementations.
*/
private static class DefaultExtensibleEnum implements ExtensibleEnum {

private final String id;

/**
* Creates a new DefaultExtensibleEnum with the specified ID.
*
* @param id the identifier for this enum value, must not be null
*/
DefaultExtensibleEnum(String id) {
this.id = Objects.requireNonNull(id);
}

/**
* Returns the identifier for this enum value.
*
* @return the identifier
*/
public String id() {
return id;
}
Expand All @@ -66,37 +107,73 @@ public String toString() {
}
}

/**
* Implementation of the PathScope interface.
*/
private static class DefaultPathScope extends DefaultExtensibleEnum implements PathScope {
private final ProjectScope projectScope;
private final Set<DependencyScope> dependencyScopes;

/**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again not for this PR, but why is this all in one class? It feels like these should be split out to different classes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole class is package protected and the classes are even private. Ideally they'd be refactored as records. And they'd become a one line record definition (we may need the toString though).
Having them top-level classes make them more visible (not in the java sense), and I don't think they need to be.

* Creates a new DefaultPathScope with the specified ID, project scope, and dependency scopes.
*
* @param id the identifier for this path scope
* @param projectScope the project scope associated with this path scope, must not be null
* @param dependencyScopes the dependency scopes associated with this path scope, must not be null
*/
DefaultPathScope(String id, ProjectScope projectScope, DependencyScope... dependencyScopes) {
super(id);
this.projectScope = Objects.requireNonNull(projectScope);
this.dependencyScopes =
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Objects.requireNonNull(dependencyScopes))));
}

/**
* Returns the project scope associated with this path scope.
*
* @return the project scope
*/
@Override
public ProjectScope projectScope() {
return projectScope;
}

/**
* Returns the dependency scopes associated with this path scope.
*
* @return an unmodifiable set of dependency scopes
*/
@Override
public Set<DependencyScope> dependencyScopes() {
return dependencyScopes;
}
}

/**
* Implementation of the ProjectScope interface.
*/
private static class DefaultProjectScope extends DefaultExtensibleEnum implements ProjectScope {

/**
* Creates a new DefaultProjectScope with the specified ID.
*
* @param id the identifier for this project scope
*/
DefaultProjectScope(String id) {
super(id);
}
}

/**
* Implementation of the Language interface.
*/
private static class DefaultLanguage extends DefaultExtensibleEnum implements Language {

/**
* Creates a new DefaultLanguage with the specified ID.
*
* @param id the identifier for this language
*/
DefaultLanguage(String id) {
super(id);
}
Expand Down
Loading