1 package paolomind.commons.xml;
2
3 import java.beans.XMLDecoder;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.URL;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.Map;
10
11 import paolomind.commons.NamedObject;
12 import paolomind.commons.ObjectContainer;
13
14 /**
15 * classe di ogetti che si preoccupano di leggere uno stream di dati in formato
16 * XML e ne ricavo degli ogetti. Si consiglia nel file XML di aggiungere alla
17 * fine il seguente codice per mappare gli ogetti desiderati:
18 *
19 * <pre>
20 * <void property="owner">
21 * <void method="register">
22 * <string>integer</string>
23 * <object idref="num" />
24 * </void>
25 * </void>
26 * </pre>
27 *
28 * <li>owner è questo stesso oggetto</li>
29 * <li>register è il metodo per registrare gli oggetti</li>
30 * <li>la prima stringa è l'argomento chiave,l'identificativo dell'oggetto</li>
31 * <li>il secondo argomento è l'ogetto da mappare</li>
32 *
33 * @author paolo
34 * @see java.beans.XMLDecoder,
35 */
36 public class XMLObjectContainer implements ObjectContainer {
37
38 /** */
39 private Map objectmap;
40
41 /** */
42 private XMLListener listener;
43
44 /** */
45 private ClassLoader loader;
46
47 /**
48 * costruttore vuoto che inizializza la hashmap.
49 */
50 public XMLObjectContainer() {
51 objectmap = new HashMap();
52 }
53
54 /**
55 * costruttore che si occupa di interpretare lo stream di input.
56 * @param in stream di input (uno stream con formato XML)
57 * @param l il listner degli eventi
58 */
59 public XMLObjectContainer(final InputStream in, final XMLListener l) {
60 this();
61 listener = l;
62 read(in);
63 }
64
65 /**
66 * costruttore che si occupa di interpretare lo stream di input.
67 * @param in stream di input (uno stream con formato XML)
68 * @param l il listner degli eventi
69 * @param cl il classloader da cui caricare le risorse
70 */
71 public XMLObjectContainer(final InputStream in, final XMLListener l,
72 final ClassLoader cl) {
73 this(l, cl);
74 read(in);
75 }
76
77 /**
78 * costruttore di inizializzazione.
79 * @param l il listner degli eventi
80 * @param cl il classloader da cui caricare le risorse
81 */
82 public XMLObjectContainer(final XMLListener l, final ClassLoader cl) {
83 this();
84 listener = l;
85 this.loader = cl;
86 }
87 /**
88 * interpreta da uno stream l'oggetto .
89 * @param in lo stream da interpretare
90 */
91 public final void read(final InputStream in) {
92 if (listener != null) {
93 listener.startreading();
94 }
95 XMLDecoder xmldec = new XMLDecoder(in, this, listener);
96 try {
97 while (true) {
98 Object o = xmldec.readObject();
99 if (listener != null) {
100 listener.read(o);
101 }
102 }
103 } catch (java.lang.ArrayIndexOutOfBoundsException e) {
104 if (listener != null) {
105 listener.endreading();
106 }
107 }
108 }
109
110 /**
111 * registra un ogetto associandolo alla chiave specificata.
112 * @param name chiave
113 * @param o valore
114 */
115 public final void register(final String name, final Object o) {
116 objectmap.put(name, o);
117 if (listener != null) {
118 listener.objectRegister(name, o);
119 }
120 }
121
122 /**
123 * reperisce un elemento registrato.
124 *
125 * @param name
126 * nome dell'oggetto registrato
127 * @return restituisce un ogetto registrato oppure null
128 * @see paolomind.commons.ObjectContainer#get(java.lang.String)
129 */
130 public final Object get(final String name) {
131 return objectmap.get(name);
132 }
133
134 /**
135 * restituisce una risorsa ricavandola dal class loader.
136 * @param name percosro alla risorsa relativo al classpath
137 * @return lo stream aperto dalla risorsa
138 * @see java.lang.ClassLoader#getResourceAsStream(String)
139 */
140 public final InputStream getResourceAsStream(final String name) {
141 ClassLoader cl;
142 if (loader == null) {
143 cl = this.getClass().getClassLoader();
144 } else {
145 cl = loader;
146 cl.getResourceAsStream(name);
147 }
148 return getStreamFromUrl(cl.getResource(name));
149 }
150
151 /**
152 * apre uno stream da una url specificata.
153 * @param url url della risorsa
154 * @return lo stream aperto dalla risorsa
155 */
156 public final InputStream getStreamFromUrl(final URL url) {
157 try {
158 if (listener != null) {
159 listener.openedStream(url);
160 }
161 return url.openStream();
162 } catch (IOException e) {
163 listener.exceptionThrown(e);
164 return null;
165 }
166 }
167
168 /**
169 * apre uno stream da una url specificata come una stringa.
170 * @param url la risorsa
171 * @return lo stream aperto dalla risorsa
172 */
173 public final InputStream getStreamFromUrl(final String url) {
174 try {
175 return getStreamFromUrl(new URL(url));
176 } catch (IOException e) {
177 e.printStackTrace();
178 return null;
179 }
180 }
181
182 /**
183 * restituisce tutti gli identificativi registrati.
184 * @return tutti gli identificativi registrati
185 */
186 public final Iterator getIds() {
187 return objectmap.keySet().iterator();
188 }
189
190 /**
191 * registra un ogetto.
192 *
193 * @param element
194 * l'oggetto da registrare con il suo nome
195 * @see paolomind.commons.ObjectContainer#register(paolomind.commons.NamedObject)
196 */
197 public final void register(final NamedObject element) {
198 register(element.getSelfId(), element);
199 }
200
201 /**
202 * questo metodo non è supportato da questa classe.
203 * rilancia l'eccezione UnsupportedOperationException
204 * @param name ho detto che non è supportato
205 * @return ma ci insisti a continuare a leggere!!! non ritorna nulla!!!
206 * @see paolomind.commons.ObjectContainer#select(java.lang.String)
207 * @deprecated
208 */
209 public final boolean select(final String name) {
210 throw new UnsupportedOperationException("Metodo select non supportato");
211 }
212
213 /**
214 * restituisce tutti gli elementi.
215 *
216 * @return tutti gli elementi registrati
217 * @see paolomind.commons.ObjectContainer#getAll()
218 */
219 public final Iterator getAll() {
220 return objectmap.values().iterator();
221 }
222
223 /**
224 * setta il listener per la gestione di eventi prevedibili.
225 * @param plistener listener per la gestione di eventi prevedibili.
226 */
227 public final void setListener(final XMLListener plistener) {
228 this.listener = plistener;
229 }
230
231 /**
232 * setta il classloader per caricare risorse eventualmente richieste.
233 * se null usa il proprio classloader.
234 * @param ploader classloader per caricare risorse eventualmente richieste.
235 */
236 public final void setLoader(final ClassLoader ploader) {
237 this.loader = ploader;
238 }
239
240 /**
241 * restituisce la mappa degli oggetti registrati.
242 * @return la mappa degli oggetti registrati
243 */
244 protected final Map getObjectmap() {
245 return objectmap;
246 }
247
248 /**
249 * setta la mappa degli oggetti registrati.
250 * @param pobjectmap la mappa degli oggetti registrati
251 */
252 protected final void setObjectmap(final Map pobjectmap) {
253 this.objectmap = pobjectmap;
254 }
255
256 /**
257 * restituisce il listener associato.
258 * @return il listener associato.
259 */
260 protected final XMLListener getListener() {
261 return listener;
262 }
263 }