1 /*
2 * $Id: XMLTools.java,v 1.11 2004/09/07 18:48:03 pelle Exp $
3 * $Log: XMLTools.java,v $
4 * Revision 1.11 2004/09/07 18:48:03 pelle
5 * Added support for dom4j 1.5 and added a new XPP3Reader
6 *
7 * Revision 1.10 2004/06/08 05:57:52 pelle
8 * Many changes throughout. In particular with regards to character encoding etc.
9 * The SigningServer now notifies the user and quits if another application is using the same port.
10 * ServletSignerFactory, now accepts a passphrase in web.xml
11 *
12 * Revision 1.9 2004/04/28 17:36:57 pelle
13 * Updated documentation for 0.13
14 * This will be release 0.13
15 *
16 * Revision 1.8 2004/04/26 23:57:48 pelle
17 * Trying to find the verifying error
18 *
19 * Revision 1.7 2004/04/18 01:03:48 pelle
20 * Added another varient of the id attribute to the getElementById method.
21 *
22 * Revision 1.6 2004/01/14 16:34:27 pelle
23 * New model of references and signatures now pretty much works.
24 * I am still not 100% sure on the created enveloping signatures. I need to do more testing.
25 *
26 * Revision 1.5 2004/01/13 23:37:59 pelle
27 * Refactoring parts of the core of XMLSignature. There shouldnt be any real API changes.
28 *
29 * Revision 1.4 2003/12/10 23:57:05 pelle
30 * Did some cleaning up in the builders
31 * Fixed some stuff in IdentityCreator
32 * New maven goal to create executable jarapp
33 * We are close to 0.8 final of ID, 0.11 final of XMLSIG and 0.5 of commons.
34 * Will release shortly.
35 *
36 * Revision 1.3 2003/11/21 04:44:31 pelle
37 * EncryptedFileStore now works. It uses the PBECipher with DES3 afair.
38 * Otherwise You will Finaliate.
39 * Anything that can be final has been made final throughout everyting. We've used IDEA's Inspector tool to find all instance of variables that could be final.
40 * This should hopefully make everything more stable (and secure).
41 *
42 * Revision 1.2 2003/11/19 23:33:17 pelle
43 * Signers now can generatekeys via the generateKey() method.
44 * Refactored the relationship between SignedNamedObject and NamedObjectBuilder a bit.
45 * SignedNamedObject now contains the full xml which is returned with getEncoded()
46 * This means that it is now possible to further receive on or process a SignedNamedObject, leaving
47 * NamedObjectBuilder for its original purposes of purely generating new Contracts.
48 * NamedObjectBuilder.sign() now returns a SignedNamedObject which is the prefered way of processing it.
49 * Updated all major interfaces that used the old model to use the new model.
50 *
51 * Revision 1.1.1.1 2003/11/11 16:33:20 pelle
52 * Moved over from neudist.org
53 * Moved remaining common utilities into commons
54 *
55 * Revision 1.7 2003/11/09 03:27:09 pelle
56 * More house keeping and shuffling about mainly pay
57 *
58 * Revision 1.6 2003/10/21 22:30:33 pelle
59 * Renamed NeudistException to NeuClearException and moved it to org.neuclear.commons where it makes more sense.
60 * Unhooked the XMLException in the xmlsig library from NeuClearException to make all of its exceptions an independent hierarchy.
61 * Obviously had to perform many changes throughout the code to support these changes.
62 *
63 * Revision 1.5 2003/09/26 23:52:47 pelle
64 * Changes mainly in receiver and related fun.
65 * First real neuclear stuff in the payment package. Added TransferContract and AssetControllerReceiver.
66 *
67 * Revision 1.4 2003/02/14 21:13:59 pelle
68 * The AbstractElementProxy has a new final method .asXML()
69 * which is similar to DOM4J's but it outputs the xml in the compact format and not the pretty format, thus not causing problems with Canonicalization.
70 * You can now also easily get the digest of a SignedElement with the new .getEncoded() value.
71 *
72 * Revision 1.3 2003/02/11 14:47:03 pelle
73 * Added benchmarking code.
74 * DigestValue is now a required part.
75 * If you pass a keypair when you sign, you get the PublicKey included as a KeyInfo block within the signature.
76 *
77 * Revision 1.2 2003/02/08 20:55:07 pelle
78 * Some documentation changes.
79 * Major reorganization of code. The code is slowly being cleaned up in such a way that we can
80 * get rid of the org.neuclear.utils package and split out the org.neuclear.xml.soap package.
81 * Got rid of tons of unnecessary dependencies.
82 *
83 * Revision 1.1 2003/01/18 18:12:31 pelle
84 * First Independent commit of the Independent XML-Signature API for NeuDist.
85 *
86 * Revision 1.5 2003/01/16 22:20:03 pelle
87 * First Draft of new generalised Ledger Interface.
88 * Currently we have a Book and Transaction class.
89 * We also need a Ledger class and a Ledger Factory.
90 *
91 * Revision 1.4 2002/09/29 00:22:10 pelle
92 * Several cosmetic changes.
93 * First attempt at a new CommandLine tool for signing and creating namespace files.
94 * This will be used by people to create requests for namespaces.
95 *
96 * Revision 1.3 2002/09/21 23:11:16 pelle
97 * A bunch of clean ups. Got rid of as many hard coded URL's as I could.
98 *
99 * Revision 1.2 2002/09/21 16:45:53 pelle
100 * Got the simple web based signing service working.
101 * There is also a simple User Authentication Web app to demonstrate.
102 * Docs to follow.
103 *
104 * Revision 1.1.1.1 2002/09/18 10:55:55 pelle
105 * First release in new CVS structure.
106 * Also first public release.
107 * This implemnts simple named objects.
108 * - Identity Objects
109 * - NSAuth Objects
110 *
111 * Storage systems
112 * - In Memory Storage
113 * - Clear text file based storage
114 * - Encrypted File Storage (with SHA256 digested filenames)
115 * - CachedStorage
116 * - SoapStorage
117 *
118 * Simple SOAP client/server
119 * - Simple Single method call SOAP client, for arbitrary dom4j based requests
120 * - Simple Abstract SOAP Servlet for implementing http based SOAP Servers
121 *
122 * Simple XML-Signature Implementation
123 * - Based on dom4j
124 * - SHA-RSA only
125 * - Very simple (likely imperfect) highspeed canonicalizer
126 * - Zero support for X509 (We dont like that anyway)
127 * - Super Simple
128 *
129 *
130 * Revision 1.4 2002/06/17 20:48:33 pelle
131 * The NS functionality should now work. FileStore is working properly.
132 * The example .ns objects in the neuspace folder have been updated with the
133 * latest version of the format.
134 * "neuspace/root.ns" should now be considered the universal parent of the
135 * neuclear system.
136 * Still more to go, but we're getting there. I will now focus on a quick
137 * Web interface. After which Contracts will be added.
138 *
139 * Revision 1.3 2002/06/13 19:04:08 pelle
140 * A start to a web interface into the architecture.
141 * We're getting a bit further now with functionality.
142 *
143 * Revision 1.2 2002/06/05 23:42:05 pelle
144 * The Throw clauses of several method definitions were getting out of hand, so I have
145 * added a new wrapper exception NeuClearException, to keep things clean in the ledger.
146 * This is used as a catchall wrapper for all Exceptions in the underlying API's such as IOExceptions,
147 * XML Exceptions etc.
148 * You can catch any Exception and rethrow it using Utility.rethrowException(e) as a quick way of handling
149 * exceptions.
150 * Otherwise the Store framework and the NameSpaces are really comming along quite well. I added a CachedStore
151 * which wraps around any other Store and caches the access to the store.
152 *
153 * Revision 1.1.1.1 2002/05/29 10:02:23 pelle
154 * Lets try one more time. This is the first rev of the next gen of Neudist
155 *
156 *
157 */
158 package org.neuclear.xml;
159
160 /***
161 * @author pelleb
162 * @version $Revision: 1.11 $
163 */
164
165 import org.dom4j.*;
166 import org.dom4j.dom.DOMDocument;
167 import org.dom4j.io.*;
168 import org.xmlpull.v1.XmlPullParserException;
169
170 import java.io.*;
171 import java.net.MalformedURLException;
172 import java.net.URL;
173
174
175 public final class XMLTools {
176 /***
177 * public static void writeDom(Document doc,OutputStream out) throws IOException{
178 * try {
179 * <p/>
180 * TransformerFactory fact=TransformerFactory.newInstance();
181 * Transformer tran=fact.newTransformer();
182 * tran.setOutputProperty(OutputKeys.INDENT,"2");
183 * tran.transform(new DOMSource(doc),new StreamResult(out));
184 * } catch (TransformerFactoryConfigurationError error) {
185 * Utility.handleException(error);
186 * } catch (TransformerException e) {
187 * Utility.handleException(e);
188 * }
189 * // SerializerToXML serializer = new SerializerToXML();
190 * // // Insert your PipedOutputStream here instead of System.out!
191 * // serializer.indent(2);
192 * //
193 * // serializer.setOutputStream(out);
194 * // serializer.serialize(doc);
195 * }
196 */
197 public static boolean isAttributeTrue(final Element elem, final String name) {
198 return isTrue(elem.attributeValue(name), false);
199 }
200
201 public static Document newDocument() {
202 return DocumentHelper.createDocument();
203 }
204
205 public static Document loadDocument(final String url) throws XMLException {
206 try {
207 return loadDocument(new URL(url));
208 } catch (MalformedURLException e) {
209 throw new XMLException(e);
210 }
211 }
212
213 public static Document loadDocument(final URL url) throws XMLException {
214 try {
215 final XPP3Reader xmlReader = new XPP3Reader();
216 return xmlReader.read(url);
217 } catch (Exception e) {
218 throw new XMLException(e);
219 }
220 }
221
222 public static Document loadDocument(final InputStream is) throws XMLException {
223 try {
224 final XPP3Reader xmlReader = new XPP3Reader();
225 return xmlReader.read(is);
226 } catch (Exception e) {
227 throw new XMLException(e);
228 }
229 }
230
231 public static Document loadDocument(final File f) throws XMLException {
232 final XPP3Reader xmlReader = new XPP3Reader();
233 try {
234
235 return xmlReader.read(f);
236 } catch (DocumentException e) {
237 throw new XMLException(e);
238 } catch (IOException e) {
239 throw new XMLException(e);
240 } catch (XmlPullParserException e) {
241 throw new XMLException(e);
242 }
243 }
244
245 public static void writeFile(final File outputFile, final Document doc) throws XMLException {
246 writeFile(outputFile, doc.getRootElement());
247 }
248
249 public static void writeFile(final File outputFile, final Element doc) throws XMLException {
250 try {
251 writeFile(new FileOutputStream(outputFile), doc);
252 } catch (FileNotFoundException e) {
253 rethrowException(e);
254 }
255 }
256
257 public static void writeFile(final OutputStream out, final Element doc) throws XMLException {
258
259 try {
260 // final Canonicalizer canon = new Canonicalizer();
261 // byte[] data = canon.canonicalize(doc);
262 // out.write(data);
263 // out.close();
264 final XMLWriter writer = new XMLWriter(out, getOutputFormat());
265 writer.write(doc);
266 writer.close();
267 } catch (IOException e) {
268 rethrowException(e);
269 }
270 }
271
272 public static String asXML(final Element doc) throws XMLException {
273 final StringWriter ow = new StringWriter();
274 try {
275 final XMLWriter writer = new XMLWriter(ow, getOutputFormat());
276 writer.write(doc);
277 writer.close();
278 } catch (IOException e) {
279 rethrowException(e);
280 }
281 return ow.toString();
282 }
283
284 private static OutputFormat getOutputFormat() {
285 final OutputFormat format = OutputFormat.createCompactFormat();
286 format.setEncoding("UTF-8");
287 format.setExpandEmptyElements(false);
288 format.setIndent(false);
289 format.setNewlines(false);
290 format.setPadText(false);
291 format.setTrimText(false);
292 return format;
293 }
294
295 public final org.w3c.dom.Document doc2dom(final Document doc) throws XMLException {
296 if (!(doc instanceof DOMDocument)) {
297 try {
298 final DOMWriter domWriter = new DOMWriter();
299 return domWriter.write(doc);
300 } catch (DocumentException e) {
301 rethrowException(e);
302 }
303 }
304 return (org.w3c.dom.Document) doc;
305 }
306
307 public final Document dom2doc(final org.w3c.dom.Document dom) {
308 if (dom instanceof DOMDocument)
309 return (DOMDocument) dom;
310 else {
311 final DOMReader domReader = new DOMReader();
312 return domReader.read(dom);
313 }
314 }
315
316 public static boolean isTrue(String clause, final boolean defaultVal) {
317 if (isEmpty(clause))
318 return defaultVal;
319 clause = clause.toLowerCase();
320 return (clause.equals("yes") || clause.equals("y") || clause.equals("1") || clause.equals("true"));
321 }
322
323 public static boolean isEmpty(final Object obj) {
324 return (obj == null || obj.toString().equals(""));
325 }
326
327 public static void rethrowException(final Throwable e) throws XMLException {
328 throw new XMLException(e);
329 }
330
331 /***
332 * This is used to find an Elemente with a given ID.
333 * This is necessary because of Dom4j's use of the ID attribute
334 * and not the more common in XMLSignature Id attribute.
335 *
336 * @param elem
337 * @param id
338 * @return
339 */
340 public static Element getByID(Element elem, String id) {
341 return getByID(elem.getDocument(), id);
342 }
343
344 /***
345 * This is used to find an Elemente with a given ID.
346 * This is necessary because of Dom4j's use of the ID attribute
347 * and not the more common in XMLSignature Id attribute.
348 *
349 * @param doc
350 * @param id
351 * @return
352 */
353 public static Element getByID(Document doc, String id) {
354 Element object = doc.elementByID(id);
355 if (object != null)
356 return object;
357 XPath xp = DocumentHelper.createXPath("//*[@Id='" + id + "']");
358 object = (Element) xp.selectSingleNode(doc);
359 if (object != null)
360 return object;
361 xp = DocumentHelper.createXPath("//*[@id='" + id + "']");
362 object = (Element) xp.selectSingleNode(doc);
363 return object;
364 }
365
366 }
This page was automatically generated by Maven