json-serialiser

Details

diff --git a/src/main/java/br/ufrgs/inf/prosoft/jsonserialiser/JSONSerialiser.java b/src/main/java/br/ufrgs/inf/prosoft/jsonserialiser/JSONSerialiser.java
index 3442f68..cba63bf 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/jsonserialiser/JSONSerialiser.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/jsonserialiser/JSONSerialiser.java
@@ -13,11 +13,15 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
 /**
  *
@@ -26,6 +30,8 @@ import java.util.Map;
 public class JSONSerialiser {
 
     private final List<Object> visited;
+    private static final boolean TRACER_SERIALISE_INTERNALS = System.getenv("TRACER_SERIALISE_INTERNALS") != null && System.getenv("TRACER_SERIALISE_INTERNALS").equals("true");
+    private static final String TRACER_IGNORED_PACKAGES = System.getenv("TRACER_IGNORED_PACKAGES") != null ? System.getenv("TRACER_IGNORED_PACKAGES") : "./ignored";
 
     private JSONSerialiser() {
         this.visited = new ArrayList<>();
@@ -137,6 +143,10 @@ public class JSONSerialiser {
             if (object instanceof Enum) {
                 return serialiseString(((Enum<?>) object).name());
             }
+            if (object instanceof HashSet) {
+                HashSet<?> hashSet = (HashSet<?>) object;
+                return serialiseHashSet(hashSet);
+            }
             if (object instanceof Collection) {
                 Collection<?> collection = (Collection<?>) object;
                 return serialiseCollection(collection);
@@ -144,6 +154,10 @@ public class JSONSerialiser {
             if (object.getClass().isArray()) {
                 return serialiseArray(object);
             }
+            if (object instanceof HashMap) {
+                HashMap<?, ?> hashMap = (HashMap<?, ?>) object;
+                return serialiseHashMap(hashMap);
+            }
             if (object instanceof Map) {
                 Map<?, ?> map = (Map<?, ?>) object;
                 return serialiseMap(map);
@@ -152,18 +166,12 @@ public class JSONSerialiser {
                 Date date = (Date) object;
                 return new StringBuilder().append("\"").append(String.valueOf(date.getTime())).append("\"");
             }
-            String serialiseInternals = System.getenv("TRACER_SERIALISE_INTERNALS");
-            if (serialiseInternals == null || serialiseInternals.equals("false")) {
+            if (!TRACER_SERIALISE_INTERNALS) {
                 Package objectPackage = object.getClass().getPackage();
                 String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
-
-                String ignoredPackagesPath = System.getenv("TRACER_IGNORED_PACKAGES");
-                if (ignoredPackagesPath == null) {
-                    ignoredPackagesPath = "./ignored";
-                }
                 List<String> ignoredPackages;
                 try {
-                    ignoredPackages = Files.readAllLines(Paths.get(ignoredPackagesPath));
+                    ignoredPackages = Files.readAllLines(Paths.get(TRACER_IGNORED_PACKAGES));
                 } catch (IOException ex) {
                     ignoredPackages = new ArrayList<>();
                 }
@@ -228,6 +236,45 @@ public class JSONSerialiser {
         return stringBuilder.append("}");
     }
 
+    private StringBuilder serialiseHashMap(HashMap map) {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("{");
+        try {
+            TreeMap<String, StringBuilder> serialisedMap = new TreeMap<>();
+            for (Iterator<Map.Entry<?, ?>> iterator = map.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry<?, ?> entry = iterator.next();
+                Object key = entry.getKey();
+                Object value = entry.getValue();
+                if (key == null || value == null) {
+                    continue;
+                }
+                String serialisedKey;
+                if (key instanceof String) {
+                    serialisedKey = serialiseString((String) key).toString();
+                } else if (this.visited.stream().parallel().anyMatch(visited -> visited == key)) {
+                    serialisedKey = serialiseString(getReference(key)).toString();
+                } else {
+                    serialisedKey = serialiseString(JSONSerialiser.serialise(key)).toString();
+                }
+                StringBuilder wrappedValue = wrap(value);
+                serialisedMap.put(serialisedKey, wrappedValue);
+            }
+            for (Iterator<Map.Entry<String, StringBuilder>> iterator = serialisedMap.entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry<String, StringBuilder> entry = iterator.next();
+                String key = entry.getKey();
+                StringBuilder value = entry.getValue();
+                stringBuilder.append(key).append(":").append(value);
+                if (iterator.hasNext()) {
+                    stringBuilder.append(",");
+                }
+            }
+        } catch (Exception ex) {
+            System.err.println("[JSONSerialiser] hashmap serialise exception: " + ex);
+            return new StringBuilder().append("{\"e\":\"JSON_HASHMAP_EXCEPTION\"}");
+        }
+        return stringBuilder.append("}");
+    }
+
     private StringBuilder serialiseArray(Object array) {
         StringBuilder stringBuilder = new StringBuilder();
         stringBuilder.append("[");
@@ -252,12 +299,11 @@ public class JSONSerialiser {
         StringBuilder stringBuilder = new StringBuilder();
         stringBuilder.append("[");
         try {
-            Iterator it = collection.iterator();
-            while (it.hasNext()) {
-                Object object = it.next();
+            for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+                Object object = iterator.next();
                 StringBuilder wrap = wrap(object);
                 stringBuilder.append(wrap);
-                if (it.hasNext()) {
+                if (iterator.hasNext()) {
                     stringBuilder.append(",");
                 }
             }
@@ -272,6 +318,35 @@ public class JSONSerialiser {
         return stringBuilder.append("]");
     }
 
+    private StringBuilder serialiseHashSet(HashSet hashSet) {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("[");
+        try {
+            List<String> serialisedCollection = new ArrayList<>();
+            for (Iterator iterator = hashSet.iterator(); iterator.hasNext();) {
+                Object object = iterator.next();
+                StringBuilder wrap = wrap(object);
+                serialisedCollection.add(wrap.toString());
+            }
+            Collections.sort(serialisedCollection);
+            for (Iterator<String> iterator = serialisedCollection.iterator(); iterator.hasNext();) {
+                String next = iterator.next();
+                stringBuilder.append(next);
+                if (iterator.hasNext()) {
+                    stringBuilder.append(",");
+                }
+            }
+        } catch (Exception ex) {
+            String toString = ex.toString();
+            if (!toString.startsWith("org.hibernate")) {
+                System.err.println("[JSONSerialiser] hashset serialise exception: " + toString);
+                return new StringBuilder().append("[\"JSON_HASHSET_HIBERNATE_EXCEPTION\"]");
+            }
+            return new StringBuilder().append("[\"JSON_HASHSET_EXCEPTION\"]");
+        }
+        return stringBuilder.append("]");
+    }
+
     private StringBuilder serialiseString(CharSequence string) {
         StringBuilder stringBuilder = new StringBuilder();
         if (string == null || string.length() == 0) {