Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / execution / DefaultInstallPackageService.java @ 40560

History | View | Annotate | Download (16.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2010 {Prodevelop}   {Task}
27
 */
28

    
29
package org.gvsig.installer.lib.impl.execution;
30

    
31
import java.io.BufferedInputStream;
32
import java.io.File;
33
import java.io.FileFilter;
34
import java.io.FileInputStream;
35
import java.io.FileNotFoundException;
36
import java.io.IOException;
37
import java.io.InputStream;
38
import java.net.MalformedURLException;
39
import java.net.URL;
40
import java.util.ArrayList;
41
import java.util.Collections;
42
import java.util.HashMap;
43
import java.util.HashSet;
44
import java.util.List;
45
import java.util.Map;
46
import java.util.Set;
47

    
48
import org.slf4j.Logger;
49
import org.slf4j.LoggerFactory;
50

    
51
import org.gvsig.installer.lib.api.InstallerManager;
52
import org.gvsig.installer.lib.api.PackageInfo;
53
import org.gvsig.installer.lib.api.Version;
54
import org.gvsig.installer.lib.api.creation.MakePluginPackageServiceException;
55
import org.gvsig.installer.lib.api.execution.InstallPackageService;
56
import org.gvsig.installer.lib.api.execution.InstallPackageServiceException;
57
import org.gvsig.installer.lib.impl.DefaultInstallerManager;
58
import org.gvsig.installer.lib.impl.utils.Download;
59
import org.gvsig.installer.lib.spi.InstallPackageProviderServices;
60
import org.gvsig.installer.lib.spi.InstallerProviderLocator;
61
import org.gvsig.installer.lib.spi.InstallerProviderManager;
62
import org.gvsig.installer.lib.spi.execution.InstallPackageProvider;
63
import org.gvsig.tools.exception.BaseException;
64
import org.gvsig.tools.service.Manager;
65
import org.gvsig.tools.service.ServiceException;
66
import org.gvsig.tools.task.SimpleTaskStatus;
67

    
68
/**
69
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodr&aacute;</a>
70
 */
71

    
72
public class DefaultInstallPackageService extends Thread implements
73
                InstallPackageService {
74

    
75
        private static final Logger LOG = LoggerFactory
76
                        .getLogger(DefaultInstallPackageService.class);
77
        
78
        private static final String PACKAGE_FILE_NAME = "packages.gvspki";
79

    
80
        private Map<PackageInfo, File> packageInfoFileMap = null;
81
        private Map<PackageInfo, String> zipEntriesMap = null;
82
        private List<PackageInfo> packageInfos = null;
83
        private InstallerManager manager;
84
        private InstallPackageProviderServices installerProviderServices = null;
85

    
86
        public DefaultInstallPackageService(DefaultInstallerManager manager) {
87
                super();
88
                this.manager = manager;
89
                this.reset();
90
        }
91

    
92
        public void reset() {
93
                packageInfoFileMap = new HashMap<PackageInfo, File>();
94
                packageInfos = new ArrayList<PackageInfo>();
95
                zipEntriesMap = new HashMap<PackageInfo, String>();
96
                installerProviderServices = InstallerProviderLocator
97
                                .getProviderManager().createInstallerProviderServices();
98
        }
99

    
100
        public class InstallerApplicationDirectoryNotFoundException extends
101
                        InstallPackageServiceException {
102

    
103
                private static final long serialVersionUID = -1130408094135962456L;
104

    
105
                private static final String message = "Aplication directory '%(directory)s' not found";
106

    
107
                private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
108

    
109
                public InstallerApplicationDirectoryNotFoundException(File file) {
110
                        super(message, KEY, serialVersionUID);
111
                        setValue("directory", file.toString());
112
                }
113

    
114
        }
115

    
116
        public class InstallerNoDirectoryException extends
117
                        InstallPackageServiceException {
118

    
119
                private static final long serialVersionUID = -8685263049644983769L;
120

    
121
                private static final String message = "'%(directory)s' is not a directory";
122

    
123
                private static final String KEY = "_XdirectoryX_is_not_a_directory";
124

    
125
                public InstallerNoDirectoryException(File file) {
126
                        super(message, KEY, serialVersionUID);
127
                        setValue("directory", file.toString());
128
                }
129

    
130
        }
131

    
132
        public class InstallerFileNotFoundException extends
133
                        InstallPackageServiceException {
134

    
135
                private static final long serialVersionUID = 556517830330132149L;
136

    
137
                private static final String message = "File '%(file)s' not found";
138

    
139
                private static final String KEY = "_file_XfileX_not_found";
140

    
141
                public InstallerFileNotFoundException(File file) {
142
                        super(message, KEY, serialVersionUID);
143
                        setValue("file", file.toString());
144
                }
145

    
146
        }
147

    
148
        public class InstallerBundleNotFoundException extends
149
                        InstallPackageServiceException {
150

    
151
                private static final long serialVersionUID = 5065410511582625301L;
152

    
153
                private static final String message = "File '%(file)s' not found";
154

    
155
                private static final String KEY = "_file_XfileX_not_found";
156

    
157
                public InstallerBundleNotFoundException(File file,
158
                                FileNotFoundException e) {
159
                        super(message, e, KEY, serialVersionUID);
160
                        setValue("file", file.toString());
161
                }
162

    
163
        }
164

    
165
        public class InstallerIOException extends InstallPackageServiceException {
166

    
167
                private static final long serialVersionUID = 3153613550157712363L;
168

    
169
                private static final String message = "IO error installing the file '%(file)s'";
170

    
171
                private static final String KEY = "_IO_error installing_file_XfileX_";
172

    
173
                public InstallerIOException(File file, IOException e) {
174
                        super(message, e, KEY, serialVersionUID);
175
                        setValue("file", file.toString());
176
                }
177

    
178
        }
179

    
180
        public class InstallerFileDownloadException extends
181
                        InstallPackageServiceException {
182

    
183
                private static final long serialVersionUID = 8640183295766490512L;
184

    
185
                private static final String message = "File '%(url)s' download error";
186

    
187
                private static final String KEY = "_File_XurlX_download_error";
188

    
189
                public InstallerFileDownloadException(URL url, IOException e) {
190
                        super(message, e, KEY, serialVersionUID);
191
                        setValue("url", url.toString());
192
                }
193

    
194
        }
195

    
196
        public class InstallerPackageNotFoundException extends
197
                        InstallPackageServiceException {
198

    
199
                private static final long serialVersionUID = 1726608498886963868L;
200

    
201
                private static final String message = "Package not found";
202

    
203
                private static final String KEY = "_package_not_found";
204

    
205
                public InstallerPackageNotFoundException() {
206
                        super(message, KEY, serialVersionUID);
207
                }
208

    
209
        }
210

    
211
        public class InstallerNoPackageException extends
212
                        InstallPackageServiceException {
213

    
214
                private static final long serialVersionUID = -2292735515704746966L;
215

    
216
                private static final String message = "Package does not exist";
217

    
218
                private static final String KEY = "_package__does_not_exist";
219

    
220
                public InstallerNoPackageException() {
221
                        super(message, KEY, serialVersionUID);
222
                }
223

    
224
        }
225

    
226
        public class InstallerProviderCreationException extends
227
                        InstallPackageServiceException {
228

    
229
                private static final long serialVersionUID = -7985786807492393584L;
230

    
231
                private static final String message = "Error creating the provider";
232

    
233
                private static final String KEY = "_Error_creating_the_provider";
234

    
235
                public InstallerProviderCreationException(ServiceException e) {
236
                        super(message, e, KEY, serialVersionUID);
237
                }
238

    
239
        }
240

    
241
        public void installPackage(File applicationDirectory,
242
                        PackageInfo packageInfo) throws InstallPackageServiceException {
243
                if (!applicationDirectory.exists()) {
244
                        throw new InstallerApplicationDirectoryNotFoundException(
245
                                        applicationDirectory);
246
                }
247
                if (!packageInfoFileMap.containsKey(packageInfo)) {
248
                        throw new InstallerPackageNotFoundException();
249
                }
250

    
251
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
252

    
253
                // Get the package or package set file
254
                File file = packageInfoFileMap.get(packageInfo);
255
                if (file == null) {
256
                        if (packageInfo.getDownloadURL() == null) {
257
                                throw new InstallerPackageNotFoundException();
258
                        }
259
                        this.downloadPackage(packageInfo);
260
                        file = packageInfoFileMap.get(packageInfo);
261
                }
262

    
263
                // Open and install the package or package set file
264
                try {
265

    
266
                        InputStream packageStream;
267
                        InputStream fis = new FileInputStream(file);
268
                        InputStream bis = new BufferedInputStream(fis);
269
                        if (isPackage(file)) {
270
                                packageStream = bis;
271
                        } else {
272
                                if (!isPackageSet(file)) {
273
                                        LOG.info("Trying to install a package file ({0}) "
274
                                                        + "without a known file extension. Will try "
275
                                                        + "to install it as a package set", file);
276
                                }
277
                                packageStream = installerProviderServices.searchPackage(bis,
278
                                                zipEntriesMap.get(packageInfo));
279
                        }
280

    
281
                        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.info("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 = installerProviderServices.searchPackage(
307
                                                        bis, zipEntriesMap.get(packageInfo));
308
                                }
309
                                installerExecutionProvider.installLater(applicationDirectory,
310
                                                packageStream, packageInfo);
311
                        }
312

    
313
                        packageStream.close();
314
                        if (bis != packageStream) {
315
                                bis.close();
316
                        }
317
                        fis.close();
318

    
319
                } catch (FileNotFoundException e) {
320
                        throw new InstallerFileNotFoundException(file);
321
                } catch (IOException e) {
322
                        throw new InstallerIOException(file, e);
323
                }
324

    
325
        }
