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

History | View | Annotate | Download (16.4 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.creation.MakePluginPackageServiceException;
53
import org.gvsig.installer.lib.api.execution.InstallPackageService;
54
import org.gvsig.installer.lib.api.execution.InstallPackageServiceException;
55
import org.gvsig.installer.lib.impl.DefaultInstallerManager;
56
import org.gvsig.installer.lib.impl.utils.Download;
57
import org.gvsig.installer.lib.spi.InstallPackageProviderServices;
58
import org.gvsig.installer.lib.spi.InstallerProviderLocator;
59
import org.gvsig.installer.lib.spi.InstallerProviderManager;
60
import org.gvsig.installer.lib.spi.execution.InstallPackageProvider;
61
import org.gvsig.tools.service.Manager;
62
import org.gvsig.tools.service.ServiceException;
63
import org.gvsig.tools.task.SimpleTaskStatus;
64

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

    
69
public class DefaultInstallPackageService extends Thread implements
70
                InstallPackageService {
71

    
72
        private static final Logger LOG = LoggerFactory
73
                        .getLogger(DefaultInstallPackageService.class);
74

    
75
        private Map<PackageInfo, File> packageInfoFileMap = null;
76
        private Map<PackageInfo, String> zipEntriesMap = null;
77
        private List<PackageInfo> packageInfos = null;
78
        private InstallerManager manager;
79
        private InstallPackageProviderServices installerProviderServices = null;
80

    
81
        public DefaultInstallPackageService(DefaultInstallerManager manager) {
82
                super();
83
                this.manager = manager;
84
                this.reset();
85
        }
86

    
87
        public void reset() {
88
                packageInfoFileMap = new HashMap<PackageInfo, File>();
89
                packageInfos = new ArrayList<PackageInfo>();
90
                zipEntriesMap = new HashMap<PackageInfo, String>();
91
                installerProviderServices = InstallerProviderLocator
92
                                .getProviderManager().createInstallerProviderServices();
93
        }
94

    
95
        public class InstallerApplicationDirectoryNotFoundException extends
96
                        InstallPackageServiceException {
97

    
98
                private static final long serialVersionUID = -1130408094135962456L;
99

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

    
102
                private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
103

    
104
                public InstallerApplicationDirectoryNotFoundException(File file) {
105
                        super(message, KEY, serialVersionUID);
106
                        setValue("directory", file.toString());
107
                }
108

    
109
        }
110

    
111
        public class InstallerNoDirectoryException extends
112
                        InstallPackageServiceException {
113

    
114
                private static final long serialVersionUID = -8685263049644983769L;
115

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

    
118
                private static final String KEY = "_XdirectoryX_is_not_a_directory";
119

    
120
                public InstallerNoDirectoryException(File file) {
121
                        super(message, KEY, serialVersionUID);
122
                        setValue("directory", file.toString());
123
                }
124

    
125
        }
126

    
127
        public class InstallerFileNotFoundException extends
128
                        InstallPackageServiceException {
129

    
130
                private static final long serialVersionUID = 556517830330132149L;
131

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

    
134
                private static final String KEY = "_file_XfileX_not_found";
135

    
136
                public InstallerFileNotFoundException(File file) {
137
                        super(message, KEY, serialVersionUID);
138
                        setValue("file", file.toString());
139
                }
140

    
141
        }
142

    
143
        public class InstallerBundleNotFoundException extends
144
                        InstallPackageServiceException {
145

    
146
                private static final long serialVersionUID = 5065410511582625301L;
147

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

    
150
                private static final String KEY = "_file_XfileX_not_found";
151

    
152
                public InstallerBundleNotFoundException(File file,
153
                                FileNotFoundException e) {
154
                        super(message, e, KEY, serialVersionUID);
155
                        setValue("file", file.toString());
156
                }
157

    
158
        }
159

    
160
        public class InstallerIOException extends InstallPackageServiceException {
161

    
162
                private static final long serialVersionUID = 3153613550157712363L;
163

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

    
166
                private static final String KEY = "_IO_error installing_file_XfileX_";
167

    
168
                public InstallerIOException(File file, IOException e) {
169
                        super(message, e, KEY, serialVersionUID);
170
                        setValue("file", file.toString());
171
                }
172

    
173
        }
174

    
175
        public class InstallerFileDownloadException extends
176
                        InstallPackageServiceException {
177

    
178
                private static final long serialVersionUID = 8640183295766490512L;
179

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

    
182
                private static final String KEY = "_File_XurlX_download_error";
183

    
184
                public InstallerFileDownloadException(URL url, IOException e) {
185
                        super(message, e, KEY, serialVersionUID);
186
                        setValue("url", url.toString());
187
                }
188

    
189
        }
190

    
191
        public class InstallerPackageNotFoundException extends
192
                        InstallPackageServiceException {
193

    
194
                private static final long serialVersionUID = 1726608498886963868L;
195

    
196
                private static final String message = "Package not found";
197

    
198
                private static final String KEY = "_package_not_found";
199

    
200
                public InstallerPackageNotFoundException() {
201
                        super(message, KEY, serialVersionUID);
202
                }
203

    
204
        }
205

    
206
        public class InstallerNoPackageException extends
207
                        InstallPackageServiceException {
208

    
209
                private static final long serialVersionUID = -2292735515704746966L;
210

    
211
                private static final String message = "Package does not exist";
212

    
213
                private static final String KEY = "_package__does_not_exist";
214

    
215
                public InstallerNoPackageException() {
216
                        super(message, KEY, serialVersionUID);
217
                }
218

    
219
        }
220

    
221
        public class InstallerProviderCreationException extends
222
                        InstallPackageServiceException {
223

    
224
                private static final long serialVersionUID = -7985786807492393584L;
225

    
226
                private static final String message = "Error creating the provider";
227

    
228
                private static final String KEY = "_Error_creating_the_provider";
229

    
230
                public InstallerProviderCreationException(ServiceException e) {
231
                        super(message, e, KEY, serialVersionUID);
232
                }
233

    
234
        }
235

    
236
        public void installPackage(File applicationDirectory,
237
                        PackageInfo packageInfo) throws InstallPackageServiceException {
238
                if (!applicationDirectory.exists()) {
239
                        throw new InstallerApplicationDirectoryNotFoundException(
240
                                        applicationDirectory);
241
                }
242
                if (!packageInfoFileMap.containsKey(packageInfo)) {
243
                        throw new InstallerPackageNotFoundException();
244
                }
245

    
246
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
247

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

    
258
                // Open and install the package or package set file
259
                try {
260

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

    
276
                        try {
277
                                installerExecutionProvider.install(applicationDirectory,
278
                                                packageStream, packageInfo);
279
                        } catch (InstallPackageServiceException e) {
280

    
281
                                packageStream.close();
282
                                if (bis != packageStream) {
283
                                        bis.close();
284
                                }
285
                                fis.close();
286

    
287
                                // if fails the installation, zip files need to be reopen
288
                                // the package will be installed into the update folder for
289
                                // installation after a gvSIG restart
290

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

    
308
                        packageStream.close();
309
                        if (bis != packageStream) {
310
                                bis.close();
311
                        }
312
                        fis.close();
313

    
314
                } catch (FileNotFoundException e) {
315
                        throw new InstallerFileNotFoundException(file);
316
                } catch (IOException e) {
317
                        throw new InstallerIOException(file, e);
318
                }
319

    
320
        }
321

    
322
        public void installPackage(File applicationDirectory, String packageCode)
323
                        throws InstallPackageServiceException {
324
                PackageInfo packageInfo = getPackageInfo(packageCode);
325
                if (packageInfo == null) {
326
                        throw new InstallerNoPackageException();
327
                }
328
                installPackage(applicationDirectory, packageInfo);
329
        }
330

    
331
        private InstallPackageProvider createProvider(PackageInfo packageInfo)
332
                        throws InstallPackageServiceException {
333
                InstallerProviderManager installerProviderManager = (InstallerProviderManager) ((DefaultInstallerManager) manager)
334
                                .getProviderManager();
335

    
336
                try {
337
                        return installerProviderManager.createExecutionProvider(packageInfo
338
                                        .getType());
339
                } catch (ServiceException e) {
340
                        throw new InstallerProviderCreationException(e);
341
                }
342
        }
343

    
344
        public PackageInfo getPackageInfo(int index) {
345
                if (index >= packageInfos.size()) {
346
                        return null;
347
                }
348
                return packageInfos.get(index);
349
        }
350

    
351
        public PackageInfo getPackageInfo(String packageCode) {
352
                for (int i = 0; i < getPackageCount(); i++) {
353
                        if (packageInfos.get(i).getCode().equals(packageCode)) {
354
                                return packageInfos.get(i);
355
                        }
356
                }
357
                return null;
358
        }
359

    
360
        public void addBundle(File bundle) throws InstallPackageServiceException {
361

    
362
                if (!bundle.exists()) {
363
                        throw new InstallPackageServiceException();
364
                }
365

    
366
                int packageInfoCount = packageInfos.size();
367

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

    
397
                for (int i = packageInfoCount; i < packageInfos.size(); i++) {
398
                        packageInfoFileMap.put(packageInfos.get(i), bundle);
399
                }
400
        }
401

    
402
        private boolean isPackageSet(File file) {
403
                return file.getName().endsWith(
404
                                manager.getDefaultPackageSetFileExtension());
405
        }
406

    
407
        private boolean isPackage(File file) {
408
                return file.getName()
409
                                .endsWith(manager.getDefaultPackageFileExtension());
410
        }
411

    
412
        // public void addBundle(URL bundleURL) throws
413
        // InstallPackageServiceException {
414
        // File bundle = downloadFile(bundleURL, "packages.gvspki");
415
        // addBundle(bundle);
416
        // }
417

    
418
        public void addBundle(URL bundleURL) throws InstallPackageServiceException {
419
                String packageFileName = "packages.gvspki";
420
                File bundle;
421
                if (bundleURL.toString().endsWith(packageFileName)) {
422
                        bundle = downloadFile(bundleURL, packageFileName);
423
                        addBundle(bundle);
424
                } else {
425

    
426
                        manager.setDownloadBaseURL(bundleURL);
427

    
428
                        String urlString = bundleURL.toString();
429
                        if (!urlString.endsWith("/")) {
430
                                urlString += "/";
431
                        }
432
                        urlString += ("dists/" + manager.getVersion() + "/" + packageFileName);
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
                        bundle = downloadFile(completeURL, packageFileName);
444
                        addBundle(bundle);
445
                }
446

    
447
        }
448

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

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

    
466
                listRecursively(directory, new FileFilter() {
467

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

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

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

    
490
                if (fileOrDir.isDirectory()) {
491

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

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

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

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

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

    
518
        public void downloadPackage(PackageInfo packageInfo,
519
                        SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
520
                File file = packageInfo.downloadFile(taskStatus);
521
                this.packageInfoFileMap.put(packageInfo, file);
522
        }
523

    
524
        public List<String> getDefaultSelectedPackagesIDs() {
525
                return installerProviderServices.getDefaultSelectedPackagesIDs();
526
        }
527

    
528
        public List<String> getCategories() {
529
                Set<String> categories = new HashSet<String>();
530

    
531
                for (int i = 0; i < packageInfos.size(); i++) {
532
                        PackageInfo pkginfo = packageInfos.get(i);
533
                        List<String> pkgcategories = pkginfo.getCategories();
534
                        categories.addAll(pkgcategories);
535
                }
536
                try {
537
                        PackageInfo[] pkgs = manager.getInstalledPackages();
538
                        for (int i = 0; i < pkgs.length; i++) {
539
                                PackageInfo pkginfo = pkgs[i];
540
                                List<String> pkgcategories = pkginfo.getCategories();
541
                                categories.addAll(pkgcategories);
542
                        }
543
                        
544
                } catch (MakePluginPackageServiceException e) {
545
                        // Ignore exceptions
546
                }
547
                ArrayList<String> l = new ArrayList<String>(categories);
548
                Collections.sort(l);
549
                return l;
550
        }
551

    
552
        public List<String> getTypes() {
553
                Set<String> types = new HashSet<String>();
554

    
555
                for (int i = 0; i < packageInfos.size(); i++) {
556
                        PackageInfo pkginfo = packageInfos.get(i);
557
                        types.add(pkginfo.getType());
558
                }
559
                try {
560
                        PackageInfo[] pkgs = manager.getInstalledPackages();
561
                        for (int i = 0; i < pkgs.length; i++) {
562
                                PackageInfo pkginfo = pkgs[i];
563
                                types.add(pkginfo.getType());
564
                        }
565
                        
566
                } catch (MakePluginPackageServiceException e) {
567
                        // Ignore exceptions
568
                }
569
                ArrayList<String> l = new ArrayList<String>(types);
570
                Collections.sort(l);
571
                return l;
572
        }
573

    
574
}