1   package kerho;
2   
3   import java.util.*;
4   
5   /**
6    * Kerhon harrastukset, joka osaa mm. lisätä uuden harrastuksen
7    *
8    * @author Vesa Lappalainen
9    * @version 1.0, 22.02.2003
10   */
11  public class Harrastukset implements Iterable<Harrastus> {
12    // private boolean muutettu = false;
13    private String tiedostonNimi = "";
14    private String bakNimi = "";
15    private String kokoNimi = "";
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      alkiot.add(har);
37    }
38  
39  
40    /**
41     * Lukee jäsenistön tiedostosta.  Kesken.
42     * @param tied tiedoston nimen alkuosa
43     * @throws SailoException jos lukeminen epäonnistuu
44     */
45    public void lueTiedostosta(String tied) throws SailoException {
46      tiedostonNimi = tied + ".har";
47      kokoNimi = "Kelmien kerho";
48    }
49  
50    
51    /**
52     * Tallentaa jäsenistön tiedostoon.  Kesken.
53     * @throws SailoException jos talletus epäonnistuu
54     */
55    public void talleta() throws SailoException { 
56        // TODO: täydennä lukeminen
57    }
58  
59    
60    /**
61     * Palauttaa Kerhon koko nimen
62     * @return Kerhon koko nimi merkkijononna
63     */
64    public String getKokoNimi()            { return kokoNimi;                   }
65  
66    
67    /**
68     * Palauttaa kerhon harrastusten lukumäärän
69     * @return harrastusten lukumäärä
70     */
71    public int getLkm()                    { return alkiot.size();               }
72  
73    
74    /**
75     * Palauttaa tiedoston nimen, jota käytetään tallennukseen
76     * @return tallennustiedoston nimi
77     */
78    public String getTiedostonNimi()       { return tiedostonNimi;              }
79  
80    
81    /**
82     * Palauttaa varakopiotiedoston nimen
83     * @return varakopiotiedoston nimi
84     */
85    public String getBakNimi()             { return bakNimi;                    }
86  
87    
88    /**
89     * Tekee nykyisestä tiedostosta varakopiotiedoston. Kesken.
90     * @param bak_tark tarkennin varakopioiedostoille
91     * @return onnistuiko (true) vai ei (false)
92     */
93    public boolean teeBak(String bak_tark) { bakNimi = bak_tark; return true;   }
94  
95    
96    /**
97     * Iteraattori kaikkien harrastusten läpikäymiseen
98     * @return harrastusiteraattori
99     * 
100    * @example
101    * <pre name="test">
102    * #PACKAGEIMPORT
103    * #import java.util.*;
104    * 
105    *  Harrastukset harrasteet = new Harrastukset();
106    *  Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
107    *  Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
108    *  Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
109    *  Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
110    *  Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
111    * 
112    *  Iterator<Harrastus> i2=harrasteet.iterator();
113    *  i2.next() === pitsi21;
114    *  i2.next() === pitsi11;
115    *  i2.next() === pitsi22;
116    *  i2.next() === pitsi12;
117    *  i2.next() === pitsi23;
118    *  i2.next() === pitsi12;  #THROWS NoSuchElementException  
119    *  
120    *  int n = 0;
121    *  int jnrot[] = {2,1,2,1,2};
122    *  
123    *  for ( Harrastus har:harrasteet ) { 
124    *    har.getJasenNro() === jnrot[n]; n++;  
125    *  }
126    *  
127    *  n === 5;
128    *  
129    * </pre>
130    */
131   public Iterator<Harrastus> iterator() {
132     return alkiot.iterator();
133   }
134 
135   
136   /**
137    * Luokka tietyn jäsen harrastusten iteroimiseksi
138    * 
139    * @example
140    * <pre name="test">
141    * #PACKAGEIMPORT
142    * #import java.util.*;
143    * 
144    *  Harrastukset harrasteet = new Harrastukset();
145    *  Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
146    *  Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
147    *  Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
148    *  Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
149    *  Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
150    *  Harrastus pitsi51 = new Harrastus(5); harrasteet.lisaa(pitsi51);
151    * 
152    *  Iterator<Harrastus> i2=harrasteet.iterator(2);
153    *  i2.next() === pitsi21;
154    *  i2.next() === pitsi22;
155    *  i2.next() === pitsi23;
156    *  i2.next() === pitsi12;  #THROWS NoSuchElementException  
157    *  
158    *  int n = 0;
159    *  for (Iterator<Harrastus> i = harrasteet.iterator(2); i.hasNext(); ) {
160    *    i.next().getJasenNro() === 2; n++;
161    *  }
162    *  
163    *  n === 3;
164    *  
165    *  Iterator<Harrastus> i3=harrasteet.iterator(3);
166    *  i3.hasNext() === false;
167    *  i3.next()    === pitsi12;  #THROWS NoSuchElementException  
168    *  
169    *  Iterator<Harrastus> i4=harrasteet.iterator(4);
170    *  i4.next()    === pitsi12;  #THROWS NoSuchElementException  
171    *  
172    *  Iterator<Harrastus> i5=harrasteet.iterator(5);
173    *  i5.next()    === pitsi51;    
174    *  i5.next()    === pitsi51;  #THROWS NoSuchElementException  
175    * </pre>
176    * 
177    * @example
178    * <pre name="test">
179    * // Testataan erikoistapauksia
180    *  Harrastukset harrasteet = new Harrastukset();
181    *  Iterator<Harrastus> i;
182    *  
183    *  i = harrasteet.iterator(2); // Iteroidaan tyhjään joukoon
184    *  i.next()    === null;       #THROWS NoSuchElementException  
185    *  i = harrasteet.iterator(2);
186    *  i.hasNext() === false;
187    *  
188    *  Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
189    *  i = harrasteet.iterator(1); // Iteroidaan harrastusta jota ei ole
190    *  i.next()    === null;       #THROWS NoSuchElementException  
191    *  i = harrasteet.iterator(1);
192    *  i.hasNext() === false;
193    *  
194    *  i = harrasteet.iterator(2); // Iteroidaan 1. olevaa
195    *  i.next()    === pitsi21;  
196    *  i.next()    === null;       #THROWS NoSuchElementException  
197    *  
198    *  i = harrasteet.iterator(2); // Iteroidaan 1. olevaa hasNext():in kanssa
199    *  i.hasNext() === true;       // hasNext ekalla kertaa 
200    *  i.next()    === pitsi21;  
201    *  i.hasNext() === false; 
202    *  i.next()    === null;       #THROWS NoSuchElementException
203    *    
204    *  Harrastus pitsi31 = new Harrastus(3); harrasteet.lisaa(pitsi31);
205    *  i = harrasteet.iterator(1); // Iteroidaan 2. alkion joukosta olematonta
206    *  i.next()    === null;       #THROWS NoSuchElementException  
207    *  i = harrasteet.iterator(1); // Kokeillaan olematonta hasNext():in kanssa
208    *  i.hasNext() === false;
209    *  
210    *  i = harrasteet.iterator(2); // Iteroidaan ei viimeisenä olevaa
211    *  i.next()    === pitsi21;  
212    *  i.next()    === null;       #THROWS NoSuchElementException  
213    *  
214    *  i = harrasteet.iterator(2); // 1. hasNext():in avulla
215    *  i.hasNext() === true; 
216    *  i.next()    === pitsi21;  
217    *  i.hasNext() === false; 
218    *  i.next()    === null;       #THROWS NoSuchElementException
219    *    
220    *  i=harrasteet.iterator(3);   // Iteroidaan viimeisenä olevaa
221    *  i.hasNext() === true; 
222    *  i.next()    === pitsi31;  
223    *  i.hasNext() === false; 
224    *  // i.next()    === null;       #THROWS NoSuchElementException // NOPMD ei tykkää
225    * </pre>
226    */
227   public class HarrastuksetIterator implements Iterator<Harrastus> {
228     private final int jasenNro;
229     private final Iterator<Harrastus> iter = alkiot.iterator();
230     private Harrastus har;
231 
232     
233     /**
234      * Alustetaan iteraattori käymään läpi tietyn jäsenen harrastukset
235      * @param vnro viitenumero jäseneen
236      */
237     public HarrastuksetIterator(int vnro) {
238       jasenNro = vnro;
239     }
240 
241     
242     /**
243      * Tutkitaan onko vielä halutun jäsenen harrastuksia jäljellä.
244      * @return true jos jäsenen harrastuksia on vielä 
245      * @see java.util.Iterator#hasNext()
246      */
247     public boolean hasNext() {
248       while ( true ) {
249         har = null;                // NOPMD: tarkoituksella null 
250         if ( !iter.hasNext() ) return false;
251         har = iter.next();
252         if ( har.getJasenNro()== jasenNro ) return true;
253       }
254     }
255 
256     
257     /**
258      * Palautetaan jäsenen seuraava harrastus.
259      * @return jäsenen seuraava harrastus
260      * @throws NoSuchElementException jos harrastuksia ei enää ole
261      * @see java.util.Iterator#next()
262      */
263     public Harrastus next() throws NoSuchElementException {
264       if ( har != null ) {
265         Harrastus pal = har;
266         har = null;              // NOPMD: tarkoituksella null
267         return pal;
268       }
269       while ( true ) {
270         Harrastus har = iter.next();
271         if ( har.getJasenNro() == jasenNro ) return har;
272       }
273     }
274 
275     
276     /**
277      * Tuhoamista ei ole toteutettu
278      * @throws UnsupportedOperationException aina
279      * @see java.util.Iterator#remove()
280      */
281     public void remove() throws UnsupportedOperationException {
282       throw new UnsupportedOperationException("Me ei poisteta");
283     }
284 
285   }
286 
287   
288   /**
289    * Palautetaan tietyn jäsenen harrastuksia käsittelevä iteraattori
290    * @param vnro tutkittavan jäsenen viitenumero
291    * @return valitun jäsenen harrastusten iteraattori
292    */
293   public Iterator<Harrastus> iterator(int vnro) {
294     return new HarrastuksetIterator(vnro);
295   }
296   
297 
298   /**
299    * Testiohjelma harrastuksille
300    * @param args ei käytössä
301    */
302   public static void main(String[] args) {
303     Harrastukset harrasteet = new Harrastukset();
304     Harrastus pitsi1 = new Harrastus();
305     pitsi1.vastaaPitsinNyplays(2);
306     Harrastus pitsi2 = new Harrastus();
307     pitsi2.vastaaPitsinNyplays(1);
308     Harrastus pitsi3 = new Harrastus();
309     pitsi3.vastaaPitsinNyplays(2);
310     Harrastus pitsi4 = new Harrastus();
311     pitsi4.vastaaPitsinNyplays(2);
312 
313     harrasteet.lisaa(pitsi1);
314     harrasteet.lisaa(pitsi2);
315     harrasteet.lisaa(pitsi3);
316     harrasteet.lisaa(pitsi2);
317     harrasteet.lisaa(pitsi4);
318 
319     System.out.println("============= Harrastukset testi =================");
320 
321     { // Testataan toimiiko iteraattori ilman hasNextiä
322     Iterator<Harrastus> i2=harrasteet.iterator(2);
323     Harrastus har = i2.next();
324     System.out.print(har.getJasenNro() + " ");
325     har.tulosta(System.out);
326     har = i2.next();
327     System.out.print(har.getJasenNro() + " ");
328     har.tulosta(System.out);
329     har = i2.next();
330     System.out.print(har.getJasenNro() + " ");
331     har.tulosta(System.out);
332     }
333 
334     for (Iterator<Harrastus> i=harrasteet.iterator(2); i.hasNext(); ) {
335       Harrastus har = i.next();
336       System.out.print(har.getJasenNro() + " ");
337       har.tulosta(System.out);
338     }
339 
340   }
341 
342 }
343 
344 
345