1   package kerho;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.IOException;
6   import java.io.PrintWriter;
7   import java.util.*;
8   
9   import fi.jyu.mit.ohj2.Tiedosto;
10  
11  /**
12   * Kerhon harrastukset, joka osaa mm. lisätä uuden harrastuksen
13   *
14   * @author Vesa Lappalainen
15   * @version 1.0, 22.02.2003
16   */
17  public class Harrastukset implements Iterable<Harrastus> {
18      private boolean                     muutettu           = false;
19      private String                      tiedostonPerusNimi = "";
20  
21      /** Taulukko harrastuksista */
22      private final Collection<Harrastus> alkiot        = new ArrayList<Harrastus>();
23  
24  
25      /**
26       * Harrastusten alustaminen
27       */
28      public Harrastukset() {
29          // toistaiseksi ei tarvitse tehdä mitään
30      }
31  
32  
33      /**
34       * Lisää uuden harrastuksen tietorakenteeseen.  Ottaa harrastuksen omistukseensa.
35       * @param har lisättävä harrastus.  Huom tietorakenne muuttuu omistajaksi
36       */
37      public void lisaa(Harrastus har) {
38          alkiot.add(har);
39          muutettu = true;
40      }
41  
42  
43      /**
44       * Poistaa valitun harrastuksen
45       * @param harrastus poistettava harrastus
46       * @return tosi jos löytyi poistettava harrastus 
47       * <pre name="test">
48       * #THROWS SailoException 
49       * #import java.io.File;
50       *  Harrastukset harrasteet = new Harrastukset();
51       *  Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
52       *  Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
53       *  Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2); 
54       *  Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1); 
55       *  Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2); 
56       *  harrasteet.lisaa(pitsi21);
57       *  harrasteet.lisaa(pitsi11);
58       *  harrasteet.lisaa(pitsi22);
59       *  harrasteet.lisaa(pitsi12);
60       *  harrasteet.poista(pitsi23) === false ; harrasteet.getLkm() === 4;
61       *  harrasteet.poista(pitsi11) === true;   harrasteet.getLkm() === 3;
62       *  List<Harrastus> h = harrasteet.annaHarrastukset(1);
63       *  h.size() === 1; 
64       *  h = harrasteet.annaHarrastukset(1);
65       *  h.get(0) === pitsi12;
66       * </pre>
67       */
68      public boolean poista(Harrastus harrastus) {
69          boolean ret = alkiot.remove(harrastus);
70          if (ret) muutettu = true;
71          return ret;
72      }
73  
74  
75      /**
76       * Poistaa kaikki tietyn jäsenen harrastukset
77       * @param jasenNro viite siihen, minkä jäsenen harrastukset poistetaan
78       * @return montako poistettiin 
79       * @example
80       * <pre name="test">
81       * #THROWS SailoException 
82       * #import java.io.File;
83       *  Harrastukset harrasteet = new Harrastukset();
84       *  Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
85       *  Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
86       *  Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2); 
87       *  Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1); 
88       *  Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2); 
89       *  harrasteet.lisaa(pitsi21);
90       *  harrasteet.lisaa(pitsi11);
91       *  harrasteet.lisaa(pitsi22);
92       *  harrasteet.lisaa(pitsi12);
93       *  harrasteet.lisaa(pitsi23);
94       *  harrasteet.poista(2) === 3;  harrasteet.getLkm() === 2;
95       *  harrasteet.poista(3) === 0;  harrasteet.getLkm() === 2;
96       *  List<Harrastus> h = harrasteet.annaHarrastukset(2);
97       *  h.size() === 0; 
98       *  h = harrasteet.annaHarrastukset(1);
99       *  h.get(0) === pitsi11;
100      *  h.get(1) === pitsi12;
101      * </pre>
102      */
103     public int poista(int jasenNro) {
104         int n = 0;
105         for (Iterator<Harrastus> it = alkiot.iterator(); it.hasNext();) {
106             Harrastus har = it.next();
107             if (har.getJasenNro() == jasenNro) {
108                 it.remove();
109                 n++;
110             }
111         }
112         if (n > 0) muutettu = true;
113         return n;
114     }
115 
116 
117     /**
118      * Lukee harrastukset tiedostosta.
119      * @param tied tiedoston nimen alkuosa
120      * @throws SailoException jos lukeminen epäonnistuu
121      * 
122      * @example
123      * <pre name="test">
124      * #THROWS SailoException 
125      * #import java.io.File;
126      *  Harrastukset harrasteet = new Harrastukset();
127      *  Harrastus pitsi21 = new Harrastus(); pitsi21.vastaaPitsinNyplays(2);
128      *  Harrastus pitsi11 = new Harrastus(); pitsi11.vastaaPitsinNyplays(1);
129      *  Harrastus pitsi22 = new Harrastus(); pitsi22.vastaaPitsinNyplays(2); 
130      *  Harrastus pitsi12 = new Harrastus(); pitsi12.vastaaPitsinNyplays(1); 
131      *  Harrastus pitsi23 = new Harrastus(); pitsi23.vastaaPitsinNyplays(2); 
132      *  String tiedNimi = "testikelmit";
133      *  File ftied = new File(tiedNimi+".har");
134      *  ftied.delete();
135      *  harrasteet.lueTiedostosta(tiedNimi); #THROWS SailoException
136      *  harrasteet.lisaa(pitsi21);
137      *  harrasteet.lisaa(pitsi11);
138      *  harrasteet.lisaa(pitsi22);
139      *  harrasteet.lisaa(pitsi12);
140      *  harrasteet.lisaa(pitsi23);
141      *  harrasteet.talleta();
142      *  harrasteet = new Harrastukset();
143      *  harrasteet.lueTiedostosta(tiedNimi);
144      *  Iterator<Harrastus> i = harrasteet.iterator();
145      *  i.next().toString() === pitsi21.toString();
146      *  i.next().toString() === pitsi11.toString();
147      *  i.next().toString() === pitsi22.toString();
148      *  i.next().toString() === pitsi12.toString();
149      *  i.next().toString() === pitsi23.toString();
150      *  i.hasNext() === false;
151      *  harrasteet.lisaa(pitsi23);
152      *  harrasteet.talleta();
153      *  ftied.delete() === true;
154      *  File fbak = new File(tiedNimi+".hbak");
155      *  fbak.delete() === true;
156      * </pre>
157      */
158     public void lueTiedostosta(String tied) throws SailoException {
159         muutettu = true;
160         setTiedostonPerusNimi(tied);
161         BufferedReader fi = Tiedosto.avaa_lukemista_varten(getTiedostonNimi());
162         if (fi == null) throw new SailoException("Tiedosto " + getTiedostonNimi() + " ei aukea");
163 
164         String rivi;
165         try {
166             while ((rivi = fi.readLine()) != null) { 
167                 rivi = rivi.trim();
168                 if ("".equals(rivi) || rivi.charAt(0) == ';') continue;
169                 Harrastus har = new Harrastus(); 
170                 har.parse(rivi); // voisi olla virhekäsittely
171                 lisaa(har);
172             }
173             muutettu = false;
174 
175         } catch (IOException e) {
176             throw new SailoException("Ongelmia tiedoston kanssa: " + e.getMessage());
177         } finally {
178             try {
179                 fi.close();
180             } catch (IOException e) {
181                 throw new SailoException("Tiedoston sulkeminen ei onnistu: " + e.getMessage()); 
182             }
183         }
184     }
185 
186 
187     /**
188      * Tallentaa harrastukset tiedostoon.
189      * @throws SailoException jos talletus epäonnistuu
190      */
191     public void talleta() throws SailoException {
192         if (!muutettu) return;
193 
194         File fbak = new File(getBakNimi());
195         File ftied = new File(getTiedostonNimi());
196         fbak.delete(); //  if ... System.err.println("Ei voi tuhota");
197         ftied.renameTo(fbak); //  if ... System.err.println("Ei voi nimetä");
198 
199         PrintWriter fo = Tiedosto.avaa_kirjoittamista_varten(ftied.getName());
200         if (fo == null) throw new SailoException("Tiedosto " + ftied.getName() + " ei aukea");
201         try {
202             for (Harrastus har : this) {
203                 fo.println(har.toString());
204             }
205         } finally {
206             fo.close();
207         }
208 
209         muutettu = false;
210     }
211 
212 
213     /**
214      * Palauttaa kerhon harrastusten lukumäärän
215      * @return harrastusten lukumäärä
216      */
217     public int getLkm() {
218         return alkiot.size();
219     }
220     
221     
222     /**
223      * Asettaa tiedoston perusnimen ilan tarkenninta
224      * @param tied tallennustiedoston perusnimi
225      */
226     public void setTiedostonPerusNimi(String tied) {
227         tiedostonPerusNimi = tied;
228     }
229 
230     
231     /**
232      * Palauttaa tiedoston nimen, jota käytetään tallennukseen
233      * @return tallennustiedoston nimi
234      */
235     public String getTiedostonPerusNimi() {
236         return tiedostonPerusNimi;
237     }
238 
239 
240     /**
241      * Palauttaa tiedoston nimen, jota käytetään tallennukseen
242      * @return tallennustiedoston nimi
243      */
244     public String getTiedostonNimi() {
245         return tiedostonPerusNimi + ".har";
246     }
247 
248 
249     /**
250      * Palauttaa varakopiotiedoston nimen
251      * @return varakopiotiedoston nimi
252      */
253     public String getBakNimi() {
254         return tiedostonPerusNimi + ".hbak";
255     }
256 
257 
258     /**
259      * Iteraattori kaikkien harrastusten läpikäymiseen
260      * @return harrastusiteraattori
261      * 
262      * @example
263      * <pre name="test">
264      * #PACKAGEIMPORT
265      * #import java.util.*;
266      * 
267      *  Harrastukset harrasteet = new Harrastukset();
268      *  Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
269      *  Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
270      *  Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
271      *  Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
272      *  Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
273      * 
274      *  Iterator<Harrastus> i2=harrasteet.iterator();
275      *  i2.next() === pitsi21;
276      *  i2.next() === pitsi11;
277      *  i2.next() === pitsi22;
278      *  i2.next() === pitsi12;
279      *  i2.next() === pitsi23;
280      *  i2.next() === pitsi12;  #THROWS NoSuchElementException  
281      *  
282      *  int n = 0;
283      *  int jnrot[] = {2,1,2,1,2};
284      *  
285      *  for ( Harrastus har:harrasteet ) { 
286      *    har.getJasenNro() === jnrot[n]; n++;  
287      *  }
288      *  
289      *  n === 5;
290      *  
291      * </pre>
292      */
293     @Override
294     public Iterator<Harrastus> iterator() {
295         return alkiot.iterator();
296     }
297 
298 
299     /**
300      * Haetaan kaikki jäsen harrastukset
301      * @param tunnusnro jäsenen tunnusnumero jolle harrastuksia haetaan
302      * @return tietorakenne jossa viiteet löydetteyihin harrastuksiin
303      * @example
304      * <pre name="test">
305      * #import java.util.*;
306      * 
307      *  Harrastukset harrasteet = new Harrastukset();
308      *  Harrastus pitsi21 = new Harrastus(2); harrasteet.lisaa(pitsi21);
309      *  Harrastus pitsi11 = new Harrastus(1); harrasteet.lisaa(pitsi11);
310      *  Harrastus pitsi22 = new Harrastus(2); harrasteet.lisaa(pitsi22);
311      *  Harrastus pitsi12 = new Harrastus(1); harrasteet.lisaa(pitsi12);
312      *  Harrastus pitsi23 = new Harrastus(2); harrasteet.lisaa(pitsi23);
313      *  Harrastus pitsi51 = new Harrastus(5); harrasteet.lisaa(pitsi51);
314      *  
315      *  List<Harrastus> loytyneet;
316      *  loytyneet = harrasteet.annaHarrastukset(3);
317      *  loytyneet.size() === 0; 
318      *  loytyneet = harrasteet.annaHarrastukset(1);
319      *  loytyneet.size() === 2; 
320      *  loytyneet.get(0) == pitsi11 === true;
321      *  loytyneet.get(1) == pitsi12 === true;
322      *  loytyneet = harrasteet.annaHarrastukset(5);
323      *  loytyneet.size() === 1; 
324      *  loytyneet.get(0) == pitsi51 === true;
325      * </pre> 
326      */
327     public List<Harrastus> annaHarrastukset(int tunnusnro) {
328         List<Harrastus> loydetyt = new ArrayList<Harrastus>();
329         for (Harrastus har : alkiot)
330             if (har.getJasenNro() == tunnusnro) loydetyt.add(har);
331         return loydetyt;
332     }
333 
334 
335     /**
336      * Laitetaan muutos, jolloin pakotetaan tallentamaan.  
337      */
338     public void setMuutos() {
339         muutettu = true;
340     }
341 
342     
343     /**
344      * Testiohjelma harrastuksille
345      * @param args ei käytössä
346      */
347     public static void main(String[] args) {
348         Harrastukset harrasteet = new Harrastukset();
349         Harrastus pitsi1 = new Harrastus();
350         pitsi1.vastaaPitsinNyplays(2);
351         Harrastus pitsi2 = new Harrastus();
352         pitsi2.vastaaPitsinNyplays(1);
353         Harrastus pitsi3 = new Harrastus();
354         pitsi3.vastaaPitsinNyplays(2);
355         Harrastus pitsi4 = new Harrastus();
356         pitsi4.vastaaPitsinNyplays(2);
357 
358         harrasteet.lisaa(pitsi1);
359         harrasteet.lisaa(pitsi2);
360         harrasteet.lisaa(pitsi3);
361         harrasteet.lisaa(pitsi2);
362         harrasteet.lisaa(pitsi4);
363 
364         System.out.println("============= Harrastukset testi =================");
365 
366         List<Harrastus> harrastukset2 = harrasteet.annaHarrastukset(2);
367 
368         for (Harrastus har : harrastukset2) {
369             System.out.print(har.getJasenNro() + " ");
370             har.tulosta(System.out);
371         }
372 
373     }
374 
375 }
376