326

    
327
        public void installPackage(File applicationDirectory, String packageCode)
328
                        throws InstallPackageServiceException {
329
                PackageInfo packageInfo = getPackageInfo(packageCode);
330
                if (packageInfo == null) {
331
                        throw new InstallerNoPackageException();
332
                }
333
                installPackage(applicationDirectory, packageInfo);
334
        }
335

    
336
        private InstallPackageProvider createProvider(PackageInfo packageInfo)
337
                        throws InstallPackageServiceException {
338
                InstallerProviderManager installerProviderManager = (InstallerProviderManager) ((DefaultInstallerManager) manager)
339
                                .getProviderManager();
340

    
341
                try {
342
                        return installerProviderManager.createExecutionProvider(packageInfo
343
                                        .getType());
344
                } catch (ServiceException e) {
345
                        throw new InstallerProviderCreationException(e);
346
                }
347
        }
348

    
349
        public PackageInfo getPackageInfo(int index) {
350
                if (index >= packageInfos.size()) {
351
                        return null;
352
                }
353
                return packageInfos.get(index);
354
        }
355

    
356
        public PackageInfo getPackageInfo(String packageCode) {
357
                for (int i = 0; i < getPackageCount(); i++) {
358
                        if (packageInfos.get(i).getCode().equals(packageCode)) {
359
                                return packageInfos.get(i);
360
                        }
361
                }
362
                return null;
363
        }
364

    
365
        public void addBundle(File bundle) throws InstallPackageServiceException {
366

    
367
                if (!bundle.exists()) {
368
                        throw new InstallPackageServiceException();
369
                }
370

    
371
                int packageInfoCount = packageInfos.size();
372

    
373
                FileInputStream fis;
374
                try {
375
                        fis = new FileInputStream(bundle);
376
                } catch (FileNotFoundException e) {
377
                        throw new InstallerBundleNotFoundException(bundle, e);
378
                }
379
                BufferedInputStream bis = new BufferedInputStream(fis);
380
                if (isPackage(bundle)) {
381
                        installerProviderServices.readPackageInfo(bis, packageInfos,
382
                                        zipEntriesMap, bundle.getName());
383
                } else {
384
                        if (!isPackageSet(bundle)) {
385
                                LOG
386
                                                .info(
387
                                                                "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.info("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
        }
406

    
407
        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
        public void addBundle(URL bundleURL) throws InstallPackageServiceException {
418
                File bundle;
419
                String urlString = bundleURL.toString(); 
420
                if (urlString.endsWith(InstallerManager.PACKAGE_EXTENSION) || urlString.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION)) {
421
            manager.setDownloadBaseURL(bundleURL);
422
                        bundle = downloadFile(bundleURL, PACKAGE_FILE_NAME);
423
                        addBundle(bundle);
424
                } else {
425
                        if (!urlString.endsWith("/")) {
426
                                urlString += "/";
427
                        }
428
                        
429
                        Version version = manager.getVersionEx(); 
430
                        urlString += ("dists/"
431
                        + version.getMayor() + "." + version.getMinor() + "."
432
                        + version.getRevision() + "/" + PACKAGE_FILE_NAME);
433
                        
434

    
435
                        URL completeURL;
436
                        try {
437
                                completeURL = new URL(urlString);
438
                        } catch (MalformedURLException e) {
439
                                // TODO Auto-generated catch block
440
                                e.printStackTrace();
441
                                return;
442
                        }
443

    
444
            manager.setDownloadBaseURL(completeURL);
445
                        bundle = downloadFile(completeURL, PACKAGE_FILE_NAME);
446
                        addBundle(bundle);
447
                }
448

    
449
        }
450

    
451
        private File downloadFile(URL bundleURL, String defaultFileName)
452
                        throws InstallPackageServiceException {
453
                try {
454
                        Download download = new Download();
455
                        return download.downloadFile(bundleURL, defaultFileName);
456
                } catch (IOException e) {
457
                        throw new InstallerFileDownloadException(bundleURL, e);
458
                }
459
        }
460

    
461
        public void addBundlesFromDirectory(File directory)
462
                        throws InstallPackageServiceException {
463
                if (!directory.isDirectory()) {
464
                        throw new InstallerNoDirectoryException(directory);
465
                }
466
                List<File> files = new ArrayList<File>();
467

    
468
                listRecursively(directory, new FileFilter() {
469

    
470
                        private String packageExt = manager
471
                                        .getDefaultPackageFileExtension();
472
                        private String packageSetExt = manager
473
                                        .getDefaultPackageSetFileExtension();
474

    
475
                        public boolean accept(File file) {
476
                                String name = file.getName().toLowerCase();
477
                                return file.isDirectory() || name.endsWith(packageExt)
478
                                                || name.endsWith(packageSetExt);
479
                        }
480
                }, files);
481
                for (int i = 0; i < files.size(); i++) {
482
                        if (files.get(i).isFile()) {
483
                                addBundle(files.get(i));
484
                        }
485
                }
486
        }
487

    
488
        private void listRecursively(File fileOrDir, FileFilter filter,
489
                        List<File> files) {
490
                files.add(fileOrDir);
491

    
492
                if (fileOrDir.isDirectory()) {
493

    
494
                        File[] dirContents = fileOrDir.listFiles(filter);
495

    
496
                        for (File f : dirContents) {
497
                                listRecursively(f, filter, files); // Recursively list.
498
                        }
499
                } else {
500
                        files.add(fileOrDir);
501
                }
502
        }
503

    
504
        public int getPackageCount() {
505
                if (packageInfos == null) {
506
                        return 0;
507
                }
508
                return packageInfos.size();
509
        }
510

    
511
        public Manager getManager() {
512
                return this.manager;
513
        }
514

    
515
        public void downloadPackage(PackageInfo packageInfo)
516
                        throws InstallPackageServiceException {
517
                this.downloadPackage(packageInfo, null);
518
        }
519

    
520
        public void downloadPackage(PackageInfo packageInfo,
521
                        SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
522
            
523
                File file = null;
524
                
525
                try {
526
            file = packageInfo.downloadFile(taskStatus);
527
        } catch (BaseException e) {
528
            throw new InstallPackageServiceException(e);
529
        }
530
                this.packageInfoFileMap.put(packageInfo, file);
531
        }
532

    
533
        public List<String> getDefaultSelectedPackagesIDs() {
534
                return installerProviderServices.getDefaultSelectedPackagesIDs();
535
        }
536

    
537
        public List<String> getCategories() {
538
                Set<String> categories = new HashSet<String>();
539

    
540
                for (int i = 0; i < packageInfos.size(); i++) {
541
                        PackageInfo pkginfo = packageInfos.get(i);
542
                        List<String> pkgcategories = pkginfo.getCategories();
543
                        categories.addAll(pkgcategories);
544
                }
545
                try {
546
                        PackageInfo[] pkgs = manager.getInstalledPackages();
547
                        for (int i = 0; i < pkgs.length; i++) {
548
                                PackageInfo pkginfo = pkgs[i];
549
                                List<String> pkgcategories = pkginfo.getCategories();
550
                                categories.addAll(pkgcategories);
551
                        }
552
                        
553
                } catch (MakePluginPackageServiceException e) {
554
                        // Ignore exceptions
555
                }
556
                ArrayList<String> l = new ArrayList<String>(categories);
557
                Collections.sort(l);
558
                return l;
559
        }
560

    
561
        public List<String> getTypes() {
562
                Set<String> types = new HashSet<String>();
563

    
564
                for (int i = 0; i < packageInfos.size(); i++) {
565
                        PackageInfo pkginfo = packageInfos.get(i);
566
                        types.add(pkginfo.getType());
567
                }
568
                try {
569
                        PackageInfo[] pkgs = manager.getInstalledPackages();
570
                        for (int i = 0; i < pkgs.length; i++) {
571
                                PackageInfo pkginfo = pkgs[i];
572
                                types.add(pkginfo.getType());
573
                        }
574
                        
575
                } catch (MakePluginPackageServiceException e) {
576
                        // Ignore exceptions
577
                }
578
                ArrayList<String> l = new ArrayList<String>(types);
579
                Collections.sort(l);
580
                return l;
581
        }
582

    
583
}