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

History | View | Annotate | Download (16.7 KB)

1
/* 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
import java.io.BufferedInputStream;
31
import java.io.File;
32
import java.io.FileFilter;
33
import java.io.FileInputStream;
34
import java.io.FileNotFoundException;
35
import java.io.IOException;
36
import java.io.InputStream;
37
import java.net.MalformedURLException;
38
import java.net.URL;
39
import java.util.ArrayList;
40
import java.util.Collections;
41
import java.util.HashMap;
42
import java.util.HashSet;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.Set;
46

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

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

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

    
71
public class DefaultInstallPackageService extends Thread implements
72
                InstallPackageService {
73

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

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

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

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

    
99
        public class InstallerApplicationDirectoryNotFoundException extends
100
                        InstallPackageServiceException {
101

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

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

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

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

    
113
        }
114

    
115
        public class InstallerNoDirectoryException extends
116
                        InstallPackageServiceException {
117

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

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

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

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

    
129
        }
130

    
131
        public class InstallerFileNotFoundException extends
132
                        InstallPackageServiceException {
133

    
134
                private static final long serialVersionUID = 556517830330132149L;
135

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

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

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

    
145
        }
146

    
147
        public class InstallerBundleNotFoundException extends
148
                        InstallPackageServiceException {
149

    
150
                private static final long serialVersionUID = 5065410511582625301L;
151

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

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

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

    
162
        }
163

    
164
        public class InstallerIOException extends InstallPackageServiceException {
165

    
166
                private static final long serialVersionUID = 3153613550157712363L;
167

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

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

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

    
177
        }
178

    
179
        public class InstallerFileDownloadException extends
180
                        InstallPackageServiceException {
181

    
182
                private static final long serialVersionUID = 8640183295766490512L;
183

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

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

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

    
193
        }
194

    
195
        public class InstallerPackageNotFoundException extends
196
                        InstallPackageServiceException {
197

    
198
                private static final long serialVersionUID = 1726608498886963868L;
199

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

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

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

    
208
        }
209

    
210
        public class InstallerNoPackageException extends
211
                        InstallPackageServiceException {
212

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

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

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

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

    
223
        }
224

    
225
        public class InstallerProviderCreationException extends
226
                        InstallPackageServiceException {
227

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

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

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

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

    
238
        }
239

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

    
250
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
251

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

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

    
265
                        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.info("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 = installerProviderServices.searchPackage(bis,
277
                                                zipEntriesMap.get(packageInfo));
278
                        }
279

    
280
                        try {
281
                                installerExecutionProvider.install(applicationDirectory,
282
                                                packageStream, packageInfo);
283
                        } catch (InstallPackageServiceException e) {
284

    
285
                                packageStream.close();
286
                                if (bis != packageStream) {
287
                                        bis.close();
288
                                }
289
                                fis.close();
290

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

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

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

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

    
324
        }
325

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

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

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

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

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

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

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

    
370
                int packageInfoCount = packageInfos.size();
371

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

    
401
                for (int i = packageInfoCount; i < packageInfos.size(); i++) {
402
                        packageInfoFileMap.put(packageInfos.get(i), bundle);
403
                }
404
        }
405

    
406
        private boolean isPackageSet(File file) {
407
                return file.getName().endsWith(
408
                                manager.getDefaultPackageSetFileExtension());
409
        }
410

    
411
        private boolean isPackage(File file) {
412
                return file.getName()
413
                                .endsWith(manager.getDefaultPackageFileExtension());
414
        }
415

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

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

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

    
448
        }
449

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

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

    
467
                listRecursively(directory, new FileFilter() {
468

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

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

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

    
491
                if (fileOrDir.isDirectory()) {
492

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

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

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

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

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

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

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

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

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

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

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

    
582
}