Guest User

Untitled

a guest
Jan 17th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.75 KB | None | 0 0
  1. /**
  2. * Copyright (c) 2008-2013, http://www.snakeyaml.org
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.yaml.snakeyaml.representer;
  17.  
  18. import java.io.UnsupportedEncodingException;
  19. import java.math.BigInteger;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Calendar;
  23. import java.util.Date;
  24. import java.util.HashMap;
  25. import java.util.Iterator;
  26. import java.util.LinkedHashMap;
  27. import java.util.List;
  28. import java.util.Map;
  29. import java.util.Set;
  30. import java.util.TimeZone;
  31. import java.util.regex.Pattern;
  32.  
  33. import org.yaml.snakeyaml.error.YAMLException;
  34. import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
  35. import org.yaml.snakeyaml.nodes.Node;
  36. import org.yaml.snakeyaml.nodes.Tag;
  37. import org.yaml.snakeyaml.reader.StreamReader;
  38.  
  39. /**
  40. * Represent standard Java classes
  41. */
  42. class SafeRepresenter extends BaseRepresenter {
  43.  
  44. protected Map<Class<? extends Object>, Tag> classTags;
  45. protected TimeZone timeZone = null;
  46.  
  47. public SafeRepresenter() {
  48. this.nullRepresenter = new RepresentNull();
  49. this.representers.put(String.class, new RepresentString());
  50. this.representers.put(Boolean.class, new RepresentBoolean());
  51. this.representers.put(Character.class, new RepresentString());
  52. this.representers.put(byte[].class, new RepresentByteArray());
  53.  
  54. Represent primitiveArray = new RepresentPrimitiveArray();
  55. representers.put(short[].class, primitiveArray);
  56. representers.put(int[].class, primitiveArray);
  57. representers.put(long[].class, primitiveArray);
  58. representers.put(float[].class, primitiveArray);
  59. representers.put(double[].class, primitiveArray);
  60. representers.put(char[].class, primitiveArray);
  61. representers.put(boolean[].class, primitiveArray);
  62.  
  63. this.multiRepresenters.put(Number.class, new RepresentNumber());
  64. this.multiRepresenters.put(List.class, new RepresentList());
  65. this.multiRepresenters.put(Map.class, new RepresentMap());
  66. this.multiRepresenters.put(Set.class, new RepresentSet());
  67. this.multiRepresenters.put(Iterator.class, new RepresentIterator());
  68. this.multiRepresenters.put(new Object[0].getClass(), new RepresentArray());
  69. this.multiRepresenters.put(Date.class, new RepresentDate());
  70. this.multiRepresenters.put(Enum.class, new RepresentEnum());
  71. this.multiRepresenters.put(Calendar.class, new RepresentDate());
  72. classTags = new HashMap<Class<? extends Object>, Tag>();
  73. }
  74.  
  75. protected Tag getTag(Class<?> clazz, Tag defaultTag) {
  76. if (classTags.containsKey(clazz)) {
  77. return classTags.get(clazz);
  78. } else {
  79. return defaultTag;
  80. }
  81. }
  82.  
  83. /**
  84. * Define a tag for the <code>Class</code> to serialize
  85. *
  86. * @deprecated use Tag instead of String
  87. * @param clazz
  88. * <code>Class</code> which tag is changed
  89. * @param tag
  90. * new tag to be used for every instance of the specified
  91. * <code>Class</code>
  92. * @return the previous tag associated with the <code>Class</code>
  93. */
  94. public Tag addClassTag(Class<? extends Object> clazz, String tag) {
  95. return addClassTag(clazz, new Tag(tag));
  96. }
  97.  
  98. /**
  99. * Define a tag for the <code>Class</code> to serialize.
  100. *
  101. * @param clazz
  102. * <code>Class</code> which tag is changed
  103. * @param tag
  104. * new tag to be used for every instance of the specified
  105. * <code>Class</code>
  106. * @return the previous tag associated with the <code>Class</code>
  107. */
  108. public Tag addClassTag(Class<? extends Object> clazz, Tag tag) {
  109. if (tag == null) {
  110. throw new NullPointerException("Tag must be provided.");
  111. }
  112. return classTags.put(clazz, tag);
  113. }
  114.  
  115. protected class RepresentNull implements Represent {
  116. public Node representData(Object data) {
  117. return representScalar(Tag.NULL, "null");
  118. }
  119. }
  120.  
  121. public static Pattern MULTILINE_PATTERN = Pattern.compile("\n|\u0085|\u2028|\u2029");
  122.  
  123. protected class RepresentString implements Represent {
  124. public Node representData(Object data) {
  125. Tag tag = Tag.STR;
  126. Character style = null;
  127. String value = data.toString();
  128. if (StreamReader.NON_PRINTABLE.matcher(value).find()) {
  129. tag = Tag.BINARY;
  130. char[] binary;
  131. try {
  132. binary = Base64Coder.encode(value.getBytes("UTF-8"));
  133. } catch (UnsupportedEncodingException e) {
  134. throw new YAMLException(e);
  135. }
  136. value = String.valueOf(binary);
  137. style = '|';
  138. }
  139. // if no other scalar style is explicitly set, use literal style for
  140. // multiline scalars
  141. if (defaultScalarStyle == null && MULTILINE_PATTERN.matcher(value).find()) {
  142. style = '|';
  143. }
  144. return representScalar(tag, value, style);
  145. }
  146. }
  147.  
  148. protected class RepresentBoolean implements Represent {
  149. public Node representData(Object data) {
  150. String value;
  151. if (Boolean.TRUE.equals(data)) {
  152. value = "true";
  153. } else {
  154. value = "false";
  155. }
  156. return representScalar(Tag.BOOL, value);
  157. }
  158. }
  159.  
  160. protected class RepresentNumber implements Represent {
  161. public Node representData(Object data) {
  162. Tag tag;
  163. String value;
  164. if (data instanceof Byte || data instanceof Short || data instanceof Integer
  165. || data instanceof Long || data instanceof BigInteger) {
  166. tag = Tag.INT;
  167. value = data.toString();
  168. } else {
  169. Number number = (Number) data;
  170. tag = Tag.FLOAT;
  171. if (number.equals(Double.NaN)) {
  172. value = ".NaN";
  173. } else if (number.equals(Double.POSITIVE_INFINITY)) {
  174. value = ".inf";
  175. } else if (number.equals(Double.NEGATIVE_INFINITY)) {
  176. value = "-.inf";
  177. } else {
  178. value = number.toString();
  179. }
  180. }
  181. return representScalar(getTag(data.getClass(), tag), value);
  182. }
  183. }
  184.  
  185. protected class RepresentList implements Represent {
  186. @SuppressWarnings("unchecked")
  187. public Node representData(Object data) {
  188. return representSequence(getTag(data.getClass(), Tag.SEQ), (List<Object>) data, null);
  189. }
  190. }
  191.  
  192. protected class RepresentIterator implements Represent {
  193. @SuppressWarnings("unchecked")
  194. public Node representData(Object data) {
  195. Iterator<Object> iter = (Iterator<Object>) data;
  196. return representSequence(getTag(data.getClass(), Tag.SEQ), new IteratorWrapper(iter),
  197. null);
  198. }
  199. }
  200.  
  201. private static class IteratorWrapper implements Iterable<Object> {
  202. private Iterator<Object> iter;
  203.  
  204. public IteratorWrapper(Iterator<Object> iter) {
  205. this.iter = iter;
  206. }
  207.  
  208. public Iterator<Object> iterator() {
  209. return iter;
  210. }
  211. }
  212.  
  213. protected class RepresentArray implements Represent {
  214. public Node representData(Object data) {
  215. Object[] array = (Object[]) data;
  216. List<Object> list = Arrays.asList(array);
  217. return representSequence(Tag.SEQ, list, null);
  218. }
  219. }
  220.  
  221. /**
  222. * Represents primitive arrays, such as short[] and float[], by converting
  223. * them into equivalent List<Short> and List<Float> using the appropriate
  224. * autoboxing type.
  225. */
  226. protected class RepresentPrimitiveArray implements Represent {
  227. public Node representData(Object data) {
  228. Class<?> type = data.getClass().getComponentType();
  229.  
  230. if (byte.class == type) {
  231. return representSequence(Tag.SEQ, asByteList(data), null);
  232. } else if (short.class == type) {
  233. return representSequence(Tag.SEQ, asShortList(data), null);
  234. } else if (int.class == type) {
  235. return representSequence(Tag.SEQ, asIntList(data), null);
  236. } else if (long.class == type) {
  237. return representSequence(Tag.SEQ, asLongList(data), null);
  238. } else if (float.class == type) {
  239. return representSequence(Tag.SEQ, asFloatList(data), null);
  240. } else if (double.class == type) {
  241. return representSequence(Tag.SEQ, asDoubleList(data), null);
  242. } else if (char.class == type) {
  243. return representSequence(Tag.SEQ, asCharList(data), null);
  244. } else if (boolean.class == type) {
  245. return representSequence(Tag.SEQ, asBooleanList(data), null);
  246. }
  247.  
  248. throw new YAMLException("Unexpected primitive '"
  249. + type.getCanonicalName() + "'");
  250. }
  251.  
  252. private List<Byte> asByteList(Object in) {
  253. byte[] array = (byte[]) in;
  254. List<Byte> list = new ArrayList<Byte>(array.length);
  255. for (int i = 0; i < array.length; ++i)
  256. list.add(array[i]);
  257. return list;
  258. }
  259.  
  260. private List<Short> asShortList(Object in) {
  261. short[] array = (short[]) in;
  262. List<Short> list = new ArrayList<Short>(array.length);
  263. for (int i = 0; i < array.length; ++i)
  264. list.add(array[i]);
  265. return list;
  266. }
  267.  
  268. private List<Integer> asIntList(Object in) {
  269. int[] array = (int[]) in;
  270. List<Integer> list = new ArrayList<Integer>(array.length);
  271. for (int i = 0; i < array.length; ++i)
  272. list.add(array[i]);
  273. return list;
  274. }
  275.  
  276. private List<Long> asLongList(Object in) {
  277. long[] array = (long[]) in;
  278. List<Long> list = new ArrayList<Long>(array.length);
  279. for (int i = 0; i < array.length; ++i)
  280. list.add(array[i]);
  281. return list;
  282. }
  283.  
  284. private List<Float> asFloatList(Object in) {
  285. float[] array = (float[]) in;
  286. List<Float> list = new ArrayList<Float>(array.length);
  287. for (int i = 0; i < array.length; ++i)
  288. list.add(array[i]);
  289. return list;
  290. }
  291.  
  292. private List<Double> asDoubleList(Object in) {
  293. double[] array = (double[]) in;
  294. List<Double> list = new ArrayList<Double>(array.length);
  295. for (int i = 0; i < array.length; ++i)
  296. list.add(array[i]);
  297. return list;
  298. }
  299.  
  300. private List<Character> asCharList(Object in) {
  301. char[] array = (char[]) in;
  302. List<Character> list = new ArrayList<Character>(array.length);
  303. for (int i = 0; i < array.length; ++i)
  304. list.add(array[i]);
  305. return list;
  306. }
  307.  
  308. private List<Boolean> asBooleanList(Object in) {
  309. boolean[] array = (boolean[]) in;
  310. List<Boolean> list = new ArrayList<Boolean>(array.length);
  311. for (int i = 0; i < array.length; ++i)
  312. list.add(array[i]);
  313. return list;
  314. }
  315. }
  316.  
  317. protected class RepresentMap implements Represent {
  318. @SuppressWarnings("unchecked")
  319. public Node representData(Object data) {
  320. return representMapping(getTag(data.getClass(), Tag.MAP),
  321. (Map<Object, Object>) data, null);
  322. }
  323. }
  324.  
  325. protected class RepresentSet implements Represent {
  326. @SuppressWarnings("unchecked")
  327. public Node representData(Object data) {
  328. Map<Object, Object> value = new LinkedHashMap<Object, Object>();
  329. Set<Object> set = (Set<Object>) data;
  330. for (Object key : set) {
  331. value.put(key, null);
  332. }
  333. return representMapping(getTag(data.getClass(), Tag.SET), value, null);
  334. }
  335. }
  336.  
  337. protected class RepresentDate implements Represent {
  338. public Node representData(Object data) {
  339. // because SimpleDateFormat ignores timezone we have to use Calendar
  340. Calendar calendar;
  341. if (data instanceof Calendar) {
  342. calendar = (Calendar) data;
  343. } else {
  344. calendar = Calendar.getInstance(getTimeZone() == null ? TimeZone.getTimeZone("UTC")
  345. : timeZone);
  346. calendar.setTime((Date) data);
  347. }
  348. int years = calendar.get(Calendar.YEAR);
  349. int months = calendar.get(Calendar.MONTH) + 1; // 0..12
  350. int days = calendar.get(Calendar.DAY_OF_MONTH); // 1..31
  351. int hour24 = calendar.get(Calendar.HOUR_OF_DAY); // 0..24
  352. int minutes = calendar.get(Calendar.MINUTE); // 0..59
  353. int seconds = calendar.get(Calendar.SECOND); // 0..59
  354. int millis = calendar.get(Calendar.MILLISECOND);
  355. StringBuilder buffer = new StringBuilder(String.valueOf(years));
  356. while (buffer.length() < 4) {
  357. // ancient years
  358. buffer.insert(0, "0");
  359. }
  360. buffer.append("-");
  361. if (months < 10) {
  362. buffer.append("0");
  363. }
  364. buffer.append(String.valueOf(months));
  365. buffer.append("-");
  366. if (days < 10) {
  367. buffer.append("0");
  368. }
  369. buffer.append(String.valueOf(days));
  370. buffer.append("T");
  371. if (hour24 < 10) {
  372. buffer.append("0");
  373. }
  374. buffer.append(String.valueOf(hour24));
  375. buffer.append(":");
  376. if (minutes < 10) {
  377. buffer.append("0");
  378. }
  379. buffer.append(String.valueOf(minutes));
  380. buffer.append(":");
  381. if (seconds < 10) {
  382. buffer.append("0");
  383. }
  384. buffer.append(String.valueOf(seconds));
  385. if (millis > 0) {
  386. if (millis < 10) {
  387. buffer.append(".00");
  388. } else if (millis < 100) {
  389. buffer.append(".0");
  390. } else {
  391. buffer.append(".");
  392. }
  393. buffer.append(String.valueOf(millis));
  394. }
  395. if (TimeZone.getTimeZone("UTC").equals(calendar.getTimeZone())) {
  396. buffer.append("Z");
  397. } else {
  398. // Get the Offset from GMT taking DST into account
  399. int gmtOffset = calendar.getTimeZone().getOffset(calendar.get(Calendar.ERA),
  400. calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
  401. calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK),
  402. calendar.get(Calendar.MILLISECOND));
  403. int minutesOffset = gmtOffset / (60 * 1000);
  404. int hoursOffset = minutesOffset / 60;
  405. int partOfHour = minutesOffset % 60;
  406. buffer.append((hoursOffset > 0 ? "+" : "") + hoursOffset + ":"
  407. + (partOfHour < 10 ? "0" + partOfHour : partOfHour));
  408. }
  409. return representScalar(getTag(data.getClass(), Tag.TIMESTAMP), buffer.toString(), null);
  410. }
  411. }
  412.  
  413. protected class RepresentEnum implements Represent {
  414. public Node representData(Object data) {
  415. Tag tag = new Tag(data.getClass());
  416. return representScalar(getTag(data.getClass(), tag), ((Enum<?>) data).name());
  417. }
  418. }
  419.  
  420. protected class RepresentByteArray implements Represent {
  421. public Node representData(Object data) {
  422. char[] binary = Base64Coder.encode((byte[]) data);
  423. return representScalar(Tag.BINARY, String.valueOf(binary), '|');
  424. }
  425. }
  426.  
  427. public TimeZone getTimeZone() {
  428. return timeZone;
  429. }
  430.  
  431. public void setTimeZone(TimeZone timeZone) {
  432. this.timeZone = timeZone;
  433. }
  434. }
Add Comment
Please, Sign In to add comment