Statistics
| Revision:

root / 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 @ 38190

History | View | Annotate | Download (16.3 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 static final String PACKAGE_FILE_NAME = "packages.gvspki";
76

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

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

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

    
97
        public class InstallerApplicationDirectoryNotFoundException extends
98
                        InstallPackageServiceException {
99

    
100
                private static final long serialVersionUID = -1130408094135962456L;
101

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

    
104
                private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
105

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

    
111
        }
112

    
113
        public class InstallerNoDirectoryException extends
114
                        InstallPackageServiceException {
115

    
116
                private static final long serialVersionUID = -8685263049644983769L;
117

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

    
120
                private static final String KEY = "_XdirectoryX_is_not_a_directory";
121

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

    
127
        }
128

    
129
        public class InstallerFileNotFoundException extends
130
                        InstallPackageServiceException {
131

    
132
                private static final long serialVersionUID = 556517830330132149L;
133

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

    
136
                private static final String KEY = "_file_XfileX_not_found";
137

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

    
143
        }
144

    
145
        public class InstallerBundleNotFoundException extends
146
                        InstallPackageServiceException {
147

    
148
                private static final long serialVersionUID = 5065410511582625301L;
149

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

    
152
                private static final String KEY = "_file_XfileX_not_found";
153

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

    
160
        }
161

    
162
        public class InstallerIOException extends InstallPackageServiceException {
163

    
164
                private static final long serialVersionUID = 3153613550157712363L;
165

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

    
168
                private static final String KEY = "_IO_error installing_file_XfileX_";
169

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

    
175
        }
176

    
177
        public class InstallerFileDownloadException extends
178
                        InstallPackageServiceException {
179

    
180
                private static final long serialVersionUID = 8640183295766490512L;
181

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

    
184
                private static final String KEY = "_File_XurlX_download_error";
185

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

    
191
        }
192

    
193
        public class InstallerPackageNotFoundException extends
194
                        InstallPackageServiceException {
195

    
196
                private static final long serialVersionUID = 1726608498886963868L;
197

    
198
                private static final String message = "Package not found";
199

    
200
                private static final String KEY = "_package_not_found";
201

    
202
                public InstallerPackageNotFoundException() {
203
                        super(message, KEY, serialVersionUID);
204
                }
205

    
206
        }
207

    
208
        public class InstallerNoPackageException extends
209
                        InstallPackageServiceException {
210

    
211
                private static final long serialVersionUID = -2292735515704746966L;
212

    
213
                private static final String message = "Package does not exist";
214

    
215
                private static final String KEY = "_package__does_not_exist";
216

    
217
                public InstallerNoPackageException() {
218
                        super(message, KEY, serialVersionUID);
219
                }
220

    
221
        }
222

    
223
        public class InstallerProviderCreationException extends
224
                        InstallPackageServiceException {
225

    
226
                private static final long serialVersionUID = -7985786807492393584L;
227

    
228
                private static final String message = "Error creating the provider";
229

    
230
                private static final String KEY = "_Error_creating_the_provider";
231

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

    
236
        }
237

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

    
248
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
249

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

    
260
                // Open and install the package or package set file
261
                try {
262

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

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

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

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

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

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

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

    
322
        }
323

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

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

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

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

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

    
362
        public void addBundle(File bundle) throws InstallPackageServiceException {
363

    
364
                if (!bundle.exists()) {
365
                        throw new InstallPackageServiceException();
366
                }
367

    
368
                int packageInfoCount = packageInfos.size();
369

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

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

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

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

    
414
        public void addBundle(URL bundleURL) throws InstallPackageServiceException {
415
                File bundle;
416
                if (bundleURL.toString().endsWith(PACKAGE_FILE_NAME)) {
417
            manager.setDownloadBaseURL(bundleURL);
418
                        bundle = downloadFile(bundleURL, PACKAGE_FILE_NAME);
419
                        addBundle(bundle);
420
                } else {
421
                        String urlString = bundleURL.toString();
422
                        if (!urlString.endsWith("/")) {
423
                                urlString += "/";
424
                        }
425
                        urlString += ("dists/" + manager.getVersion() + "/" + PACKAGE_FILE_NAME);
426

    
427
                        URL completeURL;
428
                        try {
429
                                completeURL = new URL(urlString);
430
                        } catch (MalformedURLException e) {
431
                                // TODO Auto-generated catch block
432
                                e.printStackTrace();
433
                                return;
434
                        }
435

    
436
            manager.setDownloadBaseURL(completeURL);
437
                        bundle = downloadFile(completeURL, PACKAGE_FILE_NAME);
438
                        addBundle(bundle);
439
                }
440

    
441
        }
442

    
443
        private File downloadFile(URL bundleURL, String defaultFileName)
444
                        throws InstallPackageServiceException {
445
                try {
446
                        Download download = new Download();
447
                        return download.downloadFile(bundleURL, defaultFileName);
448
                } catch (IOException e) {
449
                        throw new InstallerFileDownloadException(bundleURL, e);
450
                }
451
        }
452

    
453
        public void addBundlesFromDirectory(File directory)
454
                        throws InstallPackageServiceException {
455
                if (!directory.isDirectory()) {
456
                        throw new InstallerNoDirectoryException(directory);
457
                }
458
                List<File> files = new ArrayList<File>();
459

    
460
                listRecursively(directory, new FileFilter() {
461

    
462
                        private String packageExt = manager
463
                                        .getDefaultPackageFileExtension();
464
                        private String packageSetExt = manager
465
                                        .getDefaultPackageSetFileExtension();
466

    
467
                        public boolean accept(File file) {
468
                                String name = file.getName().toLowerCase();
469
                                return file.isDirectory() || name.endsWith(packageExt)
470
                                                || name.endsWith(packageSetExt);
471
                        }
472
                }, files);
473
                for (int i = 0; i < files.size(); i++) {
474
                        if (files.get(i).isFile()) {
475
                                addBundle(files.get(i));
476
                        }
477
                }
478
        }
479

    
480
        private void listRecursively(File fileOrDir, FileFilter filter,
481
                        List<File> files) {
482
                files.add(fileOrDir);
483

    
484
                if (fileOrDir.isDirectory()) {
485

    
486
                        File[] dirContents = fileOrDir.listFiles(filter);
487

    
488
                        for (File f : dirContents) {
489
                                listRecursively(f, filter, files); // Recursively list.
490
                        }
491
                } else {
492
                        files.add(fileOrDir);
493
                }
494
        }
495

    
496
        public int getPackageCount() {
497
                if (packageInfos == null) {
498
                        return 0;
499
                }
500
                return packageInfos.size();
501
        }
502

    
503
        public Manager getManager() {
504
                return this.manager;
505
        }
506

    
507
        public void downloadPackage(PackageInfo packageInfo)
508
                        throws InstallPackageServiceException {
509
                this.downloadPackage(packageInfo, null);
510
        }
511

    
512
        public void downloadPackage(PackageInfo packageInfo,
513
                        SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
514
                File file = packageInfo.downloadFile(taskStatus);
515
                this.packageInfoFileMap.put(packageInfo, file);
516
        }
517

    
518
        public List<String> getDefaultSelectedPackagesIDs() {
519
                return installerProviderServices.getDefaultSelectedPackagesIDs();
520
        }
521

    
522
        public List<String> getCategories() {
523
                Set<String> categories = new HashSet<String>();
524

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

    
546
        public List<String> getTypes() {
547
                Set<String> types = new HashSet<String>();
548

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

    
568
}