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

History | View | Annotate | Download (15.5 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 = LoggerFactory
71
                        .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 = InstallerProviderLocator
90
                                .getProviderManager().createInstallerProviderServices();
91
        }
92

    
93
        public class InstallerApplicationDirectoryNotFoundException extends
94
                        InstallPackageServiceException {
95

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

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

    
100
                private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
101

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

    
107
        }
108

    
109
        public class InstallerNoDirectoryException extends
110
                        InstallPackageServiceException {
111

    
112
                private static final long serialVersionUID = -8685263049644983769L;
113

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

    
116
                private static final String KEY = "_XdirectoryX_is_not_a_directory";
117

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

    
123
        }
124

    
125
        public class InstallerFileNotFoundException extends
126
                        InstallPackageServiceException {
127

    
128
                private static final long serialVersionUID = 556517830330132149L;
129

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

    
132
                private static final String KEY = "_file_XfileX_not_found";
133

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

    
139
        }
140

    
141
        public class InstallerBundleNotFoundException extends
142
                        InstallPackageServiceException {
143

    
144
                private static final long serialVersionUID = 5065410511582625301L;
145

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

    
148
                private static final String KEY = "_file_XfileX_not_found";
149

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

    
156
        }
157

    
158
        public class InstallerIOException extends InstallPackageServiceException {
159

    
160
                private static final long serialVersionUID = 3153613550157712363L;
161

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

    
164
                private static final String KEY = "_IO_error installing_file_XfileX_";
165

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

    
171
        }
172

    
173
        public class InstallerFileDownloadException extends
174
                        InstallPackageServiceException {
175

    
176
                private static final long serialVersionUID = 8640183295766490512L;
177

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

    
180
                private static final String KEY = "_File_XurlX_download_error";
181

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

    
187
        }
188

    
189
        public class InstallerPackageNotFoundException extends
190
                        InstallPackageServiceException {
191

    
192
                private static final long serialVersionUID = 1726608498886963868L;
193

    
194
                private static final String message = "Package not found";
195

    
196
                private static final String KEY = "_package_not_found";
197

    
198
                public InstallerPackageNotFoundException() {
199
                        super(message, KEY, serialVersionUID);
200
                }
201

    
202
        }
203

    
204
        public class InstallerNoPackageException extends
205
                        InstallPackageServiceException {
206

    
207
                private static final long serialVersionUID = -2292735515704746966L;
208

    
209
                private static final String message = "Package does not exist";
210

    
211
                private static final String KEY = "_package__does_not_exist";
212

    
213
                public InstallerNoPackageException() {
214
                        super(message, KEY, serialVersionUID);
215
                }
216

    
217
        }
218

    
219
        public class InstallerProviderCreationException extends
220
                        InstallPackageServiceException {
221

    
222
                private static final long serialVersionUID = -7985786807492393584L;
223

    
224
                private static final String message = "Error creating the provider";
225

    
226
                private static final String KEY = "_Error_creating_the_provider";
227

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

    
232
        }
233

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

    
244
                InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
245

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

    
256
                // Open and install the package or package set file
257
                try {
258

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

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

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

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

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

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

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

    
318
        }
319

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

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

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

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

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

    
358
        public void addBundle(File bundle) throws InstallPackageServiceException {
359

    
360
                if (!bundle.exists()) {
361
                        throw new InstallPackageServiceException();
362
                }
363

    
364
                int packageInfoCount = packageInfos.size();
365

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

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

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

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

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

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

    
424
                        manager.setDownloadBaseURL(bundleURL);
425

    
426
                        String urlString = bundleURL.toString();
427
                        if (!urlString.endsWith("/")) {
428
                                urlString += "/";
429
                        }
430
                        urlString += ("dists/" + manager.getVersion() + "/" + packageFileName);
431

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

    
441
                        bundle = downloadFile(completeURL, packageFileName);
442
                        addBundle(bundle);
443
                }
444

    
445
        }
446

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

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

    
464
                listRecursively(directory, new FileFilter() {
465

    
466
                        private String packageExt = manager
467
                                        .getDefaultPackageFileExtension();
468
                        private String packageSetExt = manager
469
                                        .getDefaultPackageSetFileExtension();
470

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

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

    
488
                if (fileOrDir.isDirectory()) {
489

    
490
                        File[] dirContents = fileOrDir.listFiles(filter);
491

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

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

    
507
        public Manager getManager() {
508
                return this.manager;
509
        }
510

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

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

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

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

    
529
                for (int i = 0; i < getPackageCount(); i++) {
530
                        categories.addAll(packageInfos.get(i).getCategories());
531
                }
532

    
533
                return new ArrayList<String>(categories);
534
        }
535

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

    
539
                for (int i = 0; i < getPackageCount(); i++) {
540
                        types.add(packageInfos.get(i).getType());
541
                }
542

    
543
                return new ArrayList<String>(types);
544
        }
545

    
546
}