Adds in some XmlRpc functions
This commit is contained in:
parent
3d34b5f508
commit
609ffd6a86
4 changed files with 431 additions and 0 deletions
|
@ -0,0 +1,44 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class XmlRpcDeserializer {
|
||||
private XmlRpcStreamReader xmlStreamReader;
|
||||
|
||||
public XmlRpcDeserializer ( InputStream inputStream ) throws Exception {
|
||||
xmlStreamReader = new XmlRpcStreamReader ( inputStream );
|
||||
}
|
||||
public String skipXmlHeader(String xml) {
|
||||
int startIndex = xml.indexOf("<?xml");
|
||||
if (startIndex >= 0) {
|
||||
int endIndex = xml.indexOf("?>", startIndex);
|
||||
if (endIndex >= 0) {
|
||||
return xml.substring(endIndex + 2);
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
public XmlRpcDeserializer ( String xml ) throws Exception {
|
||||
byte[] xmlBytes = xml.getBytes ( );
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream ( xmlBytes );
|
||||
xmlStreamReader = new XmlRpcStreamReader ( inputStream );
|
||||
}
|
||||
|
||||
public String readMethodName ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodCallMethodName ( );
|
||||
}
|
||||
|
||||
public Object[] readMethodParams ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodCallParams ( );
|
||||
}
|
||||
|
||||
public Object readMethodResponse ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodResponseResult ( );
|
||||
}
|
||||
|
||||
public void close ( ) throws Exception {
|
||||
xmlStreamReader.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
public class XmlRpcSerializer {
|
||||
private XmlRpcStreamWriter writer;
|
||||
|
||||
public XmlRpcSerializer ( OutputStream outputStream ) {
|
||||
this.writer = new XmlRpcStreamWriter ( outputStream );
|
||||
}
|
||||
|
||||
public void serializeMethodCall ( String methodName , List<Object> params ) throws IOException {
|
||||
writer.writeMethodCall ( methodName , params );
|
||||
}
|
||||
|
||||
public void serializeMethodResponse ( Object value ) throws IOException {
|
||||
writer.writeMethodResponse ( value );
|
||||
}
|
||||
|
||||
public void close ( ) throws IOException {
|
||||
writer.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmlRpcStreamReader {
|
||||
private XMLStreamReader xmlStreamReader;
|
||||
|
||||
public XmlRpcStreamReader ( InputStream inputStream ) throws XMLStreamException {
|
||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance ( );
|
||||
xmlStreamReader = inputFactory.createXMLStreamReader ( inputStream );
|
||||
}
|
||||
|
||||
public boolean nextTag ( ) throws XMLStreamException {
|
||||
while ( xmlStreamReader.hasNext ( ) ) {
|
||||
int eventType = xmlStreamReader.next ( );
|
||||
if ( eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getLocalName ( ) {
|
||||
return xmlStreamReader.getLocalName ( );
|
||||
}
|
||||
|
||||
public String getElementText ( ) throws XMLStreamException {
|
||||
return xmlStreamReader.getElementText ( );
|
||||
}
|
||||
|
||||
public void require ( int type , String namespaceURI , String localName ) throws XMLStreamException {
|
||||
xmlStreamReader.require ( type , namespaceURI , localName );
|
||||
}
|
||||
|
||||
public String readMethodCallMethodName ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodCall" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodName" );
|
||||
return getElementText ( );
|
||||
}
|
||||
|
||||
public Object[] readMethodCallParams ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "params" );
|
||||
return deserializeParams ( );
|
||||
}
|
||||
|
||||
private Object[] deserializeParams ( ) throws XMLStreamException {
|
||||
Object[] params = new Object[ 0 ];
|
||||
boolean isValueElement = false;
|
||||
while ( nextTag ( ) ) {
|
||||
if ( xmlStreamReader.getLocalName ( ).equals ( "value" ) ) {
|
||||
isValueElement = true;
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "param" ) ) {
|
||||
if ( isValueElement ) {
|
||||
Object value = deserializeValue ( );
|
||||
Object[] newParams = new Object[ params.length + 1 ];
|
||||
System.arraycopy ( params , 0 , newParams , 0 , params.length );
|
||||
newParams[ params.length ] = value;
|
||||
params = newParams;
|
||||
isValueElement = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public Object readMethodResponseResult ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodResponse" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "params" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "param" );
|
||||
return deserializeValue ( );
|
||||
}
|
||||
|
||||
private Object deserializeValue ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
int eventType = xmlStreamReader.getEventType ( );
|
||||
if ( eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA ) {
|
||||
return xmlStreamReader.getText ( );
|
||||
}
|
||||
else if ( eventType == XMLStreamConstants.START_ELEMENT ) {
|
||||
String localName = xmlStreamReader.getLocalName ( );
|
||||
switch ( localName ) {
|
||||
case "string":
|
||||
return deserializeString ( );
|
||||
case "int":
|
||||
return deserializeInt ( );
|
||||
case "double":
|
||||
return deserializeDouble ( );
|
||||
case "boolean":
|
||||
return deserializeBoolean ( );
|
||||
case "array":
|
||||
return deserializeArray ( );
|
||||
case "struct":
|
||||
return deserializeStruct ( );
|
||||
case "nil":
|
||||
return null;
|
||||
default:
|
||||
throw new IllegalArgumentException ( "Unsupported element: " + localName );
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException ( "Unexpected event type: " + eventType );
|
||||
}
|
||||
}
|
||||
|
||||
private String deserializeString ( ) throws XMLStreamException {
|
||||
return getElementText ( );
|
||||
}
|
||||
|
||||
private int deserializeInt ( ) throws XMLStreamException {
|
||||
return Integer.parseInt ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private double deserializeDouble ( ) throws XMLStreamException {
|
||||
return Double.parseDouble ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private boolean deserializeBoolean ( ) throws XMLStreamException {
|
||||
return Boolean.parseBoolean ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private Object[] deserializeArray ( ) throws XMLStreamException {
|
||||
Object[] array = new Object[ 0 ];
|
||||
boolean isValueElement = false;
|
||||
while ( nextTag ( ) ) {
|
||||
if ( xmlStreamReader.getLocalName ( ).equals ( "value" ) ) {
|
||||
isValueElement = true;
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "data" ) ) {
|
||||
if ( isValueElement ) {
|
||||
array = deserializeArrayData ( );
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private Object[] deserializeArrayData ( ) throws XMLStreamException {
|
||||
Object[] array = new Object[ 0 ];
|
||||
boolean isArrayElement = false;
|
||||
while ( nextTag ( ) ) {
|
||||
if ( xmlStreamReader.getLocalName ( ).equals ( "array" ) ) {
|
||||
isArrayElement = true;
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "value" ) ) {
|
||||
if ( isArrayElement ) {
|
||||
Object value = deserializeValue ( );
|
||||
Object[] newArray = new Object[ array.length + 1 ];
|
||||
System.arraycopy ( array , 0 , newArray , 0 , array.length );
|
||||
newArray[ array.length ] = value;
|
||||
array = newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private Map<String, Object> deserializeStruct ( ) throws XMLStreamException {
|
||||
Map<String, Object> struct = new HashMap<> ( );
|
||||
String name = null;
|
||||
while ( nextTag ( ) ) {
|
||||
if ( xmlStreamReader.getLocalName ( ).equals ( "member" ) ) {
|
||||
name = null;
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "name" ) ) {
|
||||
name = getElementText ( );
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "value" ) ) {
|
||||
if ( name != null ) {
|
||||
Object value = deserializeValue ( );
|
||||
struct.put ( name , value );
|
||||
}
|
||||
}
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
|
||||
public static String skipXmlHeader(String xml) {
|
||||
int startIndex = xml.indexOf("<?xml");
|
||||
if (startIndex >= 0) {
|
||||
int endIndex = xml.indexOf("?>", startIndex);
|
||||
if (endIndex >= 0) {
|
||||
return xml.substring(endIndex + 2);
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
|
||||
public void close ( ) throws XMLStreamException {
|
||||
xmlStreamReader.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmlRpcStreamWriter {
|
||||
private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
private static final String METHOD_CALL_START_TAG = "<methodCall>";
|
||||
private static final String METHOD_CALL_END_TAG = "</methodCall>";
|
||||
private static final String METHOD_NAME_START_TAG = "<methodName>";
|
||||
private static final String METHOD_NAME_END_TAG = "</methodName>";
|
||||
private static final String METHOD_RESPONSE_START_TAG = "<methodResponse>";
|
||||
private static final String METHOD_RESPONSE_END_TAG = "</methodResponse>";
|
||||
private static final String PARAMS_START_TAG = "<params>";
|
||||
private static final String PARAMS_END_TAG = "</params>";
|
||||
private static final String PARAM_START_TAG = "<param>";
|
||||
private static final String PARAM_END_TAG = "</param>";
|
||||
private static final String VALUE_START_TAG = "<value>";
|
||||
private static final String VALUE_END_TAG = "</value>";
|
||||
private static final String ARRAY_START_TAG = "<array>";
|
||||
private static final String ARRAY_END_TAG = "</array>";
|
||||
private static final String DATA_START_TAG = "<data>";
|
||||
private static final String DATA_END_TAG = "</data>";
|
||||
private static final String STRUCT_START_TAG = "<struct>";
|
||||
private static final String STRUCT_END_TAG = "</struct>";
|
||||
private static final String MEMBER_START_TAG = "<member>";
|
||||
private static final String MEMBER_END_TAG = "</member>";
|
||||
private static final String NAME_START_TAG = "<name>";
|
||||
private static final String NAME_END_TAG = "</name>";
|
||||
|
||||
private Writer writer;
|
||||
|
||||
public XmlRpcStreamWriter ( OutputStream outputStream ) {
|
||||
this.writer = new OutputStreamWriter ( outputStream );
|
||||
}
|
||||
|
||||
public void writeMethodCall ( String methodName , List<Object> params ) throws IOException {
|
||||
writer.write ( XML_VERSION );
|
||||
writer.write ( METHOD_CALL_START_TAG );
|
||||
writer.write ( METHOD_NAME_START_TAG );
|
||||
writer.write ( methodName );
|
||||
writer.write ( METHOD_NAME_END_TAG );
|
||||
writer.write ( PARAMS_START_TAG );
|
||||
|
||||
if ( params != null ) {
|
||||
for ( Object param : params ) {
|
||||
writer.write ( PARAM_START_TAG );
|
||||
writeValue ( param );
|
||||
writer.write ( PARAM_END_TAG );
|
||||
}
|
||||
}
|
||||
|
||||
writer.write ( PARAMS_END_TAG );
|
||||
writer.write ( METHOD_CALL_END_TAG );
|
||||
writer.flush ( );
|
||||
}
|
||||
|
||||
public void writeMethodResponse ( Object value ) throws IOException {
|
||||
writer.write ( XML_VERSION );
|
||||
writer.write ( METHOD_RESPONSE_START_TAG );
|
||||
writer.write ( PARAMS_START_TAG );
|
||||
writer.write ( PARAM_START_TAG );
|
||||
writeValue ( value );
|
||||
writer.write ( PARAM_END_TAG );
|
||||
writer.write ( PARAMS_END_TAG );
|
||||
writer.write ( METHOD_RESPONSE_END_TAG );
|
||||
writer.flush ( );
|
||||
}
|
||||
|
||||
private void writeValue ( Object value ) throws IOException {
|
||||
if ( value == null ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<nil/>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof String ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<string>" );
|
||||
writer.write ( escapeXml ( ( String ) value ) );
|
||||
writer.write ( "</string>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Integer ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<int>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</int>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Double ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<double>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</double>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Boolean ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<boolean>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</boolean>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof List ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( ARRAY_START_TAG );
|
||||
writer.write ( DATA_START_TAG );
|
||||
List<?> list = ( List<?> ) value;
|
||||
for ( Object item : list ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writeValue ( item );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
writer.write ( DATA_END_TAG );
|
||||
writer.write ( ARRAY_END_TAG );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Map ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( STRUCT_START_TAG );
|
||||
Map<?, ?> map = ( Map<?, ?> ) value;
|
||||
for ( Map.Entry<?, ?> entry : map.entrySet ( ) ) {
|
||||
writer.write ( MEMBER_START_TAG );
|
||||
writer.write ( NAME_START_TAG );
|
||||
writer.write ( escapeXml ( entry.getKey ( ).toString ( ) ) );
|
||||
writer.write ( NAME_END_TAG );
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writeValue ( entry.getValue ( ) );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
writer.write ( MEMBER_END_TAG );
|
||||
}
|
||||
writer.write ( STRUCT_END_TAG );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException ( "Unsupported data type: " + value.getClass ( ).getName ( ) );
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeXml ( String value ) {
|
||||
return value
|
||||
.replace ( "&" , "&" )
|
||||
.replace ( "<" , "<" )
|
||||
.replace ( ">" , ">" )
|
||||
.replace ( "\"" , """ )
|
||||
.replace ( "'" , "'" );
|
||||
}
|
||||
|
||||
public void close ( ) throws IOException {
|
||||
writer.close ( );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue