1 package net.sourceforge.pmd.lang.rule.properties;
2
3 import java.util.HashSet;
4 import java.util.Map;
5 import java.util.Set;
6
7 import net.sourceforge.pmd.lang.rule.properties.factories.BasicPropertyDescriptorFactory;
8 import static net.sourceforge.pmd.PropertyDescriptorFields.*;
9
10
11
12
13
14
15
16
17
18
19 public abstract class AbstractPackagedProperty<T> extends AbstractProperty<T> {
20
21 private String[] legalPackageNames;
22
23 private static final char PACKAGE_NAME_DELIMITER = ' ';
24
25 protected static final Map<String, Boolean> packagedFieldTypesByKey = BasicPropertyDescriptorFactory.expectedFieldTypesWith(
26 new String[] { LEGAL_PACKAGES},
27 new Boolean[] { Boolean.FALSE}
28 );
29
30
31 protected static String[] packageNamesIn(Map<String, String> params) {
32
33 return null;
34 }
35
36
37
38
39
40
41
42
43
44
45 protected AbstractPackagedProperty(String theName, String theDescription, T theDefault, String[] theLegalPackageNames, float theUIOrder) {
46 super(theName, theDescription, theDefault, theUIOrder);
47
48 checkValidPackages(theDefault, theLegalPackageNames);
49
50 legalPackageNames = theLegalPackageNames;
51 }
52
53
54
55
56 protected void addAttributesTo(Map<String, String> attributes) {
57 super.addAttributesTo(attributes);
58
59 attributes.put(LEGAL_PACKAGES, delimitedPackageNames());
60 }
61
62
63
64
65 private final String delimitedPackageNames() {
66
67 if (legalPackageNames == null || legalPackageNames.length == 0) { return ""; }
68 if (legalPackageNames.length == 1) { return legalPackageNames[0]; }
69
70 StringBuilder sb = new StringBuilder();
71 sb.append(legalPackageNames[0]);
72 for (int i=1; i<legalPackageNames.length; i++) {
73 sb.append(PACKAGE_NAME_DELIMITER).append(legalPackageNames[i]);
74 }
75 return sb.toString();
76 }
77
78
79
80
81
82
83
84
85
86 private void checkValidPackages(Object item, String[] legalNamePrefixes) {
87 Object[] items;
88 if (item.getClass().isArray()) {
89 items = (Object[])item;
90 } else{
91 items = new Object[]{item};
92 }
93
94 String[] names = new String[items.length];
95 Set<String> nameSet = new HashSet<String>(items.length);
96 String name = null;
97
98 for (int i=0; i<items.length; i++) {
99 name = packageNameOf(items[i]);
100 names[i] = name;
101 nameSet.add(name);
102 }
103
104 for (int i=0; i<names.length; i++) {
105 for (int l=0; l<legalNamePrefixes.length; l++) {
106 if (names[i].startsWith(legalNamePrefixes[l])) {
107 nameSet.remove(names[i]);
108 break;
109 }
110 }
111 }
112 if (nameSet.isEmpty()) { return; }
113
114 throw new IllegalArgumentException("Invalid items: " + nameSet);
115 }
116
117
118
119
120
121 abstract protected String itemTypeName();
122
123
124
125
126
127
128 protected String valueErrorFor(Object value) {
129
130 if (value == null) {
131 String err = super.valueErrorFor(null);
132 if (err != null) { return err; }
133 }
134
135 if (legalPackageNames == null) {
136 return null;
137 }
138
139 String name = packageNameOf(value);
140
141 for (int i=0; i<legalPackageNames.length; i++) {
142 if (name.startsWith(legalPackageNames[i])) {
143 return null;
144 }
145 }
146
147 return "Disallowed " + itemTypeName() + ": " + name;
148 }
149
150
151
152
153
154
155 abstract protected String packageNameOf(Object item);
156
157
158
159
160
161 public String[] legalPackageNames() {
162 return legalPackageNames;
163 }
164
165 }