/* * Copyright (c) 2015 iTAC Software AG, Germany. All Rights Reserved. * * This software is protected by copyright. Under no circumstances may any part of this file in any form be copied, * printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language * without the written permission of iTAC Software AG. */ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Text; namespace com.itac.mes.tools { /// /// This Class is able to serialize all objects to a xml string. /// public class ItacXmlSerializer { private static int MAX_INDENT_LEVEL = 15; private static int indentationWidth = 2; private int indentationLevel = 0; private bool formatting = true; private StringBuilder writer; private static String[] indentStrings; private bool logXmlFormat = true;// Eine Möglichkeit auch nicht-XML zu loggen static ItacXmlSerializer() { indentStrings = new String[MAX_INDENT_LEVEL]; for (int level = 0; level < MAX_INDENT_LEVEL; level++) { StringBuilder indentBuffer = new StringBuilder(); int count = level * indentationWidth; for (int i = 0; i < count; i++) { indentBuffer.Append(' '); } indentStrings[level] = indentBuffer.ToString(); } } // [MethodImpl(MethodImplOptions.Synchronized)] /// /// /// public StringBuilder serialize(Object source) { if (source == null) { return new StringBuilder("null"); } writer = new StringBuilder(); if (source.GetType().IsArray) { writeArray("", source); } else { writeStart(source.GetType().Name, true); writeStructure(source); writeEnd(source.GetType().Name, true, true); } return writer; } private void indent() { if (formatting) { indentationLevel += 1; } } private void unindent() { if (formatting && indentationLevel > 0) { indentationLevel -= 1; } } private void writeArray(String fieldName, Object fieldvalue) { Object[] array = (Object[])fieldvalue; // do not print empty arrays if (array != null && array.Length > 0) { if (!fieldName.Equals("")) { writeStart(fieldName, true); } String simpleClassName = fieldvalue.GetType().Name.Substring(0, fieldvalue.GetType().Name.Length - 2); for (int i = 0; i < array.Length; i++) { writeStart(simpleClassName, true); writeObject("", array[i]); writeEnd(simpleClassName, true, false); } if (!fieldName.Equals("")) { writeEnd(fieldName, true, false); } } } private void writeList(String fieldName, Object fieldvalue) { IList array = (IList)fieldvalue; // do not print empty arrays if (array != null && array.Count > 0) { if (!fieldName.Equals("")) { writeStart(fieldName, true); } String simpleClassName = fieldvalue.GetType().Name.Substring(0, fieldvalue.GetType().Name.Length - 2); for (int i = 0; i < array.Count; i++) { // writeStart(simpleClassName, true); writeStructure(array[i]); // writeEnd(simpleClassName, true, false); } if (!fieldName.Equals("")) { writeEnd(fieldName, true, false); } } } private void allClassProperties(List fieldList, Type clazz) { // über alle Felder aller parent Interfaces, solange das Interface nicht Object ist. if (clazz == null || clazz == typeof(Object)) { return; } // fields: all public fields PropertyInfo[] fields = clazz.GetProperties(); foreach (PropertyInfo field in fields) { fieldList.Add(field); } allClassProperties(fieldList, clazz.BaseType); } private void allClassFields(List fieldList, Type clazz) { // über alle Felder aller parent Interfaces, solange das Interface nicht Object ist. if (clazz == null || clazz == typeof(Object)) { return; } // fields: all public fields FieldInfo[] fields = clazz.GetFields(BindingFlags.Instance| BindingFlags.NonPublic); foreach (FieldInfo field in fields) { fieldList.Add(field); } // allClassFields(fieldList, clazz.BaseType); } private void writeStructure(Object source) { List propertyList = new List(); allClassProperties(propertyList, source.GetType()); List fieldList = new List(); allClassFields(fieldList, source.GetType()); foreach (PropertyInfo field2 in propertyList) { try { Object fieldvalue = field2.GetValue(source, null); writeObject(field2.Name, fieldvalue); } catch (Exception) { writeObject(field2.Name, "property write failed"); } } foreach (FieldInfo field2 in fieldList) { try { Object fieldvalue = field2.GetValue(source); writeObject(field2.Name, fieldvalue); } catch (Exception) { writeObject(field2.Name, "field write failed"); } } } private void writeObject(String fieldName, object fieldvalue) { if (fieldvalue == null) { return; } if (fieldvalue.GetType() == typeof(String)) { writeString(fieldName, (String)fieldvalue); } else if (fieldvalue.GetType() == typeof(DateTime)) { writeDate(fieldName, (DateTime)fieldvalue); } else if (fieldvalue.GetType() == typeof(bool) || fieldvalue.GetType() == typeof(Boolean)) { if (((bool)fieldvalue)) { writeString(fieldName, "true"); } else { writeString(fieldName, "false"); } } else if (fieldvalue.GetType() == typeof(byte) || fieldvalue.GetType() == typeof(int) || fieldvalue.GetType() == typeof(Int16) || fieldvalue.GetType() == typeof(Int32) || fieldvalue.GetType() == typeof(Int64)) { writeIntNumber(fieldName, (Object)fieldvalue); } else if (fieldvalue.GetType() == typeof(double) || fieldvalue.GetType() == typeof(float)) { writeNumber(fieldName, (Object)fieldvalue); } else if (fieldvalue.GetType() == typeof(Double)) { writeNumber(fieldName, (Object)fieldvalue); } else if (fieldvalue.GetType().IsGenericType) { writeList(fieldName, fieldvalue); } else if (fieldvalue.GetType().IsArray) { writeArray(fieldName, fieldvalue); } else { // Strukturierten Wert schreiben writeStart(fieldName, true); writeStructure(fieldvalue); writeEnd(fieldName, true, false); } } private void writeDate(String fieldName, DateTime fieldvalue) { writeStart(fieldName, false); writer.Append(fieldvalue.ToString("o")); writeEnd(fieldName, false, false); } private void writeStart(string fieldName, bool endLineAndIndent) { startLine(); if (logXmlFormat) { writer.Append("<"); writer.Append(fieldName); writer.Append(">"); } else { writer.Append(fieldName); writer.Append(": "); } if (endLineAndIndent) { endLine(); indent(); } } private void writeEnd(string fieldName, bool indenting, bool newLine) { if (logXmlFormat) { if (indenting) { unindent(); startLine(); } writer.Append(""); endLine(); } else { if (indenting) { unindent(); } if (newLine) { endLine(); } } } private void writeNumber(String fieldName, Object fieldvalue) { writeStart(fieldName, false); writer.Append(fieldvalue.ToString()); writeEnd(fieldName, false, true); } private void writeIntNumber(String fieldName, Object fieldvalue) { writeStart(fieldName, false); writer.Append(fieldvalue.ToString()); writeEnd(fieldName, false, true); } private void writeString(String fieldName, String value) { writeStart(fieldName, false); writer.Append(value); writeEnd(fieldName, false, true); } private void endLine() { if (formatting) { writer.Append("\n"); } } private void startLine() { if (formatting) { writer.Append(indentStrings[Math.Min(indentationLevel, MAX_INDENT_LEVEL)]); } } } }