diff --git a/pmd/codestyle.xml b/pmd/codestyle.xml new file mode 100644 index 000000000..8f88ea7d0 --- /dev/null +++ b/pmd/codestyle.xml @@ -0,0 +1,1847 @@ + + + + + + Rules which enforce a specific coding style. + + + + + Avoid using dollar signs in variable/method/class/interface names. + + 3 + + + + + + + + + + + + + + + Do not use protected fields in final classes since they cannot be subclassed. + Clarify your intent by using private or package access modifiers instead. + + 3 + + + + + + + + + + + + + + + Do not use protected methods in most final classes since they cannot be subclassed. This should + only be allowed in final classes that extend other classes with protected methods (whose + visibility cannot be reduced). Clarify your intent by using private or package access modifiers instead. + + 3 + + + + + + + + + + + + + + + Unnecessary reliance on Java Native Interface (JNI) calls directly reduces application portability + and increases the maintenance burden. + + 2 + + + //MethodCall[TypeExpression/ClassType[pmd-java:typeIs('java.lang.System')] + and @MethodName = 'loadLibrary'] + + + + + + + + + + Methods that return boolean results should be named as predicate statements to denote this. + I.e, 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get' + prefix for these methods. + + 4 + + + + + + + + + + + + + + + + It is a good practice to call super() in a constructor. If super() is not called but + another constructor (such as an overloaded constructor) is called, this rule will not report it. + + 3 + + + + + + + + + + + + + + + Configurable naming conventions for type declarations. This rule reports + type declarations which do not match the regex that applies to their + specific kind (e.g. enum or interface). Each regex can be configured through + properties. + + By default, this rule uses the standard Java naming convention (Pascal case). + + The rule can detect utility classes and enforce a different naming convention + on those. E.g. setting the property `utilityClassPattern` to + `[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)` reports any utility class, whose name + does not end in "Util(s)", "Helper" or "Constants". + + For this rule, a utility class is defined as: a concrete class that does not + inherit from a super class or implement any interface and only has static fields + or methods. + + This rule detects test classes using the following convention: Test classes are top-level classes, that + either inherit from JUnit 3 TestCase or have at least one method annotated with the Test annotations from + JUnit4/5 or TestNG. + + 1 + + + + + + + + To avoid mistakes if we want that an Annotation, Class, Enum, Method, Constructor or Field have a default access modifier + we must add a comment at the beginning of its declaration. + By default, the comment must be `/* default */` or `/* package */`, if you want another, you have to provide a regular expression. + + This rule ignores by default all cases that have a `@VisibleForTesting` annotation or any JUnit5/TestNG annotation. Use the + property "ignoredAnnotations" to customize the recognized annotations. + + 3 + + + + + + + + Avoid negation within an "if" expression with an "else" clause. For example, rephrase: + `if (x != y) diff(); else same();` as: `if (x == y) same(); else diff();`. + + Most "if (x != y)" cases without an "else" are often return cases, so consistent use of this + rule makes the code easier to read. Also, this resolves trivial ordering problems, such + as "does the error case go first?" or "does the common case go first?". + + 3 + + + + + + + + Enforce a policy for braces on control statements. It is recommended to use braces on 'if ... else' + statements and loop statements, even if they are optional. This usually makes the code clearer, and + helps prepare the future when you need to add another statement. That said, this rule lets you control + which statements are required to have braces via properties. + + From 6.2.0 on, this rule supersedes WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces, + and IfElseStmtMustUseBraces. + + 3 + + + + + + + + + + + 1 and not(self::Block or self::IfStatement)] + [ $checkSingleIfStmt + (: Inside this (...) is the definition of a "single if statement" :) + or not(parent::*/@Else = false() (: No else stmt :) + (: Not the last branch of an 'if ... else if' chain :) + and not(parent::IfStatement[parent::IfStatement]))] + + | + (: Reports case labels if one of their subordinate statements is not braced :) + //SwitchFallthroughBranch[$checkCaseStmt] + [count(*) > 1 and (count(*) > 2 or not(child::*[2]/self::Block))] + ]]> + + + + + + + + + + Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inapproprate + usage by developers who should be implementing their own versions in the concrete subclasses. + + 1 + + + + + + + + + + + + + + + + + + + 3 + + + + + + + No need to explicitly extend Object. + 4 + + + + + + + + + + + + + + + Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes. + + 3 + + + + + + + + + Configurable naming conventions for field declarations. This rule reports variable declarations + which do not match the regex that applies to their specific kind ---e.g. constants (static final), + enum constant, final field. Each regex can be configured through properties. + + By default this rule uses the standard Java naming convention (Camel case), and uses the ALL_UPPER + convention for constants and enum constants. + + 1 + + + + + + + + Declaring a method parameter as final for an interface method is useless because the implementation may choose to not respect it. + + 1 + + + + + + + + + + + + + + + Some for loops can be simplified to while loops, this makes them more concise. + + 3 + + + + + + + + + + + + + + + Configurable naming conventions for formal parameters of methods and lambdas. + This rule reports formal parameters which do not match the regex that applies to their + specific kind (e.g. lambda parameter, or final formal parameter). Each regex can be + configured through properties. + + By default this rule uses the standard Java naming convention (Camel case). + + 1 + + lambda1 = s_str -> { }; + + // lambda parameters with an explicit type can be configured separately + Consumer lambda1 = (String str) -> { }; + + } + + } + ]]> + + + + + + Names for references to generic values should be limited to a single uppercase letter. + + 4 + + + + 1 + or + upper-case(@Name) != @Name +] +]]> + + + + + extends BaseDao { + // This is ok... +} + +public interface GenericDao { + // Also this +} + +public interface GenericDao { + // 'e' should be an 'E' +} + +public interface GenericDao { + // 'EF' is not ok. +} +]]> + + + + + + + Identical `catch` branches use up vertical space and increase the complexity of code without + adding functionality. It's better style to collapse identical branches into a single multi-catch + branch. + + 3 + + + + + + + + + This rule reports lambda expressions that can be written more succinctly as a method reference. This is the case if the lambda is an expression lambda that only calls one method, passing the entire lambda parameter list in order to the method. For instance: + ```java + x -> Foo.call(x) // can be Foo::call + x -> call(x) // can be this::call, if call is an instance method + (x, y, z) -> call(x, y, z) // can be this::call + () -> foo.get() // can be foo::get + x -> x.foo() // can be XType::foo (where XType is the type of x) + ``` + + In some cases rewriting a lambda to a method reference can change the semantics of the code. For instance in `(x) -> someVar.call(x)`, the invocation of the lambda may produce a NullPointerException (NPE) if `someVar` is null. The method reference `someVar::call` will also NPE if `someVar` is null, but it will do so at the point the method reference is created, while the lambda is created without error and its NPE is only thrown if the lambda is invoked (which may be never). Code should probably not rely on this subtle semantic difference, therefore these potentially problematic lambdas are also reported by default. This behavior can be disabled by setting the property `ignoreIfMayNPE` to `true`. + + The property `ignoreIfMayNPE` is true by default. By default, calls whose receiver is itself a method call are ignored, because they could cause side effects. This may be changed by setting the property `ignoreIfReceiverIsMethod` to `false`. + + Scope limitations: + - This rule will not report lambdas of the form `x -> new CtorCall().something(x)`, because the semantics of the method reference would be to create a single new object, while the lambda creates one object per invocation. + - The rule cannot know if the qualifier of a method call performs side effects. This means `(x) -> sideEffectingMethod().foo(x)` will be reported. Suppress the warning in this case. + + 3 + + s.length()) // could be String::length + .reduce((x, y) -> Integer.sum(x, y)) // could be Integer::sum + .getAsInt(); + } + } + ]]> + + + + + + This rule finds Linguistic Naming Antipatterns. It checks for fields, that are named, as if they should + be boolean but have a different type. It also checks for methods, that according to their name, should + return a boolean, but don't. Further, it checks, that getters return something and setters won't. + Finally, it checks that methods, that start with "to" - so called transform methods - actually return + something, since according to their name, they should convert or transform one object into another. + There is additionally an option, to check for methods that contain "To" in their name - which are + also transform methods. However, this is disabled by default, since this detection is prone to + false positives. + + For more information, see [Linguistic Antipatterns - What They Are and How + Developers Perceive Them](https://doi.org/10.1007/s10664-014-9350-8). + + 3 + + + + + + + + The Local Home interface of a Session EJB should be suffixed by 'LocalHome'. + + 4 + + + + + + + + + + + + + + + The Local Interface of a Session EJB should be suffixed by 'Local'. + + 4 + + + + + + + + + + + + + + + Configurable naming conventions for local variable declarations and other locally-scoped + variables. This rule reports variable declarations which do not match the regex that applies to their + specific kind (e.g. final variable, or catch-clause parameter). Each regex can be configured through + properties. + + By default this rule uses the standard Java naming convention (Camel case). + + 1 + + + + + + + + The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'. + + 4 + + + + + + + + + + + + + + + Configurable naming conventions for method declarations. This rule reports + method declarations which do not match the regex that applies to their + specific kind (e.g. JUnit test or native method). Each regex can be + configured through properties. + + By default this rule uses the standard Java naming convention (Camel case). + + 1 + + + + + + + + Detects when a class, interface, enum or annotation does not have a package definition. + + 3 + + + /CompilationUnit[not(PackageDeclaration)]/*[pmd-java:nodeIs("TypeDeclaration")][1] + + + + + + + + + + Since Java 1.7, numeric literals can use underscores to separate digits. This rule enforces that + numeric literals above a certain length use these underscores to increase readability. + + The rule only supports decimal (base 10) literals for now. The acceptable length under which literals + are not required to have underscores is configurable via a property. Even under that length, underscores + that are misplaced (not making groups of 3 digits) are reported. + + 3 + + + + + + + + + + + + + + + + Detects when a package definition contains uppercase characters. + + 3 + + + //PackageDeclaration[lower-case(@Name) != @Name] + + + + + + + + + + Checks for variables that are defined before they might be used. A declaration is + deemed to be premature if there are some statements that may return or throw an + exception between the time the variable is declared and the time it is first read. + + Some variables cannot be declared close to their first usage because of side-effects + occurring before they're first used. We try to avoid reporting those by considering + most method and constructor invocations to be impure. See the second example. + + Note that this rule is meant to improve code readability but is not an optimization. + A smart JIT will not care whether the variable is declared prematurely or not, as it + can reorder code. + + 3 + + + + + + + + + + + Remote Interface of a Session EJB should not have a suffix. + + 4 + + + + + + + + + + + + + + + A Remote Home interface type of a Session EJB should be suffixed by 'Home'. + + 4 + + + + + + + + + + + + + + + Short Classnames with fewer than e.g. five characters are not recommended. + + 4 + + + + + + + + + + + + + + + + If you overuse the static import feature, it can make your program unreadable and + unmaintainable, polluting its namespace with all the static members you import. + Readers of your code (including you, a few months after you wrote it) will not know + which class a static member comes from (Sun 1.5 Language Guide). + + 3 + + + + + $maximumStaticImports] +]]> + + + + + + + + + + + + Avoid the use of value in annotations when it's the only element. + + 3 + + + + + + + + + + + + + + + + Reports explicit boxing and unboxing conversions that may safely be removed, + either because they would be inserted by the compiler automatically, + or because they're semantically a noop (eg unboxing a value to rebox it immediately). + + Note that this only handles boxing and unboxing conversions occurring through + calls to `valueOf` or one of the `intValue`, `byteValue`, etc. methods. Casts + that command a conversion are reported by {% rule UnnecessaryCast %} instead. + + 3 + + + + + + + + 3 + + ) "string"; // unnecessary + + // primitive conversions + + l = (long) 2; // unnecessary + l = (long) 2.0; // necessary (narrowing cast) + l = (byte) i; // necessary (narrowing cast) + + // boxing/unboxing casts (since java 5) + + o = (Integer) 3; // unnecessary (autoboxing would apply) + o = (long) 3; // necessary (would be boxed to Long) + l = (int) boxedInt; // necessary (cannot cast Integer to long) + + // casts that give a target type to a lambda/ method ref are necessary + + o = (Function) Integer::toString; // necessary (no target type) + } +} +]]> + + + `. + */ + List stringList = Arrays.asList("a", "b"); + String element = (String) stringList.get(0); // this cast is unnecessary + } +} +]]> + + + + + + This rule detects when a constructor is not necessary; i.e., when there is only one constructor and the + constructor is identical to the default constructor. The default constructor should has same access + modifier as the declaring class. In an enum type, the default constructor is implicitly private. + + 3 + + + + + + + + Import statements allow the use of non-fully qualified names. The use of a fully qualified name + which is covered by an import statement is redundant. Consider using the non-fully qualified name. + + 4 + + + + + + + + Reports import statements that can be removed. They are either unused, + duplicated, or the members they import are already implicitly in scope, + because they're in java.lang, or the current package. + + If some imports cannot be resolved, for instance because you run PMD with + an incomplete auxiliary classpath, some imports may be conservatively marked + as used even if they're not to avoid false positives. + + 4 + + + + + + + + Avoid the creation of unnecessary local variables + + 3 + + + + + + + + Fields in interfaces and annotations are automatically `public static final`, and methods are `public abstract`. + Classes, interfaces or annotations nested in an interface or annotation are automatically `public static` + (all nested interfaces and annotations are automatically static). + Nested enums are automatically `static`. + For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous. + + 3 + + + + + + + + Avoid the use of unnecessary return statements. A return is unnecessary when no + instructions follow anyway. + + 3 + + + + + + + + Reports unnecessary semicolons (so called "empty statements" and "empty declarations"). + These can be removed without changing the program. The Java grammar + allows them for historical reasons, but they should be avoided. + + This rule will not report empty statements that are syntactically + required, for instance, because they are the body of a control statement. + + This rule replaces EmptyStatementNotInLoop. + + 3 + + + + + + + + + + + + + + `), and be inferred by the compiler. +This rule recommends that you use diamond type arguments anywhere possible, since +it avoids duplication of the type arguments, and makes the code more concise and readable. + +This rule is useful when upgrading a codebase to Java 1.7, Java 1.8, or Java 9. +The diamond syntax was first introduced in Java 1.7. In Java 8, improvements in Java's +type inference made more type arguments redundant. In Java 9, type arguments inference +was made possible for anonymous class constructors. + ]]> + 3 + + strings; + strings = new ArrayList(); // unnecessary duplication of type parameters + strings = new ArrayList<>(); // using diamond type arguments is more concise + + strings = new ArrayList(); // accidental use of a raw type, you can use ArrayList<> instead + + strings = new ArrayList<>() { + // for anonymous classes, this is possible since Java 9 only + }; + } + } + ]]> + + + + + + Parenthesized expressions are used to override the default operator precedence + rules. Parentheses whose removal would not change the relative nesting of operators + are unnecessary, because they don't change the semantics of the enclosing expression. + + Some parentheses that strictly speaking are unnecessary, may still be considered useful + for readability. This rule allows to ignore violations on two kinds of unnecessary parentheses: + - "Clarifying" parentheses, which separate operators of difference precedence. While + unnecessary, they make precedence rules explicit, which may be useful for rarely used + operators. For example: + ```java + (a + b) & c // is equivalent to `a + b & c`, but probably clearer + ``` + Unset the property `ignoreClarifying` to report them. + + - "Balancing" parentheses, which are unnecessary but visually balance out another pair + of parentheses around an equality operator. For example, those two expressions are equivalent: + ```java + (a == null) != (b == null) + a == null != (b == null) + ``` + The parentheses on the right are required, and the parentheses on the left are + just more visually pleasing. Unset the property `ignoreBalancing` to report them. + + + 4 + + + + + + + + Reports qualified this usages in the same class. + + 3 + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 03f84ad7d..46f17ab03 100644 --- a/pom.xml +++ b/pom.xml @@ -292,6 +292,7 @@ pmd/bestpractices.xml + pmd/codestyle.xml /category/java/security.xml /category/java/performance.xml diff --git a/spec/src/main/asciidoc/chapters/api/entity.adoc b/spec/src/main/asciidoc/chapters/api/entity.adoc index 15f167c95..fa3d8943f 100644 --- a/spec/src/main/asciidoc/chapters/api/entity.adoc +++ b/spec/src/main/asciidoc/chapters/api/entity.adoc @@ -336,6 +336,55 @@ However, every Jakarta NoSQL provider is strongly encouraged to support embeddab Some databases might require the use of the `udt` attribute in the `@Column` annotation for embedded fields. ==== + +==== Array Support + +Jakarta NoSQL implementations MUST support binding Java arrays of the basic types, as referenced in <>, and arrays of entities and embedded classes. + +Arrays of entities and embedded classes are supported and will function as embedded classes with *grouping*. + +Consider an entity class `Library` with an array of `Book` entities and an array of `String` tags. + +[source,java] +---- +@Entity +public class Library { + @Id + private Long id; + + @Column + private Book[] books; + + @Column + private String[] tags; +} + +@Entity +public class Book { + @Id + private Long id; + + @Column + private String title; +} +---- + +In this example, the array of `Book` entities will be treated as an embedded collection within the `Library` entity, using *grouping* to represent the structure. + +The JSON representation of an instance of the `Library` entity might be: + +[source,json] +---- +{ + "id": 1, + "books": [ + {"id": 101, "title": "Java Programming"}, + {"id": 102, "title": "Introduction to NoSQL"} + ], + "tags": ["Programming", "NoSQL", "Java"] +} +---- + ==== Entity Associations An association field is a field of an entity class whose declared type is also an entity class.