1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package pl.edu.agh.cast.backward.resources.xml;
19
20 import java.lang.reflect.Field;
21 import java.util.Arrays;
22 import java.util.Comparator;
23 import java.util.Map;
24
25 import pl.edu.agh.cast.Activator;
26 import pl.edu.agh.cast.model.attributes.Attribute;
27 import pl.edu.agh.cast.model.attributes.AttributeManager;
28 import pl.edu.agh.cast.model.attributes.AttributeMergePolicy;
29 import pl.edu.agh.cast.model.attributes.AttributeValue;
30 import pl.edu.agh.cast.model.visual.backward.Connection;
31 import pl.edu.agh.cast.model.visual.backward.Diagram;
32 import pl.edu.agh.cast.model.visual.backward.DiagramSettings;
33 import pl.edu.agh.cast.model.visual.backward.IDiagramSettings;
34 import pl.edu.agh.cast.model.visual.backward.ModelElement;
35 import pl.edu.agh.cast.model.visual.backward.Node;
36 import pl.edu.agh.cast.model.visual.backward.VisualModelCachingFactory;
37
38 import com.thoughtworks.xstream.XStream;
39 import com.thoughtworks.xstream.converters.reflection.FieldDictionary;
40 import com.thoughtworks.xstream.converters.reflection.FieldKey;
41 import com.thoughtworks.xstream.converters.reflection.FieldKeySorter;
42 import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
43 import com.thoughtworks.xstream.core.util.OrderRetainingMap;
44
45
46
47
48
49
50 public class XStreamInitializer {
51
52
53
54
55
56
57
58 private static final class AttributeManagersFirstKeySorter implements FieldKeySorter {
59
60
61
62
63
64
65 private static final class FieldKeyComparator implements Comparator<FieldKey> {
66 public int compare(FieldKey o1, FieldKey o2) {
67 if (isAttributeManagerField(o1)) {
68 return -1;
69 } else if (isAttributeManagerField(o2)) {
70 return 1;
71 } else {
72 return 0;
73 }
74 }
75
76 private boolean isAttributeManagerField(FieldKey fieldKey) {
77 try {
78 Field field = fieldKey.getDeclaringClass().getDeclaredField(fieldKey.getFieldName());
79 return AttributeManager.class.isAssignableFrom(field.getType());
80 } catch (Exception e) {
81
82 Activator.getLogger().warn("Exception when sorting fields", e);
83 return false;
84 }
85 }
86 }
87
88 @SuppressWarnings("unchecked")
89 public Map sort(Class type, Map keyedByFieldKey) {
90
91 if (Diagram.class.isAssignableFrom(type)) {
92
93
94
95 FieldKey[] fieldKeys = (FieldKey[])keyedByFieldKey.keySet().toArray(
96 new FieldKey[keyedByFieldKey.size()]);
97 Arrays.sort(fieldKeys, new FieldKeyComparator());
98
99 Map result = new OrderRetainingMap();
100 for (int i = 0; i < fieldKeys.length; i++) {
101 result.put(fieldKeys[i], keyedByFieldKey.get(fieldKeys[i]));
102 }
103 return result;
104 } else {
105
106 return keyedByFieldKey;
107 }
108 }
109 }
110
111 private static final Class<?>[] CLASSES_WITH_ALIASES = { XMLProjectContainer.class, Diagram.class,
112 DiagramSettings.class, ModelElement.class, VisualModelCachingFactory.class, Connection.class, Node.class,
113 AttributeValue.class, Attribute.class, AttributeMergePolicy.MergePolicyAlwaysFirst.class,
114 AttributeMergePolicy.MergePolicyAlwaysSecond.class, AttributeMergePolicy.MergePolicyLogicalAnd.class,
115 AttributeMergePolicy.MergePolicyLogicalOr.class };
116
117
118
119
120
121
122 public static XStream createXStreamInstance() {
123 return init(null);
124 }
125
126
127
128
129
130
131
132
133 public static XStream createXStreamInstance(Class<?>[] classes) {
134 return init(classes);
135 }
136
137 private static XStream init(Class<?>[] additionalClassesWithAliases) {
138 XStream xstream = new XStream(new Sun14ReflectionProvider(new FieldDictionary(
139 new AttributeManagersFirstKeySorter())));
140
141
142 xstream.processAnnotations(CLASSES_WITH_ALIASES);
143 if (additionalClassesWithAliases != null) {
144 xstream.processAnnotations(additionalClassesWithAliases);
145 }
146
147
148 xstream.autodetectAnnotations(true);
149
150
151
152 xstream.addDefaultImplementation(DiagramSettings.class, IDiagramSettings.class);
153
154
155 xstream.registerConverter(new VisualModelCachingFactoryConverter());
156 xstream.registerConverter(new AttributeManagerConverter());
157 xstream.registerConverter(new AttributeValuesConverter());
158
159 return xstream;
160 }
161
162 }