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 @ 40936

History | View | Annotate | Download (17 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
                        LOG.warn("Can install package '"+packageInfo.getCode()+"', application folder '"+applicationDirectory.toString()+"' does not exits.");
245
                        throw new InstallerApplicationDirectoryNotFoundException(
246
                                        applicationDirectory);
247
                }
248
                if (!packageInfoFileMap.containsKey(packageInfo)) {
249
                        LOG.warn("Can install package '"+packageInfo.getCode()+"', package not found.");
250
                        throw new InstallerPackageNotFoundException();
251
                }
252

    
253
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
254

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

    
265
                // Open and install the package or package set file
266
                try {
267

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

    
283
                        try {
284
                                installerExecutionProvider.install(applicationDirectory,
285
                                                packageStream, packageInfo);
286
                        } catch (InstallPackageServiceException e) {
287

    
288
                                packageStream.close();
289
                                if (bis != packageStream) {
290
                                        bis.close();
291
                                }
292
                                fis.close();
293

    
294
                                // if fails the installation, zip files need to be reopen
295
                                // the package will be installed into the update folder for
296
                                // installation after a gvSIG restart
297

    
298
                                fis = new FileInputStream(file);
299
                                bis = new BufferedInputStream(fis);
300
                                if (isPackage(file)) {
301
                                        packageStream = bis;
302
                                } else {
303
                                        if (!isPackageSet(file)) {
304
                                                LOG.info("Trying to install a package file ({0}) "
305
                                                                + "without a known file extension. Will try "
306
                                                                + "to install it as a package set", file);
307
                                        }
308
                                        packageStream = installerProviderServices.searchPackage(
309
                                                        bis, zipEntriesMap.get(packageInfo));
310
                                }
311
                                installerExecutionProvider.installLater(applicationDirectory,
312
                                                packageStream, packageInfo);
313
                        }
314

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

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

    
327
        }
328

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

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

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

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

    
358
        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

    
367
        public void addBundle(File bundle) throws InstallPackageServiceException {
368

    
369
                if (!bundle.exists()) {
370
                        throw new InstallPackageServiceException();
371
                }
372

    
373
                int packageInfoCount = packageInfos.size();
374

    
375
                FileInputStream fis;
376
                try {
377
                        fis = new FileInputStream(bundle);
378
                } catch (FileNotFoundException e) {
379
                        throw new InstallerBundleNotFoundException(bundle, e);
380
                }
381
                BufferedInputStream bis = new BufferedInputStream(fis);
382
                if (isPackage(bundle)) {
383
                        installerProviderServices.readPackageInfo(bis, packageInfos,
384
                                        zipEntriesMap, bundle.getName());
385
                } else {
386
                        if (!isPackageSet(bundle)) {
387
                                LOG
388
                                                .info(
389
                                                                "Trying to add a package file ({0}) without a known "
390
                                                                                + "file extension. Will try to add it as a package set",
391
                                                                bundle);
392
                        }
393
                        installerProviderServices.readPackageSetInfo(fis, packageInfos,
394
                                        zipEntriesMap);
395
                }
396
                try {
397
                        bis.close();
398
                        fis.close();
399
                } catch (IOException e) {
400
                        LOG.info("Error closing the input streams of the package file: "
401
                                        + bundle, e);
402
                }
403

    
404
                for (int i = packageInfoCount; i < packageInfos.size(); i++) {
405
                        packageInfoFileMap.put(packageInfos.get(i), bundle);
406
                }
407
        }
408

    
409
        private boolean isPackageSet(File file) {
410
                return file.getName().endsWith(
411
                                manager.getDefaultPackageSetFileExtension());
412
        }
413

    
414
        private boolean isPackage(File file) {
415
                return file.getName()
416
                                .endsWith(manager.getDefaultPackageFileExtension());
417
        }
418

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

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

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

    
451
        }
452

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

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

    
470
                listRecursively(directory, new FileFilter() {
471

    
472
                        private String packageExt = manager
473
                                        .getDefaultPackageFileExtension();
474
                        private String packageSetExt = manager
475
                                        .getDefaultPackageSetFileExtension();
476

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

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

    
494
                if (fileOrDir.isDirectory()) {
495

    
496
                        File[] dirContents = fileOrDir.listFiles(filter);
497

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

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

    
513
        public Manager getManager() {
514
                return this.manager;
515
        }
516

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

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

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

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

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

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

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

    
585
}