1 | package geniusweb.domaineditor.model;
|
---|
2 |
|
---|
3 | import java.math.BigDecimal;
|
---|
4 | import java.util.HashMap;
|
---|
5 | import java.util.Map;
|
---|
6 | import java.util.Map.Entry;
|
---|
7 | import java.util.logging.Level;
|
---|
8 |
|
---|
9 | import geniusweb.issuevalue.Bid;
|
---|
10 | import geniusweb.issuevalue.DiscreteValue;
|
---|
11 | import geniusweb.issuevalue.NumberValue;
|
---|
12 | import geniusweb.issuevalue.Value;
|
---|
13 | import tudelft.utilities.listener.DefaultListenable;
|
---|
14 | import tudelft.utilities.logging.Reporter;
|
---|
15 | import tudelft.utilities.mvc.model.BasicModel;
|
---|
16 | import tudelft.utilities.mvc.model.DefaultSelectionModel;
|
---|
17 | import tudelft.utilities.mvc.model.ListModel;
|
---|
18 | import tudelft.utilities.mvc.model.MapFromKeys;
|
---|
19 | import tudelft.utilities.mvc.model.MapModel;
|
---|
20 | import tudelft.utilities.mvc.model.SelectionModel;
|
---|
21 | import tudelft.utilities.mvc.model.StringModel;
|
---|
22 | import tudelft.utilities.mvc.model.TypedModel;
|
---|
23 | import tudelft.utilities.mvc.model.events.Added;
|
---|
24 | import tudelft.utilities.mvc.model.events.Changed;
|
---|
25 | import tudelft.utilities.mvc.model.events.Event;
|
---|
26 | import tudelft.utilities.mvc.model.events.Removed;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * contains modifyable {@link Bid} with values for all issues in the original
|
---|
30 | * domain. Automatically adapts to changes in the {@link DomainModel}.
|
---|
31 | *
|
---|
32 | * BidModel implements MapModel. However add and delete operations are not
|
---|
33 | * allowed. That's because we do not want to modify the domain from here.
|
---|
34 | *
|
---|
35 | * <br>
|
---|
36 | * FIXME this implementation probably can be done much cleaner with
|
---|
37 | * {@link MapFromKeys}
|
---|
38 | *
|
---|
39 | */
|
---|
40 | public class BidModel extends DefaultListenable<Event> implements
|
---|
41 | MapModel<StringModel, SelectionModel<BasicModel>>, TypedModel<Bid> {
|
---|
42 | private final MapModel<StringModel, ValueSetModel> issuevalues;
|
---|
43 | private final Map<StringModel, SelectionModel<BasicModel>> selections = new HashMap<>();
|
---|
44 | private final Reporter log;
|
---|
45 |
|
---|
46 | /**
|
---|
47 | *
|
---|
48 | * @param issuevalues the map with issue values from
|
---|
49 | * {@link DomainModel#getIssues()}
|
---|
50 | */
|
---|
51 | public BidModel(MapModel<StringModel, ValueSetModel> issuevalues,
|
---|
52 | Reporter log) {
|
---|
53 | if (log == null || issuevalues == null)
|
---|
54 | throw new NullPointerException();
|
---|
55 | this.issuevalues = issuevalues;
|
---|
56 | this.log = log;
|
---|
57 | ListModel<StringModel> keys = issuevalues.getKeys();
|
---|
58 | for (int n = 0; n < keys.getSize(); n++) {
|
---|
59 | StringModel key = keys.get(n);
|
---|
60 | add(key, issuevalues.getValue(key).getList());
|
---|
61 | }
|
---|
62 | issuevalues.addListener((e) -> handleChange(e));
|
---|
63 |
|
---|
64 | // user's changes to the issuevalues are inconsequential
|
---|
65 | }
|
---|
66 |
|
---|
67 | private void add(StringModel key, ListModel value) {
|
---|
68 | selections.put(key, new DefaultSelectionModel(value));
|
---|
69 | }
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * Domain change occured. Handle it.
|
---|
73 | */
|
---|
74 | private void handleChange(Event e) {
|
---|
75 | // we only handle add/remove of issues. If a value is removed,
|
---|
76 | // this should automatically reflect into the selectionmodel.
|
---|
77 | if (!(e instanceof Changed)) {
|
---|
78 | System.out.println("Unexpected event " + e);
|
---|
79 | return;
|
---|
80 | }
|
---|
81 | e = e.getChildEvent();
|
---|
82 | if (e instanceof Removed) {
|
---|
83 | // an issue was removed.
|
---|
84 | selections.remove(e.getSource());
|
---|
85 | } else if (e instanceof Added) {
|
---|
86 | StringModel issuemodel = (StringModel) e.getSource();
|
---|
87 | add(issuemodel, issuevalues.getValue(issuemodel).getList());
|
---|
88 | } else
|
---|
89 | System.out.println("Ignored event " + e);
|
---|
90 | notifyListeners(e);
|
---|
91 | }
|
---|
92 |
|
---|
93 | @Override
|
---|
94 | public SelectionModel getValue(StringModel key) {
|
---|
95 | return selections.get(key);
|
---|
96 | }
|
---|
97 |
|
---|
98 | @Override
|
---|
99 | public void put(StringModel key, SelectionModel val) {
|
---|
100 | throw new UnsupportedOperationException();
|
---|
101 | }
|
---|
102 |
|
---|
103 | @Override
|
---|
104 | public void remove(StringModel key) {
|
---|
105 | throw new UnsupportedOperationException();
|
---|
106 | }
|
---|
107 |
|
---|
108 | @Override
|
---|
109 | public ListModel<StringModel> getKeys() {
|
---|
110 | return issuevalues.getKeys();
|
---|
111 | }
|
---|
112 |
|
---|
113 | @Override
|
---|
114 | public int getMinimumSize() {
|
---|
115 | return 1;
|
---|
116 | }
|
---|
117 |
|
---|
118 | @Override
|
---|
119 | public String getColumnName(int n) {
|
---|
120 | return n == 0 ? "issue" : "value";
|
---|
121 | }
|
---|
122 |
|
---|
123 | @Override
|
---|
124 | public Bid getCurrentValue() throws IllegalStateException {
|
---|
125 | Map<String, Value> selectionmap = new HashMap<>();
|
---|
126 | for (Entry<StringModel, SelectionModel<BasicModel>> entry : selections
|
---|
127 | .entrySet()) {
|
---|
128 | Value val = getVal(entry);
|
---|
129 | // ignore non-set values
|
---|
130 | if (val != null)
|
---|
131 | selectionmap.put(entry.getKey().getValue(), val);
|
---|
132 | }
|
---|
133 | return new Bid(selectionmap);
|
---|
134 | }
|
---|
135 |
|
---|
136 | @Override
|
---|
137 | public void setCurrentValue(Bid bid) throws IllegalArgumentException {
|
---|
138 | ListModel<StringModel> issues = issuevalues.getKeys();
|
---|
139 | for (int n = 0; n < issues.getSize(); n++) {
|
---|
140 | StringModel issuemodel = issues.get(n);
|
---|
141 | String issue = issuemodel.getValue();
|
---|
142 | Value val = bid.getValue(issue);
|
---|
143 | if (val == null) {
|
---|
144 | log.log(Level.WARNING,
|
---|
145 | "Bid does not contain value for the issue " + issue);
|
---|
146 | continue;
|
---|
147 | }
|
---|
148 | ValueSetModel values = issuevalues.getValue(issues.get(n));
|
---|
149 | // now find & select the current model containing val
|
---|
150 | boolean isSet = false;
|
---|
151 | for (int v = 0; v < values.getList().getSize(); v++) {
|
---|
152 | BasicModel valuem = values.getList().get(v);
|
---|
153 | if (valuem.getValue().equals(val.getValue())) {
|
---|
154 | selections.get(issuemodel).setSelection(valuem);
|
---|
155 | isSet = true;
|
---|
156 | }
|
---|
157 | }
|
---|
158 | if (!isSet)
|
---|
159 | log.log(Level.WARNING,
|
---|
160 | "Ignoring unknown value " + val + " in bid " + bid);
|
---|
161 | }
|
---|
162 | }
|
---|
163 |
|
---|
164 | /**
|
---|
165 | *
|
---|
166 | * @param entry the key-value entry that was selected.
|
---|
167 | * @return the selected value, or null if nothing is selected.
|
---|
168 | */
|
---|
169 | private Value getVal(Entry<StringModel, SelectionModel<BasicModel>> entry) {
|
---|
170 | BasicModel sel = entry.getValue().getSelection();
|
---|
171 | if (sel == null)
|
---|
172 | return null;
|
---|
173 | Object val = sel.getValue();
|
---|
174 | if (val instanceof String)
|
---|
175 | return new DiscreteValue((String) val);
|
---|
176 | if (val instanceof BigDecimal)
|
---|
177 | return new NumberValue((BigDecimal) val);
|
---|
178 | throw new IllegalStateException(
|
---|
179 | "Value " + val + " is not string or number");
|
---|
180 |
|
---|
181 | }
|
---|
182 |
|
---|
183 | @Override
|
---|
184 | public SelectionModel<BasicModel> create(StringModel key) {
|
---|
185 | throw new UnsupportedOperationException();
|
---|
186 | }
|
---|
187 |
|
---|
188 | }
|
---|