| Harrastukset.java |
1 package kerho;
2
3 import java.io.*;
4 import java.util.*;
5 import fi.jyu.mit.ohj2.*;
6
7 /**
8 * Kerhon harrastukset, joka osaa mm. lisätä uuden harrastuksen
9 *
10 * @author Vesa Lappalainen
11 * @version 1.0, 22.02.2003
12 */
13 public class Harrastukset implements Iterable<Harrastus> {
14 private boolean muutettu = false;
15 private String tiedostonPerusNimi = "";
16
17 /**
18 * Taulukko harrastuksista
19 */
20 private final Collection<Harrastus> alkiot = new ArrayList<Harrastus>();
21
22
23 /**
24 * Harrastusten alustaminen
25 */
26 public Harrastukset() {
27 // toistaiseksi ei tarvitse tehdä mitään
28 }
29
30
31 /**
32 * Lisää uuden harrastuksen tietorakenteeseen. Ottaa harrastuksen omistukseensa.
33 * @param har lisättävä harrastus. Huom tietorakenne muuttuu omistajaksi
34 */
35 public void lisaa(Harrastus har) {
36 muutettu = true;
37 alkiot.add(har);
38 }
39
40
41 /**
42 * Poistaa valitun harrastuksen
43 * @param harrastus poistettava harrastus
44 * @return tosi jos löytyi poistettava harrastus
45 * <pre name="test">
46 * #THROWS SailoException
47 * #import java.io.File;
48 * Harrastukset harrasteet = new Harrastukset();
49 * Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
50 * Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
51 * Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2);
52 * Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1);
53 * Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2);
54 * harrasteet.lisaa(pitsi21);
55 * harrasteet.lisaa(pitsi11);
56 * harrasteet.lisaa(pitsi22);
57 * harrasteet.lisaa(pitsi12);
58 * harrasteet.poista(pitsi23) === false ; harrasteet.getLkm() === 4;
59 * harrasteet.poista(pitsi11) === true; harrasteet.getLkm() === 3;
60 * List<Harrastus> h = harrasteet.annaHarrastukset(1);
61 * h.size() === 1;
62 * h = harrasteet.annaHarrastukset(1);
63 * h.get(0) === pitsi12;
64 * </pre>
65 */
66 public boolean poista(Harrastus harrastus) {
67 boolean ret = alkiot.remove(harrastus);
68 if (ret) muutettu = true;
69 return ret;
70 }
71
72
73 /**
74 * Poistaa kaikki tietyn jäsenen harrastukset
75 * @param jasenNro viite siihen, minkä jäsenen harrastukset poistetaan
76 * @return montako poistettiin
77 * @example
78 * <pre name="test">
79 * #THROWS SailoException
80 * #import java.io.File;
81 * Harrastukset harrasteet = new Harrastukset();
82 * Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
83 * Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
84 * Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2);
85 * Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1);
86 * Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2);
87 * harrasteet.lisaa(pitsi21);
88 * harrasteet.lisaa(pitsi11);
89 * harrasteet.lisaa(pitsi22);
90 * harrasteet.lisaa(pitsi12);
91 * harrasteet.lisaa(pitsi23);
92 * harrasteet.poista(2) === 3; harrasteet.getLkm() === 2;
93 * harrasteet.poista(3) === 0; harrasteet.getLkm() === 2;
94 * List<Harrastus> h = harrasteet.annaHarrastukset(2);
95 * h.size() === 0;
96 * h = harrasteet.annaHarrastukset(1);
97 * h.get(0) === pitsi11;
98 * h.get(1) === pitsi12;
99 * </pre>
100 */
101 public int poista(int jasenNro) {
102 int n = 0;
103 for (Iterator<Harrastus> it = alkiot.iterator(); it.hasNext();) {
104 Harrastus har = it.next();
105 if (har.getJasenNro() == jasenNro) {
106 it.remove();
107 n++;
108 }
109 }
110 if (n > 0) muutettu = true;
111 return n;
112 }
113
114
115 /**
116 * Lukee harrastukset tiedostosta.
117 * @param tied tiedoston nimen alkuosa
118 * @throws SailoException jos lukeminen epäonnistuu
119 *
120 * @example
121 * <pre name="test">
122 * #THROWS SailoException
123 * #import java.io.File;
124 * Harrastukset harrasteet = new Harrastukset();
125 * Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
126 * Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
127 * Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2);
128 * Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1);
129 * Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2);
130 * String tiedNimi = "testikelmit";
131 * File ftied = new File(tiedNimi+".har");
132 * ftied.delete();
133 * harrasteet.lueTiedostosta(tiedNimi); #THROWS SailoException
134 * harrasteet.lisaa(pitsi21);
135 * harrasteet.lisaa(pitsi11);
136 * harrasteet.lisaa(pitsi22);
137 * harrasteet.lisaa(pitsi12);
138 * harrasteet.lisaa(pitsi23);
139 * harrasteet.talleta();
140 * harrasteet = new Harrastukset();
141 * harrasteet.lueTiedostosta(tiedNimi);
142 * Iterator<Harrastus> i = harrasteet.iterator();
143 * i.next().toString() === pitsi21.toString();
144 * i.next().toString() === pitsi11.toString();
145 * i.next().toString() === pitsi22.toString();
146 * i.next().toString() === pitsi12.toString();
147 * i.next().toString() === pitsi23.toString();
148 * i.hasNext() === false;
149 * harrasteet.lisaa(pitsi23);
150 * harrasteet.talleta();
151 * ftied.delete() === true;
152 * File fbak = new File(tiedNimi+".hbak");
153 * fbak.delete() === true;
154 * </pre>
155 */
156 public void lueTiedostosta(String tied) throws SailoException {
157 muutettu = true;
158 setTiedostonPerusNimi(tied);
159 BufferedReader fi = Tiedosto.avaa_lukemista_varten(getTiedostonNimi());
160 if (fi == null) throw new SailoException("Tiedosto " + getTiedostonNimi() + " ei aukea");
161
162 String rivi;
163 try {
164 while ((rivi = fi.readLine()) != null) { // NOPMD
165 rivi = rivi.trim();
166 if ("".equals(rivi) || rivi.charAt(0) == ';') continue;
167 Harrastus har = new Harrastus(); // NOPMD: pakko luoda silmukassa
168 har.parse(rivi); // voisi olla virhekäsittely
169 lisaa(har);
170 }
171 muutettu = false;
172
173 } catch (IOException e) {
174 throw new SailoException("Ongelmia tiedoston kanssa: " + e.getMessage()); // NOPMD
175 } finally {
176 try {
177 fi.close();
178 } catch (IOException e) {
179 throw new SailoException("Tiedoston sulkeminen ei onnistu: " + e.getMessage()); // NOPMD
180 }
181 }
182 }
183
184
185 /**
186 * Tallentaa harrastukset tiedostoon.
187 * @throws SailoException jos talletus epäonnistuu
188 */
189 public void talleta() throws SailoException {
190 if (!muutettu) return;
191
192 File fbak = new File(getBakNimi());
193 File ftied = new File(getTiedostonNimi());
194 fbak.delete(); // if ... System.err.println("Ei voi tuhota");
195 ftied.renameTo(fbak); // if ... System.err.println("Ei voi nimetä");
196
197 PrintWriter fo = Tiedosto.avaa_kirjoittamista_varten(ftied.getName());
198 if (fo == null) throw new SailoException("Tiedosto " + ftied.getName() + " ei aukea");
199 try {
200 for (Harrastus har : this) {
201 fo.println(har.toString());
202 }
203 } finally {
204 fo.close();
205 }
206
207 muutettu = false;
208 }
209
210
211 /**
212 * Palauttaa kerhon harrastusten lukumäärän
213 * @return harrastusten lukumäärä
214 */
215 public int getLkm() {
216 return alkiot.size();
217 }
218
219
220 /**
221 * Asettaa tiedoston perusnimen ilan tarkenninta
222 * @param tied tallennustiedoston perusnimi
223 */
224 public void setTiedostonPerusNimi(String tied) {
225 tiedostonPerusNimi = tied;
226 }
227
228
229 /**
230 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
231 * @return tallennustiedoston nimi
232 */
233 public String getTiedostonPerusNimi() {
234 return tiedostonPerusNimi;
235 }
236
237
238 /**
239 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
240 * @return tallennustiedoston nimi
241 */
242 public String getTiedostonNimi() {
243 return tiedostonPerusNimi + ".har";
244 }
245
246
247 /**
248 * Palauttaa varakopiotiedoston nimen
249 * @return varakopiotiedoston nimi
250 */
251 public String getBakNimi() {
252 return tiedostonPerusNimi + ".hbak";
253 }
254
255
256 /**
257 * Iteraattori kaikkien harrastusten läpikäymiseen
258 * @return harrastusiteraattori
259 *
260 * @example
261 * <pre name="test">
262 * #PACKAGEIMPORT
263 * #import java.util.*;
264 *
265 * Harrastukset harrasteet = new Harrastukset();
266 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
267 * Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
268 * Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
269 * Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
270 * Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
271 *
272 * Iterator<Harrastus> i2=harrasteet.iterator();
273 * i2.next() === pitsi21;
274 * i2.next() === pitsi11;
275 * i2.next() === pitsi22;
276 * i2.next() === pitsi12;
277 * i2.next() === pitsi23;
278 * i2.next() === pitsi12; #THROWS NoSuchElementException
279 *
280 * int n = 0;
281 * int jnrot[] = {2,1,2,1,2};
282 *
283 * for ( Harrastus har:harrasteet ) {
284 * har.getJasenNro() === jnrot[n]; n++;
285 * }
286 *
287 * n === 5;
288 *
289 * </pre>
290 */
291 @Override
292 public Iterator<Harrastus> iterator() {
293 return alkiot.iterator();
294 }
295
296 /**
297 * Luokka tietyn jäsen harrastusten iteroimiseksi
298 *
299 * @example
300 * <pre name="test">
301 * #PACKAGEIMPORT
302 * #import java.util.*;
303 *
304 * Harrastukset harrasteet = new Harrastukset();
305 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
306 * Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
307 * Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
308 * Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
309 * Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
310 * Harrastus pitsi51 = new Harrastus(5); harrasteet.lisaa(pitsi51);
311 *
312 * Iterator<Harrastus> i2=harrasteet.iterator(2);
313 * i2.next() === pitsi21;
314 * i2.next() === pitsi22;
315 * i2.next() === pitsi23;
316 * i2.next() === pitsi12; #THROWS NoSuchElementException
317 *
318 * int n = 0;
319 * for (Iterator<Harrastus> i = harrasteet.iterator(2); i.hasNext(); ) {
320 * i.next().getJasenNro() === 2; n++;
321 * }
322 *
323 * n === 3;
324 *
325 * Iterator<Harrastus> i3=harrasteet.iterator(3);
326 * i3.hasNext() === false;
327 * i3.next() === pitsi12; #THROWS NoSuchElementException
328 *
329 * Iterator<Harrastus> i4=harrasteet.iterator(4);
330 * i4.next() === pitsi12; #THROWS NoSuchElementException
331 *
332 * Iterator<Harrastus> i5=harrasteet.iterator(5);
333 * i5.next() === pitsi51;
334 * i5.next() === pitsi51; #THROWS NoSuchElementException
335 * </pre>
336 *
337 * @example
338 * <pre name="test">
339 * // Testataan erikoistapauksia
340 * Harrastukset harrasteet = new Harrastukset();
341 * Iterator<Harrastus> i;
342 *
343 * i = harrasteet.iterator(2); // Iteroidaan tyhjään joukoon
344 * i.next() === null; #THROWS NoSuchElementException
345 * i = harrasteet.iterator(2);
346 * i.hasNext() === false;
347 *
348 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
349 * i = harrasteet.iterator(1); // Iteroidaan harrastusta jota ei ole
350 * i.next() === null; #THROWS NoSuchElementException
351 * i = harrasteet.iterator(1);
352 * i.hasNext() === false;
353 *
354 * i = harrasteet.iterator(2); // Iteroidaan 1. olevaa
355 * i.next() === pitsi21;
356 * i.next() === null; #THROWS NoSuchElementException
357 *
358 * i = harrasteet.iterator(2); // Iteroidaan 1. olevaa hasNext():in kanssa
359 * i.hasNext() === true; // hasNext ekalla kertaa
360 * i.next() === pitsi21;
361 * i.hasNext() === false;
362 * i.next() === null; #THROWS NoSuchElementException
363 *
364 * Harrastus pitsi31 = new Harrastus(3); harrasteet.lisaa(pitsi31);
365 * i = harrasteet.iterator(1); // Iteroidaan 2. alkion joukosta olematonta
366 * i.next() === null; #THROWS NoSuchElementException
367 * i = harrasteet.iterator(1); // Kokeillaan olematonta hasNext():in kanssa
368 * i.hasNext() === false;
369 *
370 * i = harrasteet.iterator(2); // Iteroidaan ei viimeisenä olevaa
371 * i.next() === pitsi21;
372 * i.next() === null; #THROWS NoSuchElementException
373 *
374 * i = harrasteet.iterator(2); // 1. hasNext():in avulla
375 * i.hasNext() === true;
376 * i.next() === pitsi21;
377 * i.hasNext() === false;
378 * i.next() === null; #THROWS NoSuchElementException
379 *
380 * i=harrasteet.iterator(3); // Iteroidaan viimeisenä olevaa
381 * i.hasNext() === true;
382 * i.hasNext() === true; // Ei saa siirtyä ohi
383 * i.next() === pitsi31;
384 * i.hasNext() === false;
385 * // i.next() === null; #THROWS NoSuchElementException // NOPMD ei tykkää
386 * </pre>
387 */
388 public class HarrastuksetIterator implements Iterator<Harrastus> {
389 private final int jasenNro;
390 private final Iterator<Harrastus> iter = iterator();
391 private Harrastus harrastus;
392
393
394 /**
395 * Alustetaan iteraattori käymään läpi tietyn jäsenen harrastukset
396 * @param vnro viitenumero jäseneen
397 */
398 public HarrastuksetIterator(int vnro) {
399 jasenNro = vnro;
400 }
401
402
403 /**
404 * Tutkitaan onko vielä halutun jäsenen harrastuksia jäljellä.
405 * @return true jos jäsenen harrastuksia on vielä
406 * @see java.util.Iterator#hasNext()
407 */
408 @Override
409 public boolean hasNext() {
410 while (true) {
411 if (harrastus != null && harrastus.getJasenNro() == jasenNro) return true; //
412 harrastus = null; // NOPMD: tarkoituksella null
413 if (!iter.hasNext()) return false;
414 harrastus = iter.next();
415 if (harrastus.getJasenNro() == jasenNro) return true;
416 }
417 }
418
419
420 /**
421 * Palautetaan jäsenen seuraava harrastus.
422 * @return jäsenen seuraava harrastus
423 * @throws NoSuchElementException jos harrastuksia ei enää ole
424 * @see java.util.Iterator#next()
425 */
426 @Override
427 public Harrastus next() throws NoSuchElementException {
428 if (harrastus != null) {
429 Harrastus pal = harrastus;
430 harrastus = null; // NOPMD: tarkoituksella null
431 return pal;
432 }
433 while (true) {
434 Harrastus har = iter.next();
435 if (har.getJasenNro() == jasenNro) return har;
436 }
437 }
438
439
440 /**
441 * Tuhoamista ei ole toteutettu
442 * @throws UnsupportedOperationException aina
443 * @see java.util.Iterator#remove()
444 */
445 @Override
446 public void remove() throws UnsupportedOperationException {
447 throw new UnsupportedOperationException("Me ei poisteta");
448 }
449
450 }
451
452
453 /**
454 * Haetaan kaikki jäsen harrastukset
455 * @param tunnusnro jäsenen tunnusnumero jolle harrastuksia haetaan
456 * @return tietorakenne jossa viiteet löydetteyihin harrastuksiin
457 * @example
458 * <pre name="test">
459 * #import java.util.*;
460 *
461 * Harrastukset harrasteet = new Harrastukset();
462 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
463 * Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
464 * Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
465 * Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
466 * Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
467 * Harrastus pitsi51 = new Harrastus(5); harrasteet.lisaa(pitsi51);
468 *
469 * List<Harrastus> loytyneet;
470 * loytyneet = harrasteet.annaHarrastukset(3);
471 * loytyneet.size() === 0;
472 * loytyneet = harrasteet.annaHarrastukset(1);
473 * loytyneet.size() === 2;
474 * loytyneet.get(0) == pitsi11 === true;
475 * loytyneet.get(1) == pitsi12 === true;
476 * loytyneet = harrasteet.annaHarrastukset(5);
477 * loytyneet.size() === 1;
478 * loytyneet.get(0) == pitsi51 === true;
479 * </pre>
480 */
481 public List<Harrastus> annaHarrastukset(int tunnusnro) {
482 List<Harrastus> loydetyt = new ArrayList<Harrastus>();
483 for (Harrastus har : alkiot)
484 if (har.getJasenNro() == tunnusnro) loydetyt.add(har);
485 return loydetyt;
486 }
487
488
489 /**
490 * Palautetaan tietyn jäsenen harrastuksia käsittelevä iteraattori
491 * @param vnro tutkittavan jäsenen viitenumero
492 * @return valitun jäsenen harrastusten iteraattori
493 */
494 public Iterator<Harrastus> iterator(int vnro) {
495 return new HarrastuksetIterator(vnro);
496 }
497
498
499 /**
500 * Laitetaan muutos, jolloin pakotetaan tallentamaan.
501 */
502 public void setMuutos() {
503 muutettu = true;
504 }
505
506
507 /**
508 * Testiohjelma harrastuksille
509 * @param args ei käytössä
510 */
511 public static void main(String[] args) {
512 Harrastukset harrasteet = new Harrastukset();
513 Harrastus pitsi1 = new Harrastus();
514 pitsi1.vastaaPitsinNyplays(2);
515 Harrastus pitsi2 = new Harrastus();
516 pitsi2.vastaaPitsinNyplays(1);
517 Harrastus pitsi3 = new Harrastus();
518 pitsi3.vastaaPitsinNyplays(2);
519 Harrastus pitsi4 = new Harrastus();
520 pitsi4.vastaaPitsinNyplays(2);
521
522 harrasteet.lisaa(pitsi1);
523 harrasteet.lisaa(pitsi2);
524 harrasteet.lisaa(pitsi3);
525 harrasteet.lisaa(pitsi2);
526 harrasteet.lisaa(pitsi4);
527
528 System.out.println("============= Harrastukset testi =================");
529
530 { // Testataan toimiiko iteraattori ilman hasNextiä
531 Iterator<Harrastus> i2 = harrasteet.iterator(2);
532 Harrastus har = i2.next();
533 System.out.print(har.getJasenNro() + " ");
534 har.tulosta(System.out);
535 har = i2.next();
536 System.out.print(har.getJasenNro() + " ");
537 har.tulosta(System.out);
538 har = i2.next();
539 System.out.print(har.getJasenNro() + " ");
540 har.tulosta(System.out);
541 }
542
543 for (Iterator<Harrastus> i = harrasteet.iterator(2); i.hasNext();) {
544 Harrastus har = i.next();
545 System.out.print(har.getJasenNro() + " ");
546 har.tulosta(System.out);
547 }
548
549 }
550
551 }
552