Fixed CommandContextImpl.merge to not duplicate same values in result
[simantics/platform.git] / bundles / org.simantics.document.server.io / src / org / simantics / document / server / io / CommandContextImpl.java
1 package org.simantics.document.server.io;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 public class CommandContextImpl implements CommandContextMutable {
10
11         private Map<String,List<List<Object>>> data = new HashMap<String,List<List<Object>>>();
12
13         @Override
14         public boolean containsKey(String key) {
15                 return data.containsKey(key);
16         }
17         
18         @Override
19         public List<List<Object>> getRows(String key) {
20                 List<List<Object>> rows = data.get(key);
21                 if (rows != null) 
22                         return rows;
23                 else
24                         return Collections.emptyList();
25         }
26
27         @Override
28         public CommandContextMutable putRow(String key, List<Object> row) {
29                 List<List<Object>> rows = ensureRowsAvailable(key);
30                 rows.add(row);
31                 return this;
32         }
33
34         @Override
35         public String getString(String key) {
36                 Object o = getValue(key);
37                 return (String)o;
38         }
39         
40         @Override
41         public CommandContextMutable putString(String key, String value) {
42             return putValue(key, value);
43         }
44
45         private List<List<Object>> ensureRowsAvailable(String key) {
46                 List<List<Object>> rows = data.get(key);
47                 if (rows == null) {
48                         rows = new ArrayList<List<Object>>();
49                         data.put(key, rows);
50                 }
51                 return rows;
52         }
53
54         @Override
55         public Map<String, List<List<Object>>> getData() {
56                 return data;
57         }
58         
59         @Override
60         public List<String> getKeys() {
61                 return new ArrayList<String>(data.keySet());
62         }
63         
64         @Override
65         public CommandContextMutable merge(CommandContext context) {
66                 if (context != null) {
67                         Map<String,List<List<Object>>> from = context.getData(); 
68                         for (Map.Entry<String, List<List<Object>>> entry : from.entrySet()) {
69                                 String key = entry.getKey();
70                                 Object existing = getValue(key);
71                                 Object newValue = context.getValue(key);
72                                 // Do not merge duplicates!
73                                 if (newValue != null && newValue.equals(existing))
74                                         continue;
75                                 List<List<Object>> rows = ensureRowsAvailable(entry.getKey());
76                                 rows.addAll(entry.getValue());
77                         }
78                 }
79                 return this;
80         }
81         
82         public static CommandContextMutable create() {
83                 return new CommandContextImpl();
84         }
85         
86         @Override
87         public String toString() {
88                 StringBuilder sb = new StringBuilder();
89                 sb.append("CommandContext:\n");
90                 for (Map.Entry<String, List<List<Object>>> entry : data.entrySet()) {
91                         String key = entry.getKey();
92                         if(key.startsWith("__")) continue;
93                         sb.append(key);
94                         sb.append(":");
95                         List<List<Object>> value = entry.getValue();
96                         if(value.size() == 1) {
97                                 List<Object> t = (List<Object>)value.get(0);
98                                 if(t.size() == 2) {
99                                         sb.append(t.get(1));
100                                 } else {
101                                         sb.append(t);
102                                 }
103                         } else {
104                                 sb.append(value);
105                         }
106                         sb.append("\n");
107                 }
108                 return sb.toString();
109         }
110         
111         @Override
112         public int hashCode() {
113                 final int prime = 31;
114                 int result = 1;
115                 result = prime * result + ((data == null) ? 0 : data.hashCode());
116                 return result;
117         }
118
119         @Override
120         public boolean equals(Object obj) {
121                 if (this == obj)
122                         return true;
123                 if (obj == null)
124                         return false;
125                 if (getClass() != obj.getClass())
126                         return false;
127                 CommandContextImpl other = (CommandContextImpl) obj;
128                 if (data == null) {
129                         if (other.data != null)
130                                 return false;
131                 } else if (!data.equals(other.data))
132                         return false;
133                 return true;
134         }
135
136     @Override
137     public CommandContextMutable putValue(String key, Object value) {
138         if(data.containsKey(key)) data.remove(key);
139         List<List<Object>> rows = ensureRowsAvailable(key);
140         List<Object> t = new ArrayList<Object>();
141         t.add(key);
142         t.add(value);
143         rows.add(t);
144         return this;
145     }
146     
147     @Override
148     public <T> T getValue(String key) {
149         List<List<Object>> rows = getRows(key);
150         if((rows == null) || (rows.size() != 1)) return null;
151         List<Object> t = (List<Object>)rows.get(0);
152         if(t.size() != 2) return null;
153         @SuppressWarnings("unchecked")
154         T o = (T) t.get(1);
155         return o;
156     }
157 }