|
1 | 1 | package com.linkedlogics.bio.utility;
|
2 | 2 |
|
| 3 | +import java.util.Arrays; |
| 4 | +import java.util.Comparator; |
| 5 | +import java.util.List; |
| 6 | +import java.util.Map.Entry; |
| 7 | +import java.util.regex.Pattern; |
| 8 | +import java.util.stream.Collectors; |
| 9 | + |
| 10 | +import com.linkedlogics.bio.dictionary.BioDictionary; |
| 11 | +import com.linkedlogics.bio.dictionary.BioEnumObj; |
| 12 | +import com.linkedlogics.bio.dictionary.BioObj; |
| 13 | +import com.linkedlogics.bio.dictionary.BioTag; |
| 14 | +import com.linkedlogics.bio.dictionary.BioType; |
| 15 | +import com.linkedlogics.bio.object.BioEnum; |
3 | 16 | import com.linkedlogics.bio.object.BioObject;
|
4 | 17 | import com.linkedlogics.bio.parser.BioObjectXmlParser;
|
| 18 | +import com.linkedlogics.bio.time.BioTime; |
5 | 19 |
|
6 | 20 | public class XMLUtility {
|
7 | 21 | public static String toXml(BioObject object) {
|
8 |
| - return null ; |
| 22 | + StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") ; |
| 23 | + toXml(xml, "", object.getBioName(), object) ; |
| 24 | + return xml.toString() ; |
| 25 | + } |
| 26 | + |
| 27 | + private static void toXml(StringBuilder xml, String tab, String tag, BioObject object) { |
| 28 | + if (tag == null) { |
| 29 | + tag = "bio"; |
| 30 | + } |
| 31 | + |
| 32 | + BioDictionary dictionary = BioDictionary.getDictionary(object.getBioDictionary()); |
| 33 | + if (dictionary.getObjByCode(object.getBioCode()) != null) { |
| 34 | + BioObj obj = dictionary.getObjByCode(object.getBioCode()); |
| 35 | + xml.append(tab).append("<") |
| 36 | + .append(tag.replaceAll("_", "-")) |
| 37 | + .append(" type=\"").append(obj.getType()) |
| 38 | + .append("\" code=\"").append(object.getBioCode()) ; |
| 39 | + if (object.getBioVersion() != 0) { |
| 40 | + xml.append("\" version=\"").append(object.getBioVersion()) ; |
| 41 | + } |
| 42 | + if (object.getBioDictionary() != 0) { |
| 43 | + xml.append("\" dictionary=\"").append(object.getBioDictionary()) ; |
| 44 | + } |
| 45 | + xml.append("\">\n"); |
| 46 | + object.stream().sorted(Comparator.comparing(Entry::getKey)).forEach(e -> { |
| 47 | + // keys starting with _ will not be exported |
| 48 | + if (!e.getKey().startsWith("_")) { |
| 49 | + Object value = object.get(e.getKey()); |
| 50 | + |
| 51 | + BioTag bioTag = obj.getTag(e.getKey()) ; |
| 52 | + if (bioTag == null) { |
| 53 | + toXml(xml, tab, e.getKey(), value, ConversionUtility.getType(value), null); |
| 54 | + } else if (bioTag.isExportable()) { |
| 55 | + toXml(xml, tab, e.getKey(), value, bioTag.getType(), bioTag); |
| 56 | + } |
| 57 | + } |
| 58 | + }); |
| 59 | + } else { |
| 60 | + xml.append(tab).append("<") |
| 61 | + .append(tag.replaceAll("_", "-")) |
| 62 | + .append(" type=\"BioObject") |
| 63 | + .append("\" code=\"").append(object.getBioCode()) |
| 64 | + .append("\" version=\"").append(object.getBioVersion()) |
| 65 | + .append("\">\n"); |
| 66 | + object.stream().sorted(Comparator.comparing(Entry::getKey)).forEach(e -> { |
| 67 | + if (!e.getKey().startsWith("_")) { |
| 68 | + Object value = object.get(e.getKey()); |
| 69 | + toXml(xml, tab, e.getKey(), value, ConversionUtility.getType(value), null); |
| 70 | + } |
| 71 | + }); |
| 72 | + } |
| 73 | + |
| 74 | + xml.append(tab).append("</").append(tag.replaceAll("_", "-")).append(">\n"); |
| 75 | + } |
| 76 | + |
| 77 | + public static void toXml(StringBuilder xml, String tab, String key, Object value, BioType type, BioTag tag) { |
| 78 | + if (value instanceof BioObject[]) { |
| 79 | + xml.append(tab).append(TAB).append("<").append(key) |
| 80 | + .append(" type=\"").append(type) |
| 81 | + .append("\" is-array=\"true\">\n"); |
| 82 | + BioObject[] array = (BioObject[]) value; |
| 83 | + for (int i = 0; i < array.length; i++) { |
| 84 | + toXml(xml, tab + TAB + TAB, array[i].getBioName(), array[i]); |
| 85 | + } |
| 86 | + xml.append(tab).append(TAB).append("</").append(key).append(">\n"); |
| 87 | + } else if (value instanceof BioEnum[]) { |
| 88 | + BioEnum[] array = (BioEnum[]) value; |
| 89 | + xml.append(tab).append(TAB).append("<").append(key) |
| 90 | + .append(" type=\"").append(tag.getEnumObj().getName()) |
| 91 | + .append("\" is-array=\"true\">") |
| 92 | + .append(Arrays.stream(array).map(e -> { |
| 93 | + return e.toString() ; |
| 94 | + }).collect(Collectors.joining(SEP))) |
| 95 | + .append("</").append(key).append(">\n"); |
| 96 | + } else if (value instanceof Object[]) { |
| 97 | + Object[] array = (Object[]) value; |
| 98 | + xml.append(tab).append(TAB).append("<").append(key) |
| 99 | + .append(" type=\"").append(type) |
| 100 | + .append("\" is-array=\"true\">") |
| 101 | + .append(Arrays.stream(array).map(e -> { |
| 102 | + return e.toString() ; |
| 103 | + }).collect(Collectors.joining(SEP))) |
| 104 | + .append("</").append(key).append(">\n"); |
| 105 | + } else if (value instanceof List) { |
| 106 | + List<Object> list = (List<Object>) value; |
| 107 | + if (tag != null) { |
| 108 | + // If list bio type is another bio object then we can't join them with commas |
| 109 | + // it will same as array but only xml attribute will is-list="true" |
| 110 | + if (tag.getObj() != null) { |
| 111 | + xml.append(tab).append(TAB).append("<").append(key) |
| 112 | + .append(" type=\"").append(tag.getObj().getName()) |
| 113 | + .append("\" is-list=\"true\">\n"); |
| 114 | + for (int i = 0; i < list.size(); i++) { |
| 115 | + toXml(xml, tab + TAB + TAB, ((BioObject)list.get(i)).getBioName(), (BioObject) list.get(i)); |
| 116 | + } |
| 117 | + xml.append(tab).append(TAB).append("</").append(key).append(">\n"); |
| 118 | + return ; |
| 119 | + } else if (tag.getEnumObj() != null) { |
| 120 | + xml.append(tab).append(TAB).append("<").append(key) |
| 121 | + .append(" type=\"").append(tag.getEnumObj().getName()) ; |
| 122 | + } else { |
| 123 | + xml.append(tab).append(TAB).append("<").append(key) |
| 124 | + .append(" type=\"").append(tag.getType()) ; |
| 125 | + } |
| 126 | + } else { |
| 127 | + xml.append(tab).append(TAB).append("<").append(key) |
| 128 | + .append(" type=\"").append(type) ; |
| 129 | + } |
| 130 | + |
| 131 | + xml.append("\" is-list=\"true\">") |
| 132 | + .append(list.stream().map(e -> { |
| 133 | + return e.toString() ; |
| 134 | + }).collect(Collectors.joining(SEP))) |
| 135 | + .append("</").append(key).append(">\n"); |
| 136 | + } else if (value instanceof BioObject) { |
| 137 | + toXml(xml, tab + TAB, key, ((BioObject) value)); |
| 138 | + } else if (type == BioType.String || type == BioType.UtfString) { |
| 139 | + int bytes = value.toString().getBytes().length; |
| 140 | + if (xmlForbiddenChars.matcher(value.toString()).find() || bytes > value.toString().length() || type == BioType.UtfString) { |
| 141 | + xml.append(tab).append(TAB).append("<").append(key) |
| 142 | + .append(" type=\"").append(type) |
| 143 | + .append("\"><![CDATA[").append(value).append("]]></") |
| 144 | + .append(key).append(">\n"); |
| 145 | + } else { |
| 146 | + xml.append(tab).append(TAB).append("<").append(key) |
| 147 | + .append(" type=\"").append(type).append("\">") |
| 148 | + .append(value).append("</") |
| 149 | + .append(key).append(">\n"); |
| 150 | + } |
| 151 | + } else if (type == BioType.Time && value instanceof Long) { |
| 152 | + xml.append(tab).append(TAB).append("<").append(key) |
| 153 | + .append(" type=\"").append(type).append("\">") |
| 154 | + .append(BioTime.format((Long) value, BioTime.DATETIME_FORMAT)) |
| 155 | + .append("</").append(key).append(">\n"); |
| 156 | + } else if (type == BioType.BioEnum && value instanceof BioEnum) { |
| 157 | + BioEnum bioEnum = (BioEnum) value; |
| 158 | + String enumObjName = value.getClass().getSimpleName(); |
| 159 | + BioEnumObj bioEnumObj = BioDictionary.getDictionary(bioEnum.getBioDictionary()).getBioEnumObj(enumObjName); |
| 160 | + if (bioEnumObj == null) { |
| 161 | + bioEnumObj = BioDictionary.getDictionary(bioEnum.getBioDictionary()).getBioEnumObj(bioEnum.getBioCode()); |
| 162 | + } |
| 163 | + if (bioEnumObj != null) { |
| 164 | + xml.append(tab).append(TAB).append("<").append(key) |
| 165 | + .append(" type=\"").append(bioEnumObj.getName()).append("\">") |
| 166 | + .append(value).append("</") |
| 167 | + .append(key).append(">\n"); |
| 168 | + } |
| 169 | + } else { |
| 170 | + xml.append(tab).append(TAB).append("<").append(key) |
| 171 | + .append(" type=\"").append(type).append("\">") |
| 172 | + .append(value).append("</") |
| 173 | + .append(key).append(">\n"); |
| 174 | + } |
9 | 175 | }
|
10 | 176 |
|
11 | 177 | public static BioObject fromXml(String xml) {
|
12 | 178 | return new BioObjectXmlParser().parse(xml) ;
|
13 | 179 | }
|
| 180 | + |
| 181 | + public static final String TAB = " "; |
| 182 | + public static final String SEP = "," ; |
| 183 | + public static final Pattern xmlForbiddenChars = Pattern.compile("[<>&\"']"); |
14 | 184 | }
|
0 commit comments