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