Jasen.java |
1 package kerho; 2 3 import java.io.*; 4 import java.util.Comparator; 5 6 import kanta.HetuKentta; 7 import kanta.HetuTarkistus; 8 import kanta.IntKentta; 9 import kanta.JonoKentta; 10 import kanta.Kentta; 11 import kanta.PuhelinKentta; 12 import kanta.RahaKentta; 13 import kanta.RegExpTarkistaja; 14 import kanta.SisaltaaTarkistaja; 15 16 import fi.jyu.mit.ohj2.Mjonot; 17 18 import static kanta.HetuTarkistus.*; 19 20 /** 21 * Kerhon jäsen joka osaa mm. itse huolehtia tunnusNro:staan. 22 * 23 * @author Vesa Lappalainen 24 * @version 1.0, 22.02.2003 25 * @version 2.0, 09.01.2011 - kentät indeksoituna 26 */ 27 public class Jasen implements Cloneable { 28 private Kentta kentat[] = { // valitettavasti ei voi olla final 29 // vaikka pitäisi, clone estää tämän :-( 30 new IntKentta("id"), 31 new JonoKentta("nimi"), 32 new HetuKentta("hetu", new HetuTarkistus()), 33 new JonoKentta("katuosoite"), 34 new JonoKentta("postinumero", new SisaltaaTarkistaja(SisaltaaTarkistaja.NUMEROT)), 35 new JonoKentta("postiosoite"), 36 new PuhelinKentta("kotipuhelin"), 37 new PuhelinKentta("työpuhelin"), 38 new JonoKentta("autopuhelin", new RegExpTarkistaja("[- 0-9]*")), 39 new IntKentta("liittymisvuosi"), 40 new RahaKentta("jäsenmaksu"), 41 new RahaKentta("maksettumaksu"), 42 new JonoKentta("lisätietoja") 43 }; 44 45 private static int seuraavaNro = 1; 46 47 /** 48 * Luokka joka vertaa kahta jäsentä keskenään 49 */ 50 public static class Vertailija implements Comparator<Jasen> { 51 52 private final int kenttanro; 53 54 55 /** 56 * Alustetaan vertailija vertailemaan tietyn kentän perusteella 57 * @param k vertailtavan kentän indeksi. 58 */ 59 public Vertailija(int k) { 60 this.kenttanro = k; 61 } 62 63 64 /** 65 * Verrataana kahta jäsentä keskenään. 66 * @param j1 1. verrattava jäsen 67 * @param j2 2. verrattava jäsen 68 * @return <0 jos j1 < j2, == 0 jos j1 == j2 ja muuten >0 69 */ 70 @Override 71 public int compare(Jasen j1, Jasen j2) { 72 String s1 = j1.getAvain(kenttanro); 73 String s2 = j2.getAvain(kenttanro); 74 75 return s1.compareTo(s2); 76 77 } 78 79 } 80 81 /** 82 * Palauttaa jäsenen kenttien lukumäärän 83 * @return kenttien lukumäärä 84 */ 85 public int getKenttia() { 86 return kentat.length; 87 } 88 89 90 /** 91 * Eka kenttä joka on mielekäs kysyttäväksi 92 * @return eknn kentän indeksi 93 */ 94 public int ekaKentta() { 95 return 1; 96 } 97 98 99 /** 100 * Alustetaan jäsenen merkkijono-attribuuti tyhjiksi jonoiksi 101 * ja tunnusnro = 0. 102 */ 103 public Jasen() { 104 // Toistaiseksi ei tarvita mitään 105 } 106 107 108 /** 109 * @return jäsenen nimi 110 * @example 111 * <pre name="test"> 112 * Jasen aku = new Jasen(); 113 * aku.vastaaAkuAnkka(); 114 * aku.getNimi() =R= "Ankka Aku .*"; 115 * </pre> 116 */ 117 public String getNimi() { 118 return anna(1); 119 } 120 121 122 /** 123 * Antaa k:n kentän sisällön merkkijonona 124 * @param k monenenko kentän sisältö palautetaan 125 * @return kentän sisältö merkkijonona 126 */ 127 public String anna(int k) { 128 try { 129 return kentat[k].toString(); 130 } catch (Exception ex) { 131 return ""; 132 } 133 } 134 135 136 /** 137 * Antaa k:n kentän sisällön avain-merkkijonona 138 * jonka perusteella voi lajitella 139 * @param k monenenko kentän sisältö palautetaan 140 * @return kentän sisältö merkkijonona 141 * 142 * @example 143 * <pre name="test"> 144 * Jasen aku = new Jasen(); 145 * aku.parse(" 1 | Ankka Aku | 030201-111C"); 146 * aku.getAvain(0) === " 1"; 147 * aku.getAvain(1) === "ANKKA AKU"; 148 * aku.getAvain(2) === "010203-111C"; 149 * aku.getAvain(20) === ""; 150 * </pre> 151 */ 152 public String getAvain(int k) { 153 try { 154 return kentat[k].getAvain(); 155 } catch (Exception ex) { 156 return ""; 157 } 158 } 159 160 161 /** 162 * Asettaa k:n kentän arvoksi parametrina tuodun merkkijonon arvon 163 * @param k kuinka monennen kentän arvo asetetaan 164 * @param jono jonoa joka asetetaan kentän arvoksi 165 * @return null jos asettaminen onnistuu, muuten vastaava virheilmoitus. 166 * @example 167 * <pre name="test"> 168 * Jasen jasen = new Jasen(); 169 * jasen.aseta(1,"Ankka Aku") === null; 170 * jasen.aseta(2,"kissa") =R= "Hetu liian lyhyt" 171 * jasen.aseta(2,"030201-1111") === "Tarkistusmerkin kuuluisi olla C"; 172 * jasen.aseta(2,"030201-111C") === null; 173 * jasen.aseta(9,"kissa") === "Virhe: jono = \"kissa\""; 174 * jasen.aseta(9,"1940") === null; 175 * </pre> 176 */ 177 public String aseta(int k, String jono) { 178 try { 179 String virhe = kentat[k].aseta(jono.trim()); 180 if ( virhe == null && k == 0 ) setTunnusNro(getTunnusNro()); 181 return virhe; 182 } catch (Exception ex) { 183 return "Virhe: " + ex.getMessage(); 184 } 185 } 186 187 188 /** 189 * Palauttaa k:tta jäsenen kenttää vastaavan kysymyksen 190 * @param k kuinka monennen kentän kysymys palautetaan (0-alkuinen) 191 * @return k:netta kenttää vastaava kysymys 192 */ 193 public String getKysymys(int k) { 194 try { 195 return kentat[k].getKysymys(); 196 } catch (Exception ex) { 197 return "Ääliö"; 198 } 199 } 200 201 /** 202 * Apumetodi, jolla saadaan täytettyä testiarvot jäsenelle. 203 * @param apuhetu hetu joka annetaan henkilölle 204 */ 205 public void vastaaAkuAnkka(String apuhetu) { 206 aseta(1,"Ankka Aku " + kanta.HetuTarkistus.rand(1000, 9999)); 207 aseta(2,apuhetu); 208 aseta(3,"Ankkakuja 6"); 209 aseta(4,"12345"); 210 aseta(5,"ANKKALINNA"); 211 aseta(6,"12-1234"); 212 aseta(7,""); 213 aseta(8,""); 214 aseta(9,"1996"); 215 aseta(10,"50"); 216 aseta(11,"30"); 217 aseta(12,"Velkaa Roopelle"); 218 } 219 220 221 /** 222 * Apumetodi, jolla saadaan täytettyä testiarvot jäsenelle. 223 * Henkilötunnus arvotaan, jotta kahdella jäsenellä ei olisi 224 * samoja tietoja. 225 */ 226 public void vastaaAkuAnkka() { 227 String apuhetu = arvoHetu(); 228 vastaaAkuAnkka(apuhetu); 229 } 230 231 232 /** 233 * Tulostetaan henkilön tiedot 234 * @param out tietovirta johon tulostetaan 235 */ 236 public void tulosta(PrintStream out) { 237 int pisin = 0; 238 for (Kentta kentta : kentat) 239 if (kentta.getKysymys().length() > pisin) 240 pisin = kentta.getKysymys().length(); 241 242 for (Kentta kentta : kentat) 243 out.println(Mjonot.fmt(kentta.getKysymys(), -pisin - 1) + 244 ": " + kentta.toString()); 245 } 246 247 248 /** 249 * Tulostetaan henkilön tiedot 250 * @param os tietovirta johon tulostetaan 251 */ 252 public void tulosta(OutputStream os) { 253 tulosta(new PrintStream(os)); 254 } 255 256 257 /** 258 * Antaa jäsenelle seuraavan rekisterinumeron. 259 * @return jäsenen uusi tunnusNro 260 * @example 261 * <pre name="test"> 262 * Jasen aku1 = new Jasen(); 263 * aku1.getTunnusNro() === 0; 264 * aku1.rekisteroi(); 265 * Jasen aku2 = new Jasen(); 266 * aku2.rekisteroi(); 267 * int n1 = aku1.getTunnusNro(); 268 * int n2 = aku2.getTunnusNro(); 269 * n1 === n2-1; 270 * </pre> 271 */ 272 public int rekisteroi() { 273 return setTunnusNro(seuraavaNro); 274 } 275 276 277 /** 278 * Palauttaa jäsenen tunnusnumeron. 279 * @return jäsenen tunnusnumero 280 */ 281 public int getTunnusNro() { 282 return ((IntKentta)(kentat[0])).getValue(); 283 } 284 285 286 /** 287 * Asettaa tunnusnumeron ja samalla varmistaa että 288 * seuraava numero on aina suurempi kuin tähän mennessä suurin. 289 * @param nr asetettava tunnusnumero 290 */ 291 private int setTunnusNro(int nr) { 292 IntKentta k = ((IntKentta)(kentat[0])); 293 k.setValue(nr); 294 if (nr >= seuraavaNro) seuraavaNro = nr + 1; 295 return k.getValue(); 296 } 297 298 299 /** 300 * Palauttaa jäsenen tiedot merkkijonona jonka voi tallentaa tiedostoon. 301 * @return jäsen tolppaeroteltuna merkkijonona 302 * @example 303 * <pre name="test"> 304 * Jasen jasen = new Jasen(); 305 * jasen.parse(" 3 | Ankka Aku | 030201-111C"); 306 * jasen.toString().startsWith("3|Ankka Aku|030201-111C|") === true; // on enemmäkin kuin 3 kenttää, siksi loppu | 307 * </pre> 308 */ 309 @Override 310 public String toString() { 311 StringBuffer sb = new StringBuffer(""); 312 String erotin = ""; 313 for (int k = 0; k < getKenttia(); k++) { 314 sb.append(erotin); 315 sb.append(anna(k)); 316 erotin = "|"; 317 } 318 return sb.toString(); 319 } 320 321 322 /** 323 * Selvitää jäsenen tiedot | erotellusta merkkijonosta 324 * Pitää huolen että seuraavaNro on suurempi kuin tuleva tunnusNro. 325 * @param rivi josta jäsenen tiedot otetaan 326 * 327 * @example 328 * <pre name="test"> 329 * Jasen jasen = new Jasen(); 330 * jasen.parse(" 3 | Ankka Aku | 030201-111C"); 331 * jasen.getTunnusNro() === 3; 332 * jasen.toString().startsWith("3|Ankka Aku|030201-111C|") === true; // on enemmäkin kuin 3 kenttää, siksi loppu | 333 * 334 * jasen.rekisteroi(); 335 * int n = jasen.getTunnusNro(); 336 * jasen.parse(""+(n+20)); // Otetaan merkkijonosta vain tunnusnumero 337 * jasen.rekisteroi(); // ja tarkistetaan että seuraavalla kertaa tulee yhtä isompi 338 * jasen.getTunnusNro() === n+20+1; 339 * 340 * </pre> 341 */ 342 public void parse(String rivi) { 343 StringBuffer sb = new StringBuffer(rivi); 344 for (int k = 0; k < getKenttia(); k++) 345 aseta(k, Mjonot.erota(sb, '|')); 346 } 347 348 349 /** 350 * Tehdään identtinen klooni jäsenestä 351 * @return Object kloonattu jäsen 352 * @example 353 * <pre name="test"> 354 * #THROWS CloneNotSupportedException 355 * Jasen jasen = new Jasen(); 356 * jasen.parse(" 3 | Ankka Aku | 123"); 357 * Jasen kopio = jasen.clone(); 358 * kopio.toString() === jasen.toString(); 359 * jasen.parse(" 4 | Ankka Tupu | 123"); 360 * kopio.toString().equals(jasen.toString()) === false; 361 * </pre> 362 */ 363 @Override 364 public Jasen clone() throws CloneNotSupportedException { // NOPMD 365 Jasen uusi; 366 uusi = (Jasen)super.clone(); 367 uusi.kentat = kentat.clone(); 368 369 for (int k = 0; k < getKenttia(); k++) 370 uusi.kentat[k] = kentat[k].clone(); 371 return uusi; 372 } 373 374 375 /** 376 * Tutkii onko jäsenen tiedot samat kuin parametrina tuodun jäsenen tiedot 377 * @param jasen jäsen johon verrataan 378 * @return true jos kaikki tiedot samat, false muuten 379 * @example 380 * <pre name="test"> 381 * Jasen jasen1 = new Jasen(); 382 * jasen1.parse(" 3 | Ankka Aku | 030201-111C"); 383 * Jasen jasen2 = new Jasen(); 384 * jasen2.parse(" 3 | Ankka Aku | 030201-111C"); 385 * Jasen jasen3 = new Jasen(); 386 * jasen3.parse(" 3 | Ankka Aku | 030201-115H"); 387 * 388 * jasen1.equals(jasen2) === true; 389 * jasen2.equals(jasen1) === true; 390 * jasen1.equals(jasen3) === false; 391 * jasen3.equals(jasen2) === false; 392 * </pre> 393 */ 394 public boolean equals(Jasen jasen) { // NOPMD 395 for (int k = 0; k < getKenttia(); k++) 396 if (!anna(k).equals(jasen.anna(k))) return false; 397 return true; 398 } 399 400 401 /** 402 * Testiohjelma jäsenelle. 403 * @param args ei käytössä 404 */ 405 public static void main(String args[]) { 406 Jasen aku = new Jasen(), aku2 = new Jasen(); 407 aku.rekisteroi(); 408 aku2.rekisteroi(); 409 aku.tulosta(System.out); 410 aku.vastaaAkuAnkka(); 411 aku.tulosta(System.out); 412 413 aku2.vastaaAkuAnkka(); 414 aku2.tulosta(System.out); 415 416 aku2.vastaaAkuAnkka(); 417 aku2.tulosta(System.out); 418 } 419 420 } 421