| 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 setTiedostonPerusNimi(tied);
85 BufferedReader fi = Tiedosto.avaa_lukemista_varten(getTiedostonNimi());
86 if ( fi == null ) throw new SailoException("Tiedosto " + getTiedostonNimi() + " ei aukea");
87
88 String rivi;
89 try {
90 while ( ( rivi = fi.readLine() ) != null ) {
91 rivi = rivi.trim();
92 if ( "".equals(rivi) || rivi.charAt(0) == ';' ) continue;
93 Harrastus har = new Harrastus(); // NOPMD: pakko luoda silmukassa
94 har.parse(rivi); // voisi olla virhekäsittely
95 lisaa(har);
96 }
97 muutettu = false;
98
99 } catch ( IOException e ) {
100 throw new SailoException("Ongelmia tiedoston kanssa: " + e.getMessage()); // NOPMD
101 } finally {
102 try {
103 fi.close();
104 } catch (IOException e ) {
105 throw new SailoException("Tiedoston sulkeminen ei onnistu: " + e.getMessage()); // NOPMD
106 }
107 }
108 }
109
110
111 /**
112 * Tallentaa harrastukset tiedostoon.
113 * @throws SailoException jos talletus epäonnistuu
114 */
115 public void talleta() throws SailoException {
116 if ( !muutettu ) return;
117
118 File fbak = new File(getBakNimi());
119 File ftied = new File(getTiedostonNimi());
120 fbak.delete(); // if ... System.err.println("Ei voi tuhota");
121 ftied.renameTo(fbak); // if ... System.err.println("Ei voi nimetä");
122
123 PrintWriter fo = Tiedosto.avaa_kirjoittamista_varten(ftied.getName());
124 if ( fo == null ) throw new SailoException("Tiedosto " + ftied.getName() + "ei aukea");
125 try {
126 for (Harrastus har : this) {
127 fo.println(har.toString());
128 }
129 } finally {
130 fo.close();
131 }
132
133 muutettu = false;
134 }
135
136
137 /**
138 * Palauttaa kerhon harrastusten lukumäärän
139 * @return harrastusten lukumäärä
140 */
141 public int getLkm() { return alkiot.size(); }
142
143
144 /**
145 * Asettaa tiedoston perusnimen ilan tarkenninta
146 * @param tied tallennustiedoston perusnimi
147 */
148 public void setTiedostonPerusNimi(String tied) { tiedostonPerusNimi = tied; }
149
150
151 /**
152 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
153 * @return tallennustiedoston nimi
154 */
155 public String getTiedostonPerusNimi() { return tiedostonPerusNimi; }
156
157
158 /**
159 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
160 * @return tallennustiedoston nimi
161 */
162 public String getTiedostonNimi() { return tiedostonPerusNimi + ".har"; }
163
164
165 /**
166 * Palauttaa varakopiotiedoston nimen
167 * @return varakopiotiedoston nimi
168 */
169 public String getBakNimi() { return tiedostonPerusNimi + ".hbak"; }
170
171
172 /**
173 * Iteraattori kaikkien harrastusten läpikäymiseen
174 * @return harrastusiteraattori
175 *
176 * @example
177 * <pre name="test">
178 * #PACKAGEIMPORT
179 * #import java.util.*;
180 *
181 * Harrastukset harrasteet = new Harrastukset();
182 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
183 * Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
184 * Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
185 * Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
186 * Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
187 *
188 * Iterator<Harrastus> i2=harrasteet.iterator();
189 * i2.next() === pitsi21;
190 * i2.next() === pitsi11;
191 * i2.next() === pitsi22;
192 * i2.next() === pitsi12;
193 * i2.next() === pitsi23;
194 * i2.next() === pitsi12; #THROWS NoSuchElementException
195 *
196 * int n = 0;
197 * int jnrot[] = {2,1,2,1,2};
198 *
199 * for ( Harrastus har:harrasteet ) {
200 * har.getJasenNro() === jnrot[n]; n++;
201 * }
202 *
203 * n === 5;
204 *
205 * </pre>
206 */
207 public Iterator<Harrastus> iterator() {
208 return alkiot.iterator();
209 }
210
211
212 /**
213 * Luokka tietyn jäsen harrastusten iteroimiseksi
214 *
215 * @example
216 * <pre name="test">
217 * #PACKAGEIMPORT
218 * #import java.util.*;
219 *
220 * Harrastukset harrasteet = new Harrastukset();
221 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
222 * Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
223 * Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
224 * Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
225 * Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
226 * Harrastus pitsi51 = new Harrastus(5); harrasteet.lisaa(pitsi51);
227 *
228 * Iterator<Harrastus> i2=harrasteet.iterator(2);
229 * i2.next() === pitsi21;
230 * i2.next() === pitsi22;
231 * i2.next() === pitsi23;
232 * i2.next() === pitsi12; #THROWS NoSuchElementException
233 *
234 * int n = 0;
235 * for (Iterator<Harrastus> i = harrasteet.iterator(2); i.hasNext(); ) {
236 * i.next().getJasenNro() === 2; n++;
237 * }
238 *
239 * n === 3;
240 *
241 * Iterator<Harrastus> i3=harrasteet.iterator(3);
242 * i3.hasNext() === false;
243 * i3.next() === pitsi12; #THROWS NoSuchElementException
244 *
245 * Iterator<Harrastus> i4=harrasteet.iterator(4);
246 * i4.next() === pitsi12; #THROWS NoSuchElementException
247 *
248 * Iterator<Harrastus> i5=harrasteet.iterator(5);
249 * i5.next() === pitsi51;
250 * i5.next() === pitsi51; #THROWS NoSuchElementException
251 * </pre>
252 *
253 * @example
254 * <pre name="test">
255 * // Testataan erikoistapauksia
256 * Harrastukset harrasteet = new Harrastukset();
257 * Iterator<Harrastus> i;
258 *
259 * i = harrasteet.iterator(2); // Iteroidaan tyhjään joukoon
260 * i.next() === null; #THROWS NoSuchElementException
261 * i = harrasteet.iterator(2);
262 * i.hasNext() === false;
263 *
264 * Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
265 * i = harrasteet.iterator(1); // Iteroidaan harrastusta jota ei ole
266 * i.next() === null; #THROWS NoSuchElementException
267 * i = harrasteet.iterator(1);
268 * i.hasNext() === false;
269 *
270 * i = harrasteet.iterator(2); // Iteroidaan 1. olevaa
271 * i.next() === pitsi21;
272 * i.next() === null; #THROWS NoSuchElementException
273 *
274 * i = harrasteet.iterator(2); // Iteroidaan 1. olevaa hasNext():in kanssa
275 * i.hasNext() === true; // hasNext ekalla kertaa
276 * i.next() === pitsi21;
277 * i.hasNext() === false;
278 * i.next() === null; #THROWS NoSuchElementException
279 *
280 * Harrastus pitsi31 = new Harrastus(3); harrasteet.lisaa(pitsi31);
281 * i = harrasteet.iterator(1); // Iteroidaan 2. alkion joukosta olematonta
282 * i.next() === null; #THROWS NoSuchElementException
283 * i = harrasteet.iterator(1); // Kokeillaan olematonta hasNext():in kanssa
284 * i.hasNext() === false;
285 *
286 * i = harrasteet.iterator(2); // Iteroidaan ei viimeisenä olevaa
287 * i.next() === pitsi21;
288 * i.next() === null; #THROWS NoSuchElementException
289 *
290 * i = harrasteet.iterator(2); // 1. hasNext():in avulla
291 * i.hasNext() === true;
292 * i.next() === pitsi21;
293 * i.hasNext() === false;
294 * i.next() === null; #THROWS NoSuchElementException
295 *
296 * i=harrasteet.iterator(3); // Iteroidaan viimeisenä olevaa
297 * i.hasNext() === true;
298 * i.next() === pitsi31;
299 * i.hasNext() === false;
300 * // i.next() === null; #THROWS NoSuchElementException // NOPMD ei tykkää
301 * </pre>
302 */
303 public class HarrastuksetIterator implements Iterator<Harrastus> {
304 private final int jasenNro;
305 private final Iterator<Harrastus> iter = alkiot.iterator();
306 private Harrastus har;
307
308
309 /**
310 * Alustetaan iteraattori käymään läpi tietyn jäsenen harrastukset
311 * @param vnro viitenumero jäseneen
312 */
313 public HarrastuksetIterator(int vnro) {
314 jasenNro = vnro;
315 }
316
317
318 /**
319 * Tutkitaan onko vielä halutun jäsenen harrastuksia jäljellä.
320 * @return true jos jäsenen harrastuksia on vielä
321 * @see java.util.Iterator#hasNext()
322 */
323 public boolean hasNext() {
324 while ( true ) {
325 har = null; // NOPMD: tarkoituksella null
326 if ( !iter.hasNext() ) return false;
327 har = iter.next();
328 if ( har.getJasenNro()== jasenNro ) return true;
329 }
330 }
331
332
333 /**
334 * Palautetaan jäsenen seuraava harrastus.
335 * @return jäsenen seuraava harrastus
336 * @throws NoSuchElementException jos harrastuksia ei enää ole
337 * @see java.util.Iterator#next()
338 */
339 public Harrastus next() throws NoSuchElementException {
340 if ( har != null ) {
341 Harrastus pal = har;
342 har = null; // NOPMD: tarkoituksella null
343 return pal;
344 }
345 while ( true ) {
346 Harrastus har = iter.next();
347 if ( har.getJasenNro() == jasenNro ) return har;
348 }
349 }
350
351
352 /**
353 * Tuhoamista ei ole toteutettu
354 * @throws UnsupportedOperationException aina
355 * @see java.util.Iterator#remove()
356 */
357 public void remove() throws UnsupportedOperationException {
358 throw new UnsupportedOperationException("Me ei poisteta");
359 }
360
361 }
362
363
364 /**
365 * Palautetaan tietyn jäsenen harrastuksia käsittelevä iteraattori
366 * @param vnro tutkittavan jäsenen viitenumero
367 * @return valitun jäsenen harrastusten iteraattori
368 */
369 public Iterator<Harrastus> iterator(int vnro) {
370 return new HarrastuksetIterator(vnro);
371 }
372
373
374 /**
375 * Testiohjelma harrastuksille
376 * @param args ei käytössä
377 */
378 public static void main(String[] args) {
379 Harrastukset harrasteet = new Harrastukset();
380 Harrastus pitsi1 = new Harrastus();
381 pitsi1.vastaaPitsinNyplays(2);
382 Harrastus pitsi2 = new Harrastus();
383 pitsi2.vastaaPitsinNyplays(1);
384 Harrastus pitsi3 = new Harrastus();
385 pitsi3.vastaaPitsinNyplays(2);
386 Harrastus pitsi4 = new Harrastus();
387 pitsi4.vastaaPitsinNyplays(2);
388
389 harrasteet.lisaa(pitsi1);
390 harrasteet.lisaa(pitsi2);
391 harrasteet.lisaa(pitsi3);
392 harrasteet.lisaa(pitsi2);
393 harrasteet.lisaa(pitsi4);
394
395 System.out.println("============= Harrastukset testi =================");
396
397 { // Testataan toimiiko iteraattori ilman hasNextiä
398 Iterator<Harrastus> i2=harrasteet.iterator(2);
399 Harrastus har = i2.next();
400 System.out.print(har.getJasenNro() + " ");
401 har.tulosta(System.out);
402 har = i2.next();
403 System.out.print(har.getJasenNro() + " ");
404 har.tulosta(System.out);
405 har = i2.next();
406 System.out.print(har.getJasenNro() + " ");
407 har.tulosta(System.out);
408 }
409
410 for (Iterator<Harrastus> i=harrasteet.iterator(2); i.hasNext(); ) {
411 Harrastus har = i.next();
412 System.out.print(har.getJasenNro() + " ");
413 har.tulosta(System.out);
414 }
415
416 }
417
418
419 /**
420 * Palautetana lista jäsenen harrastuksia
421 * @param tunnusnro minkä id:n mukaisia harrastuksia etsitään.
422 * @return lista jäsenen harrastuksia
423 */
424 public List<Harrastus> annaHarrastukset(int tunnusnro) {
425 List<Harrastus> jasenenHarrastukset = new ArrayList<Harrastus>();
426 for (Harrastus har : this) {
427 if ( har.getJasenNro() == tunnusnro ) jasenenHarrastukset.add(har);
428 }
429 return jasenenHarrastukset;
430 }
431
432 }
433
434
435