JOSParser - Der neue SimpleParser
Veröffentlicht: 16.09.2010 um 09:24 von Tomate_Salat
Aktualisiert: 04.02.2011 um 15:55 von Tomate_Salat (Kommentare korrigiert)
Aktualisiert: 04.02.2011 um 15:55 von Tomate_Salat (Kommentare korrigiert)
Der JOSParser ist die Weiterentwicklung des SimpleParsers. Neben der Namensänderung hat sich auch technisch viel geändert. So muss er nicht mehr geerbt werden, sondern arbeitet mit Referenzen. Auch nutzt er keine getter/setter mehr zum erkennen/initialisieren von Werten, sondern arbeitet direkt mit den Feldern. Er kann Numbers, Characters und Strings in einem Objekt serialisieren. Die größte Neuerung ist allerdings: Er kann Objekte im Objekt nun bearbeiten.
JOSParser.java
Noch ein kleines Anwendungsbeispiel:
DemoPaket.java
irgendeine main:
Die Ausgabe:
Zukunftsvisionen
Mit freundichen Grüßen
Tomate_Salat
JOSParser.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * JOSParser ermöglicht es, simple Datentypen (String, Number, Char) und * Objekte, bestehend aus diesen Datentypen, in Strings umzuwandeln. Dabei verbraucht der * JOSParser weit weniger Overheap als die Serialisierung. <br> * <br> * Objekte wandeln Sie zu einem Byte-Array um über:<br> * byte[] myObject = JOSParser.parse(myObject);<br> * <br> * Der Rückweg ist genauso einfach:<br> * myObject = JOSParser.create(MyClass.class,myObject);<br> * <br> * * * @author Tomate_Salat */ public class JOSParser { private final static String[] TAG = { "\\]", "\\[" }; private final static String[] UML = { "&#lob;", "&#lcb;" }; /** * Diese Methode ermöglicht das parsen eines Objektes in einen String. * * @param obj * @return Das geparste Objekt als String */ public static String parseAsString(Object obj) { return getObject(obj); } /** * Diese Methode ermöglicht das parsen eines Objektes in ein Byte-Array * * @param obj * @return Das Objekt in bytes */ public static byte[] parse(Object obj) { return getObject(obj).getBytes(); } /** * Versucht das Objekt anhand der übergebenen bytes wieder herzustellen und eine Referenz * darauf zurückzugeben. Dazu benötigt es die Klasse des ursprünglichen Objektes. * * @param clazz * die Klasse des zu wiederherstelenden Objektes * @param data * das Objekt als Byte-Array * @return * eine Referenz auf das Objekt */ public static <T> T create(Class<T> clazz, byte[] data) { return JOSParser.create(clazz, new String(data)); } /** * Versucht das Objekt anhand des übergebenen Strings wieder herzustellen und eine Referenz * darauf zurückzugeben. Dazu benötigt es die Klasse des ursprünglichen Objektes. * * @param clazz * die Klasse des zu wiederherstelenden Objektes * @param data * das Objekt als String * @return * eine Referenz auf das Objekt */ public static <T> T create(Class<T> clazz, String data) { try { return setData(data.trim(), clazz); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } private static boolean isObject(String data) { return Pattern.compile("^\\[(.*)\\]$").matcher(data).matches(); } private static String getObject(Object obj) { Field[] felder = obj.getClass().getDeclaredFields(); try { String index = "[{", value = "", temp = ""; Object tObj = null; for (Field f : felder) { f.setAccessible(true); tObj = f.get(obj); if (tObj instanceof Number || tObj instanceof String || tObj instanceof Character) { temp = String.valueOf(tObj); temp = decode(temp); } else temp = getObject(tObj); value += temp; index += temp.length() + "|"; } return index.substring(0, index.length() - 1) + "}" + value + "]"; } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return ""; } private static <T> T setData(String data, Class<T> clazz) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InstantiationException, SecurityException, NoSuchMethodException, InvocationTargetException { if (!isObject(data)) return null; Constructor<T> cons = clazz.getDeclaredConstructor(); cons.setAccessible(true); T object = cons.newInstance(); data = data.substring(1, data.length() - 1); Matcher dataset = Pattern.compile("^\\{([^\\}]*?)\\}(.*)$").matcher( data); Field[] felder = clazz.getDeclaredFields(); String[] index = null; String defines = ""; if (dataset.matches()) { index = dataset.group(1).split("\\|"); defines = dataset.group(2); } if (index.length > felder.length) return null; int iLength; int cursor = 0; String subValue = ""; Field feld = null; for (int i = 0; i < index.length; i++) { feld = felder[i]; iLength = Integer.valueOf(index[i]); subValue = defines.substring(cursor, cursor + iLength); feld.setAccessible(true); if (isObject(subValue)) feld.set(object, setData(subValue, feld.getType())); else safeDataToField(object, feld, subValue); cursor += iLength; } return object; } @SuppressWarnings("unchecked") private static void safeDataToField(Object obj, Field feld, String value) throws IllegalArgumentException, IllegalAccessException { Class clazz = feld.getType(); if (clazz == String.class) feld.set(obj, encode(value)); else if (clazz == Integer.class || clazz == int.class) feld.set(obj, Integer.parseInt(value)); else if (clazz == Float.class || clazz == float.class) feld.set(obj, Float.parseFloat(value)); else if (clazz == Long.class || clazz == long.class) feld.set(obj, Long.parseLong(value)); else if (clazz == Double.class || clazz == double.class) feld.set(obj, Double.parseDouble(value)); else if (clazz == Character.class || clazz == char.class) feld.set(obj, value.charAt(0)); } private static String decode(String str) { for (int i = 0; i < TAG.length; i++) { str = str.replaceAll(TAG[i], UML[i]); } return str; } private static String encode(String str) { for (int i = 0; i < TAG.length; i++) { str = str.replaceAll(UML[i], TAG[i]); } return str; } }
Noch ein kleines Anwendungsbeispiel:
DemoPaket.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import java.io.Serializable; public class DemoPaket implements Serializable { private String name; private User user; public DemoPaket() { user = new User(); } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAlter(int alter) { user.alter = alter; } public int getAlter() { return user.alter; } } class User implements Serializable { int alter = 19; }
irgendeine main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public static void main(String[] args) { DemoPaket paket = new DemoPaket(); paket.setName("Tomate_Salat"); byte[] josbytes = JOSParser.parse(paket); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(paket); } catch (IOException e) { e.printStackTrace(); } System.out.println("Protokoll: " + JOSParser.parseAsString(paket)); System.out.println("JOS: " + josbytes.length + " bytes"); System.out.println("OoS: " + baos.size() + " bytes"); DemoPaket p = JOSParser.create(DemoPaket.class, josbytes); System.out.println("p#getName: " + p.getName()); System.out.println("p#getAlter: " + p.getAlter()); }
Die Ausgabe:
Code:
Protokoll: [{12|7}Tomate_Salat[{2}19]]
JOS: 27 bytes
OoS: 128 bytes
p#getName: Tomate_Salat
p#getAlter: 19
- Arrays unterstützen
- Listen unsterstützen
- EMF
Mit freundichen Grüßen
Tomate_Salat
Kommentare 0







