Statistics
| Revision:

root / org.gvsig.educa.thematicmap / trunk / org.gvsig.educa.thematicmap / org.gvsig.educa.thematicmap.lib / org.gvsig.educa.thematicmap.lib.impl / src / main / java / org / gvsig / educa / thematicmap / impl / DefaultThematicMapManager.java @ 195

History | View | Annotate | Download (16.9 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
package org.gvsig.educa.thematicmap.impl;
23

    
24
import java.io.File;
25
import java.io.IOException;
26
import java.text.MessageFormat;
27
import java.util.ArrayList;
28
import java.util.Collections;
29
import java.util.List;
30

    
31
import org.apache.commons.io.FilenameUtils;
32
import org.apache.commons.lang3.ObjectUtils;
33
import org.apache.commons.lang3.StringUtils;
34
import org.gvsig.educa.thematicmap.ThematicMapException;
35
import org.gvsig.educa.thematicmap.ThematicMapManager;
36
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompilation;
37
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompiler;
38
import org.gvsig.educa.thematicmap.impl.compilation.DefaultThematicMapCompilation;
39
import org.gvsig.educa.thematicmap.impl.compilation.DefaultThematicMapCompiler;
40
import org.gvsig.educa.thematicmap.impl.map.DefaultThematicMap;
41
import org.gvsig.educa.thematicmap.impl.map.ThematicMapLoader;
42
import org.gvsig.educa.thematicmap.impl.util.FileUtils;
43
import org.gvsig.educa.thematicmap.map.CantLoadContextException;
44
import org.gvsig.educa.thematicmap.map.InvalidInstalledThematicMapException;
45
import org.gvsig.educa.thematicmap.map.InvalidThematicMapFormatException;
46
import org.gvsig.educa.thematicmap.map.ThematicMap;
47
import org.gvsig.educa.thematicmap.map.ThematicMapInformation;
48
import org.gvsig.educa.thematicmap.spi.ThematicMapProviderLocator;
49
import org.gvsig.i18n.Messages;
50
import org.gvsig.installer.lib.api.InstallerLocator;
51
import org.gvsig.installer.lib.api.InstallerManager;
52
import org.gvsig.installer.lib.api.PackageInfo;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.dynobject.DynObject;
55
import org.gvsig.tools.service.AbstractManager;
56
import org.gvsig.tools.service.Service;
57
import org.gvsig.tools.service.ServiceException;
58
import org.gvsig.tools.service.spi.ProviderManager;
59
import org.slf4j.Logger;
60
import org.slf4j.LoggerFactory;
61

    
62
/**
63
 * Default {@link ThematicMapManager} implementation.
64
 * 
65
 * @author gvSIG Team
66
 * @version $Id$
67
 */
68
public class DefaultThematicMapManager extends AbstractManager implements
69
                ThematicMapManager {
70

    
71
        /**
72
         * Extension for Thematic Map files
73
         */
74
        public static String THEMATIC_MAP_FILE_EXTENSION = "gvsthm";
75

    
76
        private static final Logger LOG = LoggerFactory
77
                        .getLogger(DefaultThematicMapManager.class);
78

    
79
        public static final String BASENAME_FORMAT_STRING = "{0}-v{1}-BN{2}";
80

    
81
        public static final String PACKAGE_BASENAME_FORMAT_STRING = "ThematicMap-{0}-{1}-BN{2}";
82

    
83
        /**
84
         * Manager which manages when deploy/clean maps in temporal folder
85
         */
86
        private MapResoucesManager resourceManager;
87

    
88
        private final ThematicMapLoader mapLoader;
89

    
90
        private final InstallerManager installerManager;
91

    
92
        /**
93
         * Map Instalation's folder
94
         */
95
        private String installationFolderInput;
96
        private File installationFolder;
97

    
98
        private String temporalDelployFolderInput;
99
        private File temporalDeployMapFolder;
100

    
101
        private final ThematicMapFileFilter thematicMapFileFilter;
102

    
103
        public DefaultThematicMapManager(ProviderManager providerManager) {
104
                super(providerManager);
105

    
106
                // TODO Auto-generated constructor stub
107

    
108
                // initially, installation folder is null
109
                installationFolder = null;
110
                installationFolderInput = null;
111

    
112
                // default temporal folder tmp.dir + '/ThematicMap.tmp'
113
                temporalDeployMapFolder = FileUtils.getWritableFolder(
114
                                new File(System.getProperty("java.io.tmpdir")),
115
                                "ThematicMap.tmp");
116
                temporalDelployFolderInput = temporalDeployMapFolder.getAbsolutePath();
117

    
118
                // Create file filter to identify map candidate in a folder
119
                thematicMapFileFilter = new ThematicMapFileFilter(
120
                                THEMATIC_MAP_FILE_EXTENSION);
121

    
122
                // Create loader instance
123
                mapLoader = new ThematicMapLoader();
124

    
125
                // Create resource manager instance
126
                resourceManager = new MapResoucesManager(mapLoader);
127

    
128
                installerManager = InstallerLocator.getInstallerManager();
129
        }
130
        
131
        public DefaultThematicMapManager() {
132
//                super(new DefaultInstallerProviderManager());
133
//                this(ThematicMapProviderLocator.getManager());
134
                this(null);
135
        }
136

    
137
//        public DefaultThematicMapManager() {
138
//
139
//                // initially, installation folder is null
140
//                installationFolder = null;
141
//                installationFolderInput = null;
142
//
143
//                // default temporal folder tmp.dir + '/ThematicMap.tmp'
144
//                temporalDeployMapFolder = FileUtils.getWritableFolder(
145
//                                new File(System.getProperty("java.io.tmpdir")),
146
//                                "ThematicMap.tmp");
147
//                temporalDelployFolderInput = temporalDeployMapFolder.getAbsolutePath();
148
//
149
//                // Create file filter to identify map candidate in a folder
150
//                thematicMapFileFilter = new ThematicMapFileFilter(
151
//                                THEMATIC_MAP_FILE_EXTENSION);
152
//
153
//                // Create loader instance
154
//                mapLoader = new ThematicMapLoader();
155
//
156
//                // Create resource manager instance
157
//                resourceManager = new MapResoucesManager(mapLoader);
158
//
159
//                installerManager = InstallerLocator.getInstallerManager();
160
//        }
161

    
162
        /** {@inheridDoc} */
163
        public String getInstallationMapFolder() {
164
                return installationFolderInput;
165
        }
166

    
167
        /**
168
         * Checks if <code>folder</code> is a folder an is readable
169
         * 
170
         * @param folder
171
         * @return file representation of folder
172
         * @throws IllegalArgumentException
173
         */
174
        private File checkValidReadableFolder(String folder) {
175
                File fileObject = new File(folder);
176
                if (!FileUtils.isReadableFolder(fileObject)) {
177
                        throw new IllegalArgumentException("Invalid folder");
178
                }
179
                return fileObject;
180
        }
181

    
182
        /**
183
         * Checks if <code>folder</code> is a folder and is writable
184
         * 
185
         * @param folder
186
         * @return file representation of folder
187
         * @throws IllegalArgumentException
188
         */
189
        private File checkValidWritableFolder(String folder) {
190
                File fileObject = new File(folder);
191
                if (!FileUtils.isWritableFolder(fileObject)) {
192
                        throw new IllegalArgumentException("Invalid folder");
193
                }
194
                return fileObject;
195
        }
196

    
197
        /** {@inheridDoc} */
198
        public void setInstallationMapFolder(String folder) {
199
                installationFolder = checkValidReadableFolder(folder);
200
                installationFolderInput = folder;
201
        }
202

    
203
        /** {@inheridDoc} */
204
        public String getTemporalFolder() {
205
                return temporalDelployFolderInput;
206
        }
207

    
208
        /** {@inheridDoc} */
209
        public void setTemporalFolder(String folder) {
210
                if (FilenameUtils.equals(temporalDelployFolderInput, folder)) {
211
                        return;
212
                }
213
                temporalDeployMapFolder = checkValidWritableFolder(folder);
214
                temporalDelployFolderInput = folder;
215
                resourceManager.cleanAllResources();
216
        }
217

    
218
        /** {@inheridDoc} */
219
        public List<ThematicMap> getInstalledMaps() {
220
                return getMapsFromFolder(installationFolder);
221
        }
222

    
223
        /** {@inheridDoc} */
224
        public List<ThematicMap> getInstalledMaps(String folder) {
225
                File fileObject = checkValidReadableFolder(folder);
226
                return getMapsFromFolder(fileObject);
227
        }
228

    
229
        /**
230
         * <p>
231
         * Gets all maps from a folder
232
         * </p>
233
         * <p>
234
         * List all files which matches with filter and try to load it information.
235
         * If a file load throws an Invalid format found ignores this file.
236
         * </p>
237
         * 
238
         * @param folder
239
         * @return
240
         */
241
        private List<ThematicMap> getMapsFromFolder(File folder) {
242
                File[] files = folder.listFiles();
243
                List<ThematicMap> result = new ArrayList<ThematicMap>(files.length);
244
                ThematicMap map;
245
                for (File file : files) {
246

    
247
                        try {
248
                                map = getThematicMapIntalledFolder(file);
249
                        } catch (ThematicMapException ex) {
250
                                // Ignore this folder
251
                                if (LOG.isDebugEnabled()) {
252
                                        LOG.debug(
253
                                                        "Folder exception reading map from it (not a map): {}"
254
                                                                        .concat(file.getAbsolutePath()), ex);
255
                                }
256
                                continue;
257
                        }
258
                        result.add(map);
259
                }
260
                resourceManager.adjustResourceSize();
261
                return Collections.unmodifiableList(result);
262
        }
263

    
264
        /** {@inheridDoc} */
265
        public ThematicMap getMapFromFile(File file)
266
                        throws InvalidThematicMapFormatException {
267
                if (!thematicMapFileFilter.accept(file)) {
268
                        throw new InvalidThematicMapFormatException(file,
269
                                        "Bad file extension (".concat(
270
                                                        thematicMapFileFilter.getFileNameEnding()).concat(
271
                                                        ")"));
272
                }
273
                ThematicMapInformation info = resourceManager.getInfoOfFile(file);
274

    
275
                if (info == null) {
276
                        try {
277
                                info = mapLoader.getInformationFromMapFile(file);
278
                        } catch (Exception e) {
279
                                throw new InvalidThematicMapFormatException(file,
280
                                                "Can't load information file", e);
281
                        }
282
                }
283
                return createThematicMap(file, info);
284
        }
285

    
286
        public ThematicMap getMapById(String mapId) {
287
                List<ThematicMap> installedMaps = getInstalledMaps();
288
                for (ThematicMap map : installedMaps) {
289
                        if (ObjectUtils.equals(map.getInformation().getId(), mapId)) {
290
                                return map;
291
                        }
292
                }
293
                return null;
294
        }
295

    
296
        private ThematicMap createThematicMap(File file, ThematicMapInformation info) {
297
                return new DefaultThematicMap(file, info, resourceManager);
298
        }
299

    
300
        /** {@inheridDoc} */
301
        public boolean isMap(File file) {
302
                if (LOG.isDebugEnabled()) {
303
                        LOG.debug("Checking is map : {}", file.getAbsolutePath());
304
                }
305

    
306
                if (!thematicMapFileFilter.accept(file)) {
307
                        return false;
308
                }
309
                try {
310
                        return mapLoader.getInformationFromMapFile(file) != null;
311
                } catch (Exception e) {
312
                        LOG.debug("file is not a mapFile:", e);
313
                        return false;
314
                }
315
        }
316

    
317
        /** {@inheridDoc} */
318
        public ThematicMapCompilation createCompilationInstance() {
319
                return new DefaultThematicMapCompilation(this);
320
        }
321

    
322
        /** {@inheridDoc} */
323
        public ThematicMapCompiler createCompilerInstance() {
324
                return new DefaultThematicMapCompiler(THEMATIC_MAP_FILE_EXTENSION);
325
        }
326

    
327
        /** {@inheridDoc} */
328
        public void dispose() {
329
                resourceManager.dispose();
330
                resourceManager = null;
331
                ToolsLocator.getDisposableManager().release(this);
332
        }
333

    
334
        /** {@inheridDoc} */
335
        public void cleanAllTemporalData() {
336
                resourceManager.cleanAllResources();
337
        }
338

    
339
        /** {@inheridDoc} */
340
        public ThematicMapCompilation createCompilationInstanceFromMap(
341
                        ThematicMap map) throws InvalidThematicMapFormatException,
342
                        CantLoadContextException, IOException {
343
                if (!map.isOpen()) {
344
                        map.open();
345
                }
346
                return new DefaultThematicMapCompilation(map, this);
347
        }
348

    
349
        /**
350
         * Gets a ThematicMap from a installed maps
351
         * 
352
         * @param folder
353
         * @return
354
         * @throws InvalidInstalledThematicMapException
355
         */
356
        public ThematicMap getThematicMapIntalledFolder(File folder)
357
                        throws ThematicMapException {
358
                // Only readable folder
359
                if (!FileUtils.isReadableFolder(folder)) {
360
                        throw new InvalidInstalledThematicMapException(folder,
361
                                        "not a readable folder");
362
                }
363
                String code = folder.getName();
364

    
365
                // Load package info
366
                PackageInfo packageInfo = mapLoader
367
                                .getPackageInfoFromInstalledThematicMap(folder);
368

    
369
                if (packageInfo == null) {
370
                        throw new InvalidInstalledThematicMapException(folder,
371
                                        "missing package.info file");
372
                }
373

    
374
                if (!StringUtils.equals(code, packageInfo.getCode())) {
375
                        throw new InvalidInstalledThematicMapException(folder,
376
                                        "folder name doesn't match with package.info code");
377
                }
378

    
379
                if (!StringUtils.equals("ThematicMap", packageInfo.getType())) {
380
                        throw new InvalidInstalledThematicMapException(folder,
381
                                        "package.info type is not 'ThematicMap': "
382
                                                        .concat(packageInfo.getType()));
383
                }
384

    
385
                // Gets the thematic map file
386
                ThematicMap map;
387
                String mapFileName = getBaseFileNameFromInfo(packageInfo.getCode(),
388
                                packageInfo.getName(), packageInfo.getVersion().getMayor(),
389
                                packageInfo.getVersion().getBuild()).concat(
390
                                thematicMapFileFilter.getFileNameEnding());
391
                File mapFile = new File(folder, mapFileName);
392
                if (!mapFile.exists()) {
393
                        throw new InvalidInstalledThematicMapException(folder, "missing '"
394
                                        .concat(mapFileName).concat("' file"));
395
                }
396
                map = getMapFromFile(mapFile);
397

    
398
                if (map == null) {
399
                        // This must be unreachable code
400
                        throw new IllegalStateException();
401
                }
402
                ThematicMapInformation info = map.getInformation();
403

    
404
                // Compares pkgInfo.code and thmInfo.id
405
                if (!StringUtils.equals(packageInfo.getCode(), info.getId())) {
406
                        throw new InvalidInstalledThematicMapException(folder,
407
                                        "package.info code doesn't match with ThematicMap.id");
408
                }
409

    
410
                // Compares pkgInfo.version and thmInfo.version
411
                if (packageInfo.getVersion().getMayor() != info.getVersion()) {
412
                        throw new InvalidInstalledThematicMapException(folder,
413
                                        "package.info version doesn't match with ThematicMap.version");
414
                }
415

    
416
                // Compares pkgInfo.buildNumber and thmInfo.buildNumber
417
                if (packageInfo.getVersion().getBuild() != info.getBuildNumber()) {
418
                        throw new InvalidInstalledThematicMapException(folder,
419
                                        "package.info build doesn't match with ThematicMap.buildNumber");
420
                }
421

    
422
                return map;
423
        }
424

    
425
        /** {@inheridDoc} */
426
        public boolean isAThematicMapIntalledFolder(File folder) {
427
                if (!FileUtils.isReadableFolder(folder)) {
428
                        return false;
429
                }
430

    
431
                ThematicMap map;
432
                try {
433
                        map = getThematicMapIntalledFolder(folder);
434
                } catch (Exception ex) {
435
                        return false;
436
                }
437

    
438
                return map != null;
439

    
440
        }
441

    
442
        /** {@inheridDoc} */
443
        public String getBaseFileNameFromInfo(ThematicMapInformation info) {
444
                return getBaseFileNameFromInfo(info.getId(), info.getName(),
445
                                info.getVersion(), info.getBuildNumber());
446
        }
447

    
448
        /** {@inheridDoc} */
449
        public String getBaseFileNameFromInfo(String id, String name, int version,
450
                        int buildNumber) {
451
                return MessageFormat.format(BASENAME_FORMAT_STRING, id, version,
452
                                buildNumber);
453
        }
454

    
455
        /** {@inheridDoc} */
456
        public File generatePackageFile(String mapId, File targetFolder)
457
                        throws ThematicMapException, IOException {
458

    
459
                ThematicMap map = getMapById(mapId);
460
                if (map == null) {
461
                        throw new IllegalArgumentException("Thematic Map not foudn: '"
462
                                        .concat(mapId).concat("'"));
463
                }
464

    
465
                File mapFolder = new File(installationFolder, mapId);
466

    
467
                return generatePackageFile(mapFolder, targetFolder);
468
        }
469

    
470
        /** {@inheridDoc} */
471
        public File generatePackageFile(File thematicMapIntallFolder,
472
                        File targetFolder) throws ThematicMapException, IOException {
473

    
474
                // Checks if it's a map folder
475
                ThematicMap map = null;
476
                try {
477
                        map = getThematicMapIntalledFolder(thematicMapIntallFolder);
478
                } catch (Exception ex) {
479
                        throw new IllegalArgumentException("Source is not a map folder: '"
480
                                        .concat(thematicMapIntallFolder.getAbsolutePath()).concat(
481
                                                        "'"));
482
                }
483
                if (map == null) {
484
                        throw new IllegalArgumentException("Source is not a map folder: '"
485
                                        .concat(thematicMapIntallFolder.getAbsolutePath()).concat(
486
                                                        "'"));
487
                }
488

    
489
                // Check target folder
490
                if (!FileUtils.isWritableFolder(targetFolder)) {
491
                        throw new IllegalArgumentException(
492
                                        "Target is not a writable folder: '".concat(
493
                                                        targetFolder.getAbsolutePath()).concat("'"));
494
                }
495

    
496
                // Prepare target file name
497
                ThematicMapInformation info = map.getInformation();
498
                String pkgFileName = MessageFormat
499
                                .format(PACKAGE_BASENAME_FORMAT_STRING, info.getId(),
500
                                                info.getVersion(), info.getBuildNumber()).concat(".")
501
                                .concat(installerManager.getDefaultPackageFileExtension());
502
                File targetFile = new File(targetFolder, pkgFileName);
503

    
504
                // Prepare temporal folder
505
                File workFolder = FileUtils.getNewWritableFolder(
506
                                temporalDeployMapFolder, "__tmp__".concat(pkgFileName));
507
                File tempFolder = new File(workFolder, info.getId());
508

    
509
                // Copy all content of map folder
510
                FileUtils.copyDirectory(thematicMapIntallFolder, tempFolder, true);
511

    
512
                // Remove unused thematicMap files
513
                String mapFileName = FilenameUtils.getName(map.getSourceFilePath());
514
                File[] tmFiles = tempFolder.listFiles(thematicMapFileFilter);
515
                for (File thFile : tmFiles) {
516
                        if (!StringUtils.equals(thFile.getName(), mapFileName)) {
517
                                thFile.delete();
518
                        }
519
                }
520

    
521
                // Zip file
522
                FileUtils.zipFolder(workFolder, targetFile);
523

    
524
                return targetFile;
525
        }
526

    
527
        public String getTranslation(String key) {
528
                // TODO: add I18nManager usage when org.gvsig.tools.lib 2.1.0 becomes
529
                // available
530
                // return this.i18nmanager.getTranslation(key);
531
                return Messages.getText(key);
532
        }
533

    
534
        public Service getService(DynObject parameters) throws ServiceException {
535
                // return thematic map compilation (ThematicMapService)
536

    
537
                // supose que he d'agafar un identificador de parameters del mapa que busque
538
                // despres, buscar-lo i passar-lo a DefaultThematicMapCompilation i
539
                // tornar la compilacio.
540
                
541
                ThematicMap map = null;
542
                
543
                List<ThematicMap> mapsList = getInstalledMaps();
544
                
545
                // TODO: Get the thematicmap that has the given parameters
546

    
547
                DefaultThematicMapCompilation serviceCompilation = new DefaultThematicMapCompilation(
548
                                map, this);
549

    
550
                return serviceCompilation;
551

    
552
        }
553

    
554
        public ThematicMapCompilation createCompilationInstance(String gameName)
555
                        throws ServiceException {
556
                DynObject params = createServiceParameters(gameName);
557
                
558

    
559
//                DefaultThematicMapCompilation compilation = new DefaultThematicMapCompilation(this);
560
//                compilation.
561
                // Instanciar thematicmapcompilation i assignar-li params
562
                return null;
563
        }
564
}