From 810ae423920e1ef5bc59b13d740efd0f9d616b78 Mon Sep 17 00:00:00 2001 From: Brian Remedios Date: Sun, 15 Oct 2006 05:56:16 +0000 Subject: [PATCH] Documentation for the property handling framework git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4668 51baf565-9d33-0410-a72c-fc3788e3496d --- pmd/etc/pmdProperties.rtf | 229 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 pmd/etc/pmdProperties.rtf diff --git a/pmd/etc/pmdProperties.rtf b/pmd/etc/pmdProperties.rtf new file mode 100644 index 0000000000..c541b8fb02 --- /dev/null +++ b/pmd/etc/pmdProperties.rtf @@ -0,0 +1,229 @@ +{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f233\froman\fcharset238\fprq2 Times New Roman CE;}{\f234\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f236\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f237\froman\fcharset162\fprq2 Times New Roman Tur;}{\f238\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f239\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f240\froman\fcharset186\fprq2 Times New Roman Baltic;} +{\f241\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f243\fswiss\fcharset238\fprq2 Arial CE;}{\f244\fswiss\fcharset204\fprq2 Arial Cyr;}{\f246\fswiss\fcharset161\fprq2 Arial Greek;}{\f247\fswiss\fcharset162\fprq2 Arial Tur;} +{\f248\fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f249\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f250\fswiss\fcharset186\fprq2 Arial Baltic;}{\f251\fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f253\fmodern\fcharset238\fprq1 Courier New CE;} +{\f254\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f256\fmodern\fcharset161\fprq1 Courier New Greek;}{\f257\fmodern\fcharset162\fprq1 Courier New Tur;}{\f258\fmodern\fcharset177\fprq1 Courier New (Hebrew);} +{\f259\fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f260\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f261\fmodern\fcharset163\fprq1 Courier New (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255; +\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0; +\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \styrsid10772021 Normal;}{ +\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \b\f1\fs32\lang1033\langfe1033\kerning32\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \styrsid10772021 heading 1;}{ +\s2\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \styrsid10772021 heading 2;}{ +\s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \styrsid10772021 heading 3;}{\*\cs10 \additive \ssemihidden +Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\rsidtbl \rsid1983827\rsid3096849 +\rsid4678217\rsid7145406\rsid9769499\rsid10772021\rsid12590302\rsid14575721}{\*\generator Microsoft Word 11.0.6359;}{\info{\title PMD Properties}{\author Brian Remedios}{\keywords PMD}{\operator Herzum Software}{\creatim\yr2006\mo10\dy15\min54} +{\revtim\yr2006\mo10\dy15\min54}{\version2}{\edmins1}{\nofpages5}{\nofwords1366}{\nofchars7787}{\*\company }{\nofcharsws9135}{\vern24703}} +\widowctrl\ftnbj\aenddoc\makebackup\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow1\dgvshow1 +\jexpand\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\viewnobound1\snaptogridincell\allowfieldendsel +\wrppunct\asianbrkrule\rsidroot10772021\newtblstyruls\nogrowautofit \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang +{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain +\s1\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs32\lang1033\langfe1033\kerning32\cgrid\langnp1033\langfenp1033 {\insrsid10772021 PMD Properties +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 +\par The new PMD properties subsystem is intended to bring some rigor and expanded functionality to the wild world of rule properies. It defines a value type template that can be used by IDE plugins to enumerate the properties specified by indiv +idual rules and provides validation and serialization services for multi-value properties. It uses custom serialization routines to generate human-readable values that can be edited in the XML files +\par +\par The subsystem implements the following property constructors with the leading name and description arguments not shown: +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 Boolean +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021\charrsid14379459 BooleanProperty(}{\f2\fs18\insrsid10772021 \'85}{ +\f2\fs18\insrsid10772021\charrsid14379459 , boolean defaultValue, float uiOrder) +\par BooleanProperty(}{\f2\fs18\insrsid10772021 \'85}{\f2\fs18\insrsid10772021\charrsid14379459 , boolean}{\f2\fs18\insrsid10772021 []}{\f2\fs18\insrsid10772021\charrsid14379459 defaultValues, uiOrder, maxValues) BooleanProperty(}{\f2\fs18\insrsid10772021 +\'85}{\f2\fs18\insrsid10772021\charrsid14379459 , Boolea}{\f2\fs18\insrsid10772021 n[]}{\f2\fs18\insrsid10772021\charrsid14379459 }{\f2\fs18\insrsid10772021 de}{\f2\fs18\insrsid10772021\charrsid14379459 faultValues, float uiOrder, int maxValues)}{ +\f2\fs20\insrsid10772021\charrsid14379459 +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 IntegerProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021\charrsid14379459 IntegerProperty(\'85 +, int defaultValue, float uiOrder) +\par IntegerProperty(\'85, int[]defaultValues, float uiOrder, int maxValues) IntegerProperty(\'85, Integer[] defaultValues, float uiOrder, int maxValues)}{\insrsid10772021\charrsid14379459 +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 FloatProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021 Float}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{ +\f2\fs18\insrsid9769499 float}{\f2\fs18\insrsid10772021\charrsid14379459 defaultValue, float uiOrder) +\par }{\f2\fs18\insrsid10772021 Float}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid9769499 float}{\f2\fs18\insrsid10772021\charrsid14379459 []defaultValues, float uiOrder, int maxValues) }{\f2\fs18\insrsid10772021 Float}{ +\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid9769499 Float}{\f2\fs18\insrsid10772021\charrsid14379459 [] defaultValues, float uiOrder, int maxValues)}{\f2\fs18\insrsid10772021 +\par }{\f2\fs18\insrsid9769499 +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid9769499 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid9769499 DoubleProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid9769499 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid9769499 Double}{\f2\fs18\insrsid9769499\charrsid14379459 Property(\'85 +, int defaultValue, float uiOrder) +\par }{\f2\fs18\insrsid9769499 Double}{\f2\fs18\insrsid9769499\charrsid14379459 Property (\'85, }{\f2\fs18\insrsid9769499 double}{\f2\fs18\insrsid9769499\charrsid14379459 []defaultValues, float uiOrder, int maxValues) }{\f2\fs18\insrsid9769499 Double}{ +\f2\fs18\insrsid9769499\charrsid14379459 Property (\'85, }{\f2\fs18\insrsid9769499 Double}{\f2\fs18\insrsid9769499\charrsid14379459 [] defaultValues, float uiOrder, int maxValues)}{\insrsid9769499\charrsid3748839 +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\insrsid9769499\charrsid3748839 +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 StringProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021 String}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{ +\f2\fs18\insrsid10772021 String}{\f2\fs18\insrsid10772021\charrsid14379459 defaultValue, float uiOrder) +\par }{\f2\fs18\insrsid10772021 String}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid10772021 String}{\f2\fs18\insrsid10772021\charrsid14379459 []}{\f2\fs18\insrsid10772021 }{\f2\fs18\insrsid10772021\charrsid14379459 +defaultValues, float uiOrder, }{\f2\fs18\insrsid10772021 char}{\f2\fs18\insrsid10772021\charrsid14379459 }{\f2\fs18\insrsid10772021 delimiter}{\f2\fs18\insrsid10772021\charrsid14379459 )}{\f2\fs18\insrsid10772021 +\par +\par }{\insrsid10772021\charrsid6625725 The delimiter character is used in the serialized string and cannot be part of the property value strings. +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 TypeProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021 Type}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{ +\f2\fs18\insrsid10772021 Class}{\f2\fs18\insrsid10772021\charrsid14379459 defaultValue, float uiOrder) +\par }{\f2\fs18\insrsid10772021 Type}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid10772021 Class}{\f2\fs18\insrsid10772021\charrsid14379459 []defaultValues, float uiOrder)}{\f2\fs18\insrsid10772021 +\par +\par }{\insrsid10772021\charrsid9330656 (PMD doesn\rquote t currently support full type resolution at the moment) +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 CharacterProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021 Character}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, } +{\f2\fs18\insrsid10772021 char}{\f2\fs18\insrsid10772021\charrsid14379459 defaultValue, float uiOrder) +\par }{\f2\fs18\insrsid10772021 Character}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid10772021 char}{\f2\fs18\insrsid10772021\charrsid14379459 []}{\f2\fs18\insrsid10772021 }{\f2\fs18\insrsid10772021\charrsid14379459 +defaultValues, float uiOrder}{\f2\fs18\insrsid10772021 , char delimiter}{\f2\fs18\insrsid10772021\charrsid14379459 )}{\insrsid10772021\charrsid3748839 +\par }{\f2\fs18\insrsid10772021 Character}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid10772021 Character}{\f2\fs18\insrsid10772021\charrsid14379459 []}{\f2\fs18\insrsid10772021 }{\f2\fs18\insrsid10772021\charrsid14379459 +defaultValues, float uiOrder}{\f2\fs18\insrsid10772021 , char delimiter}{\f2\fs18\insrsid10772021\charrsid14379459 )}{\insrsid10772021\charrsid3748839 +\par }{\f2\fs18\insrsid10772021 Character}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85, }{\f2\fs18\insrsid10772021 String }{\f2\fs18\insrsid10772021\charrsid14379459 defaultValues, float uiOrder}{\f2\fs18\insrsid10772021 , char delimiter}{ +\f2\fs18\insrsid10772021\charrsid14379459 )}{\f2\fs18\insrsid10772021 +\par +\par }{\insrsid10772021\charrsid6625725 The delimiter character is used in the serialized string and cannot be part of the property value }{\insrsid10772021 characters}{\insrsid10772021\charrsid6625725 . +\par }{\insrsid10772021\charrsid3748839 +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 EnumerationProperty +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f2\fs18\insrsid10772021 Enumerated}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85,} +{\f2\fs18\insrsid10772021 Object[][]}{\f2\fs18\insrsid10772021\charrsid14379459 }{\f2\fs18\insrsid10772021 v}{\f2\fs18\insrsid10772021\charrsid14379459 alue}{\f2\fs18\insrsid10772021 s}{\f2\fs18\insrsid10772021\charrsid14379459 , float uiOrder) +\par }{\f2\fs18\insrsid10772021 Enumerated}{\f2\fs18\insrsid10772021\charrsid14379459 Property(\'85,}{\f2\fs18\insrsid10772021 Object[]}{\f2\fs18\insrsid10772021\charrsid14379459 []}{\f2\fs18\insrsid10772021 v}{\f2\fs18\insrsid10772021\charrsid14379459 +alues, float uiOrder}{\f2\fs18\insrsid10772021 , int maxValues}{\f2\fs18\insrsid10772021\charrsid14379459 )}{\insrsid10772021\charrsid3748839 +\par }{\insrsid10772021 +\par The 2D value array holds the label-value tuples in the order that they should be presented in the UI widget. See usage below.}{\insrsid10772021\charrsid2975317 +\par }\pard\plain \s2\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid10772021 \b\i\f1\fs28\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 For Rule developers +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 +\par All rule p +roperties need to be characterized via individual PMDProperty instances so that they can be viewed and adjusted the IDE plugin users. Since we are essentially creating descriptors for the properties rather than the properties themselves we have the option + of creating them as static singletons within the rule class definition. The following rule usage example makes use of a pair of integer properties: +\par +\par }{\f2\fs20\insrsid10772021\charrsid3702757 public My}{\f2\fs20\insrsid10772021 VarNameLength}{\f2\fs20\insrsid10772021\charrsid3702757 Rule extends AbstractRule() \{ +\par +\par }{\f2\fs20\insrsid10772021 private}{\f2\fs20\insrsid10772021\charrsid3702757 static final Property}{\f2\fs20\insrsid9769499 Descriptor}{\f2\fs20\insrsid10772021\charrsid3702757 }{\f2\fs20\insrsid10772021 minVar}{ +\f2\fs20\insrsid10772021\charrsid3702757 NameLength = }{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 new IntegerProperty(}{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 \'93m}{\f2\fs20\insrsid10772021 in}{\f2\fs20\insrsid10772021\charrsid3702757 VarNameLength\'94, }{ +\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 \'93M}{\f2\fs20\insrsid10772021 in}{\f2\fs20\insrsid10772021\charrsid3702757 imum length for variable names\'94,}{\f2\fs20\insrsid10772021 +\par 3}{\f2\fs20\insrsid10772021\charrsid3702757 , }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 1.0f}{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 );}{\f2\fs20\insrsid10772021 +\par +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 }{\f2\fs20\insrsid10772021 private}{\f2\fs20\insrsid10772021\charrsid3702757 static final }{ +\f2\fs20\insrsid9769499\charrsid3702757 Property}{\f2\fs20\insrsid9769499 Descriptor}{\f2\fs20\insrsid9769499\charrsid3702757 }{\f2\fs20\insrsid10772021 maxVar}{\f2\fs20\insrsid10772021\charrsid3702757 NameLength = }{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 new IntegerProperty(}{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 \'93m}{\f2\fs20\insrsid10772021 ax}{\f2\fs20\insrsid10772021\charrsid3702757 VarNameLength\'94, }{ +\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 \'93M}{\f2\fs20\insrsid10772021 ax}{\f2\fs20\insrsid10772021\charrsid3702757 imum length for variable names\'94,}{\f2\fs20\insrsid10772021 +\par 30}{\f2\fs20\insrsid10772021\charrsid3702757 , }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 1.}{\f2\fs20\insrsid10772021 1}{\f2\fs20\insrsid10772021\charrsid3702757 f}{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 );}{\f2\fs20\insrsid10772021 +\par +\par }\pard \ql \fi-360\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 private static final }{\f2\fs20\insrsid9769499 Map}{\f2\fs20\insrsid10772021 }{\f2\fs20\insrsid9769499\charrsid9769499 +propertyDescriptorsByName }{\f2\fs20\insrsid10772021 = }{\f2\fs20\insrsid9769499 asFixedMap(}{\f2\fs20\insrsid10772021 +\par }\pard \ql \li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 new }{\f2\fs20\insrsid9769499\charrsid3702757 Property}{\f2\fs20\insrsid9769499 Descriptor}{\f2\fs20\insrsid10772021 [] \{ + minVarNameLength, maxVarNameLength \}}{\f2\fs20\insrsid9769499 +\par )}{\f2\fs20\insrsid10772021 ; +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 +\par }\pard \ql \fi360\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 public MyVarNameLengthRule() \{ \}; +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 +\par }\pard \ql \fi360\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid9769499 protected Map}{\f2\fs20\insrsid10772021 }{\f2\fs20\insrsid9769499 p}{\f2\fs20\insrsid10772021 roperties}{ +\f2\fs20\insrsid9769499 ByName}{\f2\fs20\insrsid10772021 () \{ }{\f2\fs20\insrsid9769499 +\par }\pard \ql \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid9769499 {\f2\fs20\insrsid10772021 return }{\f2\fs20\insrsid9769499\charrsid9769499 propertyDescriptorsByName}{\f2\fs20\insrsid10772021 ; }{ +\f2\fs20\insrsid9769499 +\par }{\f2\fs20\insrsid10772021 \}; +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 // rule body methods\'85 +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021 \}}{\f2\fs20\insrsid10772021\charrsid3702757 +\par }{\insrsid10772021 +\par All property descriptors must be returned via the }{\f2\fs22\insrsid7145406\charrsid7145406 p}{\f2\fs22\insrsid10772021\charrsid7145406 roperties}{\f2\fs22\insrsid7145406\charrsid7145406 ByName}{\f2\fs22\insrsid10772021\charrsid7145406 ()}{ +\insrsid10772021 method for each rule class}{\insrsid7145406 .}{\insrsid10772021 +\par +\par Properties can also be multi-valued, that is, we can capture and define a set of them at once: +\par +\par }{\f2\fs20\insrsid10772021 private}{\f2\fs20\insrsid10772021\charrsid3702757 static final }{\f2\fs20\insrsid9769499\charrsid3702757 Property}{\f2\fs20\insrsid9769499 Descriptor}{\f2\fs20\insrsid9769499\charrsid3702757 }{\f2\fs20\insrsid10772021 +booleanPrefixes}{\f2\fs20\insrsid10772021\charrsid3702757 = }{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 new }{\f2\fs20\insrsid10772021 String}{\f2\fs20\insrsid10772021\charrsid3702757 Property(}{ +\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid3702757 \'93}{\f2\fs20\insrsid10772021 booleanPrefixes}{\f2\fs20\insrsid10772021\charrsid3702757 \'94, }{ +\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 \'93}{\f2\fs20\insrsid10772021 Legal prefixes to use for boolean field names}{\f2\fs20\insrsid10772021\charrsid3702757 \'94,}{\f2\fs20\insrsid10772021 +\par new String[] \{ \'93is\'94, \'93has\'94, \'93can\'94 \}}{\f2\fs20\insrsid10772021\charrsid3702757 , }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid3702757 1.0f}{\f2\fs20\insrsid10772021 , +\par \lquote |\rquote \tab // reserved as delimiter +\par }{\f2\fs20\insrsid10772021\charrsid3702757 );}{\f2\fs20\insrsid10772021 +\par +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\insrsid10772021\charrsid7691424 There are at least two constructors for each property type, one that limits the +property to a single value and another that accepts more than one.}{\insrsid10772021 +\par +\par In addition to the regular Java types such as Boolean, Integer, Float, Character, String, and Class/Type values you can also allow your rule users to pick between complex mixed datatypes such as maps or graphs that you define at compilation time: +\par +\par }{\f2\fs20\insrsid10772021\charrsid5918372 \tab private static final Object[][] mixedItems = new Object[][] \{ +\par \tab \tab \{"map",\tab \tab new HashMap()\}, +\par \tab \tab \{"emptyArray",\tab new Object[0]\}, +\par \tab \tab \{"list",\tab \tab new ArrayList()\}, +\par \tab \tab \{"string",\tab \tab "Hello World!"\}, +\par \tab \tab \}; +\par }{\insrsid10772021 +\par }\pard \ql \fi-720\li1440\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid5918372 private static final }{\f2\fs20\insrsid9769499\charrsid3702757 Property}{\f2\fs20\insrsid9769499 +Descriptor}{\f2\fs20\insrsid9769499\charrsid3702757 }{\f2\fs20\insrsid10772021 sampleObjects}{\f2\fs20\insrsid10772021\charrsid5918372 = }{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid5918372 new EnumeratedProperty(}{\f2\fs20\insrsid10772021 +\par }\pard \ql \fi720\li1440\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0\pararsid10772021 {\f2\fs20\insrsid10772021\charrsid5918372 "testEnumerations", }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid5918372 "Test enumerations with complex types", }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid5918372 mixedItems, }{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid5918372 1.0f}{\f2\fs20\insrsid10772021 +\par }{\f2\fs20\insrsid10772021\charrsid5918372 ) : +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\insrsid10772021 +\par Note that Java values held by the EnumeratedProperty are not written out as property values themselves, we just write out the labels they are associated with. Specifying a label in the XML file for an object that doesn\rquote +t exist will result in an IllegalArgumentException. +\par +\par }\pard\plain \s3\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel2\adjustright\rin0\lin0\itap0\pararsid10772021 \b\f1\fs26\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 XML values +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 Defining the property rules within the ruleset XML files is straightf +orward for single values: +\par +\par }\pard \ql \li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 }{\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\insrsid10772021 +\par When specifying multiple values you will need to separate them using the delimiter held by the property descriptor, most commonly a single pipe character, \lquote |\rquote : +\par +\par }\pard \ql \li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 }{\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \fi720\li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \li720\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid10772021 {\f2\fs18\insrsid10772021\charrsid13063373 }{\fs18\insrsid10772021\charrsid13063373 +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 {\insrsid10772021 +\par You can define your own datatypes by implementing a subclass of AbstractPMDProperty and implementing the serialization, and + validation routines listed in the PMDProperty interface. Just ensure that you create a corresponding JUnit test in the test.net.sourceforge.pmd.properties package to go along with it. +\par +\par One of the implementation goals in this system is to try and come up with property constructors sufficiently useful that we don\rquote t need to assemble them within static blocks. A single statement should be enough to build a rule property descriptor. + +\par +\par }\pard\plain \s2\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid10772021 \b\i\f1\fs28\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 For IDE plugin developers +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 +\par In order to assemble an effective UI to manage the rule properties the following setup sequence is suggested: +\par +\par 1) Determine whether the value is open-ended or enumerated. For example, can the user type in their own values or should they pick them from a list? Invoke the }{\f2\fs22\insrsid10772021\charrsid16523264 choices()}{\insrsid10772021 + method that may return a 2D array of label-value pairs you can use to populate your list widget. If the method returns null then jump to step #2. +\par +\par You may need to maintain a mapping of the label-value pairs to translate between them depending on the capabilities of your list widget. The first pair in the array represents the default property value. +\par +\par 2) For open-ended values, determine the cardinality of the property via the }{\f2\fs22\insrsid10772021\charrsid16523264 maxValueCount()}{\insrsid10772021 method. If it returns a value of one then use the }{\f2\fs22\insrsid10772021\charrsid16523264 type() +}{\insrsid10772021 method to determine the type-specific entry field could use next. I.e. a checkbox for booleans, text field for strings, spin buttons for ints, etc. +\par +\par 3) If the property supports more than one value then you may opt to use a single text field and parse the entries after the user leaves or hits the return key or you can create a read-only widget and add/remove values via a popup dialog. +\par +\par 4) All multi-value properties make use of a character to delimit the values in their serialized form so you will need to ensure that you prevent the user from entering values containing it. Retrive the delimiter via the }{ +\f2\fs22\insrsid10772021\charrsid16523264 multiValueDelimiter()}{\insrsid10772021 method. +\par +\par You can use the errorFor(value) method to validate the values entered by the user or check the values held by the rule configuration file. It returns null or an error + message as appropriate. It would be best to flag and disable rules that have invalid property values. +\par +\par Use the }{\f2\fs22\insrsid10772021\charrsid16523264 defaultValue()}{\insrsid10772021 method to reset the rule properties to their default value. +\par +\par The two serialization methods, }{\f2\fs22\insrsid10772021\charrsid16523264 valueFrom()}{\insrsid10772021 and }{\f2\fs22\insrsid10772021\charrsid16523264 asDelimitedString(),}{\insrsid10772021 +are to be used to retrive and store property values respectively. While the value returned from a serialization string is just an Object type you will need to cast it to the designated type (or array) as dictated by the property settings. +\par +\par Widgets should be ordered vertically according to the values returned by the }{\f2\fs22\insrsid10772021\charrsid16523264 uiOrder()}{\insrsid10772021 + method with lower-valued properties appearing above the ones with higher values. The order of the property descriptors returned from the rule cannot be guaranteed to be the same as the +presentation order. If the two or more widgets share the same integer value then you can use the fractional portions to place their widgets in a horizontal sequence (if possible). +\par +\par For types that can have null values, such as strings, then use the }{\f2\fs22\insrsid10772021\charrsid16523264 isRequired()}{\insrsid10772021 method to flag any possible missing values. +\par +\par If a property field is multi-valued then the maximum number of values it can hold is set to largest possible int value unless set explicitly in a rule property constructor. +\par +\par }\pard\plain \s2\ql \li0\ri0\sb240\sa60\keepn\widctlpar\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid10772021 \b\i\f1\fs28\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10772021 ToDo items +\par }\pard\plain \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10772021 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\i\insrsid10772021\charrsid13122723 Expand this note with further examples +\par Internationalize error strings in the code +\par Provide for additional datatypes such as Date}{\i\insrsid10772021 +\par }{\i\insrsid3096849 Figure out }{\i\insrsid12590302 the best way}{\i\insrsid3096849 to add the rowCount}{\i\insrsid12590302 value}{\i\insrsid3096849 to the StringProperty constructor}{\i\insrsid3096849\charrsid13122723 +\par }{\insrsid10772021 +\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\insrsid1983827 +\par }} \ No newline at end of file