Refactor: Migrate matcher implementations to Java records Fixes #1002#1009
Refactor: Migrate matcher implementations to Java records Fixes #1002#1009shubh586 wants to merge 2 commits into
Conversation
5a797b5 to
6bbcca1
Compare
|
@jglick would you please review this pr |
There was a problem hiding this comment.
Pull request overview
This PR refactors credential matcher implementations from boilerplate Java classes into records and adds tests covering matcher behavior and constructors.
Changes:
- Converts matcher classes such as
IdMatcher,ScopeMatcher, and composite matchers to Java records. - Updates
CredentialsMatcherdocumentation to recommend records. - Adds
MatchersTestcoverage for constructors, matching logic, equality, andtoString.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/main/java/com/cloudbees/plugins/credentials/CredentialsMatcher.java |
Updates matcher implementation guidance for records. |
src/main/java/com/cloudbees/plugins/credentials/matchers/AllOfMatcher.java |
Converts all-of matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/AnyOfMatcher.java |
Converts any-of matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/ConstantMatcher.java |
Converts constant matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/IdMatcher.java |
Converts ID matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/InstanceOfMatcher.java |
Converts type matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/NotMatcher.java |
Converts negating matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/ScopeMatcher.java |
Converts scope matcher to a record. |
src/main/java/com/cloudbees/plugins/credentials/matchers/UsernameMatcher.java |
Converts username matcher to a record. |
src/test/java/com/cloudbees/plugins/credentials/matchers/MatchersTest.java |
Adds unit tests for record-based matcher behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public AllOfMatcher(@CheckForNull List<CredentialsMatcher> matchers) { | ||
| this.matchers = new ArrayList<>(matchers == null ? Collections.emptyList() : matchers); | ||
| public AllOfMatcher { | ||
| matchers = matchers == null ? Collections.emptyList() : new ArrayList<>(matchers); |
| this.matchers = new ArrayList<>( | ||
| matchers == null ? Collections.emptyList() : matchers); | ||
| public AnyOfMatcher { | ||
| matchers = matchers == null ? Collections.emptyList() : new ArrayList<>(matchers); |
| @NonNull | ||
| private final Set<CredentialsScope> scopes; | ||
| public ScopeMatcher { | ||
| Objects.requireNonNull(scopes); |
| * For legacy implementations using classes instead of records: | ||
| * <ul> | ||
| * <li>Implement {@link Object#toString()}</li> | ||
| * <li>Implement {@link Object#equals(Object)} and {@link Object#hashCode()}</li> | ||
| * <li>Define a {@code serialVersionUID} field to ensure consistent serialization</li> | ||
| * <li>Implement {@link Object#equals(Object)} and | ||
| * {@link Object#hashCode()}</li> | ||
| * <li>Define a {@code serialVersionUID} field to ensure consistent | ||
| * serialization</li> |
- Convert AllOfMatcher, AnyOfMatcher, ConstantMatcher, IdMatcher, InstanceOfMatcher, NotMatcher, ScopeMatcher, and UsernameMatcher from classes to Java records - Keep serialVersionUID consistent with prior class-based implementation - Use pattern matching instanceof in IdMatcher and UsernameMatcher - Ensure mutable collections (Lists, Sets) in AllOfMatcher, AnyOfMatcher and ScopeMatcher are defensively copied and wrapped as unmodifiable - Retain binary-compatible constructors for ScopeMatcher - Update CredentialsMatcher javadoc to recommend records - Add MatchersTest covering compact constructors, pattern matching branches, and alternative constructors Fixes jenkinsci#1002
6bbcca1 to
0450e6d
Compare
|
@github-copilot review |
| * @since 1.5 | ||
| */ | ||
| public class AllOfMatcher implements CredentialsMatcher { | ||
| public record AllOfMatcher(@NonNull List<CredentialsMatcher> matchers) implements CredentialsMatcher { |
| * @since 1.5 | ||
| */ | ||
| public class AnyOfMatcher implements CredentialsMatcher { | ||
| public record AnyOfMatcher(@NonNull List<CredentialsMatcher> matchers) implements CredentialsMatcher { |
|
@timja will you help me in this?? yes with records, @nonnull on the component propagates to both the accessor and the canonical constructor parameter, so accepting null contradicts the advertised contract. public AllOfMatcher { as no production caller passes null they go through CredentialsMatchers which uses Arrays.asList(). The tests would be updated to assert NullPointerException instead of testing null-tolerance. is this approach good? |
Replace null-tolerant compact constructors with Objects.requireNonNull() to align with the @nonnull annotation on the record component. This makes the API contract consistent — no production caller passes null. Update tests to assert NullPointerException instead of null-tolerance.
Description
Fixes #1002
This PR modernizes the credentials plugin matcher implementations by converting them from traditional classes to Java records (Java 14+).
Changes:
This change aligns with modern Java best practices while preserving backward compatibility for existing Jenkins plugins.
Testing done
mvn compilenew IdMatcher("id")) continues to workSubmitter checklist