Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/Calculation4.java @ 9479:2b83d3a96703
i18n TODO "benutzerdefiniert" = "custom" fixed
author | gernotbelger |
---|---|
date | Mon, 10 Sep 2018 15:31:55 +0200 |
parents | 5e38e2924c07 |
children | 33ce8eba9806 |
comparison
equal
deleted
inserted
replaced
9478:7e2eebc14e1f | 9479:2b83d3a96703 |
---|---|
6 * documentation coming with Dive4Elements River for details. | 6 * documentation coming with Dive4Elements River for details. |
7 */ | 7 */ |
8 | 8 |
9 package org.dive4elements.river.artifacts.model; | 9 package org.dive4elements.river.artifacts.model; |
10 | 10 |
11 import java.util.ArrayList; | |
12 import java.util.Arrays; | |
13 import java.util.List; | |
14 | |
15 import org.apache.log4j.Logger; | |
16 import org.dive4elements.artifacts.CallMeta; | |
11 import org.dive4elements.river.artifacts.access.Calculation4Access; | 17 import org.dive4elements.river.artifacts.access.Calculation4Access; |
12 | |
13 import org.dive4elements.river.artifacts.math.BackJumpCorrector; | 18 import org.dive4elements.river.artifacts.math.BackJumpCorrector; |
14 import org.dive4elements.river.artifacts.math.Function; | 19 import org.dive4elements.river.artifacts.math.Function; |
15 import org.dive4elements.river.artifacts.math.Identity; | 20 import org.dive4elements.river.artifacts.math.Identity; |
16 import org.dive4elements.river.artifacts.math.Linear; | 21 import org.dive4elements.river.artifacts.math.Linear; |
17 | |
18 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; | 22 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; |
19 | 23 import org.dive4elements.river.artifacts.resources.Resources; |
20 import org.dive4elements.river.model.River; | 24 import org.dive4elements.river.model.River; |
21 | |
22 import org.dive4elements.river.utils.DoubleUtil; | 25 import org.dive4elements.river.utils.DoubleUtil; |
23 | 26 |
24 import java.util.ArrayList; | 27 public class Calculation4 extends Calculation { |
25 import java.util.Arrays; | |
26 import java.util.List; | |
27 | |
28 import org.apache.log4j.Logger; | |
29 | |
30 public class Calculation4 | |
31 extends Calculation | |
32 { | |
33 private static Logger log = Logger.getLogger(Calculation4.class); | 28 private static Logger log = Logger.getLogger(Calculation4.class); |
34 | 29 |
35 public static final double MINIMAL_STEP_WIDTH = 1e-5; | 30 public static final double MINIMAL_STEP_WIDTH = 1e-5; |
36 | 31 |
37 protected List<Segment> segments; | 32 protected List<Segment> segments; |
38 | 33 |
39 protected boolean isQ; | 34 protected boolean isQ; |
40 protected double from; | 35 protected double from; |
41 protected double to; | 36 protected double to; |
42 protected double step; | 37 protected double step; |
43 protected String river; | 38 protected String river; |
44 | 39 |
45 public Calculation4() { | 40 public Calculation4() { |
46 } | 41 } |
47 | 42 |
48 public Calculation4(Calculation4Access access) { | 43 public Calculation4(final Calculation4Access access) { |
49 log.debug("Calculation4Access.cnst"); | 44 log.debug("Calculation4Access.cnst"); |
50 String river = access.getRiverName(); | 45 final String river = access.getRiverName(); |
51 List<Segment> segments = access.getSegments(); | 46 final List<Segment> segments = access.getSegments(); |
52 double [] range = access.getFromToStep(); | 47 final double[] range = access.getFromToStep(); |
53 boolean isQ = access.isQ(); | 48 final boolean isQ = access.isQ(); |
54 | 49 |
55 if (river == null) { | 50 if (river == null) { |
56 addProblem("no.river.selected"); | 51 addProblem("no.river.selected"); |
57 } | 52 } |
58 | 53 |
63 if (segments == null || segments.isEmpty()) { | 58 if (segments == null || segments.isEmpty()) { |
64 addProblem("cannot.create.segments"); | 59 addProblem("cannot.create.segments"); |
65 } | 60 } |
66 | 61 |
67 if (!hasProblems()) { | 62 if (!hasProblems()) { |
68 this.river = river; | 63 this.river = river; |
69 this.segments = segments; | 64 this.segments = segments; |
70 this.from = range[0]; | 65 this.from = range[0]; |
71 this.to = range[1]; | 66 this.to = range[1]; |
72 this.step = range[2]; | 67 this.step = range[2]; |
73 this.isQ = isQ; | 68 this.isQ = isQ; |
74 } | 69 } |
75 } | 70 } |
76 | 71 |
77 public CalculationResult calculate() { | 72 public CalculationResult calculate(final CallMeta meta) { |
78 if (hasProblems()) { | 73 if (hasProblems()) { |
79 return new CalculationResult(new WQKms[0], this); | 74 return new CalculationResult(new WQKms[0], this); |
80 } | 75 } |
81 | 76 |
82 WstValueTable table = null; | 77 WstValueTable table = null; |
83 River r = RiverFactory.getRiver(river); | 78 final River r = RiverFactory.getRiver(this.river); |
84 if (r == null) { | 79 if (r == null) { |
85 addProblem("no.river.found"); | 80 addProblem("no.river.found"); |
86 } | 81 } else { |
87 else { | |
88 table = WstValueTableFactory.getTable(r); | 82 table = WstValueTableFactory.getTable(r); |
89 if (table == null) { | 83 if (table == null) { |
90 addProblem("no.wst.for.river"); | 84 addProblem("no.wst.for.river"); |
91 } | 85 } else { |
92 else { | 86 Segment.setReferencePointConvertQ(this.segments, r, this.isQ, this); |
93 Segment.setReferencePointConvertQ(segments, r, isQ, this); | 87 } |
94 } | 88 } |
95 } | 89 |
96 | 90 return hasProblems() ? new CalculationResult(new WQKms[0], this) : innerCalculate(table, meta); |
97 return hasProblems() | 91 } |
98 ? new CalculationResult(new WQKms[0], this) | 92 |
99 : innerCalculate(table); | 93 protected CalculationResult innerCalculate(final WstValueTable table, final CallMeta meta) { |
100 } | 94 final boolean debug = log.isDebugEnabled(); |
101 | |
102 protected CalculationResult innerCalculate(WstValueTable table) { | |
103 boolean debug = log.isDebugEnabled(); | |
104 | 95 |
105 if (debug) { | 96 if (debug) { |
106 log.debug( | 97 log.debug("calculate from " + this.from + " to " + this.to + " step " + this.step); |
107 "calculate from " + from + " to " + to + " step " + step); | 98 log.debug("# segments: " + this.segments.size()); |
108 log.debug("# segments: " + segments.size()); | 99 for (final Segment segment : this.segments) { |
109 for (Segment segment: segments) { | |
110 log.debug(" " + segment); | 100 log.debug(" " + segment); |
111 } | 101 } |
112 } | 102 } |
113 | 103 |
114 int numResults = segments.get(0).values.length; | 104 final int numResults = this.segments.get(0).values.length; |
115 | 105 |
116 if (numResults < 1) { | 106 if (numResults < 1) { |
117 log.debug("no values given"); | 107 log.debug("no values given"); |
118 addProblem("no.values.given"); | 108 addProblem("no.values.given"); |
119 return new CalculationResult(new WQKms[0], this); | 109 return new CalculationResult(new WQKms[0], this); |
120 } | 110 } |
121 | 111 |
122 | 112 final WQKms[] results = new WQKms[numResults]; |
123 WQKms [] results = new WQKms[numResults]; | |
124 for (int i = 0; i < results.length; ++i) { | 113 for (int i = 0; i < results.length; ++i) { |
125 results[i] = new WQKms(); | 114 results[i] = new WQKms(); |
126 } | 115 } |
127 | 116 |
128 if (Math.abs(step) < MINIMAL_STEP_WIDTH) { | 117 if (Math.abs(this.step) < MINIMAL_STEP_WIDTH) { |
129 step = MINIMAL_STEP_WIDTH; | 118 this.step = MINIMAL_STEP_WIDTH; |
130 } | 119 } |
131 | 120 |
132 if (from > to) { | 121 if (this.from > this.to) { |
133 step = -step; | 122 this.step = -this.step; |
134 } | 123 } |
135 | 124 |
136 QPosition [] qPositions = new QPosition[numResults]; | 125 final QPosition[] qPositions = new QPosition[numResults]; |
137 | 126 |
138 Function [] functions = new Function[numResults]; | 127 final Function[] functions = new Function[numResults]; |
139 | 128 |
140 double [] out = new double[2]; | 129 final double[] out = new double[2]; |
141 | 130 |
142 Segment sentinel = new Segment(Double.MAX_VALUE); | 131 final Segment sentinel = new Segment(Double.MAX_VALUE); |
143 Segment s1 = sentinel, s2 = sentinel; | 132 Segment s1 = sentinel, s2 = sentinel; |
144 | 133 |
145 for (double pos = from; | 134 for (double pos = this.from; this.from < this.to ? pos <= this.to : pos >= this.to; pos = DoubleUtil.round(pos + this.step)) { |
146 from < to ? pos <= to : pos >= to; | |
147 pos = DoubleUtil.round(pos + step) | |
148 ) { | |
149 if (pos < s1.referencePoint || pos > s2.referencePoint) { | 135 if (pos < s1.referencePoint || pos > s2.referencePoint) { |
150 if (debug) { | 136 if (debug) { |
151 log.debug("need to find new interval for " + pos); | 137 log.debug("need to find new interval for " + pos); |
152 } | 138 } |
153 // find new interval | 139 // find new interval |
154 if (pos <= segments.get(0).referencePoint) { | 140 if (pos <= this.segments.get(0).referencePoint) { |
155 // before first segment -> "gleichwertig" | 141 // before first segment -> "gleichwertig" |
156 if (debug) { | 142 if (debug) { |
157 log.debug("before first segment -> gleichwertig"); | 143 log.debug("before first segment -> gleichwertig"); |
158 } | 144 } |
159 Segment first = segments.get(0); | 145 final Segment first = this.segments.get(0); |
160 double [] values = first.values; | 146 final double[] values = first.values; |
161 double refPos = first.referencePoint; | 147 final double refPos = first.referencePoint; |
162 for (int i = 0; i < qPositions.length; ++i) { | 148 for (int i = 0; i < qPositions.length; ++i) { |
163 qPositions[i] = table.getQPosition( | 149 qPositions[i] = table.getQPosition(refPos, values[i]); |
164 refPos, values[i]); | |
165 } | 150 } |
166 sentinel.setReferencePoint(-Double.MAX_VALUE); | 151 sentinel.setReferencePoint(-Double.MAX_VALUE); |
167 s1 = sentinel; | 152 s1 = sentinel; |
168 s2 = segments.get(0); | 153 s2 = this.segments.get(0); |
169 Arrays.fill(functions, Identity.IDENTITY); | 154 Arrays.fill(functions, Identity.IDENTITY); |
170 } | 155 } else if (pos >= this.segments.get(this.segments.size() - 1).referencePoint) { |
171 else if ( | |
172 pos >= segments.get(segments.size()-1).referencePoint | |
173 ) { | |
174 // after last segment -> "gleichwertig" | 156 // after last segment -> "gleichwertig" |
175 if (debug) { | 157 if (debug) { |
176 log.debug("after last segment -> gleichwertig"); | 158 log.debug("after last segment -> gleichwertig"); |
177 } | 159 } |
178 Segment last = segments.get(segments.size()-1); | 160 final Segment last = this.segments.get(this.segments.size() - 1); |
179 double [] values = last.values; | 161 final double[] values = last.values; |
180 double refPos = last.referencePoint; | 162 final double refPos = last.referencePoint; |
181 for (int i = 0; i < qPositions.length; ++i) { | 163 for (int i = 0; i < qPositions.length; ++i) { |
182 qPositions[i] = table.getQPosition( | 164 qPositions[i] = table.getQPosition(refPos, values[i]); |
183 refPos, values[i]); | |
184 } | 165 } |
185 sentinel.setReferencePoint(Double.MAX_VALUE); | 166 sentinel.setReferencePoint(Double.MAX_VALUE); |
186 s1 = last; | 167 s1 = last; |
187 s2 = sentinel; | 168 s2 = sentinel; |
188 Arrays.fill(functions, Identity.IDENTITY); | 169 Arrays.fill(functions, Identity.IDENTITY); |
189 } | 170 } else { // "ungleichwertig" |
190 else { // "ungleichwertig" | 171 // find matching interval |
191 // find matching interval | |
192 if (debug) { | 172 if (debug) { |
193 log.debug("in segments -> ungleichwertig"); | 173 log.debug("in segments -> ungleichwertig"); |
194 } | 174 } |
195 s1 = s2 = null; | 175 s1 = s2 = null; |
196 for (int i = 1, N = segments.size(); i < N; ++i) { | 176 for (int i = 1, N = this.segments.size(); i < N; ++i) { |
197 Segment si1 = segments.get(i-1); | 177 final Segment si1 = this.segments.get(i - 1); |
198 Segment si = segments.get(i); | 178 final Segment si = this.segments.get(i); |
199 if (debug) { | 179 if (debug) { |
200 log.debug("check " + pos + " in " | 180 log.debug("check " + pos + " in " + si1.referencePoint + " - " + si.referencePoint); |
201 + si1.referencePoint + " - " | |
202 + si.referencePoint); | |
203 } | 181 } |
204 if (pos >= si1.referencePoint | 182 if (pos >= si1.referencePoint && pos <= si.referencePoint) { |
205 && pos <= si. referencePoint) { | |
206 s1 = si1; | 183 s1 = si1; |
207 s2 = si; | 184 s2 = si; |
208 break; | 185 break; |
209 } | 186 } |
210 } | 187 } |
213 throw new IllegalStateException("no interval found"); | 190 throw new IllegalStateException("no interval found"); |
214 } | 191 } |
215 | 192 |
216 Segment anchor, free; | 193 Segment anchor, free; |
217 | 194 |
218 if (from > to) { anchor = s1; free = s2; } | 195 if (this.from > this.to) { |
219 else { anchor = s2; free = s1; } | 196 anchor = s1; |
197 free = s2; | |
198 } else { | |
199 anchor = s2; | |
200 free = s1; | |
201 } | |
220 | 202 |
221 // build transforms based on "gleichwertiger" phase | 203 // build transforms based on "gleichwertiger" phase |
222 for (int i = 0; i < qPositions.length; ++i) { | 204 for (int i = 0; i < qPositions.length; ++i) { |
223 QPosition qi = table.getQPosition( | 205 final QPosition qi = table.getQPosition(anchor.referencePoint, anchor.values[i]); |
224 anchor.referencePoint, | |
225 anchor.values[i]); | |
226 | 206 |
227 if ((qPositions[i] = qi) == null) { | 207 if ((qPositions[i] = qi) == null) { |
228 addProblem(pos, "cannot.find.q", anchor.values[i]); | 208 addProblem(pos, "cannot.find.q", anchor.values[i]); |
229 functions[i] = Identity.IDENTITY; | 209 functions[i] = Identity.IDENTITY; |
230 } | 210 } else { |
231 else { | 211 final double qA = table.getQ(qi, anchor.referencePoint); |
232 double qA = table.getQ(qi, anchor.referencePoint); | 212 final double qF = table.getQ(qi, free.referencePoint); |
233 double qF = table.getQ(qi, free .referencePoint); | 213 |
234 | 214 functions[i] = Double.isNaN(qA) || Double.isNaN(qF) ? Identity.IDENTITY : new Linear(qA, qF, anchor.values[i], free.values[i]); |
235 functions[i] = Double.isNaN(qA) || Double.isNaN(qF) | |
236 ? Identity.IDENTITY | |
237 : new Linear( | |
238 qA, qF, | |
239 anchor.values[i], free.values[i]); | |
240 | 215 |
241 if (debug) { | 216 if (debug) { |
242 log.debug( | 217 log.debug(anchor.referencePoint + ": " + qA + " -> " + functions[i].value(qA) + " / " + free.referencePoint + ": " + qF + " -> " |
243 anchor.referencePoint + ": " + | 218 + functions[i].value(qF)); |
244 qA + " -> " + functions[i].value(qA) + | |
245 " / " + free.referencePoint + ": " + | |
246 qF + " -> " + functions[i].value(qF)); | |
247 } | 219 } |
248 } | 220 } |
249 } // build transforms | 221 } // build transforms |
250 } // "ungleichwertiges" interval | 222 } // "ungleichwertiges" interval |
251 } // find matching interval | 223 } // find matching interval |
252 | 224 |
253 for (int i = 0; i < qPositions.length; ++i) { | 225 for (int i = 0; i < qPositions.length; ++i) { |
254 QPosition qPosition = qPositions[i]; | 226 final QPosition qPosition = qPositions[i]; |
255 | 227 |
256 if (qPosition == null) { | 228 if (qPosition == null) { |
257 continue; | 229 continue; |
258 } | 230 } |
259 | 231 |
260 if (table.interpolate(pos, out, qPosition, functions[i])) { | 232 if (table.interpolate(pos, out, qPosition, functions[i])) { |
261 results[i].add(out[0], out[1], pos); | 233 results[i].add(out[0], out[1], pos); |
262 } | 234 } else { |
263 else { | |
264 addProblem(pos, "cannot.interpolate.w.q"); | 235 addProblem(pos, "cannot.interpolate.w.q"); |
265 } | 236 } |
266 } | 237 } |
267 } | 238 } |
239 final String custom = Resources.format(meta, "common.custom"); | |
268 | 240 |
269 // Backjump correction | 241 // Backjump correction |
270 for (int i = 0; i < results.length; ++i) { | 242 for (int i = 0; i < results.length; ++i) { |
271 BackJumpCorrector bjc = new BackJumpCorrector(); | 243 final BackJumpCorrector bjc = new BackJumpCorrector(); |
272 | 244 |
273 double [] ws = results[i].getWs(); | 245 final double[] ws = results[i].getWs(); |
274 double [] kms = results[i].getKms(); | 246 final double[] kms = results[i].getKms(); |
275 | 247 |
276 if (bjc.doCorrection(kms, ws, this)) { | 248 if (bjc.doCorrection(kms, ws, this)) { |
277 results[i] = new WQCKms(results[i], bjc.getCorrected()); | 249 results[i] = new WQCKms(results[i], bjc.getCorrected()); |
278 } | 250 } |
279 } | 251 } |
280 | 252 |
281 // Name the curves. | 253 // Name the curves. |
282 for (int i = 0; i < results.length; ++i) { | 254 for (int i = 0; i < results.length; ++i) { |
283 results[i].setName(createName(i)); | 255 results[i].setName(createName(i, custom)); |
284 } | 256 } |
285 | 257 |
286 // Generate the "Umhuellende". | 258 // Generate the "Umhuellende". |
287 ConstantWQKms [] infoldings = | 259 final ConstantWQKms[] infoldings = generateInfolding(table, results, this.from, this.to, this.step); |
288 generateInfolding(table, results, from, to, step); | |
289 | 260 |
290 // TODO: Use qkms in a new result type. | 261 // TODO: Use qkms in a new result type. |
291 WQKms [] newResults = new WQKms[results.length + infoldings.length]; | 262 final WQKms[] newResults = new WQKms[results.length + infoldings.length]; |
292 System.arraycopy( | 263 System.arraycopy(results, 0, newResults, 0, results.length); |
293 results, 0, newResults, 0, results.length); | 264 System.arraycopy(infoldings, 0, newResults, results.length, infoldings.length); |
294 System.arraycopy( | |
295 infoldings, 0, newResults, results.length, infoldings.length); | |
296 | 265 |
297 return new CalculationResult(newResults, this); | 266 return new CalculationResult(newResults, this); |
298 } | 267 } |
299 | 268 |
300 protected ConstantWQKms [] generateInfolding( | 269 protected ConstantWQKms[] generateInfolding(final WstValueTable wst, final WQKms[] results, final double from, final double to, final double step) { |
301 WstValueTable wst, | 270 final WstValueTable.Column[] columns = wst.getColumns(); |
302 WQKms [] results, | 271 |
303 double from, | 272 final InfoldingColumns ic = new InfoldingColumns(columns); |
304 double to, | |
305 double step | |
306 ) { | |
307 WstValueTable.Column [] columns = wst.getColumns(); | |
308 | |
309 InfoldingColumns ic = new InfoldingColumns(columns); | |
310 ic.markInfoldingColumns(results); | 273 ic.markInfoldingColumns(results); |
311 | 274 |
312 List<ConstantWQKms> infoldings = new ArrayList<ConstantWQKms>(); | 275 final List<ConstantWQKms> infoldings = new ArrayList<>(); |
313 | 276 |
314 boolean [] infoldingColumns = ic.getInfoldingColumns(); | 277 final boolean[] infoldingColumns = ic.getInfoldingColumns(); |
315 | 278 |
316 double [] kms = null; | 279 double[] kms = null; |
317 double [] ws = null; | 280 double[] ws = null; |
318 | 281 |
319 for (int i = 0; i < infoldingColumns.length; ++i) { | 282 for (int i = 0; i < infoldingColumns.length; ++i) { |
320 if (!infoldingColumns[i]) { | 283 if (!infoldingColumns[i]) { |
321 continue; | 284 continue; |
322 } | 285 } |
323 | 286 |
324 if (kms == null) { | 287 if (kms == null) { |
325 kms = DoubleUtil.explode(from, to, step); | 288 kms = DoubleUtil.explode(from, to, step); |
326 ws = new double[kms.length]; | 289 ws = new double[kms.length]; |
327 } | 290 } |
328 | 291 |
329 QRangeTree.QuickQFinder qf = | 292 final QRangeTree.QuickQFinder qf = columns[i].getQRangeTree().new QuickQFinder(); |
330 columns[i].getQRangeTree().new QuickQFinder(); | 293 |
331 | 294 final int numProblemsBefore = numProblems(); |
332 int numProblemsBefore = numProblems(); | 295 final double[] qs = qf.findQs(kms, this); |
333 double [] qs = qf.findQs(kms, this); | 296 |
334 | 297 final String name = columns[i].getName(); |
335 String name = columns[i].getName(); | 298 final ConstantWQKms infolding = new ConstantWQKms(kms, qs, ws, name); |
336 ConstantWQKms infolding = new ConstantWQKms(kms, qs, ws, name); | |
337 | 299 |
338 if (numProblems() > numProblemsBefore) { | 300 if (numProblems() > numProblemsBefore) { |
339 infolding.removeNaNs(); | 301 infolding.removeNaNs(); |
340 } | 302 } |
341 | 303 |
342 infoldings.add(infolding); | 304 infoldings.add(infolding); |
343 } | 305 } |
344 | 306 |
345 for (int i = 0, I = infoldings.size(); i < I; i++) { | 307 for (int i = 0, I = infoldings.size(); i < I; i++) { |
346 ConstantWQKms infolding = infoldings.get(i); | 308 final ConstantWQKms infolding = infoldings.get(i); |
347 String name = infolding.getName(); | 309 final String name = infolding.getName(); |
348 // TODO: i18n | 310 // TODO: i18n |
349 if (i == 0) { | 311 if (i == 0) { |
350 infolding.setName("untere Umh\u00fcllende " + name); | 312 infolding.setName("untere Umh\u00fcllende " + name); |
351 } | 313 } else if (i == I - 1) { |
352 else if (i == I-1) { | |
353 infolding.setName("obere Umh\u00fcllende " + name); | 314 infolding.setName("obere Umh\u00fcllende " + name); |
354 } | 315 } else { |
355 else { | |
356 infolding.setName("geschnitten " + name); | 316 infolding.setName("geschnitten " + name); |
357 } | 317 } |
358 } | 318 } |
359 | 319 |
360 return infoldings.toArray(new ConstantWQKms[infoldings.size()]); | 320 return infoldings.toArray(new ConstantWQKms[infoldings.size()]); |
361 } | 321 } |
362 | 322 |
363 // TODO: issue1109/2, merge with FixRealizingCalculation | 323 // TODO: issue1109/2, merge with FixRealizingCalculation |
364 protected String createName(int index) { | 324 protected String createName(final int index, final String custom) { |
365 // TODO: i18n | 325 |
366 StringBuilder sb = new StringBuilder(isQ ? "Q" : "W"); | 326 final StringBuilder sb = new StringBuilder(this.isQ ? "Q" : "W"); |
367 sb.append(" benutzerdefiniert ("); | 327 sb.append(" ").append(custom).append(" ("); |
368 for (int i = 0, N = segments.size(); i < N; ++i) { | 328 for (int i = 0, N = this.segments.size(); i < N; ++i) { |
369 if (i > 0) { | 329 if (i > 0) { |
370 sb.append("; "); | 330 sb.append("; "); |
371 } | 331 } |
372 Segment segment = segments.get(i); | 332 final Segment segment = this.segments.get(i); |
373 sb.append((segment.backup != null | 333 sb.append((segment.backup != null ? segment.backup : segment.values)[index]); |
374 ? segment.backup | |
375 : segment.values)[index]); | |
376 } | 334 } |
377 sb.append(')'); | 335 sb.append(')'); |
378 return sb.toString(); | 336 return sb.toString(); |
379 } | 337 } |
380 } | 338 } |
381 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |