Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / execution / DefaultInstallPackageService.java @ 37538

History | View | Annotate | Download (18 KB)

1 32269 jpiera
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 {Prodevelop}   {Task}
26
 */
27
28
package org.gvsig.installer.lib.impl.execution;
29
30 33982 cordinyana
import java.io.BufferedInputStream;
31 32269 jpiera
import java.io.File;
32 34005 cordinyana
import java.io.FileFilter;
33 32400 jpiera
import java.io.FileInputStream;
34
import java.io.FileNotFoundException;
35 33982 cordinyana
import java.io.IOException;
36 32269 jpiera
import java.io.InputStream;
37 37489 nfrancisco
import java.net.MalformedURLException;
38 33982 cordinyana
import java.net.URL;
39 32400 jpiera
import java.util.ArrayList;
40
import java.util.HashMap;
41 37538 nfrancisco
import java.util.HashSet;
42 32287 jpiera
import java.util.List;
43 32400 jpiera
import java.util.Map;
44 37538 nfrancisco
import java.util.Set;
45 32269 jpiera
46 33729 cordinyana
import org.slf4j.Logger;
47
import org.slf4j.LoggerFactory;
48
49 34005 cordinyana
import org.gvsig.installer.lib.api.InstallerManager;
50 32562 jpiera
import org.gvsig.installer.lib.api.PackageInfo;
51
import org.gvsig.installer.lib.api.execution.InstallPackageService;
52
import org.gvsig.installer.lib.api.execution.InstallPackageServiceException;
53 32400 jpiera
import org.gvsig.installer.lib.impl.DefaultInstallerManager;
54 34925 nfrancisco
import org.gvsig.installer.lib.impl.utils.Download;
55 32627 jpiera
import org.gvsig.installer.lib.spi.InstallPackageProviderServices;
56 32498 jpiera
import org.gvsig.installer.lib.spi.InstallerProviderLocator;
57 32400 jpiera
import org.gvsig.installer.lib.spi.InstallerProviderManager;
58 32598 jpiera
import org.gvsig.installer.lib.spi.execution.InstallPackageProvider;
59 32400 jpiera
import org.gvsig.tools.service.Manager;
60
import org.gvsig.tools.service.ServiceException;
61 34967 nfrancisco
import org.gvsig.tools.task.SimpleTaskStatus;
62 32269 jpiera
63
/**
64
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodr&aacute;</a>
65
 */
