Refactored hugely XMLAttributes. Added indent method in XMLTools. Fixed

header attributes. Improved demo.
This commit is contained in:
Christian P. MOMON 2017-05-08 11:03:27 +02:00
parent 9821164d30
commit a287e14eab
7 changed files with 524 additions and 97 deletions

View file

@ -0,0 +1,175 @@
/*
* Copyright (C) 2013-2014,2017 Christian Pierre MOMON
*
* This file is part of Devinsy-xml.
*
* Devinsy-xml is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Devinsy-xml is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Devinsy-xml. If not, see <http://www.gnu.org/licenses/>
*/
package fr.devinsy.util.xml;
import org.apache.commons.lang3.StringUtils;
/**
* The Class XMLAttribute.
*
* @author Christian Pierre MOMON (christian.momon@devinsy.fr)
*/
public class XMLAttribute
{
private String label;
private String value;
/**
* Instantiates a new XML attribute.
*/
public XMLAttribute()
{
this.label = null;
this.value = null;
}
/**
* Instantiates a new XML attribute.
*
* @param label
* the label
* @param value
* the value
*/
public XMLAttribute(final String label, final String value)
{
this.label = label;
this.value = value;
}
/* (non-Javadoc)
* @see java.lang.Object#clone()
*/
@Override
public XMLAttribute clone()
{
XMLAttribute result;
result = new XMLAttribute(this.label, this.value);
//
return result;
}
/**
* Gets the label.
*
* @return the label
*/
public String getLabel()
{
return this.label;
}
/**
* Gets the value.
*
* @return the value
*/
public String getValue()
{
return this.value;
}
/**
* Checks for equal value.
*
* @param other
* the other
* @return true, if successful
*/
public boolean hasEqualValue(final Object other)
{
boolean result;
if (other == null)
{
result = false;
}
else if ((StringUtils.equals(this.label, ((XMLAttribute) other).label)) && (StringUtils.equals(this.value, ((XMLAttribute) other).value)))
{
result = true;
}
else
{
result = false;
}
//
return result;
}
/**
* Checks if is blank.
*
* @return true, if is blank
*/
public boolean isBlank()
{
boolean result;
if ((StringUtils.isBlank(this.label)) || (StringUtils.isBlank(this.value)))
{
result = true;
}
else
{
result = false;
}
//
return result;
}
/**
* Sets the label.
*
* @param label
* the new label
*/
public void setLabel(final String label)
{
this.label = label;
}
/**
* Sets the value.
*
* @param value
* the new value
*/
public void setValue(final String value)
{
this.value = value;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
String result;
result = String.format("%s=\"%s\"", this.label, this.value);
//
return result;
}
}

View file

