View Javadoc

1   package net.sourceforge.pmd.lang.jsp.rule.basic;
2   
3   import java.util.Set;
4   
5   import net.sourceforge.pmd.lang.jsp.ast.ASTAttribute;
6   import net.sourceforge.pmd.lang.jsp.ast.ASTElement;
7   import net.sourceforge.pmd.lang.jsp.rule.AbstractJspRule;
8   import net.sourceforge.pmd.util.CollectionUtil;
9   
10  /**
11   * This rule checks that no "style" elements (like <B>, <FONT>, ...) are used, and that no
12   * "style" attributes (like "font", "size", "align") are used.
13   *
14   * @author pieter_van_raemdonck
15   */
16  public class NoInlineStyleInformationRule extends AbstractJspRule {
17  
18      // These lists should probably be extended
19  	
20      /**
21       * List of HTML element-names that define style.
22       */
23      private static final Set<String> STYLE_ELEMENT_NAMES = CollectionUtil.asSet(
24      		new String[]{"B", "I", "FONT", "BASEFONT", "U", "CENTER"}
25      		);
26  
27      /**
28       * List of HTML element-names that can have attributes defining style.
29       */
30      private static final Set<String> ELEMENT_NAMES_THAT_CAN_HAVE_STYLE_ATTRIBUTES = CollectionUtil.asSet(
31      		new String[]{"P", "TABLE", "THEAD", "TBODY", "TFOOT", "TR", "TD", "COL", "COLGROUP"}
32      		);
33  
34      /**
35       * List of attributes that define style when they are attributes of HTML elements with
36       * names in ELEMENT_NAMES_THAT_CAN_HAVE_STYLE_ATTRIBUTES.
37       */
38      private static final Set<String> STYLE_ATTRIBUTES = CollectionUtil.asSet(
39      		new String[]{"STYLE", "FONT", "SIZE", "COLOR", "FACE", "ALIGN", "VALIGN", "BGCOLOR"}
40      		);
41      
42      public Object visit(ASTAttribute node, Object data) {
43          if (isStyleAttribute(node)) {
44              addViolation(data, node);
45          }
46  
47          return super.visit(node, data);
48      }
49  
50      public Object visit(ASTElement node, Object data) {
51          if (isStyleElement(node)) {
52              addViolation(data, node);
53          }
54  
55          return super.visit(node, data);
56      }
57  
58      /**
59       * Checks whether the name of the elementNode argument is one of STYLE_ELEMENT_NAMES.
60       *
61       * @param elementNode
62       * @return boolean
63       */
64      private boolean isStyleElement(ASTElement elementNode) {
65          return STYLE_ELEMENT_NAMES.contains(elementNode.getName().toUpperCase());
66      }
67  
68      /**
69       * Checks whether the attributeNode argument is a style attribute of a HTML element
70       * that can have style attributes.
71       *
72       * @param attributeNode The attribute node.
73       * @return <code>true</code> if a style attribute, <code>false</code> otherwise.
74       */
75      private boolean isStyleAttribute(ASTAttribute attributeNode) {
76          if (STYLE_ATTRIBUTES.contains(attributeNode.getName().toUpperCase())) {
77              if (attributeNode.jjtGetParent() instanceof ASTElement) {
78                  ASTElement parent = (ASTElement) attributeNode.jjtGetParent();
79                  if (ELEMENT_NAMES_THAT_CAN_HAVE_STYLE_ATTRIBUTES.contains(parent
80                          .getName().toUpperCase())) {
81                      return true;
82                  }
83              }
84          }
85  
86          return false;
87      }
88  }