NoInlineStyleInformationRule.java
01 package net.sourceforge.pmd.lang.jsp.rule.basic;
02 
03 import java.util.Set;
04 
05 import net.sourceforge.pmd.lang.jsp.ast.ASTAttribute;
06 import net.sourceforge.pmd.lang.jsp.ast.ASTElement;
07 import net.sourceforge.pmd.lang.jsp.rule.AbstractJspRule;
08 import net.sourceforge.pmd.util.CollectionUtil;
09 
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 = (ASTElementattributeNode.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 }