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

  ViewVC Help
Powered by ViewVC 1.1.20