1
2
3
4 package org.hardcode.juf;
5
6 import org.exolab.castor.xml.MarshalException;
7 import org.exolab.castor.xml.ValidationException;
8
9 import org.hardcode.juf.status.Status;
10 import org.hardcode.juf.status.UpdateInfo;
11 import org.hardcode.juf.update.Update;
12 import org.hardcode.juf.update.Updates;
13
14 import java.io.File;
15 import java.io.FileNotFoundException;
16 import java.io.FileReader;
17 import java.io.FileWriter;
18 import java.io.IOException;
19 import java.io.InputStreamReader;
20
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.net.URLClassLoader;
24
25 import java.util.ArrayList;
26 import java.util.HashMap;
27
28
29 /***
30 * Clase base de la librería
31 *
32 * @author Fernando González Cortés
33 */
34 public class JUpdate {
35 /***
36 * Crea un update con los datos del fichero que se pasa como parámetro
37 *
38 * @param name Nombre de la actualización
39 * @param file Fichero con la información de la actualización inicial
40 *
41 * @return Devuelve la información que el cliente tiene sobre la
42 * actualización cuyo nombre se pasa como parámetro. Si hay
43 * información en el cliente se lee la misma, si no la hay se
44 * obtiene la información del fichero que se pasa como parámetro
45 *
46 * @throws IOException Si se produce un error leyendo los datos del fichero
47 * que se pasa como parámetro
48 * @throws RuntimeException DOCUMENT ME!
49 */
50 public UpdateInfo getClientUpdateInformation(String name)
51 throws IOException {
52
53 try {
54 return getUpdateStatus(name);
55 } catch (ClientStatusException e) {
56 return null;
57 }
58 }
59
60 /***
61 * Realiza la actualización
62 *
63 * @param clientStatus HashMap que se pasa a las actualizaciones cuando se
64 * ejecutan
65 * @param name Nombre de la aplicación a la que pertenece la actualización
66 * u
67 * @param u Actualizacion que se quiere instalar
68 * @param listener Listener de eventos
69 *
70 * @throws BadConfigurationException Si la información descriptiva de la
71 * actualización en el servidor no es correcta
72 * @throws ClientStatusException Si no se puede actualizar el estado de la
73 * actualización en el cliente tras haberla ejecutado por
74 * problemas de formato
75 * @throws InstallException Si se produce un error en la ejecución
76 * instalación
77 * @throws IOException Si falla al actualizar el estado de la actualización
78 * en el cliente
79 */
80 public void doUpdate(HashMap clientStatus, UpdateInfo clientUpdateInfo, String name, Update u,
81 ProgressListener listener)
82 throws BadConfigurationException, ClientStatusException,
83 InstallException, IOException {
84 URL jarURL;
85 Installer installer = null;
86
87 try {
88 jarURL = new URL(u.getInstaller().getJarUrl());
89
90 URLClassLoader loader = new URLClassLoader(new URL[] { jarURL });
91 Class c = loader.loadClass(u.getInstaller().getClassName());
92
93 installer = (Installer) c.newInstance();
94 } catch (MalformedURLException e) {
95 throw new BadConfigurationException(e);
96 } catch (ClassNotFoundException e) {
97 throw new BadConfigurationException(e);
98 } catch (InstantiationException e) {
99 throw new BadConfigurationException(e);
100 } catch (IllegalAccessException e) {
101 throw new BadConfigurationException(e);
102 }
103
104 setUpdateStatus(name,
105 installer.install(clientStatus, clientUpdateInfo, listener));
106 }
107
108 /***
109 * Obtiene el estado correspondiente al componente con nombre componentName
110 * que se encuentra en el objeto UpdateInfo que se pasa como parámetro
111 *
112 * @param ui Información de la actualización
113 * @param packageName Nombre del componente del cual se quiere obtener su
114 * estado
115 *
116 * @return Estado del componente o null si no se encuentra un componente
117 * con ese nombre en el UpdateInfo
118 */
119 private Status getStatus(UpdateInfo ui, String packageName) {/package-summary.html">ong> Status getStatus(UpdateInfo ui, String packageName) {
120 Status[] status = ui.getStatus();
121
122 for (int i = 0; i < status.length; i++) {
123 >if (status[i].getComponentName().equals(packageName)) {
124 return status[i];
125 }
126 }
127
128 return null;
129 }
130
131 /***
132 * Obtiene la información del servidor sobre las actualizaciones
133 * disponibles posteriores a la versión actual
134 *
135 * @param name Nombre de la actualización
136 * @param listener Listener del progreso
137 *
138 * @return Updates disponibles
139 *
140 * @throws DownloadException Si la actualización existe pero no se puede
141 * descargar
142 * @throws ClientStatusException Si la actualización se descargó pero no se
143 * comprende el contenido
144 * @throws IOException Si falla el proceso de forma genérica
145 */
146 public Update[] checkUpdates(String name, UpdateInfo clientUpdateInfo, ProgressListener listener)
147 throws DownloadException, ClientStatusException, IOException {
148
149 Updates serverStatus = getUpdate(clientUpdateInfo, listener);
150 Update[] todas = serverStatus.getUpdate();
151 ArrayList updates = new ArrayList();
152
153 for (int i = 0; i < todas.length; i++) {
154 Status estado = getStatus(clientUpdateInfo, todas[i].getComponentName());
155
156 if (estado == null) {
157 updates.add(todas[i]);
158 } else {
159 if (estado.getVersion() < todas[i].getVersion()) {
160 updates.add(todas[i]);
161 }
162 }
163 }
164
165 return (Update[]) updates.toArray(new Update[0]);
166 }
167
168 /***
169 * Obtiene la información de la actualización
170 *
171 * @param st Información de la actualización que se quiere descargar
172 * @param listener Listener del proceso
173 *
174 * @return Jupdate
175 *
176 * @throws DownloadException Si no se pudo descargar la información de la
177 * update pero ésta existe
178 * @throws ClientStatusException No se entiende el descriptor de
179 * actualizacion
180 * @throws IOException Si falla el proceso de forma genérica
181 * @throws RuntimeException DOCUMENT ME!
182 */
183 private Updates getUpdate(UpdateInfo st, ProgressListener listener)
184 throws DownloadException, ClientStatusException, IOException {
185 URL url;
186
187 try {
188 url = new URL(st.getUrlPrefix());
189 } catch (MalformedURLException e2) {
190 throw new RuntimeException("URL no válida");
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 try {
208 Updates update = (Updates) Updates.unmarshal(new InputStreamReader(
209 url.openStream()));
210
211 return update;
212 } catch (MarshalException e) {
213 throw new ClientStatusException(e);
214 } catch (ValidationException e) {
215 throw new ClientStatusException(e);
216 }
217 }
218
219 /***
220 * Obtiene el estado de la actualización de nombre name
221 *
222 * @param name Nombre de la actualización
223 *
224 * @return La información de la actualización o null si no hay
225 * ninguna actualización instalada
226 *
227 * @throws ClientStatusException
228 */
229 private UpdateInfo getUpdateStatus(String name)
230 throws ClientStatusException {
231 try {
232 File f = getFile(name);
233 UpdateInfo info = (UpdateInfo) UpdateInfo.unmarshal(new FileReader(
234 f));
235
236 return info;
237 } catch (MarshalException e) {
238 throw new ClientStatusException(e);
239 } catch (ValidationException e) {
240 throw new ClientStatusException(e);
241 } catch (FileNotFoundException e) {
242 return null;
243 }
244 }
245
246 /***
247 * DOCUMENT ME!
248 *
249 * @param name DOCUMENT ME!
250 * @param info
251 *
252 * @throws ClientStatusException
253 * @throws IOException
254 */
255 private void setUpdateStatus(String name, UpdateInfo info)
256 throws ClientStatusException, IOException {
257 try {
258 File f = getFile(name);
259 info.marshal(new FileWriter(f));
260 } catch (MarshalException e) {
261 throw new ClientStatusException(e);
262 } catch (ValidationException e) {
263 throw new ClientStatusException(e);
264 }
265 }
266
267 /***
268 * Obtiene el fichero asociado a una actualización
269 *
270 * @param updateName Nombre de la actualización
271 *
272 * @return Fichero de la actualización. Puede no existir
273 */
274 private File getFile(String updateName) {
275 File ret = new File(System.getProperty("user.home") + File.separator +
276 "juf/org.hardcode.juf.JUpdate." + updateName + ".xml");
277
278 return ret;
279 }
280 }