PageRenderTime 62ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/swizzle-jira/src/main/java/org/codehaus/swizzle/jira/MapObject.java

https://gitlab.com/mfriedenhagen/swizzle
Java | 387 lines | 287 code | 64 blank | 36 comment | 52 complexity | dd3ffdba3f05fd431a02715acd2c63f1 MD5 | raw file
  1. /**
  2. * Copyright 2006 David Blevins
  3. * <p>
  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. * <p>
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * <p>
  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.codehaus.swizzle.jira;
  17. import org.apache.commons.collections.IteratorUtils;
  18. import org.json.JSONArray;
  19. import org.json.JSONObject;
  20. import java.lang.reflect.Constructor;
  21. import java.lang.reflect.InvocationTargetException;
  22. import java.net.MalformedURLException;
  23. import java.net.URL;
  24. import java.text.ParseException;
  25. import java.text.SimpleDateFormat;
  26. import java.util.*;
  27. /**
  28. * @version $Revision$ $Date$
  29. */
  30. public class MapObject {
  31. /**
  32. * When Sending data of the following type, do not send a HashMap, instead send a single value from the hashmap to act as a reference to the object.
  33. */
  34. protected Map xmlrpcRefs = new HashMap();
  35. /**
  36. * A list of fields in this hashmap which should not be sent on xml-rpc create or update calls.
  37. */
  38. protected List xmlrpcNoSend = new ArrayList();
  39. protected Map attributes;
  40. private final SimpleDateFormat[] formats;
  41. protected final Map fields;
  42. protected MapObject() {
  43. this(new HashMap());
  44. }
  45. protected MapObject(Map data) {
  46. fields = new HashMap(data);
  47. formats = new SimpleDateFormat[]{
  48. // JSON
  49. new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH),
  50. new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.ENGLISH),
  51. new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH),
  52. new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S", Locale.ENGLISH),
  53. // JSON releaseDate
  54. new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
  55. };
  56. attributes = new Attributes();
  57. }
  58. public Map getFields() {
  59. return fields;
  60. }
  61. public Map getAttributes() {
  62. return attributes;
  63. }
  64. protected String getString(String key) {
  65. return (String) getObject(key);
  66. }
  67. protected boolean getBoolean(String key) {
  68. final Object value = getObject(key);
  69. if (value == null) return false;
  70. if (value instanceof Boolean) {
  71. return (boolean)value;
  72. } else {
  73. final String svalue = String.valueOf(value);
  74. return (svalue.equalsIgnoreCase("true") || svalue.equals("1") || svalue.equalsIgnoreCase("yes"));
  75. }
  76. }
  77. protected int getInt(String key) {
  78. String value = getString(key);
  79. if (value == null) return 0;
  80. return Integer.parseInt(value);
  81. }
  82. protected void setString(String key, String value) {
  83. fields.put(key, value);
  84. }
  85. protected void setInt(String key, int value) {
  86. fields.put(key, Integer.toString(value));
  87. }
  88. protected void setBoolean(String key, boolean value) {
  89. fields.put(key, Boolean.toString(value));
  90. }
  91. protected void setUrl(String key, URL url) {
  92. fields.put(key, (url == null) ? null : url.toExternalForm());
  93. }
  94. protected URL getUrl(String key) {
  95. try {
  96. String value = getString(key);
  97. return (value == null) ? null : new URL(value);
  98. } catch (MalformedURLException e) {
  99. return null;
  100. }
  101. }
  102. protected void setDate(String key, Date value) {
  103. fields.put(key, formats[0].format(value));
  104. }
  105. /**
  106. * If date does not exist, return "now"
  107. * @param key
  108. * @return
  109. */
  110. protected Date getDate(String key) {
  111. String value = getString(key);
  112. if (value == null || value.equals("")) return new Date();
  113. ParseException notParsable = null;
  114. for (int i = 0; i < formats.length; i++) {
  115. try {
  116. return formats[i].parse(value);
  117. } catch (ParseException e) {
  118. notParsable = e;
  119. }
  120. }
  121. throw new RuntimeException(notParsable);
  122. }
  123. protected List getList(String key) {
  124. return (List) getObject(key);
  125. }
  126. private Object getObject(String key) {
  127. Object o = fields.get(key);
  128. if (o == null && fields.containsKey("fields")) {
  129. final JSONObject jsonFields = (JSONObject) getObject("fields");
  130. o = jsonFields.opt(key);
  131. return o == JSONObject.NULL ? null : o;
  132. } else {
  133. return o;
  134. }
  135. }
  136. protected void setList(String key, List value) {
  137. fields.put(key, value);
  138. }
  139. protected MapObject getMapObject(String key, Class type) {
  140. Object object = getObject(key);
  141. if (object == null) {
  142. return null;
  143. }
  144. if (object instanceof MapObject) {
  145. return (MapObject) object;
  146. }
  147. if (object instanceof JSONObject) {
  148. object = new JSONObjectToMap((JSONObject) object).invoke();
  149. }
  150. try {
  151. MapObject mapObject = createMapObject(type, object);
  152. fields.put(key, mapObject);
  153. return mapObject;
  154. } catch (Exception e) {
  155. throw new RuntimeException(e);
  156. }
  157. }
  158. protected void setMapObject(String key, MapObject mapObject) {
  159. fields.put(key, mapObject);
  160. }
  161. protected boolean hasField(String key) {
  162. return fields.containsKey(key);
  163. }
  164. protected <T> List<T> getMapObjects(String key, Class<T> type) {
  165. List<T> list;
  166. Object collection = getObject(key);
  167. if (collection instanceof Object[]) {
  168. Object[] vector = (Object[]) collection;
  169. try {
  170. list = toList(vector, type);
  171. Iterator iter = list.iterator();
  172. fields.put(key, list);
  173. } catch (Exception e) {
  174. list = new MapObjectList();
  175. }
  176. } else if (collection == null) {
  177. list = new MapObjectList<T>();
  178. fields.put(key, list);
  179. } else if (collection instanceof JSONArray) {
  180. Iterator<Object> iterator = ((JSONArray) collection).iterator();
  181. List<Map> tmp = new ArrayList<>();
  182. while(iterator.hasNext()) {
  183. tmp.add(new JSONObjectToMap((JSONObject)iterator.next()).invoke());
  184. }
  185. Object[] vector = tmp.toArray();
  186. try {
  187. list = toList(vector, type);
  188. Iterator iter = list.iterator();
  189. fields.put(key, list);
  190. } catch (Exception e) {
  191. list = new MapObjectList();
  192. }
  193. iterator = ((JSONArray) collection).iterator();
  194. list = IteratorUtils.toList(iterator);
  195. } else {
  196. list = (List) collection;
  197. }
  198. return list;
  199. }
  200. protected void setMapObjects(String key, List objects) {
  201. fields.put(key, objects);
  202. }
  203. protected List toList(Object[] vector, Class type) throws Exception {
  204. List list = new MapObjectList(vector.length);
  205. for (int i = 0; i < vector.length; i++) {
  206. Object object = createMapObject(type, vector[i]);
  207. list.add(object);
  208. }
  209. return list;
  210. }
  211. private MapObject createMapObject(Class type, Object value) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
  212. Constructor constructor = type.getConstructor(new Class[]{Map.class});
  213. Map data;
  214. Object idField = xmlrpcRefs.get(type);
  215. if (idField != null && !(value instanceof Map)) {
  216. data = new HashMap();
  217. data.put(idField, value);
  218. } else if (value instanceof Map) {
  219. data = (Map) value;
  220. } else {
  221. throw new RuntimeException("Cannot create a " + type.getName() + " from '" + value + "'");
  222. }
  223. Object object = constructor.newInstance(new Object[]{data});
  224. return (MapObject) object;
  225. }
  226. public Map toMap() {
  227. // The fields table might have some key->null entries,
  228. // don't want to add those to the hashmap.
  229. Map map = new HashMap(fields.size());
  230. for (Iterator i = fields.entrySet().iterator(); i.hasNext(); ) {
  231. Map.Entry entry = (Map.Entry) i.next();
  232. if (entry.getValue() != null) {
  233. map.put(entry.getKey(), entry.getValue());
  234. }
  235. }
  236. // Remove anything marked as "no send"
  237. for (int i = 0; i < xmlrpcNoSend.size(); i++) {
  238. String fieldName = (String) xmlrpcNoSend.get(i);
  239. map.remove(fieldName);
  240. }
  241. // Expand any MapObject values to be Hashmaps
  242. // Where specified, use the appropriate Id Field instead of the Hashmap
  243. for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext(); ) {
  244. Map.Entry entry = (Map.Entry) iterator.next();
  245. Object key = entry.getKey();
  246. Object value = entry.getValue();
  247. if (value instanceof MapObject) {
  248. MapObject mapObject = (MapObject) value;
  249. map.put(key, toMapOrId(mapObject));
  250. } else if (value instanceof List && !(value instanceof Object[])) {
  251. List objects = (List) value;
  252. Object[] vector = new Object[objects.size()];
  253. for (int i = 0; i < objects.size(); i++) {
  254. MapObject mapObject = (MapObject) objects.get(i);
  255. vector[i] = toMapOrId(mapObject);
  256. }
  257. map.put(key, vector);
  258. }
  259. }
  260. return map;
  261. }
  262. private Object toMapOrId(MapObject mapObject) {
  263. Map child = mapObject.toMap();
  264. Object object;
  265. String idField = (String) xmlrpcRefs.get(mapObject.getClass());
  266. if (idField != null) {
  267. object = child.get(idField);
  268. } else {
  269. object = child;
  270. }
  271. return object;
  272. }
  273. protected void merge(MapObject source) {
  274. if (source != null) {
  275. fields.putAll(source.fields);
  276. }
  277. }
  278. private class Attributes implements Map {
  279. public Attributes() {
  280. fields.put("#attributes", new LinkedHashMap());
  281. xmlrpcNoSend.add("#attributes");
  282. }
  283. private Map map() {
  284. return (Map) getObject("#attributes");
  285. }
  286. public void clear() {
  287. map().clear();
  288. }
  289. public boolean containsKey(Object object) {
  290. return map().containsKey(object);
  291. }
  292. public boolean containsValue(Object object) {
  293. return map().containsValue(object);
  294. }
  295. public Set entrySet() {
  296. return map().entrySet();
  297. }
  298. public Object get(Object object) {
  299. return map().get(object);
  300. }
  301. public boolean isEmpty() {
  302. return map().isEmpty();
  303. }
  304. public Set keySet() {
  305. return map().keySet();
  306. }
  307. public Object put(Object object, Object object1) {
  308. return map().put(object, object1);
  309. }
  310. public void putAll(Map context) {
  311. map().putAll(context);
  312. }
  313. public Object remove(Object object) {
  314. return map().remove(object);
  315. }
  316. public int size() {
  317. return map().size();
  318. }
  319. public Collection values() {
  320. return map().values();
  321. }
  322. }
  323. }