Pattern.java
/*******************************************************************************
* Copyright (c) 2025 Carsten Hammer.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Carsten Hammer - initial API and implementation
*******************************************************************************/
package org.sandbox.jdt.triggerpattern.api;
import java.util.Objects;
/**
* Represents a pattern for matching Java code snippets.
*
* <p>A pattern consists of:</p>
* <ul>
* <li>A pattern string with placeholders (e.g., {@code "$x + 1"})</li>
* <li>A {@link PatternKind} indicating whether it's an expression or statement</li>
* <li>Optional metadata (id, display name)</li>
* </ul>
*
* <p>Placeholders are identified by a {@code $} prefix (e.g., {@code $x}, {@code $var}, {@code $cond}).
* When a pattern matches, placeholders are bound to actual AST nodes from the matched code.</p>
*
* @since 1.2.2
*/
public final class Pattern {
private final String value;
private final PatternKind kind;
private final String id;
private final String displayName;
private final String qualifiedType;
/**
* Creates a new pattern with the specified value and kind.
*
* @param value the pattern string with placeholders (e.g., {@code "$x + 1"})
* @param kind the kind of pattern (EXPRESSION or STATEMENT)
*/
public Pattern(String value, PatternKind kind) {
this(value, kind, null, null, null);
}
/**
* Creates a new pattern with the specified value, kind, id, and display name.
*
* @param value the pattern string with placeholders
* @param kind the kind of pattern (EXPRESSION or STATEMENT)
* @param id optional unique identifier for the pattern
* @param displayName optional human-readable name for the pattern
*/
public Pattern(String value, PatternKind kind, String id, String displayName) {
this(value, kind, id, displayName, null);
}
/**
* Creates a new pattern with the specified value, kind, id, display name, and qualified type.
*
* @param value the pattern string with placeholders
* @param kind the kind of pattern
* @param id optional unique identifier for the pattern
* @param displayName optional human-readable name for the pattern
* @param qualifiedType optional qualified type name (e.g., "org.junit.Before" for annotation patterns)
* @since 1.2.3
*/
public Pattern(String value, PatternKind kind, String id, String displayName, String qualifiedType) {
this.value = Objects.requireNonNull(value, "Pattern value cannot be null"); //$NON-NLS-1$
this.kind = Objects.requireNonNull(kind, "Pattern kind cannot be null"); //$NON-NLS-1$
this.id = id;
this.displayName = displayName;
this.qualifiedType = qualifiedType;
}
/**
* Creates a new pattern with the specified value, kind, and qualified type.
*
* @param value the pattern string with placeholders
* @param kind the kind of pattern
* @param qualifiedType qualified type name (e.g., "org.junit.Before")
* @since 1.2.3
*/
public Pattern(String value, PatternKind kind, String qualifiedType) {
this(value, kind, null, null, qualifiedType);
}
/**
* Returns the pattern string.
*
* @return the pattern string with placeholders
*/
public String getValue() {
return value;
}
/**
* Returns the pattern kind.
*
* @return the kind (EXPRESSION or STATEMENT)
*/
public PatternKind getKind() {
return kind;
}
/**
* Returns the optional pattern ID.
*
* @return the pattern ID or {@code null} if not set
*/
public String getId() {
return id;
}
/**
* Returns the optional display name.
*
* @return the display name or {@code null} if not set
*/
public String getDisplayName() {
return displayName;
}
/**
* Returns the optional qualified type.
*
* @return the qualified type name or {@code null} if not set
* @since 1.2.3
*/
public String getQualifiedType() {
return qualifiedType;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Pattern other = (Pattern) obj;
return Objects.equals(value, other.value)
&& kind == other.kind
&& Objects.equals(id, other.id)
&& Objects.equals(qualifiedType, other.qualifiedType);
}
@Override
public int hashCode() {
return Objects.hash(value, kind, id, qualifiedType);
}
@Override
public String toString() {
return "Pattern[kind=" + kind + ", value=" + value + ", id=" + id //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ (qualifiedType != null ? ", qualifiedType=" + qualifiedType : "") + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}