/[projects]/dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/AddressManager.java
ViewVC logotype

Contents of /dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/AddressManager.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2866 - (show annotations) (download)
Thu Jan 28 12:14:50 2016 UTC (8 years, 3 months ago) by torben
File size: 17642 byte(s)
Visit all duplicates
1 package dk.daoas.adressevedligehold;
2
3 import java.sql.SQLException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collections;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Map.Entry;
10 import java.util.TreeMap;
11
12 import org.apache.commons.lang3.StringUtils;
13
14 import dk.daoas.adressevedligehold.AddressSourceEntry.EntryType;
15 import dk.daoas.adressevedligehold.beans.Address;
16 import dk.daoas.adressevedligehold.beans.Address.AddressState;
17 import dk.daoas.adressevedligehold.db.DatabaseLayerImplementation;
18 import dk.daoas.adressevedligehold.util.DeduplicateHelper;
19 import dk.daoas.adressevedligehold.util.MiscUtils;
20 import dk.daoas.adressevedligehold.util.TimingHelper;
21
22 /*
23 * TODO: håndtering af entry dupletter ! (+ rapportering af dem)
24
25
26
27 */
28
29 public class AddressManager {
30
31
32 List<Address> addressList;
33
34 Map<Integer, TreeMap<Short, ArrayList<Address>> > searchStructure;
35
36 ArrayList<AddressSourceEntry> afvisteEntries = new ArrayList<AddressSourceEntry>();
37
38 Map<Short,Short> dbkBaneMap = new TreeMap<Short,Short>();
39
40 public AddressManager() throws SQLException {
41 DatabaseLayerImplementation db = new DatabaseLayerImplementation();
42
43 searchStructure = new TreeMap<Integer, TreeMap<Short, ArrayList<Address>> >();
44
45 addressList = db.getAllAdresses();
46
47 DeduplicateHelper<Integer> intHelper = new DeduplicateHelper<Integer>();
48 DeduplicateHelper<Short> shortHelper = new DeduplicateHelper<Short>();
49
50 List<ArrayList<Address>> arraylistCache = new ArrayList<ArrayList<Address>>();
51
52 TimingHelper timer = new TimingHelper();
53
54 for (Address a : addressList) {
55 Integer gadeid = intHelper.getInstance( a.gadeid );
56 Short husnr = shortHelper.getInstance( a.husnr );
57 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( gadeid );
58
59 if (a.dbkBane > 0 && a.postnr<=4999) {
60 Short bane = dbkBaneMap.get(a.postnr);
61 if (bane == null) {
62 dbkBaneMap.put(a.postnr, a.dbkBane);
63 }
64 }
65
66 if (gade == null) {
67 gade = new TreeMap<Short,ArrayList<Address>>();
68 searchStructure.put(gadeid, gade);
69 }
70
71 ArrayList<Address> litraList = gade.get(husnr);
72 if (litraList == null) {
73 litraList = new ArrayList<Address>();
74 gade.put(husnr, litraList);
75 arraylistCache.add(litraList);
76 }
77
78 litraList.add(a);
79 }
80
81 for (ArrayList<Address> list : arraylistCache) {
82 list.trimToSize();
83 }
84
85 System.out.println("AddressManager ready, elapsed " + timer.getElapsed() + "ms");
86
87
88 }
89
90 public void closeUnvisitedAddresses(String distributor, EntryUgedage ugedage) {
91 for (Address addr : addressList) {
92 if (addr.distributor == null)
93 continue;
94
95 if (addr.distributor.equals(distributor) == false)//irrelevant for denne indlæsning
96 continue;
97
98 int closedCount = 0;
99
100 if (addr.visitedMan == false && ugedage.mandag) {
101 if (addr.ruteMandag != null) {
102 addr.ruteMandag = null;
103 addr.korelisteMandag = null;
104 addr.stateMan = AddressState.CLOSED;
105 closedCount++;
106 }
107 }
108 if (addr.visitedTir == false && ugedage.tirsdag) {
109 if (addr.ruteTirsdag != null) {
110 addr.ruteTirsdag = null;
111 addr.korelisteTirsdag = null;
112 addr.stateTir = AddressState.CLOSED;
113 closedCount++;
114 }
115 }
116
117 if (addr.visitedOns == false && ugedage.onsdag) {
118 if (addr.ruteOnsdag != null) {
119 addr.ruteOnsdag = null;
120 addr.korelisteOnsdag = null;
121 addr.stateOns = AddressState.CLOSED;
122 closedCount++;
123 }
124 }
125
126 if (addr.visitedTor == false && ugedage.torsdag) {
127 if (addr.ruteTorsdag != null) {
128 addr.ruteTorsdag = null;
129 addr.korelisteTorsdag = null;
130 addr.stateTor = AddressState.CLOSED;
131 closedCount++;
132 }
133 }
134
135 if (addr.visitedFre == false && ugedage.fredag) {
136 if (addr.ruteFredag != null) {
137 addr.ruteFredag = null;
138 addr.korelisteFredag = null;
139 addr.stateFre = AddressState.CLOSED;
140 closedCount++;
141 }
142 }
143
144 if (addr.visitedLor == false && ugedage.lordag) {
145 if (addr.ruteLordag != null) {
146 addr.ruteLordag = null;
147 addr.korelisteLordag = null;
148 addr.stateLor = AddressState.CLOSED;
149 closedCount++;
150 }
151 }
152
153 if (addr.visitedSon == false && ugedage.sondag) {
154 if (addr.ruteSondag != null) {
155 addr.ruteSondag = null;
156 addr.korelisteSondag = null;
157 addr.stateSon = AddressState.CLOSED;
158 closedCount++;
159 }
160 }
161
162 if (addr.state == AddressState.NOT_CHANGED && closedCount>0) {
163 addr.state = AddressState.CLOSED;
164 }
165
166 }
167 }
168 public void dumpChanged() {
169 int count = 0;
170 for (Address addr : addressList) {
171 if (addr.state == AddressState.NOT_CHANGED) {
172 continue;
173 }
174 /*if (addr.stateMan == AddressState.NOT_CHANGED || addr.stateMan == AddressState.CREATED) {
175 continue;
176 }*/
177
178 if (addr.stateMan != AddressState.MODIFIED ) {
179 continue;
180 }
181
182 System.out.println(addr.state + ": " + addr.toStringExtended() );
183 System.out.println(addr.getRuteString() );
184
185 if (count++ > 50)
186 return;
187 }
188 }
189
190 public void writeBackChanges() {
191 System.out.println("Writing back changes");
192 TimingHelper timer = new TimingHelper();
193
194 List<Address> updates = new ArrayList<Address>(1024*1024);
195 List<Address> inserts = new ArrayList<Address>(16*1024);
196
197 for (Address addr : addressList) {
198 if (addr.state == AddressState.CREATED) {
199 inserts.add(addr);
200 }
201 if (addr.state == AddressState.MODIFIED || addr.state == AddressState.OPENED || addr.state == AddressState.CLOSED) {
202 updates.add(addr);
203 }
204 }
205
206 DatabaseLayerImplementation db = new DatabaseLayerImplementation();
207
208 db.updateAddresses(updates);
209
210
211
212 System.out.println("Writeback done: elapsed " + timer.getElapsed() + "ms.");
213 }
214
215
216 public void visit(AddressSourceEntry entry) {
217 if (entry.type == EntryType.TypeSingleAddress) {
218 visitSingle(entry);
219 } else {
220 visitRange(entry);
221 }
222 }
223
224 private void visitSingle(AddressSourceEntry entry) {
225 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( entry.gadeid );
226 if (gade == null) {
227 createFromEntry(entry); // if we get here there was no match - so we need to create it
228 return;
229 }
230
231 ArrayList<Address> litraList = gade.get(entry.husnr);
232 if (litraList == null) {
233 createFromEntry(entry); // if we get here there was no match - so we need to create it
234 return;
235 }
236 boolean found = false;
237 for (Address addr : litraList) {
238 if (addr.husnrbogstav.equals(entry.litra) ) {
239 updateAddress(addr, entry);
240 found = true; // 1 visit should be enough but as long as there's duplicates on gadeid+husnr+litra we will visit them all
241 //when the issue with duplicates is resolved this should be reverted to a return or break
242 }
243 }
244 if (found == false) {
245 createFromEntry(entry); // if we get here there was no match - so we need to create it
246 }
247 }
248
249 private void visitRange(AddressSourceEntry entry) {
250
251 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( entry.gadeid );
252 if (gade == null) {
253 System.out.println("[Range] Ukendt gadeID " + entry);
254 return;
255 }
256
257 for (Entry<Short, ArrayList<Address>> husnrEntry: gade.entrySet()) {
258
259 short husnummer = husnrEntry.getKey();
260
261 if ( (entry.husnr % 2) != (husnummer%2) ){ //lige/ulige skal passe sammen
262 continue;
263 }
264
265 if ( husnummer < entry.husnr || husnummer > entry.tilHusnr) {
266 continue;
267 }
268
269 ArrayList<Address> litraList = husnrEntry.getValue();
270
271 /* a=adressetabel u=input
272 * and (a.husnr>u.FraHusNr OR (a.husnr=u.FraHusNr AND a.HusnrBogstav >= u.FraBog))
273 * AND (a.husnr<u.TilHusNr OR (a.husnr=u.TilHusNr AND a.HusnrBogstav <= u.TilBog))
274 */
275
276
277 for (Address addr: litraList) {
278 if (addr.husnr > entry.husnr || (addr.husnr == entry.husnr && addr.husnrbogstav.compareTo(entry.litra) >= 0 )) {
279 //Using nested IF instead of &&
280 if (addr.husnr < entry.tilHusnr || (addr.husnr == entry.tilHusnr && addr.husnrbogstav.compareTo(entry.tilLitra) <= 0 )) {
281 updateAddress(addr, entry);
282 }
283 }
284 }
285 }
286 }
287
288
289
290 private void updateAddress(Address addr, AddressSourceEntry entry) {
291 if ( addr.distributor != null && addr.distributor.equals(entry.distributor) == false) {
292 afvisteEntries.add(entry);
293 System.out.println("Afviser " + entry);
294 return;
295 }
296
297
298
299 if (entry.ugedage.mandag) {
300 if (addr.visitedMan == false) {
301 addr.visitedMan = true;
302 if (addr.ruteMandag == null) {
303 addr.stateMan = AddressState.OPENED;
304 addr.ruteMandag = entry.rute;
305 addr.korelisteMandag = entry.koreliste;
306 } else {
307
308 if (StringUtils.equals(addr.ruteMandag, entry.rute) == false || StringUtils.equals(addr.korelisteMandag, entry.koreliste) == false) {
309 addr.stateMan = AddressState.MODIFIED;
310 addr.ruteMandag = entry.rute;
311 addr.korelisteMandag = entry.koreliste;
312 }
313 }
314 } else {
315 System.out.println( "Double visit monday " + addr);
316 }
317
318 }
319
320
321 if (entry.ugedage.tirsdag) {
322 if (addr.visitedTir == false) {
323 addr.visitedTir = true;
324 if (addr.ruteTirsdag == null) {
325 addr.stateTir = AddressState.OPENED;
326 addr.ruteTirsdag = entry.rute;
327 addr.korelisteTirsdag = entry.koreliste;
328 } else {
329
330 if (StringUtils.equals(addr.ruteTirsdag, entry.rute) == false || StringUtils.equals(addr.korelisteTirsdag, entry.koreliste) == false) {
331 addr.stateTir = AddressState.MODIFIED;
332 addr.ruteTirsdag = entry.rute;
333 addr.korelisteTirsdag = entry.koreliste;
334 }
335 }
336 } else {
337 System.out.println( "Double visit tuesday " + addr);
338 }
339 }
340
341 if (entry.ugedage.onsdag) {
342 if (addr.visitedOns == false) {
343 addr.visitedOns = true;
344 if (addr.ruteOnsdag == null) {
345 addr.stateOns = AddressState.OPENED;
346 addr.ruteOnsdag = entry.rute;
347 addr.korelisteOnsdag = entry.koreliste;
348 } else {
349
350 if (StringUtils.equals(addr.ruteOnsdag, entry.rute) == false || StringUtils.equals(addr.korelisteOnsdag, entry.koreliste) == false) {
351 addr.stateOns = AddressState.MODIFIED;
352 addr.ruteOnsdag = entry.rute;
353 addr.korelisteOnsdag = entry.koreliste;
354 }
355 }
356 } else {
357 System.out.println( "Double visit wednesday " + addr);
358 }
359 }
360
361
362 if (entry.ugedage.torsdag) {
363 if (addr.visitedTor == false) {
364 addr.visitedTor = true;
365 if (addr.ruteTorsdag == null) {
366 addr.stateTor = AddressState.OPENED;
367 addr.ruteTorsdag = entry.rute;
368 addr.korelisteTorsdag = entry.koreliste;
369 } else {
370
371
372 if (StringUtils.equals(addr.ruteTorsdag, entry.rute) == false || StringUtils.equals(addr.korelisteTorsdag, entry.koreliste) == false) {
373 addr.stateTor = AddressState.MODIFIED;
374 addr.ruteTorsdag = entry.rute;
375 addr.korelisteTorsdag = entry.koreliste;
376 }
377 }
378 } else {
379 System.out.println( "Double visit thursday " + addr);
380 }
381 }
382
383
384 if (entry.ugedage.fredag) {
385 if (addr.visitedFre == false) {
386 addr.visitedFre = true;
387 if (addr.ruteFredag == null) {
388 addr.stateFre = AddressState.OPENED;
389 addr.ruteFredag = entry.rute;
390 addr.korelisteFredag = entry.koreliste;
391 } else {
392
393 if (StringUtils.equals(addr.ruteFredag, entry.rute) == false || StringUtils.equals(addr.korelisteFredag, entry.koreliste) == false) {
394 addr.stateFre = AddressState.MODIFIED;
395 addr.ruteFredag = entry.rute;
396 addr.korelisteFredag = entry.koreliste;
397 }
398 }
399 } else {
400 System.out.println( "Double visit friday " + addr);
401 }
402 }
403
404
405 if (entry.ugedage.lordag) {
406 if (addr.visitedLor == false) {
407 addr.visitedLor = true;
408 if (addr.ruteLordag == null) {
409 addr.stateLor = AddressState.OPENED;
410 addr.ruteLordag = entry.rute;
411 addr.korelisteLordag = entry.koreliste;
412 } else {
413
414
415 if (StringUtils.equals(addr.ruteLordag, entry.rute) == false || StringUtils.equals(addr.korelisteLordag, entry.koreliste) == false) {
416 addr.stateLor = AddressState.MODIFIED;
417 addr.ruteLordag = entry.rute;
418 addr.korelisteLordag = entry.koreliste;
419 }
420 }
421 } else {
422 System.out.println( "Double visit saturday " + addr);
423 }
424 }
425
426
427 if (entry.ugedage.sondag) {
428 if (addr.visitedSon == false) {
429 addr.visitedSon = true;
430 if (addr.ruteSondag == null) {
431 addr.stateSon = AddressState.OPENED;
432 addr.ruteSondag = entry.rute;
433 addr.korelisteSondag = entry.koreliste;
434 } else {
435
436 if (StringUtils.equals(addr.ruteSondag, entry.rute) == false || StringUtils.equals(addr.korelisteSondag, entry.koreliste) == false) {
437 addr.stateSon = AddressState.MODIFIED;
438 addr.ruteSondag = entry.rute;
439 addr.korelisteSondag = entry.koreliste;
440 }
441 }
442 } else {
443 System.out.println( "Double visit sunday " + addr);
444 }
445 }
446
447
448
449 //addr.visited = true;
450 if (addr.state == AddressState.NOT_CHANGED) {
451 if (addr.distributor == null) {
452 addr.state = AddressState.OPENED;
453 addr.distributor = entry.distributor;
454 } else {
455 if (addr.stateMan != AddressState.NOT_CHANGED || addr.stateTir != AddressState.NOT_CHANGED
456 || addr.stateOns != AddressState.NOT_CHANGED || addr.stateTor != AddressState.NOT_CHANGED
457 || addr.stateFre != AddressState.NOT_CHANGED || addr.stateLor != AddressState.NOT_CHANGED || addr.stateSon != AddressState.NOT_CHANGED ){
458
459 addr.state = AddressState.MODIFIED;
460 }
461 }
462 }
463
464 updateDbkBane(addr);
465
466 }
467
468
469
470 private void createFromEntry(AddressSourceEntry entry) {
471 if (entry.husnr == 999) {
472 return;
473 }
474 if (entry.kommunekode == 0 || entry.vejkode == 0) {
475 return;
476 }
477 if (entry.kommunekode < 100) {
478 return;
479 }
480 if (Short.parseShort(Integer.toString(entry.gadeid).substring(0, 4)) != entry.postnr) {
481 return; //gadeid / postnr mismatch
482 }
483
484
485
486 System.out.println("Opretter adresse ud fra " + entry);
487
488 Address a = new Address();
489 a.state = AddressState.CREATED;
490
491 a.distributor = entry.distributor;
492 a.gadeid = entry.gadeid;
493 a.kommunekode = entry.kommunekode;
494 a.vejkode = entry.vejkode;
495 a.vejnavn = entry.vejnavn;
496 a.husnr = entry.husnr;
497 a.husnrbogstav = entry.litra;
498 a.postnr = entry.postnr;
499 //a.visited = true;
500
501 if (entry.ugedage.mandag) {
502 a.ruteMandag = entry.rute;
503 a.korelisteMandag = entry.koreliste;
504 }
505 if (entry.ugedage.tirsdag) {
506 a.ruteTirsdag = entry.rute;
507 a.korelisteTirsdag = entry.koreliste;
508 }
509 if (entry.ugedage.onsdag) {
510 a.ruteOnsdag = entry.rute;
511 a.korelisteOnsdag = entry.koreliste;
512 }
513 if (entry.ugedage.torsdag) {
514 a.ruteTorsdag = entry.rute;
515 a.korelisteTorsdag = entry.koreliste;
516 }
517 if (entry.ugedage.fredag) {
518 a.ruteFredag = entry.rute;
519 a.korelisteFredag = entry.koreliste;
520 }
521 if (entry.ugedage.lordag) {
522 a.ruteLordag = entry.rute;
523 a.korelisteLordag = entry.koreliste;
524 }
525 if (entry.ugedage.sondag) {
526 a.ruteSondag = entry.rute;
527 a.korelisteLordag = entry.koreliste;
528 }
529
530 updateDbkBane(a);
531
532 // Nu er det nye adresse object oprettet - nu skal det gemmes i søge strukturen og totallisten
533
534
535 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( a.gadeid );
536
537 if (gade == null) {
538 gade = new TreeMap<Short,ArrayList<Address>>();
539 searchStructure.put(a.gadeid, gade);
540 }
541
542 ArrayList<Address> litraList = gade.get(a.husnr);
543 if (litraList == null) {
544 litraList = new ArrayList<Address>();
545 gade.put(a.husnr, litraList);
546 }
547
548 litraList.add(a);
549 addressList.add(a);
550
551 }
552
553
554
555 /*
556 DAO:
557 UPDATE fulddaekning.adressetabel
558 SET dbkbane = case
559 when substr(korelisteMa,1,2) IN ('07','10','11','12','14','15','16','18','19','20') then 205 #DAO-BRA
560 when substr(korelisteMa,1,2) BETWEEN 24 and 30 then 201 #DAO-Ovrige
561 else 202 #dao syd (52-99=
562 END
563 WHERE distributor='DAO'
564 AND ruteMa is not null;
565
566 FD: Altid 200
567 NS: Altid 204
568 BK: 195,196,197,198
569 */
570
571 private void updateDbkBane(Address a) {
572 List<Short> daoBane205 = Arrays.asList( new Short[] {7,10,11,12,12,14,15,16,18,19,20} );
573
574
575 Short bane = null;
576
577 switch (a.distributor) {
578 case "BK":
579 bane = dbkBaneMap.get(a.postnr);
580 break;
581 case "DAO":
582 String koreliste = MiscUtils.firstNonNull(a.korelisteMandag,a.korelisteLordag, a.korelisteSondag); //DAO har kun 3 dækningstyper
583 short first2 = Short.parseShort( koreliste.substring(0,2) );
584 if ( daoBane205.contains(first2) ) {
585 bane = 205;
586 } else if (first2 >= 24 && first2<=30) {
587 bane = 201;
588 } else {
589 bane = 202;
590 }
591
592 break;
593 case "FD":
594 bane = 200;
595 break;
596 case "NS":
597 bane = 204;
598 break;
599 }
600
601 if (bane == null) {
602 throw new RuntimeException("Ukendt bane for postnr" + a.postnr);
603 }
604
605 if (a.dbkBane != bane) {
606 a.dbkBane = bane;
607 if (a.state ==AddressState.NOT_CHANGED) {
608 a.state = AddressState.MODIFIED;
609 }
610 }
611 }
612
613 public List<Address> getAddressList() {
614 return Collections.unmodifiableList(addressList);
615 }
616
617
618
619 public int getAfvistAntal() {
620 return afvisteEntries.size();
621 }
622
623 }

  ViewVC Help
Powered by ViewVC 1.1.20