View Javadoc

1   package net.sourceforge.pmd;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.HashMap;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Map;
9   import java.util.Set;
10  
11  import net.sourceforge.pmd.util.CollectionUtil;
12  
13  /**
14   * 
15   * @author Brian Remedios
16   */
17  public abstract class AbstractPropertySource implements PropertySource {
18  
19  	protected List<PropertyDescriptor<?>> propertyDescriptors = new ArrayList<PropertyDescriptor<?>>();
20  	protected Map<PropertyDescriptor<?>, Object> propertyValuesByDescriptor = new HashMap<PropertyDescriptor<?>, Object>();
21  
22  	public AbstractPropertySource() {
23  		super();
24  	}
25  
26  	protected List<PropertyDescriptor<?>> copyPropertyDescriptors() {
27  		List<PropertyDescriptor<?>> copy = new ArrayList<PropertyDescriptor<?>>(propertyDescriptors.size());
28  		copy.addAll(propertyDescriptors);
29  		return copy;
30  	}
31  
32  	protected Map<PropertyDescriptor<?>, Object> copyPropertyValues() {
33  		Map<PropertyDescriptor<?>, Object> copy = new HashMap<PropertyDescriptor<?>, Object>(propertyValuesByDescriptor.size());
34  		copy.putAll(propertyValuesByDescriptor);
35  		return copy;
36  	}
37  
38  	/**
39  	  * @see Rule#ignoredProperties()
40  	  */
41  	public Set<PropertyDescriptor<?>> ignoredProperties() {
42  		 return Collections.emptySet();
43  	 }
44  
45  	/**
46  	  * @see Rule#definePropertyDescriptor(PropertyDescriptor)
47  	  */
48  	public void definePropertyDescriptor(PropertyDescriptor<?> propertyDescriptor) {
49  		 // Check to ensure the property does not already exist.
50  		 for (PropertyDescriptor<?> descriptor : propertyDescriptors) {
51  			 if (descriptor.name().equals(propertyDescriptor.name())) {
52  				 throw new IllegalArgumentException("There is already a PropertyDescriptor with name '"
53  						 + propertyDescriptor.name() + "' defined on Rule " + getName() + ".");
54  			 }
55  		 }
56  		 propertyDescriptors.add(propertyDescriptor);
57  		 // Sort in UI order
58  		 Collections.sort(propertyDescriptors);
59  	 }
60  
61  	public abstract String getName(); 
62  	
63  	/**
64  	  * @see Rule#getPropertyDescriptor(String)
65  	  */
66  	public PropertyDescriptor<?> getPropertyDescriptor(String name) {
67  		 for (PropertyDescriptor<?> propertyDescriptor : propertyDescriptors) {
68  			 if (name.equals(propertyDescriptor.name())) {
69  				 return propertyDescriptor;
70  			 }
71  		 }
72  		 return null;
73  	 }
74  
75  	/**
76  	  * @see Rule#hasDescriptor(PropertyDescriptor)
77  	  */
78  	public boolean hasDescriptor(PropertyDescriptor<?> descriptor) {
79  	
80  		 if (propertyValuesByDescriptor.isEmpty()) {
81  			 propertyValuesByDescriptor = getPropertiesByPropertyDescriptor();
82  		 }
83  	
84  		 return propertyValuesByDescriptor.containsKey(descriptor);
85  	 }
86  
87  	/**
88  	  * @see Rule#getPropertyDescriptors()
89  	  */
90  	public List<PropertyDescriptor<?>> getPropertyDescriptors() {
91  		 return propertyDescriptors;
92  	 }
93  
94  	/**
95  	  * @see Rule#getProperty(PropertyDescriptor)
96  	  */
97  	@SuppressWarnings("unchecked")
98  	public <T> T getProperty(PropertyDescriptor<T> propertyDescriptor) {
99  		 checkValidPropertyDescriptor(propertyDescriptor);
100 		 T value;
101 		 if (propertyValuesByDescriptor.containsKey(propertyDescriptor)) {
102 			 value = (T) propertyValuesByDescriptor.get(propertyDescriptor);
103 		 } else {
104 			 value = propertyDescriptor.defaultValue();
105 		 }
106 		 return value;
107 	 }
108 
109 	/**
110 	  * @see Rule#setProperty(PropertyDescriptor, Object)
111 	  */
112 	public <T> void setProperty(PropertyDescriptor<T> propertyDescriptor, T value) {
113 		 checkValidPropertyDescriptor(propertyDescriptor);
114 		 propertyValuesByDescriptor.put(propertyDescriptor, value);
115 	 }
116 
117 	private void checkValidPropertyDescriptor(PropertyDescriptor<?> propertyDescriptor) {
118 		 if (!propertyDescriptors.contains(propertyDescriptor)) {
119 			 throw new IllegalArgumentException("Property descriptor not defined for Rule " + getName() + ": "
120 					 + propertyDescriptor);
121 		 }
122 	 }
123 
124 	/**
125 	  * @see Rule#getPropertiesByPropertyDescriptor()
126 	  */
127 	public Map<PropertyDescriptor<?>, Object> getPropertiesByPropertyDescriptor() {
128 		 if (propertyDescriptors.isEmpty()) {
129 			 return Collections.emptyMap();
130 		 }
131 	
132 		 Map<PropertyDescriptor<?>, Object> propertiesByPropertyDescriptor = new HashMap<PropertyDescriptor<?>, Object>(
133 				 propertyDescriptors.size());
134 		 // Fill with existing explicitly values
135 		 propertiesByPropertyDescriptor.putAll(this.propertyValuesByDescriptor);
136 	
137 		 // Add default values for anything not yet set
138 		 for (PropertyDescriptor<?> propertyDescriptor : this.propertyDescriptors) {
139 			 if (!propertiesByPropertyDescriptor.containsKey(propertyDescriptor)) {
140 				 propertiesByPropertyDescriptor.put(propertyDescriptor, propertyDescriptor.defaultValue());
141 			 }
142 		 }
143 	
144 		 return propertiesByPropertyDescriptor;
145 	 }
146 
147 	/**
148 	  * @see Rule#usesDefaultValues()
149 	  */
150 	public boolean usesDefaultValues() {
151 	
152 		 Map<PropertyDescriptor<?>, Object> valuesByProperty = getPropertiesByPropertyDescriptor();
153 		 if (valuesByProperty.isEmpty()) {
154 			 return true;
155 		 }
156 	
157 		 Iterator<Map.Entry<PropertyDescriptor<?>, Object>> iter = valuesByProperty.entrySet().iterator();
158 	
159 		 while (iter.hasNext()) {
160 			 Map.Entry<PropertyDescriptor<?>, Object> entry = iter.next();
161 			 if (!CollectionUtil.areEqual(entry.getKey().defaultValue(), entry.getValue())) {
162 				 return false;
163 			 }
164 		 }
165 	
166 		 return true;
167 	 }
168 
169 	public void useDefaultValueFor(PropertyDescriptor<?> desc) {
170 		 propertyValuesByDescriptor.remove(desc);
171 	 }
172 
173 	 /**
174 	  * @see PropertySource#dysfunctionReason()
175 	  */
176 	 public String dysfunctionReason() {
177 		 return null;
178 	 }
179 }