View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.xml;
5   
6   import java.io.ByteArrayInputStream;
7   import java.io.IOException;
8   
9   import org.xml.sax.EntityResolver;
10  import org.xml.sax.InputSource;
11  import org.xml.sax.SAXException;
12  
13  import net.sourceforge.pmd.Rule;
14  import net.sourceforge.pmd.lang.ParserOptions;
15  import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
16  import net.sourceforge.pmd.util.StringUtil;
17  
18  public class XmlParserOptions extends ParserOptions {
19  
20      // Note: The UI order values are chosen to be larger than those built into XPathRule.
21      public static final BooleanProperty COALESCING_DESCRIPTOR = new BooleanProperty(
22  	    "coalescing",
23  	    "Specifies that the XML parser convert CDATA nodes to Text nodes and append it to the adjacent (if any) text node.",
24  	    Boolean.FALSE, 3.0f);
25      public static final BooleanProperty EXPAND_ENTITY_REFERENCES_DESCRIPTOR = new BooleanProperty(
26  	    "expandEntityReferences", "Specifies that the XML parser expand entity reference nodes.", Boolean.TRUE,
27  	    4.0f);
28      public static final BooleanProperty IGNORING_COMMENTS_DESCRIPTOR = new BooleanProperty("ignoringComments",
29  	    "Specifies that the XML parser ignore comments.", Boolean.FALSE, 5.0f);
30      public static final BooleanProperty IGNORING_ELEMENT_CONTENT_WHITESPACE_DESCRIPTOR = new BooleanProperty(
31  	    "ignoringElementContentWhitespace",
32  	    "Specifies that the XML parser eliminate whitespace in element content.  Setting this to 'true' will force validating.",
33  	    Boolean.FALSE, 6.0f);
34      public static final BooleanProperty NAMESPACE_AWARE_DESCRIPTOR = new BooleanProperty("namespaceAware",
35  	    "Specifies that the XML parser will provide support for XML namespaces.", Boolean.TRUE, 7.0f);
36      public static final BooleanProperty VALIDATING_DESCRIPTOR = new BooleanProperty("validating",
37  	    "Specifies that the XML parser will validate documents as they are parsed.  This only works for DTDs.",
38  	    Boolean.FALSE, 8.0f);
39      public static final BooleanProperty XINCLUDE_AWARE_DESCRIPTOR = new BooleanProperty("xincludeAware",
40  	    "Specifies that the XML parser will process XInclude markup.", Boolean.FALSE, 9.0f);
41      public static final BooleanProperty LOOKUP_DESCRIPTOR_DTD = new BooleanProperty("xincludeAware",
42      	    "Specifies whether XML parser will attempt to lookup the DTD.", Boolean.FALSE, 10.0f);
43      
44      public static final EntityResolver SILENT_ENTITY_RESOLVER = new EntityResolver() {
45  		public InputSource resolveEntity(String publicId, String systemId)
46  				throws SAXException, IOException {
47  			return new InputSource( new ByteArrayInputStream( "".getBytes() ) );
48  		}
49  	};
50  
51      private boolean coalescing;
52      private boolean expandEntityReferences;
53      private boolean ignoringComments;
54      private boolean ignoringElementContentWhitespace;
55      private boolean namespaceAware;
56      private boolean validating;
57      private boolean xincludeAware;
58      private boolean lookupDescriptorDoc;
59  
60      public XmlParserOptions() {
61  	this.coalescing = COALESCING_DESCRIPTOR.defaultValue().booleanValue();
62  	this.expandEntityReferences = EXPAND_ENTITY_REFERENCES_DESCRIPTOR.defaultValue().booleanValue();
63  	this.ignoringComments = IGNORING_COMMENTS_DESCRIPTOR.defaultValue().booleanValue();
64  	this.ignoringElementContentWhitespace = IGNORING_ELEMENT_CONTENT_WHITESPACE_DESCRIPTOR.defaultValue()
65  		.booleanValue();
66  	this.namespaceAware = NAMESPACE_AWARE_DESCRIPTOR.defaultValue().booleanValue();
67  	this.validating = VALIDATING_DESCRIPTOR.defaultValue().booleanValue();
68  	this.xincludeAware = XINCLUDE_AWARE_DESCRIPTOR.defaultValue().booleanValue();
69  	this.lookupDescriptorDoc = LOOKUP_DESCRIPTOR_DTD.defaultValue().booleanValue();
70      }
71  
72      public XmlParserOptions(Rule rule) {
73  	this.coalescing = rule.getProperty(COALESCING_DESCRIPTOR);
74  	this.expandEntityReferences = rule.getProperty(EXPAND_ENTITY_REFERENCES_DESCRIPTOR);
75  	this.ignoringComments = rule.getProperty(IGNORING_COMMENTS_DESCRIPTOR);
76  	this.ignoringElementContentWhitespace = rule.getProperty(IGNORING_ELEMENT_CONTENT_WHITESPACE_DESCRIPTOR);
77  	this.namespaceAware = rule.getProperty(NAMESPACE_AWARE_DESCRIPTOR);
78  	this.validating = rule.getProperty(VALIDATING_DESCRIPTOR);
79  	this.xincludeAware = rule.getProperty(XINCLUDE_AWARE_DESCRIPTOR);
80  	this.lookupDescriptorDoc = rule.getProperty(LOOKUP_DESCRIPTOR_DTD);
81      }
82      
83      /**
84       * 
85       * @return the configured entity resolver. If {@link #lookupDescriptorDoc} is false
86       * it would normally force the XML parser to use its own resolver
87       */
88      public EntityResolver getEntityResolver(){
89      	if (!lookupDescriptorDoc) {
90      		return SILENT_ENTITY_RESOLVER;
91      	} else {
92      		return null;
93      	}
94      }
95  
96      public boolean isLookupDescriptorDoc() {
97  		return lookupDescriptorDoc;
98  	}
99  
100 	public void setLookupDescriptorDoc(boolean lookupDescriptorDoc) {
101 		this.lookupDescriptorDoc = lookupDescriptorDoc;
102 	}
103 
104 	public boolean isCoalescing() {
105 	return this.coalescing;
106     }
107 
108     public void setCoalescing(boolean coalescing) {
109         this.coalescing = coalescing;
110     }
111 
112     public boolean isExpandEntityReferences() {
113 	return this.expandEntityReferences;
114     }
115 
116     public void setExpandEntityReferences(boolean expandEntityReferences) {
117         this.expandEntityReferences = expandEntityReferences;
118     }
119 
120     public boolean isIgnoringComments() {
121 	return this.ignoringComments;
122     }
123 
124     public void setIgnoringComments(boolean ignoringComments) {
125         this.ignoringComments = ignoringComments;
126     }
127 
128     public boolean isIgnoringElementContentWhitespace() {
129 	return this.ignoringElementContentWhitespace;
130     }
131 
132     public void setIgnoringElementContentWhitespace(boolean ignoringElementContentWhitespace) {
133         this.ignoringElementContentWhitespace = ignoringElementContentWhitespace;
134     }
135 
136     public boolean isNamespaceAware() {
137 	return this.namespaceAware;
138     }
139 
140     public void setNamespaceAware(boolean namespaceAware) {
141         this.namespaceAware = namespaceAware;
142     }
143 
144     public boolean isValidating() {
145 	return this.validating;
146     }
147 
148     public void setValidating(boolean validating) {
149         this.validating = validating;
150     }
151 
152     public boolean isXincludeAware() {
153 	return this.xincludeAware;
154     }
155 
156     public void setXincludeAware(boolean xincludeAware) {
157         this.xincludeAware = xincludeAware;
158     }
159 
160     @Override
161     public int hashCode() {
162 	final int prime = 31;
163 	int result = super.hashCode();
164 	result = prime * result + (coalescing ? 1231 : 1237);
165 	result = prime * result + (expandEntityReferences ? 1231 : 1237);
166 	result = prime * result + (ignoringComments ? 1231 : 1237);
167 	result = prime * result + (ignoringElementContentWhitespace ? 1231 : 1237);
168 	result = prime * result + (namespaceAware ? 1231 : 1237);
169 	result = prime * result + (validating ? 1231 : 1237);
170 	result = prime * result + (xincludeAware ? 1231 : 1237);
171 	return result;
172     }
173 
174     @Override
175     public boolean equals(Object obj) {
176 	if (this == obj) {
177 	    return true;
178 	}
179 	if (obj == null || getClass() != obj.getClass()) {
180 	    return false;
181 	}
182 	final XmlParserOptions that = (XmlParserOptions) obj;
183 	return StringUtil.isSame(this.suppressMarker, that.suppressMarker, false, false, false)
184 		&& this.coalescing == that.coalescing && this.expandEntityReferences == that.expandEntityReferences
185 		&& this.ignoringComments == that.ignoringComments
186 		&& this.ignoringElementContentWhitespace == that.ignoringElementContentWhitespace
187 		&& this.namespaceAware == that.namespaceAware && this.validating == that.validating
188 		&& this.xincludeAware == that.xincludeAware;
189     }
190 }