The need
Atm, some rules in the code style category try to enforce a naming convention (eg a suffix) that should be respected by all the subtypes of a type. These are:
- LocalHomeNamingConvention
- LocalInterfaceSessionNamingConvention
- MDBAndSessionBeanNamingConvention
- RemoteInterfaceNamingConvention
- RemoteSessionInterfaceNamingConvention
- I think they are too specific for PMD
- They are all implemented the same way, and it could be nice to abstract that away. PMD itself uses similar conventions of its own, eg the name of all interfaces extending Node should end with "Node"
It would be nice to have one rule to rule them all, which would be configurable. Unfortunately there's no easy way to do that with our current properties.
My initial idea, was to introduce a StringMapProperty, which would have Map<String, String> as its value. We could then mention the conventions we'd like to follow using eg
<property name="typeToRegex" value="n.s.pmd.Node -> .+Node" />
This wouldn't scale to using many conventions, and is fragile and ugly because it depends of the tokenization of a single string value into a full map. Plus, the rule-side API exposes only strings so you have to do the conversions by hand, and there's no type checking/ validity checking at parse time
Moreover, for each convention, we might want to specify whether it applies eg only for concrete classes, only for interfaces, etc. So we'd need a nicer way to enter all that information cleanly in the xml.
One possible answer
My current idea to achieve that is to introduce a new type of property, which can take any object as a value, and whose values you can set using an XML element, binding XML attributes to bean properties. For example (I didn't focus on the schema, we probably should use some other element that value):
<property name="conventions" >
<value forType="n.s.pmd.lang.ast.Node" regexConvention=".+Node" onInterfaces="true">
<value forType="n.s.pmd.lang.metrics.Metric" regexConvention=".+Metric" onlyConcreteClasses="true">
</property>
Here each value element creates a new value for the property "conventions", assuming it's a multi-valued property. Each of these values is an object which has setters for properties "forType", "regexConvention", "onInterfaces", "onlyConcreteClasses", and default values for some of these. The rule then receives a list of those objects to work on via the property.
This kind of flexible property would also help many rules be more powerful and expressive, for example, the *NamingConventionsRules could, instead of just having a regex for each convention, allow setting also the minimum and maximum name length, thus superseding ShortClassName, ShortMethodName, ShortVariable and LongVariable with more flexibility. (I assume here that #972 is implemented, since this text was extracted from that issue)
Any ideas how to implement that? I think jaxb might do something similar but I have no first-hand experience with it
The need
Atm, some rules in the code style category try to enforce a naming convention (eg a suffix) that should be respected by all the subtypes of a type. These are:
It would be nice to have one rule to rule them all, which would be configurable. Unfortunately there's no easy way to do that with our current properties.
My initial idea, was to introduce a StringMapProperty, which would have Map<String, String> as its value. We could then mention the conventions we'd like to follow using eg
This wouldn't scale to using many conventions, and is fragile and ugly because it depends of the tokenization of a single string value into a full map. Plus, the rule-side API exposes only strings so you have to do the conversions by hand, and there's no type checking/ validity checking at parse time
Moreover, for each convention, we might want to specify whether it applies eg only for concrete classes, only for interfaces, etc. So we'd need a nicer way to enter all that information cleanly in the xml.
One possible answer
My current idea to achieve that is to introduce a new type of property, which can take any object as a value, and whose values you can set using an XML element, binding XML attributes to bean properties. For example (I didn't focus on the schema, we probably should use some other element that
value):Here each
valueelement creates a new value for the property "conventions", assuming it's a multi-valued property. Each of these values is an object which has setters for properties "forType", "regexConvention", "onInterfaces", "onlyConcreteClasses", and default values for some of these. The rule then receives a list of those objects to work on via the property.This kind of flexible property would also help many rules be more powerful and expressive, for example, the *NamingConventionsRules could, instead of just having a regex for each convention, allow setting also the minimum and maximum name length, thus superseding ShortClassName, ShortMethodName, ShortVariable and LongVariable with more flexibility. (I assume here that #972 is implemented, since this text was extracted from that issue)
Any ideas how to implement that? I think jaxb might do something similar but I have no first-hand experience with it