| Jasenet.java |
1 package kerho;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.PrintWriter;
6 import java.io.File;
7 import java.util.Iterator;
8 import java.util.NoSuchElementException;
9
10 import fi.jyu.mit.ohj2.Tiedosto;
11
12
13 /**
14 * Kerhon jäsenistö joka osaa mm. lisätä uuden jäsenen
15 *
16 * @author Vesa Lappalainen
17 * @version 1.0, 22.02.2003
18 */
19 public class Jasenet implements Iterable<Jasen> {
20 private boolean muutettu = false;
21 private String tiedostonPerusNimi = "";
22 private String kokoNimi = "";
23
24 private static final int MAX_JASENIA = 5;
25 private int lkm = 0;
26
27 /**
28 * Taulukko jäsenistä
29 */
30 private Jasen alkiot[] = new Jasen[MAX_JASENIA];
31
32
33 /**
34 * Oletusmuodostaja
35 */
36 public Jasenet() {
37 // Attribuuttien oma alustus riittää
38 }
39
40
41 /**
42 * Lisää uuden jäsenen tietorakenteeseen. Ottaa jäsenen omistukseensa.
43 * @param jasen lisätäävän jäsenen viite. Huom tietorakenne muuttuu omistajaksi
44 * @throws SailoException jos tietorakenne on jo täynnä
45 * @example
46 * <pre name="test">
47 * #THROWS SailoException
48 * #PACKAGEIMPORT
49 * Jasenet jasenet = new Jasenet();
50 * Jasen aku1 = new Jasen(), aku2 = new Jasen();
51 * jasenet.getLkm() === 0;
52 * jasenet.lisaa(aku1); jasenet.getLkm() === 1;
53 * jasenet.lisaa(aku2); jasenet.getLkm() === 2;
54 * jasenet.lisaa(aku1); jasenet.getLkm() === 3;
55 * jasenet.anna(0) === aku1;
56 * jasenet.anna(1) === aku2;
57 * jasenet.anna(2) === aku1;
58 * jasenet.anna(1) == aku1 === false;
59 * jasenet.anna(1) == aku2 === true;
60 * jasenet.anna(3) === aku1; #THROWS IndexOutOfBoundsException
61 * jasenet.lisaa(aku1); jasenet.getLkm() === 4;
62 * jasenet.lisaa(aku1); jasenet.getLkm() === 5;
63 * jasenet.lisaa(aku1); #THROWS SailoException
64 * </pre>
65 */
66 public void lisaa(Jasen jasen) throws SailoException {
67 muutettu = true;
68 if ( lkm >= alkiot.length ) throw new SailoException("Liikaa alkioita");
69 alkiot[lkm] = jasen;
70 lkm++;
71 }
72
73
74 /**
75 * Palauttaa viitteen i:teen jäseneen.
76 * @param i monennenko jäsenen viite halutaan
77 * @return viite jäseneen, jonka indeksi on i
78 * @throws IndexOutOfBoundsException jos i ei ole sallitulla alueella
79 */
80 public Jasen anna(int i) throws IndexOutOfBoundsException {
81 if ( i < 0 || lkm <= i ) throw new IndexOutOfBoundsException("Laiton indeksi: " + i);
82 return alkiot[i];
83 }
84
85
86 /**
87 * Lukee jäsenistön tiedostosta. Kesken.
88 * @param tied tiedoston nimen alkuosa
89 * @throws SailoException jos lukeminen epäonnistuu
90 *
91 * @example
92 * <pre name="test">
93 * #THROWS SailoException
94 * #import java.io.File;
95 *
96 * Jasenet jasenet = new Jasenet();
97 * Jasen aku1 = new Jasen(), aku2 = new Jasen();
98 * aku1.vastaaAkuAnkka();
99 * aku2.vastaaAkuAnkka();
100 * String tiedNimi = "testikelmit";
101 * File ftied = new File(tiedNimi+".dat");
102 * ftied.delete();
103 * jasenet.lueTiedostosta(tiedNimi); #THROWS SailoException
104 * jasenet.lisaa(aku1);
105 * jasenet.lisaa(aku2);
106 * jasenet.talleta();
107 * jasenet = new Jasenet(); // Poistetaan vanhat luomalla uusi
108 * jasenet.lueTiedostosta(tiedNimi); // johon ladataan tiedot tiedostosta.
109 * Iterator<Jasen> i = jasenet.iterator();
110 * i.next().toString() === aku1.toString();
111 * i.next().toString() === aku2.toString();
112 * i.hasNext() === false;
113 * jasenet.lisaa(aku2);
114 * jasenet.talleta();
115 * ftied.delete() === true;
116 * File fbak = new File(tiedNimi+".bak");
117 * fbak.delete() === true;
118 * </pre>
119 */
120 public void lueTiedostosta(String tied) throws SailoException {
121 setTiedostonPerusNimi(tied);
122 BufferedReader fi = Tiedosto.avaa_lukemista_varten(getTiedostonNimi());
123 if ( fi == null ) throw new SailoException("Tiedosto " + getTiedostonNimi() + " ei aukea");
124
125 try {
126 kokoNimi = fi.readLine();
127 if ( kokoNimi == null ) throw new SailoException("Kerhon nimi puuttuu");
128 String rivi = fi.readLine();
129 if ( rivi == null ) throw new SailoException("Maksimikoko puuttuu");
130 // int maxKoko = Mjonot.erotaInt(rivi,10); // tehdään jotakin
131
132 while ( ( rivi = fi.readLine() ) != null ) {
133 rivi = rivi.trim();
134 if ( "".equals(rivi) || rivi.charAt(0) == ';') continue;
135 Jasen jasen = new Jasen(); // NOPMD, pakko luoda täällä
136 jasen.parse(rivi); // voisi olla virhekäsittely
137 lisaa(jasen);
138 }
139 muutettu = false;
140
141
142 } catch ( IOException e ) {
143 throw new SailoException("Ongelmia tiedoston kanssa: " + e.getMessage()); // NOPMD
144 } finally {
145 try {
146 fi.close();
147 } catch (IOException e) {
148 throw new SailoException("Tiedoston sulkeminen ei onnistu: " + e.getMessage()); // NOPMD
149 }
150 }
151 }
152
153
154 /**
155 * Tallentaa jäsenistön tiedostoon.
156 * Tiedoston muoto:
157 * <pre>
158 * Kelmien kerho
159 * 20
160 * ; kommenttirivi
161 * 2|Ankka Aku|121103-706Y|Ankkakuja 6|12345|ANKKALINNA|12-1234|||1996|50.0|30.0|Velkaa Roopelle
162 * 3|Ankka Tupu|121153-706Y|Ankkakuja 6|12345|ANKKALINNA|12-1234|||1996|50.0|30.0|Velkaa Roopelle
163 * </pre>
164 * @throws SailoException jos talletus epäonnistuu
165 */
166 public void talleta() throws SailoException {
167 if ( !muutettu ) return;
168
169 File fbak = new File(getBakNimi());
170 File ftied = new File(getTiedostonNimi());
171 fbak.delete(); // if .. System.err.println("Ei voi tuhota");
172 ftied.renameTo(fbak); // if .. System.err.println("Ei voi nimetä");
173
174 PrintWriter fo = Tiedosto.avaa_kirjoittamista_varten(ftied.getName());
175 if ( fo == null ) throw new SailoException("Tiedosto " + ftied.getName() + "ei aukea");
176 try {
177 fo.println(getKokoNimi());
178 fo.println(alkiot.length);
179 for (Jasen jasen:this) {
180 fo.println(jasen.toString());
181 }
182 //} catch ( IOException e ) { // ei heitä poikkeusta
183 // throw new SailoException("Tallettamisessa ongelmia: " + e.getMessage()); // NOPMD
184 } finally {
185 fo.close();
186 }
187
188 muutettu = false;
189 }
190
191 /**
192 * Palauttaa Kerhon koko nimen
193 * @return Kerhon koko nimi merkkijononna
194 */
195 public String getKokoNimi() { return kokoNimi; }
196
197
198 /**
199 * Palauttaa kerhon jäsenten lukumäärän
200 * @return jäsenten lukumäärä
201 */
202 public int getLkm() { return lkm; }
203
204
205 /**
206 * Asettaa tiedoston perusnimen ilan tarkenninta
207 * @param tied tallennustiedoston perusnimi
208 */
209 public void setTiedostonPerusNimi(String tied) { tiedostonPerusNimi = tied; }
210
211
212 /**
213 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
214 * @return tallennustiedoston nimi
215 */
216 public String getTiedostonPerusNimi() { return tiedostonPerusNimi; }
217
218
219 /**
220 * Palauttaa tiedoston nimen, jota käytetään tallennukseen
221 * @return tallennustiedoston nimi
222 */
223 public String getTiedostonNimi() { return tiedostonPerusNimi + ".dat"; }
224
225
226 /**
227 * Palauttaa varakopiotiedoston nimen
228 * @return varakopiotiedoston nimi
229 */
230 public String getBakNimi() { return tiedostonPerusNimi + ".bak"; }
231
232
233
234 /**
235 * Luokka jäsenten iteroimiseksi.
236 * @example
237 * <pre name="test">
238 * #THROWS SailoException
239 * #PACKAGEIMPORT
240 * #import java.util.*;
241 *
242 * Jasenet jasenet = new Jasenet();
243 * Jasen aku1 = new Jasen(), aku2 = new Jasen();
244 * aku1.rekisteroi(); aku2.rekisteroi();
245 *
246 * jasenet.lisaa(aku1);
247 * jasenet.lisaa(aku2);
248 * jasenet.lisaa(aku1);
249 *
250 * StringBuffer ids = new StringBuffer(30);
251 * for (Jasen jasen:jasenet) // Kokeillaan for-silmukan toimintaa
252 * ids.append(" "+jasen.getTunnusnro()); // NOPMD
253 *
254 * String tulos = " " + aku1.getTunnusnro() + " " + aku2.getTunnusnro() + " " + aku1.getTunnusnro();
255 *
256 * ids.toString() === tulos;
257 *
258 * ids = new StringBuffer(30);
259 * for (Iterator<Jasen> i=jasenet.iterator(); i.hasNext(); ) { // ja iteraattorin toimintaa
260 * Jasen jasen = i.next();
261 * ids.append(" "+jasen.getTunnusnro()); // NOPMD
262 * }
263 *
264 * ids.toString() === tulos;
265 *
266 * Iterator<Jasen> i=jasenet.iterator();
267 * i.next() == aku1 === true;
268 * i.next() == aku2 === true;
269 * i.next() == aku1 === true;
270 *
271 * i.next(); #THROWS NoSuchElementException
272 *
273 * </pre>
274 */
275 public class JasenetIterator implements Iterator<Jasen> {
276 private int kohdalla = -1;
277
278 /**
279 * Onko olemassa vielä seuraavaa jäsentä
280 * @see java.util.Iterator#hasNext()
281 * @return true jos on vielä jäseniä
282 */
283 public boolean hasNext() {
284 // if ( kohdalla + 1 >= lkm ) return false;
285 // return true;
286 return kohdalla + 1 < lkm;
287 }
288
289
290 /**
291 * Annetaan seuraava jäsen
292 * @return seuraava jäsen
293 * @throws NoSuchElementException jos seuraava alkiota ei enää ole
294 * @see java.util.Iterator#next()
295 */
296 public Jasen next() throws NoSuchElementException {
297 if ( !hasNext() ) throw new NoSuchElementException("Ei oo");
298 kohdalla++;
299 return alkiot[kohdalla];
300 }
301
302
303
304 /**
305 * Tuhoamista ei ole toteutettu
306 * @throws UnsupportedOperationException aina
307 * @see java.util.Iterator#remove()
308 */
309 public void remove() throws UnsupportedOperationException {
310 throw new UnsupportedOperationException("Me ei poisteta");
311 }
312 }
313
314 /**
315 * Palautetaan iteraattori jäsenistöön.
316 * @return jäsen iteraattori
317 */
318 public Iterator<Jasen> iterator() {
319 // return alkiot.iterator();
320 return new JasenetIterator();
321 }
322
323
324 /**
325 * Testiohjelma jäsenistölle
326 * @param args ei käytössä
327 */
328 public static void main(String args[]) {
329 Jasenet jasenet = new Jasenet();
330
331 Jasen aku = new Jasen(), aku2 = new Jasen();
332 aku.rekisteroi(); aku.vastaaAkuAnkka();
333 aku2.rekisteroi(); aku2.vastaaAkuAnkka();
334
335 try {
336 jasenet.lisaa(aku);
337 jasenet.lisaa(aku2);
338
339 System.out.println("============= Jäsenet testi =================");
340
341 for (Iterator<Jasen> i=jasenet.iterator(); i.hasNext(); ) {
342 // Jasen jasen = jasenet.anna(i);
343 // System.out.println("Jäsen nro: " + i);
344 Jasen jasen = i.next();
345 jasen.tulosta(System.out);
346 }
347 jasenet.anna(100);
348
349 } catch ( IndexOutOfBoundsException ex ) {
350 System.out.println(ex.getMessage());
351 } catch ( SailoException ex ) {
352 System.out.println(ex.getMessage());
353 }
354 }
355
356 }
357
358
359