@ -31,8 +31,7 @@ import javax.xml.stream.events.Attribute;
* *
* @author Christian Pierre MOMON (christian.momon@devinsy.fr) * @author Christian Pierre MOMON (christian.momon@devinsy.fr)
*/ */
public class XMLAttributes extends HashMap<String, XMLAttribute> implements Iterable<XMLAttribute>
public class XMLAttributes extends HashMap<String, Attribute> implements Iterable<Attribute>
{ {
private static final long serialVersionUID = 8456469741805779474L; private static final long serialVersionUID = 8456469741805779474L;
@ -64,13 +63,41 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
public XMLAttributes(final Iterator<Attribute> source) public XMLAttributes(final Iterator<Attribute> source)
{ {
super(); super();
if (source != null) if (source != null)
{ {
while (source.hasNext()) while (source.hasNext())
{ {
Attribute attribute = source.next(); Attribute attribute = source.next();
add(attribute); add(new XMLAttribute(attribute.getName().getLocalPart(), attribute.getValue()));
}
}
}
/**
* Instantiates a new XML attributes from a string array. Strings are series
* of label and value. This constructor is a helper.
*
* @param source
* the source
*/
public XMLAttributes(final String... attributes)
{
super();
if (attributes != null)
{
if (attributes.length % 2 == 0)
{
for (int count = 0; count < attributes.length; count += 2)
{
add(new XMLAttribute(attributes[count], attributes[count + 1]));
}
}
else
{
throw new IllegalArgumentException("Parameter count is odd.");
} }
} }
} }
@ -84,6 +111,7 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
public XMLAttributes(final XMLAttributes source) public XMLAttributes(final XMLAttributes source)
{ {
super(); super();
addAll(source); addAll(source);
} }
@ -93,11 +121,11 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
* @param attribute * @param attribute
* the attribute * the attribute
*/ */
public void add(final Attribute attribute) public void add(final XMLAttribute attribute)
{ {
if (attribute != null) if (attribute != null)
{ {
put(attribute.getName().getLocalPart(), attribute); put(attribute.getLabel(), attribute);
} }
} }
@ -109,7 +137,7 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
*/ */
public void addAll(final XMLAttributes source) public void addAll(final XMLAttributes source)
{ {
for (Attribute attribute : source) for (XMLAttribute attribute : source)
{ {
this.add(attribute); this.add(attribute);
} }
@ -122,9 +150,9 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
* the label * the label
* @return the by label * @return the by label
*/ */
public Attribute getByLabel(final String label) public XMLAttribute getByLabel(final String label)
{ {
Attribute result; XMLAttribute result;
result = get(label); result = get(label);
@ -136,9 +164,9 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
* @see java.lang.Iterable#iterator() * @see java.lang.Iterable#iterator()
*/ */
@Override @Override
public Iterator<Attribute> iterator() public Iterator<XMLAttribute> iterator()
{ {
Iterator<Attribute> result; Iterator<XMLAttribute> result;
result = this.values().iterator(); result = this.values().iterator();
@ -161,16 +189,38 @@ public class XMLAttributes extends HashMap<String, Attribute> implements Iterabl
return result; return result;
} }
/**
* To array.
*
* @return the XML attribute[]
*/
public XMLAttribute[] toArray()
{
XMLAttribute[] result;
result = new XMLAttribute[size()];
int count = 0;
for (String key : this.keySet())
{
result[count] = get(key);
count += 1;
}
//
return result;
}
/** /**
* To list. * To list.
* *
* @return the list * @return the list
*/ */
public List<Attribute> toList() public List<XMLAttribute> toList()
{ {
List<Attribute> result; List<XMLAttribute> result;
result = new ArrayList<Attribute>(values()); result = new ArrayList<XMLAttribute>(values());
// //
return result; return result;

View file

@ -18,10 +18,10 @@
*/ */
package fr.devinsy.util.xml; package fr.devinsy.util.xml;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
@ -62,18 +62,25 @@ public class XMLReader
/** /**
* Instantiates a new XML reader. * Instantiates a new XML reader.
* *
* @param file * @param source
* the file * the file
* @throws FileNotFoundException * @throws FileNotFoundException
* the file not found exception * the file not found exception
* @throws XMLStreamException * @throws XMLStreamException
* the XML stream exception * the XML stream exception
*/ */
public XMLReader(final File file) throws FileNotFoundException, XMLStreamException public XMLReader(final File source) throws FileNotFoundException, XMLStreamException
{ {
this.nextEvent = null; if (source == null)
XMLInputFactory factory = XMLInputFactory.newInstance(); {
this.in = factory.createXMLEventReader(new FileInputStream(file), "UTF-8"); throw new IllegalArgumentException("Null parameter.");
}
else
{
this.nextEvent = null;
XMLInputFactory factory = XMLInputFactory.newInstance();
this.in = factory.createXMLEventReader(new FileInputStream(source), "UTF-8");
}
} }
/** /**
@ -86,9 +93,16 @@ public class XMLReader
*/ */
public XMLReader(final InputStream source) throws XMLStreamException public XMLReader(final InputStream source) throws XMLStreamException
{ {
this.nextEvent = null; if (source == null)
XMLInputFactory factory = XMLInputFactory.newInstance(); {
this.in = factory.createXMLEventReader(source); throw new IllegalArgumentException("Null parameter.");
}
else
{
this.nextEvent = null;
XMLInputFactory factory = XMLInputFactory.newInstance();
this.in = factory.createXMLEventReader(source);
}
} }
/** /**
@ -101,9 +115,34 @@ public class XMLReader
*/ */
public XMLReader(final Reader source) throws XMLStreamException public XMLReader(final Reader source) throws XMLStreamException
{ {
this.nextEvent = null; if (source == null)
XMLInputFactory factory = XMLInputFactory.newInstance(); {
this.in = factory.createXMLEventReader(source); throw new IllegalArgumentException("Null parameter.");
}
else
{
this.nextEvent = null;
XMLInputFactory factory = XMLInputFactory.newInstance();
this.in = factory.createXMLEventReader(source);
}
}
/**
* @param source
* @throws XMLStreamException
*/
public XMLReader(final String source) throws XMLStreamException
{
if (source == null)
{
throw new IllegalArgumentException("Null parameter.");
}
else
{
this.nextEvent = null;
XMLInputFactory factory = XMLInputFactory.newInstance();
this.in = factory.createXMLEventReader(new ByteArrayInputStream(source.getBytes()));
}
} }
/** /**

View file

@ -27,6 +27,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
@ -39,6 +40,8 @@ import org.apache.commons.lang3.StringUtils;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import fr.devinsy.util.strings.StringList;
/** /**
* The Class XMLTools. * The Class XMLTools.
* *
@ -70,6 +73,80 @@ public class XMLTools
return result; return result;
} }
/**
* Indent.
*
* @param source
* the source
* @return the string
* @throws XMLStreamException
* @throws XMLBadFormatException
* @throws IOException
*/
public static String indent(final String source) throws XMLStreamException, XMLBadFormatException, IOException
{
String result;
XMLReader in = new XMLReader(source);
StringList buffer = new StringList();
XMLWriter out = new XMLWriter(buffer);
boolean ended = false;
int level = 0;
while (!ended)
{
XMLTag tag = in.readTag();
if (tag == null)
{
ended = true;
}
else
{
switch (tag.getType())
{
case HEADER:
out.writeXMLHeader(tag.attributes());
out.flush();
buffer.appendln();
break;
case START:
out.flush();
buffer.append(StringUtils.repeat('\t', level));
out.writeStartTag(tag.getLabel(), tag.attributes());
out.flush();
buffer.appendln();
level += 1;
break;
case CONTENT:
out.flush();
buffer.append(StringUtils.repeat('\t', level));
out.writeTag(tag.getLabel(), tag.getContent(), tag.attributes());
out.flush();
buffer.appendln();
break;
case END:
level -= 1;
out.flush();
buffer.append(StringUtils.repeat('\t', level));
out.writeEndTag(tag.getLabel());
out.flush();
buffer.appendln();
break;
case EMPTY:
break;
case FOOTER:
break;
}
}
}
result = buffer.toString();
//
return result;
}
/** /**
* Checks if is valid. * Checks if is valid.
* *

View file

@ -28,7 +28,8 @@ import java.io.PrintWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.io.Writer; import java.io.Writer;
import org.apache.commons.lang3.ArrayUtils; import fr.devinsy.util.strings.StringList;
import fr.devinsy.util.strings.StringListWriter;
/** /**
* The Class XMLWriter. * The Class XMLWriter.
@ -51,16 +52,23 @@ public class XMLWriter
/** /**
* Initialize a XML Writer to a file. * Initialize a XML Writer to a file.
* *
* @param file * @param target
* Where write the XML data. * Where write the XML data.
* @throws UnsupportedEncodingException * @throws UnsupportedEncodingException
* the unsupported encoding exception * the unsupported encoding exception
* @throws FileNotFoundException * @throws FileNotFoundException
* the file not found exception * the file not found exception
*/ */
public XMLWriter(final File file) throws UnsupportedEncodingException, FileNotFoundException public XMLWriter(final File target) throws UnsupportedEncodingException, FileNotFoundException
{ {
this.out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); if (target == null)
{
throw new IllegalArgumentException("Null parameter.");
}
else
{
this.out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(target), "UTF-8"));
}
} }
/** /**
@ -73,7 +81,34 @@ public class XMLWriter
*/ */
public XMLWriter(final OutputStream target) throws UnsupportedEncodingException public XMLWriter(final OutputStream target) throws UnsupportedEncodingException
{ {
this.out = new PrintWriter(new OutputStreamWriter(target, "UTF-8")); if (target == null)
{
throw new IllegalArgumentException("Null parameter.");
}
else
{
this.out = new PrintWriter(new OutputStreamWriter(target, "UTF-8"));
}
}
/**
* Instantiates a new XML writer.
*
* @param target
* the target
* @throws UnsupportedEncodingException
* the unsupported encoding exception
*/
public XMLWriter(final StringList target) throws UnsupportedEncodingException
{
if (target == null)
{
throw new IllegalArgumentException("Null parameter.");
}
else
{
this.out = new PrintWriter(new StringListWriter(target));
}
} }
/** /**
@ -86,7 +121,15 @@ public class XMLWriter
*/ */
public XMLWriter(final Writer target) throws UnsupportedEncodingException public XMLWriter(final Writer target) throws UnsupportedEncodingException
{ {
this.out = new PrintWriter(target); if (target == null)
{
throw new IllegalArgumentException("Null parameter.");
}
else
{
this.out = new PrintWriter(target);
}
} }
/** /**
@ -143,6 +186,19 @@ public class XMLWriter
* the attributes * the attributes
*/ */
public void writeEmptyTag(final String label, final String... attributes) public void writeEmptyTag(final String label, final String... attributes)
{
writeEmptyTag(label, new XMLAttributes(attributes));
}
/**
* Write empty tag.
*
* @param label
* the label
* @param attributes
* the attributes
*/
public void writeEmptyTag(final String label, final XMLAttributes attributes)
{ {
this.out.print("<"); this.out.print("<");
this.out.print(label); this.out.print(label);
@ -172,6 +228,19 @@ public class XMLWriter
* the attributes * the attributes
*/ */
public void writeStartTag(final String label, final String... attributes) public void writeStartTag(final String label, final String... attributes)
{
writeStartTag(label, new XMLAttributes(attributes));
}
/**
* Write start tag.
*
* @param label
* the label
* @param attributes
* the attributes
*/
public void writeStartTag(final String label, final XMLAttributes attributes)
{ {
this.out.print("<"); this.out.print("<");
this.out.print(label); this.out.print(label);
@ -179,6 +248,17 @@ public class XMLWriter
this.out.print(">"); this.out.print(">");
} }
/**
* Write start tag.
*
* @param tag
* the tag
*/
public void writeStartTag(final XMLTag tag)
{
writeStartTag(tag.getLabel(), tag.attributes());
}
/** /**
* This method write a XML tag with attributes and boolean content data. * This method write a XML tag with attributes and boolean content data.
* *
@ -190,6 +270,21 @@ public class XMLWriter
* the attributes * the attributes
*/ */
public void writeTag(final String label, final boolean content, final String... attributes) public void writeTag(final String label, final boolean content, final String... attributes)
{
writeTag(label, content, new XMLAttributes(attributes));
}
/**
* Write tag.
*
* @param label
* the label
* @param content
* the content
* @param attributes
* the attributes
*/
public void writeTag(final String label, final boolean content, final XMLAttributes attributes)
{ {
writeStartTag(label, attributes); writeStartTag(label, attributes);
writeTagContent(String.valueOf(content)); writeTagContent(String.valueOf(content));
@ -207,6 +302,21 @@ public class XMLWriter
* the attributes * the attributes
*/ */
public void writeTag(final String label, final long content, final String... attributes) public void writeTag(final String label, final long content, final String... attributes)
{
writeTag(label, content, new XMLAttributes(attributes));
}
/**
* Write tag.
*
* @param label
* the label
* @param content
* the content
* @param attributes
* the attributes
*/
public void writeTag(final String label, final long content, final XMLAttributes attributes)
{ {
writeStartTag(label, attributes); writeStartTag(label, attributes);
writeTagContent(String.valueOf(content)); writeTagContent(String.valueOf(content));
@ -225,6 +335,21 @@ public class XMLWriter
* the attributes * the attributes
*/ */
public void writeTag(final String label, final String content, final String... attributes) public void writeTag(final String label, final String content, final String... attributes)
{
writeTag(label, content, new XMLAttributes(attributes));
}
/**
* Write tag.
*
* @param label
* the label
* @param content
* the content
* @param attributes
* the attributes
*/
public void writeTag(final String label, final String content, final XMLAttributes attributes)
{ {
if (content == null) if (content == null)
{ {
@ -244,16 +369,16 @@ public class XMLWriter
* @param attributes * @param attributes
* the attributes * the attributes
*/ */
private void writeTagAttributes(final String... attributes) private void writeTagAttributes(final XMLAttributes attributes)
{ {
if ((attributes != null) && (attributes.length > 0)) if ((attributes != null) && (!attributes.isEmpty()))
{ {
for (int count = 0; count < attributes.length; count += 2) for (XMLAttribute attribute : attributes)
{ {
this.out.print(" "); this.out.print(" ");
this.out.print(attributes[count]); this.out.print(attribute.getLabel());
this.out.print("=\""); this.out.print("=\"");
this.out.print(attributes[count + 1]); this.out.print(attribute.getValue());
this.out.print("\""); this.out.print("\"");
} }
} }
@ -302,24 +427,34 @@ public class XMLWriter
*/ */
public void writeXMLHeader(final String... attributes) public void writeXMLHeader(final String... attributes)
{ {
writeXMLHeader(new XMLAttributes(attributes));
}
/**
* This method writes a XML header with attributes.
*
* @param attributes
* the attributes
*/
public void writeXMLHeader(final XMLAttributes attributes)
{
// //
this.out.print("<?xml"); this.out.print("<?xml");
// //
if (!ArrayUtils.contains(attributes, "version")) if ((attributes == null) || (!attributes.containsKey("version")))
{ {
this.out.print(" version=\"1.0\""); this.out.print(" version=\"1.0\"");
} }
// //
if (!ArrayUtils.contains(attributes, "encoding")) if ((attributes == null) || (!attributes.containsKey("encoding")))
{ {
this.out.print(" encoding=\"UTF-8\""); this.out.print(" encoding=\"UTF-8\"");
} }
// //
if (!ArrayUtils.contains(attributes, "encoding")) if ((attributes == null) || (!attributes.containsKey("standalone")))
{ {
this.out.print(" standalone=\"no\""); this.out.print(" standalone=\"no\"");
} }
@ -327,13 +462,12 @@ public class XMLWriter
// //
if (attributes != null) if (attributes != null)
{ {
// for (XMLAttribute attribute : attributes)
for (int count = 0; count < attributes.length; count += 2)
{ {
this.out.print(" "); this.out.print(" ");
this.out.print(attributes[count]); this.out.print(attribute.getLabel());
this.out.print("=\""); this.out.print("=\"");
this.out.print(attributes[count + 1]); this.out.print(attribute.getValue());
this.out.print("\""); this.out.print("\"");
} }
} }

View file

@ -18,7 +18,6 @@
*/ */
package fr.devinsy.util.xml.demo; package fr.devinsy.util.xml.demo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -31,6 +30,7 @@ import org.apache.log4j.Logger;
import fr.devinsy.util.xml.XMLBadFormatException; import fr.devinsy.util.xml.XMLBadFormatException;
import fr.devinsy.util.xml.XMLReader; import fr.devinsy.util.xml.XMLReader;
import fr.devinsy.util.xml.XMLTag; import fr.devinsy.util.xml.XMLTag;
import fr.devinsy.util.xml.XMLTools;
import fr.devinsy.util.xml.XMLWriter; import fr.devinsy.util.xml.XMLWriter;
/** /**
@ -83,11 +83,11 @@ public class XMLDemo
System.out.println("XML generated:"); System.out.println("XML generated:");
System.out.println(xml); System.out.println(xml);
System.out.println(XMLTools.indent(xml));
System.out.println(); System.out.println();
{ {
ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes()); XMLReader in = new XMLReader(xml);
XMLReader in = new XMLReader(stream);
in.readXMLHeader(); in.readXMLHeader();

View file

@ -22,6 +22,8 @@ import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import fr.devinsy.util.xml.XMLTools;
/** /**
* The Class Foo contains study code. * The Class Foo contains study code.
* *
@ -47,57 +49,7 @@ public class Foo
{ {
event = in.nextEvent(); event = in.nextEvent();
switch (event.getEventType()) System.out.println(XMLTools.toString(event));
{
case XMLEvent.ATTRIBUTE:
System.out.println("ATTRIBUTE ");
break;
case XMLEvent.CDATA:
System.out.println("CDATA");
break;
case XMLEvent.CHARACTERS:
System.out.println("CHARACTERS [" + event.asCharacters().getData() + "]");
break;
case XMLEvent.COMMENT:
System.out.println("COMMENT");
break;
case XMLEvent.DTD:
System.out.println("DTD");
break;
case XMLEvent.END_DOCUMENT:
System.out.println("END_DOCUMENT");
break;
case XMLEvent.END_ELEMENT:
System.out.println("END_ELEMENT " + event.asEndElement().getName());
break;
case XMLEvent.ENTITY_DECLARATION:
System.out.println("ENTITY_DECLARATION");
break;
case XMLEvent.ENTITY_REFERENCE:
System.out.println("ENTITY_REFERENCE");
break;
case XMLEvent.NAMESPACE:
System.out.println("NAMESPACE");
break;
case XMLEvent.NOTATION_DECLARATION:
System.out.println("NOTATION_DECLARATION");
break;
case XMLEvent.PROCESSING_INSTRUCTION:
System.out.println("PROCESSING_INSTRUCTION");
break;
case XMLEvent.SPACE:
System.out.println("SPACE");
break;
case XMLEvent.START_DOCUMENT:
System.out.println("START_DOCUMENT");
break;
case XMLEvent.START_ELEMENT:
System.out.println("START_ELEMENT [name=" + event.asStartElement().getName() + "][namespaceURI=" + event.asStartElement().getName().getNamespaceURI() + "][prefix="
+ event.asStartElement().getName().getPrefix() + "][localPart=" + event.asStartElement().getName().getLocalPart() + "]");
break;
default:
System.out.println("DEFAULT");
}
} }
} }
} }