16.8.5. DRL のパターン制約でサポートされている演算子
DRL では、パターン制約の演算子で標準の Java セマンティクスがサポートされていますが、いくつかの例外があり、追加となる DRL 固有の演算子もいくつかあります。以下の一覧は、標準の Java セマンティクスとは異なる方法で処理される DRL の制約の演算子や DRL の制約に固有の演算子をまとめています。
.(),#.()演算子を使用すると、プロパティーのアクセサーをネストされたオブジェクトにグループ化でき、#演算子を使用すると、ネストされたオブジェクトのサブタイプにキャストできます。サブタイプにキャストすることで、親タイプの getter をサブタイプに対して使用できるようになります。オブジェクト名または完全修飾クラス名のいずれかを使用でき、1 つまたは複数のサブタイプにキャストできます。ネストされたオブジェクトが使用されるパターンの例
// Ungrouped property accessors: Person( name == "mark", address.city == "london", address.country == "uk" ) // Grouped property accessors: Person( name == "mark", address.( city == "london", country == "uk") )注記ピリオドのプリフィックス
.は、メソッド呼び出しとネストされたオブジェクト制約を区別します。サブタイプへのインラインキャストを使用したパターンの例
// Inline casting with subtype name: Person( name == "mark", address#LongAddress.country == "uk" ) // Inline casting with fully qualified class name: Person( name == "mark", address#org.domain.LongAddress.country == "uk" ) // Multiple inline casts: Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )!.この演算子を使用すると、null 安全な方法でプロパティーを逆参照します。パターンマッチングの適切な結果を得るには、
!.演算子の左側の値を null にすることはできません (!= nullと解釈される)。null 安全な逆参照を使用した制約の例
Person( $streetName : address!.street ) // This is internally rewritten in the following way: Person( address != null, $streetName : address.street )[]この演算子を使用して、インデックスで
List値にアクセスするか、またはキーでMap値にアクセスします。ListおよびMapアクセスを使用する制約の例// The following format is the same as `childList(0).getAge() == 18`: Person(childList[0].age == 18) // The following format is the same as `credentialMap.get("jdoe").isValid()`: Person(credentialMap["jdoe"].valid)<、<=、>、>=これらの演算子は、自然順序付けのあるプロパティーに使用されます。たとえば、
<演算子は、Dateフィールドでは 前 を意味し、Stringフィールドでは アルファベット順で前 であることを意味します。これらのプロパティーは、比較可能なプロパティーにのみ適用されます。before演算子を使用した制約の例Person( birthDate < $otherBirthDate ) Person( firstName < $otherFirstName )==,!=制約では、これらの演算子を、通常の
sameおよびnot sameセマンティクスではなく、equals()および!equals()メソッドとして使用します。null 安全な等価性を使用する制約の例
Person( firstName == "John" ) // This is similar to the following formats: java.util.Objects.equals(person.getFirstName(), "John") "John".equals(person.getFirstName())null 安全な非等価性を使用する制約の例
Person( firstName != "John" ) // This is similar to the following format: !java.util.Objects.equals(person.getFirstName(), "John")&&,||これらの演算子を使用して、フィールドに複数の制約を追加する略記組合せ比較条件を作成します。再帰的な構文パターンを作成するには、括弧
()を使用して制約をグループ化します。略記組合せ比較を使用する制約の例
// Simple abbreviated combined relation condition using a single `&&`: Person(age > 30 && < 40) // Complex abbreviated combined relation using groupings: Person(age ((> 30 && < 40) || (> 20 && < 25))) // Mixing abbreviated combined relation with constraint connectives: Person(age > 30 && < 40 || location == "london")matches,not matchesこれらの演算子を使用して、指定された Java 正規表現にフィールドが一致するか、または一致しないかを示します。一般に、正規表現は
Stringリテラルですが、有効な正規表現に解決される変数もサポートされます。これらの演算子はStringプロパティーのみに適用されます。null値に対してmatchesを使用する場合は、結果の評価が常にfalseになります。null値に対してnot matchesを使用する場合は、結果の評価が常にtrueになります。Java の場合のように、Stringリテラルとして記述された正規表現は二重のバックスラッシュ\\を使用してエスケープする必要があります。正規表現と一致する制約または一致しない制約の例
Person( country matches "(USA)?\\S*UK" ) Person( country not matches "(USA)?\\S*UK" )contains,not containsこれらの演算子を使用して、フィールドの
ArrayまたはCollectionが指定された値を含むか、または含まないかを検証します。これらの演算子はArrayプロパティーまたはCollectionプロパティーに適用されますが、これらの演算子をString.contains()および!String.contains()の制約チェックの代わりとして使用することもできます。コレクションに対して
containsおよびnot containsが使用された制約の例// Collection with a specified field: FamilyTree( countries contains "UK" ) FamilyTree( countries not contains "UK" ) // Collection with a variable: FamilyTree( countries contains $var ) FamilyTree( countries not contains $var )String リテラルに対して
containsおよびnot containsが使用された制約の例// Sting literal with a specified field: Person( fullName contains "Jr" ) Person( fullName not contains "Jr" ) // String literal with a variable: Person( fullName contains $var ) Person( fullName not contains $var )注記下位互換性を確保するため、
excludes演算子はnot containsの同義語としてサポートされます。memberOf,not memberOfこれらの演算子を使用して、フィールドが変数として定義されている
ArrayまたはCollectionのメンバーであるかどうかを検証します。ArrayまたはCollectionは変数でなければなりません。コレクションと
memberOfおよびnot memberOfを使用する制約の例FamilyTree( person memberOf $europeanDescendants ) FamilyTree( person not memberOf $europeanDescendants )soundslikeこの演算子を使用して、ある単語を英語で発音した場合に、指定された値と発音がほぼ同じであるかどうかを検証します (
matches演算子に類似)。この演算子は Soundex アルゴリズムを使用します。soundslikeを使用した制約の例// Match firstName "Jon" or "John": Person( firstName soundslike "John" )strこの演算子を使用して、
Stringであるフィールドが指定された値で開始しているか、または終了しているかを検証します。この演算子を使用して、Stringの長さを検証することもできます。strを使用する制約の例// Verify what the String starts with: Message( routingValue str[startsWith] "R1" ) // Verify what the String ends with: Message( routingValue str[endsWith] "R2" ) // Verify the length of the String: Message( routingValue str[length] 17 )in、notinこれらの演算子を使用して、制約の中で一致する可能性がある複数の値を指定します (複合値の制約)。複合値の制約についての機能をサポートするのは
in演算子およびnot in演算子のみです。これらの演算子の 2 番目のオペランドは、括弧で囲み、コンマ区切り値の一覧で指定する必要があります。値は変数、リテラル、戻り値、または修飾された識別子として指定できます。これらの演算子は、==または!=演算子を使用し、複数の制約のリストとして内部に再書き込みされます。inおよびnotinを使用した制約の例Person( $color : favoriteColor ) Color( type in ( "red", "blue", $color ) ) Person( $color : favoriteColor ) Color( type notin ( "red", "blue", $color ) )