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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2876 - (hide annotations) (download)
Thu Jan 28 22:14:42 2016 UTC (8 years, 4 months ago) by torben
File size: 18177 byte(s)
Implement creation of new addresses
1 torben 2838 package dk.daoas.adressevedligehold;
2    
3     import java.sql.SQLException;
4     import java.util.ArrayList;
5 torben 2847 import java.util.Arrays;
6 torben 2838 import java.util.Collections;
7     import java.util.List;
8     import java.util.Map;
9 torben 2844 import java.util.Map.Entry;
10 torben 2838 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 torben 2847 import dk.daoas.adressevedligehold.util.MiscUtils;
20 torben 2838 import dk.daoas.adressevedligehold.util.TimingHelper;
21    
22 torben 2840 /*
23     * TODO: håndtering af entry dupletter ! (+ rapportering af dem)
24 torben 2845
25    
26    
27 torben 2840 */
28    
29 torben 2838 public class AddressManager {
30    
31    
32     List<Address> addressList;
33    
34     Map<Integer, TreeMap<Short, ArrayList<Address>> > searchStructure;
35    
36 torben 2868 ArrayList<AddressSourceEntry> rejectedEntries = new ArrayList<AddressSourceEntry>();
37 torben 2838
38 torben 2873 Map<Integer,String> unknownStreets = new TreeMap<Integer, String>();
39    
40 torben 2847 Map<Short,Short> dbkBaneMap = new TreeMap<Short,Short>();
41    
42 torben 2838 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 torben 2847 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 torben 2838 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 torben 2845 /*if (addr.stateMan == AddressState.NOT_CHANGED || addr.stateMan == AddressState.CREATED) {
177 torben 2838 continue;
178 torben 2845 }*/
179 torben 2838
180 torben 2847 if (addr.stateMan != AddressState.MODIFIED ) {
181 torben 2838 continue;
182     }
183    
184     System.out.println(addr.state + ": " + addr.toStringExtended() );
185     System.out.println(addr.getRuteString() );
186    
187 torben 2847 if (count++ > 50)
188 torben 2838 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 torben 2845
210 torben 2838 db.updateAddresses(updates);
211 torben 2876 db.saveNewAddresses(inserts);
212 torben 2845
213 torben 2838
214 torben 2845
215 torben 2838 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 torben 2873 unknownStreets.putIfAbsent(entry.gadeid, entry.vejnavn);
231 torben 2838 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 torben 2866 boolean found = false;
241 torben 2838 for (Address addr : litraList) {
242     if (addr.husnrbogstav.equals(entry.litra) ) {
243     updateAddress(addr, entry);
244 torben 2866 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 torben 2838 }
247     }
248 torben 2866 if (found == false) {
249     createFromEntry(entry); // if we get here there was no match - so we need to create it
250     }
251 torben 2838 }
252    
253     private void visitRange(AddressSourceEntry entry) {
254    
255 torben 2844 TreeMap<Short, ArrayList<Address>> gade = searchStructure.get( entry.gadeid );
256     if (gade == null) {
257 torben 2873 unknownStreets.putIfAbsent(entry.gadeid, entry.vejnavn);
258 torben 2844 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 torben 2838 }
292    
293    
294    
295     private void updateAddress(Address addr, AddressSourceEntry entry) {
296     if ( addr.distributor != null && addr.distributor.equals(entry.distributor) == false) {
297 torben 2868 rejectedEntries.add(entry);
298 torben 2838 System.out.println("Afviser " + entry);
299     return;
300     }
301    
302 torben 2845
303 torben 2838
304     if (entry.ugedage.mandag) {
305 torben 2847 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 torben 2838 } else {
320 torben 2847 System.out.println( "Double visit monday " + addr);
321 torben 2838 }
322 torben 2847
323 torben 2838 }
324    
325    
326     if (entry.ugedage.tirsdag) {
327 torben 2847 if (addr.visitedTir == false) {
328     addr.visitedTir = true;
329     if (addr.ruteTirsdag == null) {
330     addr.stateTir = AddressState.OPENED;
331 torben 2838 addr.ruteTirsdag = entry.rute;
332 torben 2847 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 torben 2838 }
341 torben 2847 } else {
342     System.out.println( "Double visit tuesday " + addr);
343     }
344 torben 2838 }
345    
346     if (entry.ugedage.onsdag) {
347 torben 2847 if (addr.visitedOns == false) {
348     addr.visitedOns = true;
349     if (addr.ruteOnsdag == null) {
350     addr.stateOns = AddressState.OPENED;
351 torben 2838 addr.ruteOnsdag = entry.rute;
352 torben 2847 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 torben 2838 }
361 torben 2847 } else {
362     System.out.println( "Double visit wednesday " + addr);
363     }
364 torben 2838 }
365    
366    
367     if (entry.ugedage.torsdag) {
368 torben 2847 if (addr.visitedTor == false) {
369     addr.visitedTor = true;
370     if (addr.ruteTorsdag == null) {
371     addr.stateTor = AddressState.OPENED;
372 torben 2838 addr.ruteTorsdag = entry.rute;
373 torben 2847 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 torben 2838 }
383 torben 2847 } else {
384     System.out.println( "Double visit thursday " + addr);
385     }
386 torben 2838 }
387    
388    
389     if (entry.ugedage.fredag) {
390 torben 2847 if (addr.visitedFre == false) {
391     addr.visitedFre = true;
392     if (addr.ruteFredag == null) {
393     addr.stateFre = AddressState.OPENED;
394 torben 2838 addr.ruteFredag = entry.rute;
395 torben 2847 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 torben 2838 }
404 torben 2847 } else {
405     System.out.println( "Double visit friday " + addr);
406     }
407 torben 2838 }
408    
409    
410     if (entry.ugedage.lordag) {
411 torben 2847 if (addr.visitedLor == false) {
412     addr.visitedLor = true;
413     if (addr.ruteLordag == null) {
414     addr.stateLor = AddressState.OPENED;
415 torben 2838 addr.ruteLordag = entry.rute;
416 torben 2847 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 torben 2838 }
426 torben 2847 } else {
427     System.out.println( "Double visit saturday " + addr);
428     }
429 torben 2838 }
430    
431    
432     if (entry.ugedage.sondag) {
433 torben 2847 if (addr.visitedSon == false) {
434     addr.visitedSon = true;
435     if (addr.ruteSondag == null) {
436     addr.stateSon = AddressState.OPENED;
437 torben 2838 addr.ruteSondag = entry.rute;
438 torben 2847 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 torben 2838 }
447 torben 2847 } else {
448     System.out.println( "Double visit sunday " + addr);
449     }
450 torben 2838 }
451    
452    
453 torben 2845
454 torben 2862 //addr.visited = true;
455 torben 2845 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 torben 2847 updateDbkBane(addr);
470 torben 2845
471 torben 2838 }
472    
473    
474    
475     private void createFromEntry(AddressSourceEntry entry) {
476 torben 2849 if (entry.husnr == 999) {
477     return;
478     }
479 torben 2850 if (entry.kommunekode == 0 || entry.vejkode == 0) {
480     return;
481     }
482 torben 2855 if (entry.kommunekode < 100) {
483     return;
484     }
485 torben 2876
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 torben 2854 return; //gadeid / postnr mismatch
492     }
493 torben 2849
494    
495 torben 2854
496 torben 2838 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 torben 2862 //a.visited = true;
510 torben 2838
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 torben 2847 updateDbkBane(a);
541    
542 torben 2838 // 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 torben 2847
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 torben 2867 break;
609     default:
610     throw new RuntimeException("Ukendt distributor" + a.distributor); //Silence findBugs
611 torben 2847 }
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 torben 2838 public List<Address> getAddressList() {
626     return Collections.unmodifiableList(addressList);
627     }
628    
629 torben 2873 public Map<Integer,String> getUnknownStreets() {
630     return Collections.unmodifiableMap( unknownStreets );
631     }
632 torben 2847
633    
634 torben 2873
635 torben 2868 public int getRejectedCount() {
636     return rejectedEntries.size();
637 torben 2839 }
638    
639 torben 2838 }

  ViewVC Help
Powered by ViewVC 1.1.20