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