1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: XMLFeatureSet.java 2145 2011-04-05 01:15:52Z dmsmith $
21   */
22  /*
23   * This is inspired by DocumentChecker.
24   * @author Andy Clark, IBM
25   * @author Arnaud Le Hors, IBM
26   *
27   * Copyright 2000-2002,2004,2005 The Apache Software Foundation.
28   *
29   * Licensed under the Apache License, Version 2.0 (the "License");
30   * you may not use this file except in compliance with the License.
31   * You may obtain a copy of the License at
32   *
33   *      http://www.apache.org/licenses/LICENSE-2.0
34   *
35   * Unless required by applicable law or agreed to in writing, software
36   * distributed under the License is distributed on an "AS IS" BASIS,
37   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38   * See the License for the specific language governing permissions and
39   * limitations under the License.
40   *
41   */
42  package org.crosswire.common.xml;
43  
44  import java.util.Locale;
45  import java.util.Map;
46  import java.util.TreeMap;
47  
48  import org.xml.sax.SAXNotRecognizedException;
49  import org.xml.sax.SAXNotSupportedException;
50  import org.xml.sax.XMLReader;
51  
52  /**
53   * A set of useful XML Features
54   * 
55   * @see gnu.lgpl.License for license details.<br>
56   *      The copyright to this program is held by it's authors.
57   * @author DM Smith [dmsmith555 at yahoo dot com]
58   */
59  public final class XMLFeatureSet {
60  
61      public XMLFeatureSet() {
62          features.put("n", new XMLFeatureState(XMLFeature.NAMESPACES, true));
63          features.put("np", new XMLFeatureState(XMLFeature.NAMESPACE_PREFIX));
64          features.put("v", new XMLFeatureState(XMLFeature.VALIDATION));
65          features.put("xd", new XMLFeatureState(XMLFeature.LOAD_EXTERNAL_DTD, true));
66          features.put("s", new XMLFeatureState(XMLFeature.SCHEMA_VALIDATION));
67          features.put("f", new XMLFeatureState(XMLFeature.SCHEMA_FULL_CHECKING));
68          features.put("va", new XMLFeatureState(XMLFeature.VALIDATE_ANNOTATIONS));
69          features.put("dv", new XMLFeatureState(XMLFeature.DYNAMIC_VALIDATION));
70          features.put("xi", new XMLFeatureState(XMLFeature.XINCLUDE));
71          features.put("xb", new XMLFeatureState(XMLFeature.XINCLUDE_FIXUP_BASE_URIS, true));
72          features.put("xl", new XMLFeatureState(XMLFeature.XINCLUDE_FIXUP_LANGUAGE, true));
73  
74          for (Map.Entry<String, XMLFeatureState> entry : features.entrySet()) {
75              states.put(entry.getValue().getFeature(), entry.getKey());
76          }
77      }
78  
79      public void setFeatureState(XMLFeature feature, boolean state) {
80          features.get(states.get(feature)).setState(state);
81      }
82  
83      public void setFeatureStates(String[] argv) {
84          // process arguments
85          for (int i = 0; i < argv.length; i++) {
86              String arg = argv[i];
87              if (arg.charAt(0) == '-') {
88                  String option = arg.substring(1);
89                  String key = option.toLowerCase(Locale.ENGLISH);
90                  XMLFeatureState feature = features.get(key);
91                  if (feature != null) {
92                      feature.setState(option.equals(key));
93                  }
94              }
95          }
96      }
97  
98      @Override
99      public String toString() {
100         StringBuilder buf = new StringBuilder();
101         buf.append('\n');
102         for (XMLFeatureState state : features.values()) {
103             buf.append(state.getFeature().toString()).append('\n');
104         }
105         return buf.toString();
106     }
107 
108     /** Prints the usage. */
109     public void printUsage() {
110         System.err.println("XML Feature Set options:");
111         System.err.println("  -n  | -N    Turn on/off namespace processing.");
112         System.err.println("  -np | -NP   Turn on/off namespace prefixes.");
113         System.err.println("              NOTE: Requires use of -n.");
114         System.err.println("  -v  | -V    Turn on/off validation.");
115         System.err.println("  -xd | -XD   Turn on/off loading of external DTDs.");
116         System.err.println("              NOTE: Always on when -v in use and not supported by all parsers.");
117         System.err.println("  -s  | -S    Turn on/off Schema validation support.");
118         System.err.println("              NOTE: Not supported by all parsers.");
119         System.err.println("  -f  | -F    Turn on/off Schema full checking.");
120         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
121         System.err.println("  -va | -VA   Turn on/off validation of schema annotations.");
122         System.err.println("              NOTE: Requires use of -s and not supported by all parsers.");
123         System.err.println("  -dv | -DV   Turn on/off dynamic validation.");
124         System.err.println("              NOTE: Not supported by all parsers.");
125         System.err.println("  -xi | -XI   Turn on/off XInclude processing.");
126         System.err.println("              NOTE: Not supported by all parsers.");
127         System.err.println("  -xb | -XB   Turn on/off base URI fixup during XInclude processing.");
128         System.err.println("              NOTE: Requires use of -xi and not supported by all parsers.");
129         System.err.println("  -xl | -XL   Turn on/off language fixup during XInclude processing.");
130         System.err.println("              NOTE: Requires use of -xi and not supported by all parsers.");
131     }
132 
133     public void setFeatures(XMLReader parser) {
134         for (XMLFeatureState state : features.values()) {
135             state.setFeature(parser);
136         }
137     }
138 
139     /**
140      * A holder of the boolean state for a feature.
141      */
142     private static class XMLFeatureState {
143         public XMLFeatureState(XMLFeature feature, boolean state) {
144             this.feature = feature;
145             this.state = state;
146         }
147 
148         public XMLFeatureState(XMLFeature feature) {
149             this(feature, false);
150         }
151 
152         /**
153          * @return Returns the feature.
154          */
155         public XMLFeature getFeature() {
156             return feature;
157         }
158 
159         /**
160          * Set the new state
161          * 
162          * @param newState
163          */
164         public void setState(boolean newState) {
165             state = newState;
166         }
167 
168         /**
169          * Set the control state on the parser.
170          * 
171          * @param parser
172          */
173         public void setFeature(XMLReader parser) {
174             String control = feature.getControl();
175             try {
176                 parser.setFeature(control, state);
177             } catch (SAXNotRecognizedException e) {
178                 System.err.println("warning: Parser does not recognize feature (" + control + ")");
179             } catch (SAXNotSupportedException e) {
180                 System.err.println("warning: Parser does not support feature (" + control + ")");
181             }
182         }
183 
184         private boolean state;
185         private XMLFeature feature;
186     }
187 
188     private Map<String, XMLFeatureState> features = new TreeMap<String, XMLFeatureState>();
189     private Map<XMLFeature, String> states = new TreeMap<XMLFeature, String>();
190 }
191