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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2876 - (show annotations) (download)
Thu Jan 28 22:14:42 2016 UTC (8 years, 4 months ago) by torben
Original Path: dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/AddressManager.java
File size: 18177 byte(s)
Implement creation of new addresses
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 db.saveNewAddresses(inserts);
212
213
214
215 System.out.println("Writeback done: elapsed " + timer.getElapsed() + "ms.");
216 }
217
218
219 public void visit(AddressSourceEntry entry) {
220 if (entry.type == EntryType.TypeSingleAddress) {
221 visitSingle(entry);
222 } else {
223 visitRange(entry);
224 }
225 }
226
227 private void visitSingle(AddressSourceEntry entry) {
228 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( entry.gadeid );
229 if (gade == null) {
230 unknownStreets.putIfAbsent(entry.gadeid, entry.vejnavn);
231 createFromEntry(entry); // if we get here there was no match - so we need to create it
232 return;
233 }
234
235 ArrayList<Address> litraList = gade.get(entry.husnr);
236 if (litraList == null) {
237 createFromEntry(entry); // if we get here there was no match - so we need to create it
238 return;
239 }
240 boolean found = false;
241 for (Address addr : litraList) {
242 if (addr.husnrbogstav.equals(entry.litra) ) {
243 updateAddress(addr, entry);
244 found = true; // 1 visit should be enough but as long as there's duplicates on gadeid+husnr+litra we will visit them all
245 //when the issue with duplicates is resolved this should be reverted to a return or break
246 }
247 }
248 if (found == false) {
249 createFromEntry(entry); // if we get here there was no match - so we need to create it
250 }
251 }
252
253 private void visitRange(AddressSourceEntry entry) {
254
255 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( entry.gadeid );
256 if (gade == null) {
257 unknownStreets.putIfAbsent(entry.gadeid, entry.vejnavn);
258 System.out.println("[Range] Ukendt gadeID " + entry);
259 return;
260 }
261
262 for (Entry<Short, ArrayList<Address>> husnrEntry: gade.entrySet()) {
263
264 short husnummer = husnrEntry.getKey();
265
266 if ( (entry.husnr % 2) != (husnummer%2) ){ //lige/ulige skal passe sammen
267 continue;
268 }
269
270 if ( husnummer < entry.husnr || husnummer > entry.tilHusnr) {
271 continue;
272 }
273
274 ArrayList<Address> litraList = husnrEntry.getValue();
275
276 /* a=adressetabel u=input
277 * and (a.husnr>u.FraHusNr OR (a.husnr=u.FraHusNr AND a.HusnrBogstav >= u.FraBog))
278 * AND (a.husnr<u.TilHusNr OR (a.husnr=u.TilHusNr AND a.HusnrBogstav <= u.TilBog))
279 */
280
281
282 for (Address addr: litraList) {
283 if (addr.husnr > entry.husnr || (addr.husnr == entry.husnr && addr.husnrbogstav.compareTo(entry.litra) >= 0 )) {
284 //Using nested IF instead of &&
285 if (addr.husnr < entry.tilHusnr || (addr.husnr == entry.tilHusnr && addr.husnrbogstav.compareTo(entry.tilLitra) <= 0 )) {
286 updateAddress(addr, entry);
287 }
288 }
289 }
290 }
291 }
292
293
294
295 private void updateAddress(Address addr, AddressSourceEntry entry) {
296 if ( addr.distributor != null && addr.distributor.equals(entry.distributor) == false) {
297 rejectedEntries.add(entry);
298 System.out.println("Afviser " + entry);
299 return;
300 }
301
302
303
304 if (entry.ugedage.mandag) {
305 if (addr.visitedMan == false) {
306 addr.visitedMan = true;
307 if (addr.ruteMandag == null) {
308 addr.stateMan = AddressState.OPENED;
309 addr.ruteMandag = entry.rute;
310 addr.korelisteMandag = entry.koreliste;
311 } else {
312
313 if (StringUtils.equals(addr.ruteMandag, entry.rute) == false || StringUtils.equals(addr.korelisteMandag, entry.koreliste) == false) {
314 addr.stateMan = AddressState.MODIFIED;
315 addr.ruteMandag = entry.rute;
316 addr.korelisteMandag = entry.koreliste;
317 }
318 }
319 } else {
320 System.out.println( "Double visit monday " + addr);
321 }
322
323 }
324
325
326 if (entry.ugedage.tirsdag) {
327 if (addr.visitedTir == false) {
328 addr.visitedTir = true;
329 if (addr.ruteTirsdag == null) {
330 addr.stateTir = AddressState.OPENED;
331 addr.ruteTirsdag = entry.rute;
332 addr.korelisteTirsdag = entry.koreliste;
333 } else {
334
335 if (StringUtils.equals(addr.ruteTirsdag, entry.rute) == false || StringUtils.equals(addr.korelisteTirsdag, entry.koreliste) == false) {
336 addr.stateTir = AddressState.MODIFIED;
337 addr.ruteTirsdag = entry.rute;
338 addr.korelisteTirsdag = entry.koreliste;
339 }
340 }
341 } else {
342 System.out.println( "Double visit tuesday " + addr);
343 }
344 }
345
346 if (entry.ugedage.onsdag) {
347 if (addr.visitedOns == false) {
348 addr.visitedOns = true;
349 if (addr.ruteOnsdag == null) {
350 addr.stateOns = AddressState.OPENED;
351 addr.ruteOnsdag = entry.rute;
352 addr.korelisteOnsdag = entry.koreliste;
353 } else {
354
355 if (StringUtils.equals(addr.ruteOnsdag, entry.rute) == false || StringUtils.equals(addr.korelisteOnsdag, entry.koreliste) == false) {
356 addr.stateOns = AddressState.MODIFIED;
357 addr.ruteOnsdag = entry.rute;
358 addr.korelisteOnsdag = entry.koreliste;
359 }
360 }
361 } else {
362 System.out.println( "Double visit wednesday " + addr);
363 }
364 }
365
366
367 if (entry.ugedage.torsdag) {
368 if (addr.visitedTor == false) {
369 addr.visitedTor = true;
370 if (addr.ruteTorsdag == null) {
371 addr.stateTor = AddressState.OPENED;
372 addr.ruteTorsdag = entry.rute;
373 addr.korelisteTorsdag = entry.koreliste;
374 } else {
375
376
377 if (StringUtils.equals(addr.ruteTorsdag, entry.rute) == false || StringUtils.equals(addr.korelisteTorsdag, entry.koreliste) == false) {
378 addr.stateTor = AddressState.MODIFIED;
379 addr.ruteTorsdag = entry.rute;
380 addr.korelisteTorsdag = entry.koreliste;
381 }
382 }
383 } else {
384 System.out.println( "Double visit thursday " + addr);
385 }
386 }
387
388
389 if (entry.ugedage.fredag) {
390 if (addr.visitedFre == false) {
391 addr.visitedFre = true;
392 if (addr.ruteFredag == null) {
393 addr.stateFre = AddressState.OPENED;
394 addr.ruteFredag = entry.rute;
395 addr.korelisteFredag = entry.koreliste;
396 } else {
397
398 if (StringUtils.equals(addr.ruteFredag, entry.rute) == false || StringUtils.equals(addr.korelisteFredag, entry.koreliste) == false) {
399 addr.stateFre = AddressState.MODIFIED;
400 addr.ruteFredag = entry.rute;
401 addr.korelisteFredag = entry.koreliste;
402 }
403 }
404 } else {
405 System.out.println( "Double visit friday " + addr);
406 }
407 }
408
409
410 if (entry.ugedage.lordag) {
411 if (addr.visitedLor == false) {
412 addr.visitedLor = true;
413 if (addr.ruteLordag == null) {
414 addr.stateLor = AddressState.OPENED;
415 addr.ruteLordag = entry.rute;
416 addr.korelisteLordag = entry.koreliste;
417 } else {
418
419
420 if (StringUtils.equals(addr.ruteLordag, entry.rute) == false || StringUtils.equals(addr.korelisteLordag, entry.koreliste) == false) {
421 addr.stateLor = AddressState.MODIFIED;
422 addr.ruteLordag = entry.rute;
423 addr.korelisteLordag = entry.koreliste;
424 }
425 }
426 } else {
427 System.out.println( "Double visit saturday " + addr);
428 }
429 }
430
431
432 if (entry.ugedage.sondag) {
433 if (addr.visitedSon == false) {
434 addr.visitedSon = true;
435 if (addr.ruteSondag == null) {
436 addr.stateSon = AddressState.OPENED;
437 addr.ruteSondag = entry.rute;
438 addr.korelisteSondag = entry.koreliste;
439 } else {
440
441 if (StringUtils.equals(addr.ruteSondag, entry.rute) == false || StringUtils.equals(addr.korelisteSondag, entry.koreliste) == false) {
442 addr.stateSon = AddressState.MODIFIED;
443 addr.ruteSondag = entry.rute;
444 addr.korelisteSondag = entry.koreliste;
445 }
446 }
447 } else {
448 System.out.println( "Double visit sunday " + addr);
449 }
450 }
451
452
453
454 //addr.visited = true;
455 if (addr.state == AddressState.NOT_CHANGED) {
456 if (addr.distributor == null) {
457 addr.state = AddressState.OPENED;
458 addr.distributor = entry.distributor;
459 } else {
460 if (addr.stateMan != AddressState.NOT_CHANGED || addr.stateTir != AddressState.NOT_CHANGED
461 || addr.stateOns != AddressState.NOT_CHANGED || addr.stateTor != AddressState.NOT_CHANGED
462 || addr.stateFre != AddressState.NOT_CHANGED || addr.stateLor != AddressState.NOT_CHANGED || addr.stateSon != AddressState.NOT_CHANGED ){
463
464 addr.state = AddressState.MODIFIED;
465 }
466 }
467 }
468
469 updateDbkBane(addr);
470
471 }
472
473
474
475 private void createFromEntry(AddressSourceEntry entry) {
476 if (entry.husnr == 999) {
477 return;
478 }
479 if (entry.kommunekode == 0 || entry.vejkode == 0) {
480 return;
481 }
482 if (entry.kommunekode < 100) {
483 return;
484 }
485
486 String gadeidStr = Integer.toString(entry.gadeid);
487 if (gadeidStr.length() != 9) {
488 return;
489 }
490 if (Short.parseShort(gadeidStr.substring(0, 4)) != entry.postnr) {
491 return; //gadeid / postnr mismatch
492 }
493
494
495
496 System.out.println("Opretter adresse ud fra " + entry);
497
498 Address a = new Address();
499 a.state = AddressState.CREATED;
500
501 a.distributor = entry.distributor;
502 a.gadeid = entry.gadeid;
503 a.kommunekode = entry.kommunekode;
504 a.vejkode = entry.vejkode;
505 a.vejnavn = entry.vejnavn;
506 a.husnr = entry.husnr;
507 a.husnrbogstav = entry.litra;
508 a.postnr = entry.postnr;
509 //a.visited = true;
510
511 if (entry.ugedage.mandag) {
512 a.ruteMandag = entry.rute;
513 a.korelisteMandag = entry.koreliste;
514 }
515 if (entry.ugedage.tirsdag) {
516 a.ruteTirsdag = entry.rute;
517 a.korelisteTirsdag = entry.koreliste;
518 }
519 if (entry.ugedage.onsdag) {
520 a.ruteOnsdag = entry.rute;
521 a.korelisteOnsdag = entry.koreliste;
522 }
523 if (entry.ugedage.torsdag) {
524 a.ruteTorsdag = entry.rute;
525 a.korelisteTorsdag = entry.koreliste;
526 }
527 if (entry.ugedage.fredag) {
528 a.ruteFredag = entry.rute;
529 a.korelisteFredag = entry.koreliste;
530 }
531 if (entry.ugedage.lordag) {
532 a.ruteLordag = entry.rute;
533 a.korelisteLordag = entry.koreliste;
534 }
535 if (entry.ugedage.sondag) {
536 a.ruteSondag = entry.rute;
537 a.korelisteLordag = entry.koreliste;
538 }
539
540 updateDbkBane(a);
541
542 // Nu er det nye adresse object oprettet - nu skal det gemmes i søge strukturen og totallisten
543
544
545 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( a.gadeid );
546
547 if (gade == null) {
548 gade = new TreeMap<Short,ArrayList<Address>>();
549 searchStructure.put(a.gadeid, gade);
550 }
551
552 ArrayList<Address> litraList = gade.get(a.husnr);
553 if (litraList == null) {
554 litraList = new ArrayList<Address>();
555 gade.put(a.husnr, litraList);
556 }
557
558 litraList.add(a);
559 addressList.add(a);
560
561 }
562
563
564
565 /*
566 DAO:
567 UPDATE fulddaekning.adressetabel
568 SET dbkbane = case
569 when substr(korelisteMa,1,2) IN ('07','10','11','12','14','15','16','18','19','20') then 205 #DAO-BRA
570 when substr(korelisteMa,1,2) BETWEEN 24 and 30 then 201 #DAO-Ovrige
571 else 202 #dao syd (52-99=
572 END
573 WHERE distributor='DAO'
574 AND ruteMa is not null;
575
576 FD: Altid 200
577 NS: Altid 204
578 BK: 195,196,197,198
579 */
580
581 private void updateDbkBane(Address a) {
582 List<Short> daoBane205 = Arrays.asList( new Short[] {7,10,11,12,12,14,15,16,18,19,20} );
583
584
585 Short bane = null;
586
587 switch (a.distributor) {
588 case "BK":
589 bane = dbkBaneMap.get(a.postnr);
590 break;
591 case "DAO":
592 String koreliste = MiscUtils.firstNonNull(a.korelisteMandag,a.korelisteLordag, a.korelisteSondag); //DAO har kun 3 dækningstyper
593 short first2 = Short.parseShort( koreliste.substring(0,2) );
594 if ( daoBane205.contains(first2) ) {
595 bane = 205;
596 } else if (first2 >= 24 && first2<=30) {
597 bane = 201;
598 } else {
599 bane = 202;
600 }
601
602 break;
603 case "FD":
604 bane = 200;
605 break;
606 case "NS":
607 bane = 204;
608 break;
609 default:
610 throw new RuntimeException("Ukendt distributor" + a.distributor); //Silence findBugs
611 }
612
613 if (bane == null) {
614 throw new RuntimeException("Ukendt bane for postnr" + a.postnr);
615 }
616
617 if (a.dbkBane != bane) {
618 a.dbkBane = bane;
619 if (a.state ==AddressState.NOT_CHANGED) {
620 a.state = AddressState.MODIFIED;
621 }
622 }
623 }
624
625 public List<Address> getAddressList() {
626 return Collections.unmodifiableList(addressList);
627 }
628
629 public Map<Integer,String> getUnknownStreets() {
630 return Collections.unmodifiableMap( unknownStreets );
631 }
632
633
634
635 public int getRejectedCount() {
636 return rejectedEntries.size();
637 }
638
639 }

  ViewVC Help
Powered by ViewVC 1.1.20