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

History | View | Annotate | Download (19.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 {Prodevelop}   {Task}
26
 */
27
package org.gvsig.installer.lib.impl.execution;
28

    
29
import java.io.BufferedInputStream;
30
import java.io.File;
31
import java.io.FileInputStream;
32
import java.io.FileNotFoundException;
33
import java.io.IOException;
34
import java.io.InputStream;
35
import java.net.MalformedURLException;
36
import java.net.URL;
37
import java.util.ArrayList;
38
import java.util.Collection;
39
import java.util.Collections;
40
import java.util.HashMap;
41
import java.util.HashSet;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.Properties;
45
import java.util.Set;
46
import org.apache.commons.io.FileUtils;
47
import org.apache.commons.io.IOUtils;
48
import org.apache.commons.lang3.StringUtils;
49

    
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

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

    
69
/**
70
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodr&aacute;</a>
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 PackagesCache packagesCache = 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
//        packageInfos = new ArrayList<PackageInfo>();
94
//        zipEntriesMap = new HashMap<PackageInfo, String>();
95
        installerProviderServices = InstallerProviderLocator
96
                .getProviderManager().createInstallerProviderServices();
97
        packagesCache = new PackagesCache(installerProviderServices);
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)' 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
    @Override
242
    public void installPackage(File applicationDirectory,
243
            PackageInfo packageInfo) throws InstallPackageServiceException {
244
        if (!applicationDirectory.exists()) {
245
            LOG.warn("Can install package '" + packageInfo.getCode() + "', application folder '" + applicationDirectory.toString() + "' does not exits.");
246
            throw new InstallerApplicationDirectoryNotFoundException(
247
                    applicationDirectory);
248
        }
249
        if (!packagesCache.contains(packageInfo)) {
250
            LOG.warn("Can install package '" + packageInfo.getCode() + "', package not found.");
251
            throw new InstallerPackageNotFoundException();
252
        }
253

    
254
        InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
255

    
256
        File file = packagesCache.getFile(packageInfo);
257
        try {
258
            InputStream packageStream = this.packagesCache.getInputStream(packageInfo);
259
            try {
260
                installerExecutionProvider.install(applicationDirectory,
261
                        packageStream, packageInfo);
262
            } catch (InstallPackageServiceException e) {
263
                IOUtils.closeQuietly(packageStream);
264
                packageStream = this.packagesCache.getInputStream(packageInfo);
265
                installerExecutionProvider.installLater(applicationDirectory,
266
                        packageStream, packageInfo);
267
            } finally {
268
                IOUtils.closeQuietly(packageStream);
269
            }
270

    
271
        } catch (FileNotFoundException e) {
272
            throw new InstallerFileNotFoundException(file);
273
        } catch (IOException e) {
274
            throw new InstallerIOException(file, e);
275
        }
276

    
277
    }
278

    
279
    @Override
280
    public void installPackage(File applicationDirectory, String packageCode)
281
            throws InstallPackageServiceException {
282
        PackageInfo packageInfo = getPackageInfo(packageCode);
283
        if (packageInfo == null) {
284
            throw new InstallerNoPackageException();
285
        }
286
        installPackage(applicationDirectory, packageInfo);
287
    }
288

    
289
    private InstallPackageProvider createProvider(PackageInfo packageInfo)
290
            throws InstallPackageServiceException {
291
        InstallerProviderManager installerProviderManager = (InstallerProviderManager) ((DefaultInstallerManager) manager)
292
                .getProviderManager();
293

    
294
        try {
295
            return installerProviderManager.createExecutionProvider(packageInfo
296
                    .getType());
297
        } catch (ServiceException e) {
298
            throw new InstallerProviderCreationException(e);
299
        }
300
    }
301

    
302
    @Override
303
    public PackageInfo getPackageInfo(int index) {
304
        if (index >= packagesCache.size()) {
305
            return null;
306
        }
307
        return packagesCache.get(index);
308
    }
309

    
310
    @Override
311
    public PackageInfo getPackageInfo(String packageCode) {
312
        for( PackageInfo packageInfo : packagesCache ) {
313
            if (packageInfo.getCode().equals(packageCode)) {
314
                return packageInfo;
315
            }
316
        }
317
        return null;
318
    }
319

    
320
    @Override
321
    public void addBundle(File bundle, SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
322
        Map<PackageInfo, String> zipEntriesNames = new HashMap<>();
323
        List<PackageInfo> packages = new ArrayList<>();
324
        
325
        if (!bundle.exists()) {
326
            throw new InstallPackageServiceException();
327
        }
328

    
329
        BufferedInputStream bis = null;
330
        FileInputStream fis = null;
331
        try {
332
            fis = new FileInputStream(bundle);
333
            bis = new BufferedInputStream(fis);
334
            installerProviderServices.readPackageInfo(
335
                bis, packages, zipEntriesNames, bundle.getName(), taskStatus
336
            );
337
        } catch (FileNotFoundException e) {
338
            throw new InstallerBundleNotFoundException(bundle, e);
339
        } finally {
340
            IOUtils.closeQuietly(bis);
341
            IOUtils.closeQuietly(fis);
342
            bis = null;
343
            fis = null;
344
        }
345
        
346
        if( packages.size()==1 ) {
347
            PackageInfo pkg = packages.get(0);
348
            String entryName = zipEntriesNames.get(pkg);
349
            if( entryName.endsWith("."+manager.getDefaultPackageFileExtension()) ) {
350
                // Es un xxx.gvspkg
351
                packagesCache.addPackage(pkg, bundle);
352
                return;
353
            } else if( entryName.endsWith("."+manager.getDefaultIndexSetFileExtension()) ) {
354
                // Es un xxx.gvspki
355
                packagesCache.addPackageIndex(pkg);
356
            } else {
357
                throw new IllegalArgumentException("Can't recognize the file '"+bundle.getAbsolutePath()+"'.");
358
            }
359
        }
360
        
361
        packages.clear();
362
        zipEntriesNames.clear();
363
        try {
364
            fis = new FileInputStream(bundle);
365
            bis = new BufferedInputStream(fis);
366
            installerProviderServices.readPackageSetInfo(
367
                bis, packages, zipEntriesNames, taskStatus
368
            );
369
        } catch (FileNotFoundException e) {
370
            throw new InstallerBundleNotFoundException(bundle, e);
371
        } finally {
372
            IOUtils.closeQuietly(bis);
373
            IOUtils.closeQuietly(fis);
374
            bis = null;
375
            fis = null;
376
        }
377
        for( PackageInfo pkg : packages ) {
378
            String entryName = zipEntriesNames.get(pkg);
379
            if( entryName.endsWith("."+manager.getDefaultPackageFileExtension()) ) {
380
                // Es un xxx.gvspkg
381
                packagesCache.addBundledPackage(pkg, bundle, entryName);
382
            } else if( entryName.endsWith("."+manager.getDefaultIndexSetFileExtension()) ) {
383
                // Es un xxx.gvspki
384
                packagesCache.addBundledPackageIndex(pkg, bundle, entryName);
385
            } else {
386
                throw new IllegalArgumentException("Can't recognize the file '"+bundle.getAbsolutePath()+"'.");
387
            }
388
        }
389
    }
390

    
391
    @Override
392
    public void addBundle(URL bundleURL, SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
393
        File bundle;
394
        String urlString = bundleURL.toString();
395
        if (urlString.endsWith(InstallerManager.PACKAGE_EXTENSION) || urlString.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION)) {
396
            manager.setDownloadBaseURL(bundleURL);
397
            bundle = downloadFile(bundleURL, PACKAGE_FILE_NAME);
398
            addBundle(bundle,taskStatus);
399
        } else {
400
            if (!urlString.endsWith("/")) {
401
                urlString += "/";
402
            }
403

    
404
            Version version = manager.getVersionEx();
405
            urlString += ("dists/"
406
                    + version.getMayor() + "." + version.getMinor() + "."
407
                    + version.getRevision() + "/" + PACKAGE_FILE_NAME);
408

    
409
            URL completeURL;
410
            try {
411
                completeURL = new URL(urlString);
412
            } catch (MalformedURLException e) {
413
                // TODO Auto-generated catch block
414
                e.printStackTrace();
415
                return;
416
            }
417

    
418
            manager.setDownloadBaseURL(completeURL);
419
            bundle = downloadFile(completeURL, PACKAGE_FILE_NAME);
420
            addBundle(bundle,taskStatus);
421
        }
422

    
423
    }
424

    
425
    private File downloadFile(URL bundleURL, String defaultFileName)
426
            throws InstallPackageServiceException {
427
        try {
428
            Download download = new Download();
429
            return download.downloadFile(bundleURL, defaultFileName);
430
        } catch (IOException e) {
431
            throw new InstallerFileDownloadException(bundleURL, e);
432
        }
433
    }
434

    
435
    @Override
436
    public void addBundlesFromDirectory(File directory, SimpleTaskStatus taskStatus)
437
            throws InstallPackageServiceException {
438
        if (!directory.isDirectory()) {
439
            throw new InstallerNoDirectoryException(directory);
440
        }
441
        Collection<File> files = FileUtils.listFiles(
442
            directory, 
443
            new String[] {
444
                manager.getDefaultPackageFileExtension(),
445
                manager.getDefaultPackageSetFileExtension(),
446
                manager.getDefaultIndexSetFileExtension()
447
            },
448
            true
449
        );
450
        for( File file : files ) {
451
            addBundle(file,taskStatus);
452
        }
453
    }
454

    
455
    @Override
456
    public int getPackageCount() {
457
        if (packagesCache == null) {
458
            return 0;
459
        }
460
        return packagesCache.size();
461
    }
462

    
463
    @Override
464
    public Manager getManager() {
465
        return this.manager;
466
    }
467

    
468
    public void downloadPackage(PackageInfo packageInfo)
469
            throws InstallPackageServiceException {
470
        this.downloadPackage(packageInfo, null);
471
    }
472

    
473
    @Override
474
    public void downloadPackage(PackageInfo packageInfo,
475
            SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
476
        packagesCache.download(packageInfo, taskStatus);
477
    }
478

    
479
    @Override
480
    public List<String> getDefaultSelectedPackagesIDs() {
481
        return installerProviderServices.getDefaultSelectedPackagesIDs();
482
    }
483

    
484
    @Override
485
    public Properties getProperties() {
486
        return installerProviderServices.getProperties();
487
    }
488

    
489
    @Override
490
    public List<String> getCategories() {
491
        Set<String> categories = new HashSet<>();
492
        for( PackageInfo pkginfo : packagesCache ) {
493
            List<String> pkgcategories = pkginfo.getCategories();
494
            categories.addAll(pkgcategories);
495
        }
496
        try {
497
            PackageInfo[] pkgs = manager.getInstalledPackages();
498
            for( PackageInfo pkginfo : pkgs ) {
499
                List<String> pkgcategories = pkginfo.getCategories();
500
                categories.addAll(pkgcategories);
501
            }
502

    
503
        } catch (MakePluginPackageServiceException e) {
504
            // Ignore exceptions
505
        }
506
        ArrayList<String> l = new ArrayList<>(categories);
507
        Collections.sort(l);
508
        return l;
509
    }
510

    
511
    @Override
512
    public List<String> getTypes() {
513
        Set<String> types = new HashSet<>();
514

    
515
        for( PackageInfo pkginfo : packagesCache ) {
516
            types.add(pkginfo.getType());
517
        }
518
        try {
519
            PackageInfo[] pkgs = manager.getInstalledPackages();
520
            for( PackageInfo pkginfo : pkgs ) {
521
                types.add(pkginfo.getType());
522
            }
523

    
524
        } catch (MakePluginPackageServiceException e) {
525
            // Ignore exceptions
526
        }
527
        List<String> l = new ArrayList<>(types);
528
        Collections.sort(l);
529
        return l;
530
    }
531

    
532
    @Override
533
    public boolean needInstallPackageProviders() {
534
        boolean need = false;
535
        String ss = this.getProperties().getProperty("installers");
536
        if (ss != null) {
537
            String[] installerNames = StringUtils.split(ss);
538
            for (String installerName : installerNames) {
539
                InstallerProviderInstallers installer = new InstallerProviderInstallers(this, installerName);
540
                if( !installer.isAlreadyRegistered() ) {
541
                    need = true;
542
                    break;
543
                }
544
            }
545
        }
546
        return need;
547
    }
548

    
549
    @Override
550
    public void installPackageProviders(SimpleTaskStatus taskStatus) {
551
        Properties props = this.getProperties();
552
        String ss = props.getProperty("installers");
553
        if (ss == null) {
554
            return;
555
        }
556

    
557
        try {
558
            String[] installerNames = StringUtils.split(ss);
559
            taskStatus.setRangeOfValues(0, installerNames.length);
560
            int count=0;
561
            for (String installerName : installerNames) {
562
                taskStatus.message(installerName);
563
                taskStatus.setCurValue(count++);
564
                InstallerProviderInstallers installer = new InstallerProviderInstallers(this, installerName);
565
                installer.install();
566
            }
567
            taskStatus.setCurValue(count++);
568
        } finally {
569
            taskStatus.terminate();
570
        }
571
    }
572

    
573
}