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

History | View | Annotate | Download (18 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.HashMap;
41
import java.util.HashSet;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.Set;
45

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

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

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

    
67
public class DefaultInstallPackageService extends Thread implements
68
    InstallPackageService {
69

    
70
    private static final Logger LOG =
71
        LoggerFactory.getLogger(DefaultInstallPackageService.class);
72

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

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

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

    
94
    public class InstallerApplicationDirectoryNotFoundException extends
95
        InstallPackageServiceException {
96

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

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

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

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

    
110
    }
111

    
112
    public class InstallerNoDirectoryException extends
113
        InstallPackageServiceException {
114

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

    
117
        private static final String message =
118
            "'%(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 =
167
            "IO error installing the file '%(file)s'";
168

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

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

    
176
    }
177

    
178
    public class InstallerFileDownloadException extends
179
        InstallPackageServiceException {
180

    
181
        private static final long serialVersionUID = 8640183295766490512L;
182

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

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

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

    
192
    }
193

    
194
    public class InstallerPackageNotFoundException extends
195
        InstallPackageServiceException {
196

    
197
        private static final long serialVersionUID = 1726608498886963868L;
198

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

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

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

    
207
    }
208

    
209
    public class InstallerNoPackageException extends
210
        InstallPackageServiceException {
211

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

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

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

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

    
222
    }
223

    
224
    public class InstallerProviderCreationException extends
225
        InstallPackageServiceException {
226

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

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

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

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

    
237
    }
238

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

    
249
        InstallPackageProvider installerExecutionProvider =
250
            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.warn("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 =
277
                    installerProviderServices.searchPackage(bis, zipEntriesMap
278
                        .get(packageInfo));
279
            }
280

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

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

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

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

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

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

    
326
    }
327

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

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

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

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

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

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

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

    
373
        int packageInfoCount = packageInfos.size();
374

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

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

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

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

    
417
//    public void addBundle(URL bundleURL) throws InstallPackageServiceException {
418
//        File bundle = downloadFile(bundleURL, "packages.gvspki");
419
//        addBundle(bundle);
420
//    }
421

    
422
    public void addBundle(URL bundleURL) throws InstallPackageServiceException {
423
        String packageFileName = "packages.gvspki";
424
        File bundle;
425
        if (bundleURL.toString().endsWith(packageFileName)) {
426
            bundle = downloadFile(bundleURL, packageFileName);
427
            addBundle(bundle);
428
        } else {
429

    
430
            manager.setDownloadBaseURL(bundleURL);
431

    
432
            String urlString = bundleURL.toString();
433
            if (!urlString.endsWith("/")) {
434
                urlString += "/";
435
            }
436
            urlString +=
437
                ("dists/" + manager.getVersion() + "/" + packageFileName);
438
            
439
            URL completeURL;
440
            try {
441
                completeURL = new URL(urlString);
442
            } catch (MalformedURLException e) {
443
                // TODO Auto-generated catch block
444
                e.printStackTrace();
445
                return;
446
            }
447
            
448
            bundle = downloadFile(completeURL, packageFileName);
449
            addBundle(bundle);
450
        }
451

    
452
    }
453

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

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

    
471
        listRecursively(directory, new FileFilter() {
472

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

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

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

    
495
        if (fileOrDir.isDirectory()) {
496

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

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

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

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

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

    
523
    public void downloadPackage(PackageInfo packageInfo,
524
        SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
525
        File file = packageInfo.downloadFile(taskStatus);
526
        this.packageInfoFileMap.put(packageInfo, file);
527
    }
528

    
529
    public List<String> getDefaultSelectedPackagesIDs() {
530
        return installerProviderServices.getDefaultSelectedPackagesIDs();
531
    }
532
    
533
    // TODO: a?adir al interfaz
534
    public List<String> getCategories() {
535
        Set<String> categories = new HashSet<String>();
536
        for (int i = 0; i < getPackageCount(); i++) {
537
            categories.addAll(packageInfos.get(i).getCategories());
538
        }
539
        return new ArrayList<String>(categories);
540
    }
541

    
542
}