001: /*
002: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003: *
004: * http://izpack.org/
005: * http://izpack.codehaus.org/
006: *
007: * Copyright 2008 Ari Voutilainen
008: *
009: * Licensed under the Apache License, Version 2.0 (the "License");
010: * you may not use this file except in compliance with the License.
011: * You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: */
021:
022: package IzPack.TestLangPacks;
023:
024: import java.util.ArrayList;
025: import java.io.FileNotFoundException;
026: import java.io.IOException;
027: import java.io.File;
028: import java.io.FileInputStream;
029: import javax.xml.parsers.*;
030: import javax.xml.xpath.XPathExpressionException;
031: import javax.xml.xpath.XPathFactory;
032: import javax.xml.xpath.XPathConstants;
033: import javax.xml.xpath.XPath;
034:
035: import org.xml.sax.InputSource;
036: import org.xml.sax.SAXException;
037: import org.w3c.dom.Document;
038: import org.w3c.dom.DOMConfiguration;
039: import org.w3c.dom.DOMException;
040: import org.w3c.dom.Element;
041: import org.w3c.dom.NodeList;
042: import org.w3c.dom.Node;
043:
044: /**
045: * Capsulates XML document in TestLangPacks.
046: *
047: * @author Ari Voutilainen
048: */
049: public class XmlDocument {
050: private DocumentBuilder xmlDocBuilder = null;
051: private Document xmlDoc = null;
052: private DOMConfiguration domConf;
053: private LangPackXmlErrorHandler errorHandler = new LangPackXmlErrorHandler();
054: private InputSource inputSource = null;
055:
056: /**
057: * Constructor for XML document class.
058: *
059: * @param xmlFile XML file to load.
060: * @throws IzPack.TestLangPacks.LangPackException
061: */
062: public XmlDocument(String xmlFile) throws LangPackException {
063: try {
064: xmlDocBuilder = DocumentBuilderFactory.newInstance()
065: .newDocumentBuilder();
066: xmlDocBuilder.setErrorHandler(errorHandler);
067: xmlDoc = xmlDocBuilder.parse(xmlFile);
068: } catch (FactoryConfigurationError e) {
069: throw new LangPackException(e.getMessage());
070: } catch (ParserConfigurationException e) {
071: throw new LangPackException(e.getMessage());
072: } catch (SAXException e) {
073: throw new LangPackException(e.getMessage());
074: } catch (IOException e) {
075: throw new LangPackException(e.getMessage());
076: }
077: SetNormalizeParameters();
078:
079: try {
080: inputSource = new InputSource(new FileInputStream(new File(
081: xmlFile)));
082: } catch (FileNotFoundException e) {
083: throw new LangPackException(e.getMessage());
084: }
085: }
086:
087: /**
088: * Returns the root name of the XML file.
089: */
090: public String GetRootName() {
091: // Get the name of the root element.
092: Element rootElement = xmlDoc.getDocumentElement();
093: return rootElement.getNodeName();
094: }
095:
096: /**
097: * Checks if XML document is well-formed.
098: *
099: * @return true Documents is wel-formed. false document is not well-formed.
100: * @throws IzPack.TestLangPacks.LangPackException
101: */
102: public boolean IsWellFormed() throws LangPackException {
103: domConf = xmlDoc.getDomConfig();
104: try {
105: domConf.setParameter("cdata-sections", true);
106: domConf.setParameter("comments", true);
107: domConf.setParameter("normalize-characters", false);
108: domConf.setParameter("well-formed", true);
109: } catch (DOMException e) {
110: String msg = null;
111: if (e.code == DOMException.NOT_FOUND_ERR) {
112: msg = "Parameter name is not recognized.";
113: } else if (e.code == DOMException.NOT_SUPPORTED_ERR) {
114: msg = "Parameter name is recognized but the requested value cannot be set.";
115: } else if (e.code == DOMException.TYPE_MISMATCH_ERR) {
116: msg = "Parameter name is incompatible with the expected value type.";
117: }
118:
119: Main.PrintMessage(System.err,
120: "Error in normalize parameters", msg);
121: throw new LangPackException();
122: }
123:
124: try {
125: xmlDoc.normalizeDocument();
126: } catch (Exception e) {
127: return false;
128: }
129: return true;
130: }
131:
132: /**
133: * This is used when all additionals are first removed before testing language strings.
134: */
135: private void SetNormalizeParameters() {
136: domConf = xmlDoc.getDomConfig();
137: try {
138: domConf.setParameter("cdata-sections", false);
139: domConf.setParameter("comments", false);
140: domConf.setParameter("well-formed", true);
141: } catch (DOMException e) {
142: String msg = null;
143: if (e.code == DOMException.NOT_FOUND_ERR) {
144: msg = "Parameter name is not recognized.";
145: } else if (e.code == DOMException.NOT_SUPPORTED_ERR) {
146: msg = "Parameter name is recognized but the requested value cannot be set.";
147: } else if (e.code == DOMException.TYPE_MISMATCH_ERR) {
148: msg = "Parameter name is incompatible with the expected value type.";
149: }
150:
151: Main.PrintMessage(System.err, "Normalize parameters", msg);
152: }
153: }
154:
155: /**
156: * Returns language strings in XML file.
157: * @return Returns NodeList containing all elements with "str".
158: */
159: public NodeList GetLangStrings() {
160: return xmlDoc.getElementsByTagName("str");
161: }
162:
163: /**
164: * Returns unknown elements.
165: *
166: * @throws LangPackException
167: */
168: public String[] GetUnknownElements() {
169: if (inputSource == null) {
170: return new String[0];
171: }
172:
173: ArrayList<String> elems = new ArrayList<String>();
174: String nodeName = null;
175: String unknownElemString = null;
176:
177: // Gets all elements.
178: XPath xpath = XPathFactory.newInstance().newXPath();
179: NodeList nodes = null;
180: try {
181: nodes = (NodeList) xpath.evaluate("/langpack/*",
182: inputSource, XPathConstants.NODESET);
183: } catch (XPathExpressionException e) {
184: return new String[0];
185: }
186:
187: /* Tried several XPath 1.0 expressions to get "all other except 'str' ".
188: * Not succeeded! Only tested and working expression is wellcomed.
189: */
190: Node node = null;
191: int max = nodes.getLength();
192: for (int x = 0; x < max; x++) {
193: node = nodes.item(x);
194: nodeName = node.getNodeName();
195: if (!nodeName.equals("str")) {
196: unknownElemString = nodeName + " "
197: + node.getTextContent();
198: elems.add(unknownElemString);
199: }
200: }
201:
202: String[] templateArray = new String[0];// Make empty String array. This makes to use "T[] toArray(T[] a)" in ArrayList.
203: return elems.toArray(templateArray); // Return ArrayList items as String[].
204: }
205: }
|