66 32400 jpiera
67 34967 nfrancisco
public class DefaultInstallPackageService extends Thread implements
68
    InstallPackageService {
69 34020 cordinyana
70 34967 nfrancisco
    private static final Logger LOG =
71
        LoggerFactory.getLogger(DefaultInstallPackageService.class);
72
73 33743 cordinyana
    private Map<PackageInfo, File> packageInfoFileMap = null;
74 33729 cordinyana
    private Map<PackageInfo, String> zipEntriesMap = null;
75
    private List<PackageInfo> packageInfos = null;
76 34005 cordinyana
    private InstallerManager manager;
77 33729 cordinyana
    private InstallPackageProviderServices installerProviderServices = null;
78 32400 jpiera
79 33729 cordinyana
    public DefaultInstallPackageService(DefaultInstallerManager manager) {
80
        super();
81
        this.manager = manager;
82 35189 nfrancisco
        this.reset();
83
    }
84 35948 nfrancisco
85 35189 nfrancisco
    public void reset() {
86 33743 cordinyana
        packageInfoFileMap = new HashMap<PackageInfo, File>();
87 33729 cordinyana
        packageInfos = new ArrayList<PackageInfo>();
88
        zipEntriesMap = new HashMap<PackageInfo, String>();
89
        installerProviderServices =
90
            InstallerProviderLocator.getProviderManager()
91
                .createInstallerProviderServices();
92
    }
93 32562 jpiera
94 35948 nfrancisco
    public class InstallerApplicationDirectoryNotFoundException extends
95
        InstallPackageServiceException {
96
97
        private static final long serialVersionUID = -1130408094135962456L;
98
99
        private static final String message =
100
            "Aplication directory '%(directory)s' not found";
101
102
        private static final String KEY =
103
            "_aplication_directory_XdirectoryX_not_found";
104
105
        public InstallerApplicationDirectoryNotFoundException(File file) {
106
            super(message, KEY, serialVersionUID);
107
            setValue("directory", file.toString());
108
        }
109
110
    }
111
112
    public class InstallerNoDirectoryException extends
113
        InstallPackageServiceException {
114
115
        private static final long serialVersionUID = -8685263049644983769L;
116
117
        private static final String message =
118
            "'%(directory)s' is not a directory";
119
120
        private static final String KEY = "_XdirectoryX_is_not_a_directory";
121
122
        public InstallerNoDirectoryException(File file) {
123
            super(message, KEY, serialVersionUID);
124
            setValue("directory", file.toString());
125
        }
126
127
    }
128
129
    public class InstallerFileNotFoundException extends
130
        InstallPackageServiceException {
131
132
        private static final long serialVersionUID = 556517830330132149L;
133
134
        private static final String message = "File '%(file)s' not found";
135
136
        private static final String KEY = "_file_XfileX_not_found";
137
138
        public InstallerFileNotFoundException(File file) {
139
            super(message, KEY, serialVersionUID);
140
            setValue("file", file.toString());
141
        }
142
143
    }
144
145
    public class InstallerBundleNotFoundException extends
146
        InstallPackageServiceException {
147
148
        private static final long serialVersionUID = 5065410511582625301L;
149
150
        private static final String message = "File '%(file)s' not found";
151
152
        private static final String KEY = "_file_XfileX_not_found";
153
154
        public InstallerBundleNotFoundException(File file,
155
            FileNotFoundException e) {
156
            super(message, e, KEY, serialVersionUID);
157
            setValue("file", file.toString());
158
        }
159
160
    }
161
162
    public class InstallerIOException extends InstallPackageServiceException {
163
164
        private static final long serialVersionUID = 3153613550157712363L;
165
166
        private static final String message =
167
            "IO error installing the file '%(file)s'";
168
169
        private static final String KEY = "_IO_error installing_file_XfileX_";
170
171
        public InstallerIOException(File file, IOException e) {
172
            super(message, e, KEY, serialVersionUID);
173
            setValue("file", file.toString());
174
        }
175
176
    }
177
178
    public class InstallerFileDownloadException extends
179
        InstallPackageServiceException {
180
181
        private static final long serialVersionUID = 8640183295766490512L;
182
183
        private static final String message = "File '%(url)s' download error";
184
185
        private static final String KEY = "_File_XurlX_download_error";
186
187
        public InstallerFileDownloadException(URL url, IOException e) {
188
            super(message, e, KEY, serialVersionUID);
189
            setValue("url", url.toString());
190
        }
191
192
    }
193
194
    public class InstallerPackageNotFoundException extends
195
        InstallPackageServiceException {
196
197
        private static final long serialVersionUID = 1726608498886963868L;
198
199
        private static final String message = "Package not found";
200
201
        private static final String KEY = "_package_not_found";
202
203
        public InstallerPackageNotFoundException() {
204
            super(message, KEY, serialVersionUID);
205
        }
206
207
    }
208
209
    public class InstallerNoPackageException extends
210
        InstallPackageServiceException {
211
212
        private static final long serialVersionUID = -2292735515704746966L;
213
214
        private static final String message = "Package does not exist";
215
216
        private static final String KEY = "_package__does_not_exist";
217
218
        public InstallerNoPackageException() {
219
            super(message, KEY, serialVersionUID);
220
        }
221
222
    }
223
224
    public class InstallerProviderCreationException extends
225
        InstallPackageServiceException {
226
227
        private static final long serialVersionUID = -7985786807492393584L;
228
229
        private static final String message = "Error creating the provider";
230
231
        private static final String KEY = "_Error_creating_the_provider";
232
233
        public InstallerProviderCreationException(ServiceException e) {
234
            super(message, e, KEY, serialVersionUID);
235
        }
236
237
    }
238
239 33729 cordinyana
    public void installPackage(File applicationDirectory,
240
        PackageInfo packageInfo) throws InstallPackageServiceException {
241
        if (!applicationDirectory.exists()) {
242 35948 nfrancisco
            throw new InstallerApplicationDirectoryNotFoundException(
243
                applicationDirectory);
244 33729 cordinyana
        }
245 33743 cordinyana
        if (!packageInfoFileMap.containsKey(packageInfo)) {
246 35948 nfrancisco
            throw new InstallerPackageNotFoundException();
247 33729 cordinyana
        }
248 32269 jpiera
249 33729 cordinyana
        InstallPackageProvider installerExecutionProvider =
250
            createProvider(packageInfo);
251 32400 jpiera
252 34020 cordinyana
        // Get the package or package set file
253 34967 nfrancisco
        File file = packageInfoFileMap.get(packageInfo);
254
        if (file == null) {
255
            if (packageInfo.getDownloadURL() == null) {
256 35948 nfrancisco
                throw new InstallerPackageNotFoundException();
257 34967 nfrancisco
            }
258
            this.downloadPackage(packageInfo);
259 34020 cordinyana
            file = packageInfoFileMap.get(packageInfo);
260
        }
261
262
        // Open and install the package or package set file
263
        try {
264 35948 nfrancisco
265 34020 cordinyana
            InputStream packageStream;
266
            InputStream fis = new FileInputStream(file);
267
            InputStream bis = new BufferedInputStream(fis);
268
            if (isPackage(file)) {
269
                packageStream = bis;
270
            } else {
271
                if (!isPackageSet(file)) {
272
                    LOG.warn("Trying to install a package file ({0}) "
273
                        + "without a known file extension. Will try "
274
                        + "to install it as a package set", file);
275
                }
276
                packageStream =
277 34967 nfrancisco
                    installerProviderServices.searchPackage(bis, zipEntriesMap
278
                        .get(packageInfo));
279 34020 cordinyana
            }
280
281 35948 nfrancisco
            try {
282
                installerExecutionProvider.install(applicationDirectory,
283
                    packageStream, packageInfo);
284
            } catch (InstallPackageServiceException e) {
285
286
                packageStream.close();
287
                if (bis != packageStream) {
288
                    bis.close();
289
                }
290
                fis.close();
291
292
                // if fails the installation, zip files need to be reopen
293
                // the package will be installed into the update folder for
294
                // installation after a gvSIG restart
295
296
                fis = new FileInputStream(file);
297
                bis = new BufferedInputStream(fis);
298
                if (isPackage(file)) {
299
                    packageStream = bis;
300
                } else {
301
                    if (!isPackageSet(file)) {
302
                        LOG.warn("Trying to install a package file ({0}) "
303
                            + "without a known file extension. Will try "
304
                            + "to install it as a package set", file);
305
                    }
306
                    packageStream =
307
                        installerProviderServices.searchPackage(bis,
308
                            zipEntriesMap.get(packageInfo));
309
                }
310
                installerExecutionProvider.installLater(applicationDirectory,
311
                    packageStream, packageInfo);
312
            }
313
314 34020 cordinyana
            packageStream.close();
315
            if (bis != packageStream) {
316 33982 cordinyana
                bis.close();
317
            }
318 34020 cordinyana
            fis.close();
319 35948 nfrancisco
320 34020 cordinyana
        } catch (FileNotFoundException e) {
321 35948 nfrancisco
            throw new InstallerFileNotFoundException(file);
322 34020 cordinyana
        } catch (IOException e) {
323 35948 nfrancisco
            throw new InstallerIOException(file, e);
324 33982 cordinyana
        }
325
326 33729 cordinyana
    }
327 32269 jpiera
328 33729 cordinyana
    public void installPackage(File applicationDirectory, String packageCode)
329
        throws InstallPackageServiceException {
330
        PackageInfo packageInfo = getPackageInfo(packageCode);
331
        if (packageInfo == null) {
332 35948 nfrancisco
            throw new InstallerNoPackageException();
333 33729 cordinyana
        }
334
        installPackage(applicationDirectory, packageInfo);
335
    }
336 32400 jpiera
337 33729 cordinyana
    private InstallPackageProvider createProvider(PackageInfo packageInfo)
338
        throws InstallPackageServiceException {
339
        InstallerProviderManager installerProviderManager =
340
            (InstallerProviderManager) ((DefaultInstallerManager) manager)
341
                .getProviderManager();
342 32400 jpiera
343 33729 cordinyana
        try {
344
            return installerProviderManager.createExecutionProvider(packageInfo
345
                .getType());
346
        } catch (ServiceException e) {
347 35948 nfrancisco
            throw new InstallerProviderCreationException(e);
348 33729 cordinyana
        }
349
    }
350 32269 jpiera
351 33729 cordinyana
    public PackageInfo getPackageInfo(int index) {
352
        if (index >= packageInfos.size()) {
353
            return null;
354
        }
355
        return packageInfos.get(index);
356
    }
357 32400 jpiera
358 33729 cordinyana
    public PackageInfo getPackageInfo(String packageCode) {
359
        for (int i = 0; i < getPackageCount(); i++) {
360
            if (packageInfos.get(i).getCode().equals(packageCode)) {
361
                return packageInfos.get(i);
362
            }
363
        }
364
        return null;
365
    }
366 32400 jpiera
367 33743 cordinyana
    public void addBundle(File bundle) throws InstallPackageServiceException {
368 35948 nfrancisco
369 33743 cordinyana
        if (!bundle.exists()) {
370 35948 nfrancisco
            throw new InstallPackageServiceException();
371 33729 cordinyana
        }
372 35948 nfrancisco
373 34020 cordinyana
        int packageInfoCount = packageInfos.size();
374 35948 nfrancisco
375 34020 cordinyana
        FileInputStream fis;
376 33729 cordinyana
        try {
377 34020 cordinyana
            fis = new FileInputStream(bundle);
378 33729 cordinyana
        } catch (FileNotFoundException e) {
379 35948 nfrancisco
            throw new InstallerBundleNotFoundException(bundle, e);
380 33729 cordinyana
        }
381 34020 cordinyana
        BufferedInputStream bis = new BufferedInputStream(fis);
382
        if (isPackage(bundle)) {
383
            installerProviderServices.readPackageInfo(bis, packageInfos,
384 34027 cordinyana
                zipEntriesMap, bundle.getName());
385 34020 cordinyana
        } else {
386
            if (!isPackageSet(bundle)) {
387
                LOG.warn("Trying to add a package file ({0}) without a known "
388
                    + "file extension. Will try to add it as a package set",
389
                    bundle);
390
            }
391
            installerProviderServices.readPackageSetInfo(fis, packageInfos,
392
                zipEntriesMap);
393
        }
394
        try {
395
            bis.close();
396
            fis.close();
397
        } catch (IOException e) {
398
            LOG.warn("Error closing the input streams of the package file: "
399
                + bundle, e);
400
        }
401
402
        for (int i = packageInfoCount; i < packageInfos.size(); i++) {
403
            packageInfoFileMap.put(packageInfos.get(i), bundle);
404
        }
405 33729 cordinyana
    }
406 32562 jpiera
407 34020 cordinyana
    private boolean isPackageSet(File file) {
408
        return file.getName().endsWith(
409
            manager.getDefaultPackageSetFileExtension());
410
    }
411
412
    private boolean isPackage(File file) {
413
        return file.getName()
414
            .endsWith(manager.getDefaultPackageFileExtension());
415
    }
416
417 37489 nfrancisco
//    public void addBundle(URL bundleURL) throws InstallPackageServiceException {
418
//        File bundle = downloadFile(bundleURL, "packages.gvspki");
419
//        addBundle(bundle);
420
//    }
421
422 33982 cordinyana
    public void addBundle(URL bundleURL) throws InstallPackageServiceException {
423 37489 nfrancisco
        String packageFileName = "packages.gvspki";
424
        File bundle;
425
        if (bundleURL.toString().endsWith(packageFileName)) {
426
            bundle = downloadFile(bundleURL, packageFileName);
427
            addBundle(bundle);
428
        } else {
429
430
            manager.setDownloadBaseURL(bundleURL);
431
432
            String urlString = bundleURL.toString();
433
            if (!urlString.endsWith("/")) {
434
                urlString += "/";
435
            }
436
            urlString +=
437
                ("dists/" + manager.getVersion() + "/" + packageFileName);
438
439
            URL completeURL;
440
            try {
441
                completeURL = new URL(urlString);
442
            } catch (MalformedURLException e) {
443
                // TODO Auto-generated catch block
444
                e.printStackTrace();
445
                return;
446
            }
447
448
            bundle = downloadFile(completeURL, packageFileName);
449
            addBundle(bundle);
450
        }
451
452 33982 cordinyana
    }
453
454 34003 cordinyana
    private File downloadFile(URL bundleURL, String defaultFileName)
455 33982 cordinyana
        throws InstallPackageServiceException {
456
        try {
457 34925 nfrancisco
            Download download = new Download();
458
            return download.downloadFile(bundleURL, defaultFileName);
459 33982 cordinyana
        } catch (IOException e) {
460 35948 nfrancisco
            throw new InstallerFileDownloadException(bundleURL, e);
461 33982 cordinyana
        }
462
    }
463 34967 nfrancisco
464 33729 cordinyana
    public void addBundlesFromDirectory(File directory)
465
        throws InstallPackageServiceException {
466
        if (!directory.isDirectory()) {
467 35948 nfrancisco
            throw new InstallerNoDirectoryException(directory);
468 33729 cordinyana
        }
469 35493 nfrancisco
        List<File> files = new ArrayList<File>();
470 35948 nfrancisco
471 35493 nfrancisco
        listRecursively(directory, new FileFilter() {
472 34020 cordinyana
473 34967 nfrancisco
            private String packageExt =
474
                manager.getDefaultPackageFileExtension();
475
            private String packageSetExt =
476
                manager.getDefaultPackageSetFileExtension();
477 34020 cordinyana
478 34005 cordinyana
            public boolean accept(File file) {
479
                String name = file.getName().toLowerCase();
480 35493 nfrancisco
                return file.isDirectory() || name.endsWith(packageExt)
481 34005 cordinyana
                    || name.endsWith(packageSetExt);
482
            }
483 35493 nfrancisco
        }, files);
484
        for (int i = 0; i < files.size(); i++) {
485
            if (files.get(i).isFile()) {
486
                addBundle(files.get(i));
487 33743 cordinyana
            }
488 33729 cordinyana
        }
489
    }
490
491 35948 nfrancisco
    private void listRecursively(File fileOrDir, FileFilter filter,
492
        List<File> files) {
493 35493 nfrancisco
        files.add(fileOrDir);
494 35948 nfrancisco
495 35493 nfrancisco
        if (fileOrDir.isDirectory()) {
496
497
            File[] dirContents = fileOrDir.listFiles(filter);
498
499
            for (File f : dirContents) {
500
                listRecursively(f, filter, files); // Recursively list.
501
            }
502
        } else {
503
            files.add(fileOrDir);
504
        }
505
    }
506
507 33729 cordinyana
    public int getPackageCount() {
508
        if (packageInfos == null) {
509
            return 0;
510
        }
511
        return packageInfos.size();
512
    }
513 35948 nfrancisco
514 33729 cordinyana
    public Manager getManager() {
515
        return this.manager;
516
    }
517
518 34967 nfrancisco
    public void downloadPackage(PackageInfo packageInfo)
519
        throws InstallPackageServiceException {
520
        this.downloadPackage(packageInfo, null);
521
    }
522
523
    public void downloadPackage(PackageInfo packageInfo,
524
        SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
525
        File file = packageInfo.downloadFile(taskStatus);
526
        this.packageInfoFileMap.put(packageInfo, file);
527
    }
528 35189 nfrancisco
529
    public List<String> getDefaultSelectedPackagesIDs() {
530
        return installerProviderServices.getDefaultSelectedPackagesIDs();
531
    }
532 37538 nfrancisco
533
    // TODO: a?adir al interfaz
534
    public List<String> getCategories() {
535
        Set<String> categories = new HashSet<String>();
536
        for (int i = 0; i < getPackageCount(); i++) {
537
            categories.addAll(packageInfos.get(i).getCategories());
538
        }
539
        return new ArrayList<String>(categories);
540
    }
541 35189 nfrancisco
542 32269 jpiera
}