Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / impl / DefaultMapContextManager.java @ 44831

History | View | Annotate | Download (40 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
package org.gvsig.fmap.mapcontext.impl;
24

    
25
import java.awt.Color;
26
import java.awt.Font;
27
import java.io.File;
28
import java.io.FileFilter;
29
import java.io.InputStream;
30
import java.lang.reflect.InvocationTargetException;
31
import java.lang.reflect.Method;
32
import java.util.ArrayList;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.LinkedHashMap;
36
import java.util.List;
37
import java.util.Map;
38
import org.apache.commons.io.IOUtils;
39
import org.apache.commons.lang3.StringUtils;
40
import org.cresques.cts.ICoordTrans;
41

    
42
import org.cresques.cts.IProjection;
43
import org.gvsig.fmap.crs.CRSFactory;
44
import org.gvsig.fmap.dal.DALLocator;
45
import org.gvsig.fmap.dal.DataManager;
46
import org.gvsig.fmap.dal.DataStore;
47
import org.gvsig.fmap.dal.DataStoreParameters;
48
import org.gvsig.fmap.dal.DataStoreProviderFactory;
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.feature.FeatureStore;
51
import org.gvsig.fmap.dal.feature.FeatureType;
52
import org.gvsig.fmap.dal.raster.BandDescriptor;
53
import org.gvsig.fmap.dal.raster.RasterStore;
54
import org.gvsig.fmap.mapcontext.MapContext;
55
import org.gvsig.fmap.mapcontext.MapContextDrawer;
56
import org.gvsig.fmap.mapcontext.MapContextException;
57
import org.gvsig.fmap.mapcontext.MapContextLocator;
58
import org.gvsig.fmap.mapcontext.MapContextManager;
59
import org.gvsig.fmap.mapcontext.MapContextRuntimeException;
60
import org.gvsig.fmap.mapcontext.ViewPort;
61
import org.gvsig.fmap.mapcontext.exceptions.CantRetrieveLayerByStoreException;
62
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
63
import org.gvsig.fmap.mapcontext.layers.DefaultLayerInformationBuilder;
64
import org.gvsig.fmap.mapcontext.layers.FLayer;
65
import org.gvsig.fmap.mapcontext.layers.LayerInformationBuilder;
66
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
67
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
68
import org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer;
69
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
70
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
71
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialUniqueValueLegend;
72
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendReader;
73
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendWriter;
74
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
75
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
76
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
77
import org.gvsig.fmap.mapcontext.rendering.symbols.IWarningSymbol;
78
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolException;
79
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
80
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolPreferences;
81
import org.gvsig.raster.lib.legend.api.RasterLegend;
82
import org.gvsig.raster.lib.legend.api.RasterLegendLocator;
83
import org.gvsig.raster.lib.legend.api.RasterLegendManager;
84
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
85
import org.gvsig.tools.ToolsLocator;
86
import org.gvsig.tools.dynobject.DynObject;
87
import org.gvsig.tools.dynobject.exception.DynMethodException;
88
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
89
import org.gvsig.tools.folders.FoldersManager;
90
import org.gvsig.tools.observer.Notification;
91
import org.gvsig.tools.observer.ObservableHelper;
92
import org.gvsig.tools.observer.Observer;
93
import org.gvsig.tools.persistence.PersistenceManager;
94
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
95
import org.gvsig.tools.resourcesstorage.ResourcesStorage.Resource;
96
import org.slf4j.Logger;
97
import org.slf4j.LoggerFactory;
98

    
99
/**
100
 * Default implementation of the {@link MapContextManager}.
101
 *
102
 */
103
@SuppressWarnings("UseSpecificCatch")
104
public class DefaultMapContextManager implements MapContextManager {
105

    
106
    private static final Logger LOGGER = LoggerFactory
107
            .getLogger(DefaultMapContextManager.class);
108

    
109
    private Class drawerClazz = DefaultMapContextDrawer.class;
110

    
111
    private final Map<String,Class<ILegend>> legends = new HashMap();
112

    
113
    private final Map<String, Class<ILegendReader>> legendReaders = new LinkedHashMap<>();
114

    
115
    private final Map<String, Map<Class<ILegend>,Class<ILegendWriter>>> legendWriters = new LinkedHashMap<>();
116
    
117
    private final Map<Class<? extends DataStore>,Class<? extends FLayer>> layerClassFromStoreClass = new HashMap<>();
118

    
119
    private final Map<String,String> iconLayers = new HashMap(); //  (Map<String storeProviderName, String iconName>)
120

    
121
    private String defaultVectorLegend;
122

    
123
    private final ObservableHelper observableHelper = new ObservableHelper();
124

    
125
    private File colorTableLibraryFolder = null;
126
    private String defaultRasterLegend;
127

    
128
    @Override
129
    public MapContext createMapContext() {
130
        MapContext mapcontext = new MapContext(new ViewPort());
131
        return (MapContext) notifyObservers(CREATE_MAPCONTEXT, mapcontext).getValue();
132
    }
133

    
134
    @Override
135
    public SymbolManager getSymbolManager() {
136
        return MapContextLocator.getSymbolManager();
137
    }
138

    
139
    private SymbolPreferences getSymbolPreferences() {
140
        return getSymbolManager().getSymbolPreferences();
141
    }
142

    
143
    @Override
144
    public String getSymbolLibraryPath() {
145
        return getSymbolPreferences().getSymbolLibraryPath();
146
    }
147

    
148
    @Override
149
    public void setSymbolLibraryPath(String symbolLibraryPath) {
150
        getSymbolPreferences().setSymbolLibraryPath(symbolLibraryPath);
151
    }
152

    
153
    @Override
154
    public void resetSymbolLibraryPath() {
155
        getSymbolPreferences().resetSymbolLibraryPath();
156
    }
157

    
158
    @Override
159
    public Color getDefaultSymbolColor() {
160
        return getSymbolPreferences().getDefaultSymbolColor();
161
    }
162

    
163
    @Override
164
    public Color getDefaultSymbolFillColor() {
165
        return getSymbolPreferences().getDefaultSymbolFillColor();
166
    }
167

    
168
    @Override
169
    public Font getDefaultSymbolFont() {
170
        return getSymbolPreferences().getDefaultSymbolFont();
171
    }
172

    
173
    public String getSymbolFileExtension() {
174
        return getSymbolPreferences().getSymbolFileExtension();
175
    }
176

    
177
    @Override
178
    public boolean isDefaultSymbolFillColorAleatory() {
179
        return getSymbolPreferences().isDefaultSymbolFillColorAleatory();
180
    }
181

    
182
    @Override
183
    public void resetDefaultSymbolColor() {
184
        getSymbolPreferences().resetDefaultSymbolColor();
185
    }
186

    
187
    @Override
188
    public void resetDefaultSymbolFillColor() {
189
        getSymbolPreferences().resetDefaultSymbolFillColor();
190
    }
191

    
192
    @Override
193
    public void resetDefaultSymbolFillColorAleatory() {
194
        getSymbolPreferences().resetDefaultSymbolFillColorAleatory();
195
    }
196

    
197
    @Override
198
    public void resetDefaultSymbolFont() {
199
        getSymbolPreferences().resetDefaultSymbolFont();
200
    }
201

    
202
    @Override
203
    public void setDefaultSymbolColor(Color defaultSymbolColor) {
204
        getSymbolPreferences().setDefaultSymbolColor(defaultSymbolColor);
205
    }
206

    
207
    @Override
208
    public void setDefaultSymbolFillColor(Color defaultSymbolFillColor) {
209
        getSymbolPreferences().setDefaultSymbolFillColor(defaultSymbolFillColor);
210
    }
211

    
212
    @Override
213
    public void setDefaultSymbolFillColorAleatory(
214
            boolean defaultSymbolFillColorAleatory) {
215
        getSymbolPreferences().setDefaultSymbolFillColorAleatory(
216
                defaultSymbolFillColorAleatory);
217
    }
218

    
219
    @Override
220
    public void setDefaultSymbolFont(Font defaultSymbolFont) {
221
        getSymbolPreferences().setDefaultSymbolFont(defaultSymbolFont);
222
    }
223

    
224
    public void setSymbolFileExtension(String extension) {
225
        getSymbolPreferences().setSymbolFileExtension(extension);
226
    }
227

    
228
    @Override
229
    public int getDefaultCartographicSupportMeasureUnit() {
230
        return getSymbolPreferences().getDefaultCartographicSupportMeasureUnit();
231
    }
232

    
233
    @Override
234
    public void setDefaultCartographicSupportMeasureUnit(
235
            int defaultCartographicSupportMeasureUnit) {
236
        getSymbolPreferences().setDefaultCartographicSupportMeasureUnit(
237
                defaultCartographicSupportMeasureUnit);
238
    }
239

    
240
    @Override
241
    public int getDefaultCartographicSupportReferenceSystem() {
242
        return getSymbolPreferences().getDefaultCartographicSupportReferenceSystem();
243
    }
244

    
245
    @Override
246
    public void setDefaultCartographicSupportReferenceSystem(
247
            int defaultCartographicSupportReferenceSystem) {
248
        getSymbolPreferences().setDefaultCartographicSupportReferenceSystem(
249
                defaultCartographicSupportReferenceSystem);
250
    }
251

    
252
    @Override
253
    public MapContextDrawer createMapContextDrawerInstance(Class drawerClazz)
254
            throws MapContextException {
255
        return createMapContextDrawerInstance(drawerClazz, "NONE");
256
    }
257

    
258
    @Override
259
    public MapContextDrawer createDefaultMapContextDrawerInstance()
260
            throws MapContextException {
261

    
262
        return createMapContextDrawerInstance(drawerClazz, "default");
263
    }
264

    
265
    private MapContextDrawer createMapContextDrawerInstance(Class drawerClazz,
266
            String name) throws RegisteredClassInstantiationException {
267
        try {
268
            MapContextDrawer drawer = (MapContextDrawer) drawerClazz.newInstance();
269
            notifyObservers(CREATE_MAPCONTEXT_DRAWER, drawer);
270
            return drawer;
271
        } catch (Exception ex) {
272
            throw new RegisteredClassInstantiationException(
273
                    MapContextDrawer.class, drawerClazz, name, ex);
274
        }
275
    }
276

    
277
    @Override
278
    public void setDefaultMapContextDrawer(Class drawerClazz)
279
            throws MapContextException {
280

    
281
        validateMapContextDrawer(drawerClazz);
282
        this.drawerClazz = drawerClazz;
283
        notifyObservers(SET_MAPCONTEXT_DRAWER, drawerClazz);
284
    }
285

    
286
    @Override
287
    public void validateMapContextDrawer(Class drawerClazz)
288
            throws MapContextException {
289
        if (!MapContextDrawer.class.isAssignableFrom(drawerClazz)) {
290
            throw new InvalidRegisteredClassException(MapContextDrawer.class,
291
                    drawerClazz, "UNKNOWN");
292
        }
293
    }
294

    
295
    @Override
296
    public GraphicLayer createGraphicsLayer(IProjection projection) {
297
        DefaultGraphicLayer layer = new DefaultGraphicLayer();
298
        try {
299
            layer.initialize(projection);
300
            layer.setLegend((IVectorLegend) createLegend(IVectorialUniqueValueLegend.LEGEND_NAME));
301
        } catch (Exception e) {
302
            LOGGER.error("Error initializing the graphics layer", e);
303
        }
304
        return (GraphicLayer) notifyObservers(CREATE_GRAPHICS_LAYER, layer).getValue();
305
    }
306

    
307
    @Override
308
    public String getDefaultVectorLegend() {
309
        return defaultVectorLegend;
310
    }
311

    
312
    @Override
313
    public void setDefaultVectorLegend(String defaultVectorLegend) {
314
        this.defaultVectorLegend = defaultVectorLegend;
315
    }
316

    
317
    @Override
318
    public String getDefaultRasterLegend() {
319
        return defaultRasterLegend;
320
    }
321

    
322
    @Override
323
    public void setDefaultRasterLegend(String defaultRasterLegend) {
324
        this.defaultRasterLegend = defaultRasterLegend;
325
    }
326
    
327
    @Override
328
    public void registerLegend(String legendName, Class legendClass)
329
            throws MapContextRuntimeException {
330

    
331
        if (legendClass == null || !ILegend.class.isAssignableFrom(legendClass)) {
332
            throw new InvalidRegisteredClassException(ILegend.class,
333
                    legendClass, legendName);
334
        }
335

    
336
        legends.put(legendName, legendClass);
337
        notifyObservers(REGISTER_LEGEND, legendName, legendClass);
338
    }
339

    
340
    @Override
341
    public ILegend createLegend(String legendName)
342
            throws MapContextRuntimeException {
343
        Class legendClass = (Class) legends.get(legendName);
344

    
345
        if (legendClass != null) {
346
            try {
347
                ILegend legend = (ILegend) legendClass.newInstance();
348
                return (ILegend) notifyObservers(CREATE_LEGEND, legend).getValue();
349
            } catch (InstantiationException | IllegalAccessException e) {
350
                throw new RegisteredClassInstantiationException(ILegend.class,
351
                        legendClass, legendName, e);
352
            }
353
        }
354
        return null;
355
    }
356

    
357
    @Override
358
    public IVectorLegend createDefaultVectorLegend(int shapeType)
359
            throws MapContextRuntimeException {
360
        try {
361
            // Create legend
362
            IVectorLegend legend
363
                    = (IVectorLegend) createLegend(getDefaultVectorLegend());
364
            if (legend == null) {
365
                return null;
366
            }
367
            // Set legend values
368
            legend.setShapeType(shapeType);
369
            ISymbol symbol = getSymbolManager().createSymbol(shapeType);
370
            if (symbol == null) {
371
                String msg = "Can't create a legend for the shape type " + shapeType + ". The type can be incorrect or there is not registered a symbol by default for that value. If this a was obtained from the store settings, review your FeatureType have correctly configured this value.";
372
                throw new RuntimeException(msg);
373
            }
374
            legend.setDefaultSymbol(symbol);
375
            return legend;
376
        } catch (Exception e) {
377
            throw new MapContextRuntimeException(e);
378
        }
379
    }
380

    
381
    @Override
382
    public RasterLegend createDefaultRasterLegend(List<BandDescriptor> bands)
383
            throws MapContextRuntimeException {
384
        try {
385
            // Create legend
386
            RasterLegend legend = (RasterLegend) createLegend(getDefaultRasterLegend());
387
            if (legend == null) {
388
                return null;
389
            }
390
            ColorInterpretation colorInterpretation;
391
            RasterLegendManager legendManager = RasterLegendLocator.getRasterLegendManager();
392
            switch (bands.size()) {
393
                case 3:
394
                    colorInterpretation = legendManager.createColorInterpretation(ColorInterpretation.RGB);
395
                    break;
396
                case 4:
397
                    colorInterpretation = legendManager.createColorInterpretation(ColorInterpretation.ARGB);
398
                    break;
399
                default:
400
                    String[] colorBands = new String[bands.size()];
401
                    colorBands[0] = ColorInterpretation.GRAY_BAND;
402
                    for (int i = 1; i < colorBands.length; i++) {
403
                        colorBands[i] = ColorInterpretation.UNDEFINED_BAND;
404
                    }   colorInterpretation = legendManager.createColorInterpretation(colorBands);
405
                    break;
406
            }
407
            legend.setColorInterpretation(colorInterpretation);
408
            legend.addLinearStretchEnhancementOperationIfNeeded(colorInterpretation, bands, 0);
409
            return legend;
410
        } catch (Exception e) {
411
            throw new MapContextRuntimeException(e);
412
        }
413
    }
414

    
415
    // =============================================================
416
    // Legend reading/writing
417

    
418
    private Map<Class<ILegend>,Class<ILegendWriter>> getLegendWritersForFormat(String format) {
419
        synchronized(legendWriters) {
420
            return legendWriters.get(format);
421
        }
422
    }
423

    
424
    private Class<ILegendReader> getLegendReaderForFormat(String format) {
425
        synchronized(legendReaders) {
426
            return legendReaders.get(format);
427
        }
428
    }
429

    
430
    @Override
431
    public List<String> getLegendReadingFormats() {
432
        synchronized(legendReaders) {
433
            List<String> resp = new ArrayList();
434
            resp.addAll(legendReaders.keySet());
435
            return resp;
436
        }
437
    }
438

    
439
    @Override
440
    public List<String> getLegendWritingFormats() {
441
        synchronized(legendWriters) {
442
            List<String> resp = new ArrayList();
443
            resp.addAll(legendWriters.keySet());
444
            return resp;
445
        }
446
    }
447
    
448
    @Override
449
    public void registerLegendReader(String format, Class readerClass)
450
            throws MapContextRuntimeException {
451
        if (readerClass == null
452
                || !ILegendReader.class.isAssignableFrom(readerClass)) {
453
            throw new InvalidRegisteredClassException(ILegendReader.class,
454
                    readerClass, format);
455
        }
456
        synchronized (legendReaders) {
457
            legendReaders.put(format, readerClass);
458
        }
459
        notifyObservers(REGISTER_LEGEND_READER, format, readerClass);
460
    }
461

    
462
    @Override
463
    public void registerLegendWriter(Class legendClass, String format,
464
            Class writerClass) throws MapContextRuntimeException {
465
        if (writerClass == null || legendClass == null
466
                || !ILegendWriter.class.isAssignableFrom(writerClass)
467
                || !ILegend.class.isAssignableFrom(legendClass)) {
468

    
469
            throw new InvalidRegisteredClassException(ILegendWriter.class,
470
                    writerClass, format.concat("-").concat(
471
                            legendClass == null ? "Null" : legendClass.getName()));
472
        }
473

    
474
        synchronized (legendWriters) {
475
            Map<Class<ILegend>, Class<ILegendWriter>> legendWriterOfFormat = legendWriters.get(format);
476
            if (legendWriterOfFormat == null) {
477
                legendWriterOfFormat = new LinkedHashMap();
478
                legendWriters.put(format, legendWriterOfFormat);
479
            }
480
            legendWriterOfFormat.put(legendClass, writerClass);
481
        }
482
        notifyObservers(REGISTER_LEGEND_WRITER, format, writerClass);
483
    }
484

    
485
    @Override
486
    public ILegendReader createLegendReader(String format)
487
            throws MapContextRuntimeException {
488
        Class<ILegendReader> legendReaderClazz = getLegendReaderForFormat(format);
489

    
490
        if (legendReaderClazz != null) {
491
            try {
492
                ILegendReader reader = (ILegendReader) legendReaderClazz.newInstance();
493
                return (ILegendReader) notifyObservers(CREATE_LEGEND_READER, reader).getValue();
494
            } catch (InstantiationException|IllegalAccessException e) {
495
                throw new RegisteredClassInstantiationException(
496
                        ILegendReader.class, legendReaderClazz, format, e);
497
            }
498
        }
499
        return null;
500
    }
501

    
502
    @Override
503
    public ILegendWriter createLegendWriter(Class legendClass, String format)
504
            throws MapContextRuntimeException {
505

    
506
        if (legendClass == null || format == null) {
507
            return null;
508
        }
509

    
510
        Map<Class<ILegend>, Class<ILegendWriter>> legendFormatWriters = getLegendWritersForFormat(format);
511

    
512
        if (legendFormatWriters != null) {
513
            Class<ILegendWriter> legendWriterClazz = legendFormatWriters.get(legendClass);
514
            if (legendWriterClazz != null) {
515
                /*
516
                 * Found exact match
517
                 */
518
                try {
519
                    ILegendWriter writer = (ILegendWriter) legendWriterClazz.newInstance();
520
                    return (ILegendWriter) notifyObservers(CREATE_LEGEND_READER, writer).getValue();
521
                } catch (InstantiationException|IllegalAccessException e) {
522
                    throw new RegisteredClassInstantiationException(
523
                            ILegendWriter.class, 
524
                            legendWriterClazz,
525
                            format.concat("-").concat(legendClass.getName()), 
526
                            e
527
                    );
528
                }
529
            } else {
530
                /*
531
                 * Trying to find superclass/superinterface of parameter
532
                 */
533
                try {
534
                    return getSuperClassLegendWriter(legendFormatWriters, legendClass);
535
                } catch (Exception exc) {
536
                    throw new MapContextRuntimeException(exc);
537
                }
538
            }
539
        }
540
        return null;
541
    }
542

    
543
    private ILegendWriter getSuperClassLegendWriter(Map<Class<ILegend>, Class<ILegendWriter>> clsToWtr, Class<ILegend> legclass)
544
            throws Exception {
545

    
546
        Iterator kiter = clsToWtr.keySet().iterator();
547
        Object oitem;
548
        Class<ILegendWriter> citem;
549
        while (kiter.hasNext()) {
550
            oitem = kiter.next();
551
            if (oitem instanceof Class) {
552
                citem = (Class) oitem;
553
                if (citem.isAssignableFrom(legclass)) {
554
                    /*
555
                     * Found superclass/superinterface
556
                     */
557
                    citem = clsToWtr.get(oitem);
558
                    return (ILegendWriter) citem.newInstance();
559
                }
560
            }
561
        }
562
        /*
563
         * No superclass/superinterface found
564
         */
565
        return null;
566
    }
567

    
568
    // =============================================================
569

    
570
    @Override
571
    public IMultiLayerSymbol createMultiLayerSymbol(int shapeType)
572
            throws MapContextRuntimeException {
573
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(shapeType);
574
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
575
    }
576

    
577
    @Override
578
    public IMultiLayerSymbol createMultiLayerSymbol(String symbolName)
579
            throws MapContextRuntimeException {
580
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(symbolName);
581
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
582
    }
583

    
584
    @Override
585
    public ISymbol createSymbol(int shapeType, Color color)
586
            throws MapContextRuntimeException {
587
        ISymbol symbol = getSymbolManager().createSymbol(shapeType, color);
588
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
589
    }
590

    
591
    @Override
592
    public ISymbol createSymbol(int shapeType)
593
            throws MapContextRuntimeException {
594
        ISymbol symbol = getSymbolManager().createSymbol(shapeType);
595
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
596
    }
597

    
598
    @Override
599
    public ISymbol createSymbol(String symbolName, Color color)
600
            throws MapContextRuntimeException {
601
        ISymbol symbol = getSymbolManager().createSymbol(symbolName, color);
602
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
603
    }
604

    
605
    @Override
606
    public ISymbol createSymbol(String symbolName)
607
            throws MapContextRuntimeException {
608
        ISymbol symbol = getSymbolManager().createSymbol(symbolName);
609
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
610
    }
611

    
612
    @Override
613
    public IWarningSymbol getWarningSymbol(String message, String symbolDesc,
614
            int symbolDrawExceptionType) throws MapContextRuntimeException {
615
        return getSymbolManager().getWarningSymbol(message, symbolDesc,
616
                symbolDrawExceptionType);
617
    }
618

    
619
    public ISymbol[] loadSymbols(File folder, FileFilter filter)
620
            throws SymbolException {
621
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder, filter);
622
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
623
    }
624

    
625
    public ISymbol[] loadSymbols(File folder) throws SymbolException {
626
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder);
627
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
628
    }
629

    
630
    @Override
631
    public void registerMultiLayerSymbol(String symbolName, Class symbolClass)
632
            throws MapContextRuntimeException {
633
        getSymbolManager().registerMultiLayerSymbol(symbolName, symbolClass);
634
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass);
635
    }
636

    
637
    @Override
638
    public void registerMultiLayerSymbol(String symbolName, int[] shapeTypes,
639
            Class symbolClass) throws MapContextRuntimeException {
640
        getSymbolManager().registerMultiLayerSymbol(symbolName, shapeTypes,
641
                symbolClass);
642
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass, shapeTypes);
643
    }
644

    
645
    @Override
646
    public void registerSymbol(String symbolName, Class symbolClass)
647
            throws MapContextRuntimeException {
648
        getSymbolManager().registerSymbol(symbolName, symbolClass);
649
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass);
650
    }
651

    
652
    @Override
653
    public void registerSymbol(String symbolName, int[] shapeTypes,
654
            Class symbolClass) throws MapContextException {
655
        getSymbolManager().registerSymbol(symbolName, shapeTypes, symbolClass);
656
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass, shapeTypes);
657
    }
658

    
659
    public void saveSymbol(ISymbol symbol, String fileName, File folder,
660
            boolean overwrite) throws SymbolException {
661
        getSymbolManager().saveSymbol(symbol, fileName, folder, overwrite);
662
    }
663

    
664
    public void saveSymbol(ISymbol symbol, String fileName, File folder)
665
            throws SymbolException {
666
        getSymbolManager().saveSymbol(symbol, fileName, folder);
667
    }
668

    
669
    @Override
670
    public boolean registerLayer(
671
        Class<? extends DataStore> dataStoreClass,
672
        Class<? extends FLayer> layerClass) 
673
    {
674
        this.layerClassFromStoreClass.put(dataStoreClass, layerClass);
675
        return true;
676
    }    
677
    
678
    private Class<? extends FLayer> getLayerClassFromDataStoreClass(
679
            Class<? extends DataStore> dataStoreClass) {
680
        Class<? extends FLayer> layerClass = this.layerClassFromStoreClass.get(dataStoreClass);
681
        if( layerClass!=null ) {
682
            return layerClass;
683
        }
684
        for (Map.Entry<Class<? extends DataStore>, Class<? extends FLayer>> entry : layerClassFromStoreClass.entrySet()) {
685
            Class<? extends DataStore>  currentDataStoreClass = entry.getKey();
686
            layerClass = entry.getValue();
687
            if( currentDataStoreClass.isAssignableFrom(dataStoreClass) ) {
688
                return layerClass;
689
            }
690
        }
691
        return null;
692
    }
693
    
694
    @Override
695
    public FLayer createLayer(String layerName, DataStoreParameters dataParameters)
696
            throws LoadLayerException {
697
        try {
698
            DataManager dataManager = DALLocator.getDataManager();
699
            DataStore dataStore = dataManager.openStore(
700
                    dataParameters.getDataStoreName(), 
701
                    dataParameters
702
            );
703
            return this.createLayer(layerName, dataStore, null);
704
        } catch (Exception e) {
705
            throw new LoadLayerException(layerName, e);
706
        }
707
    }
708

    
709
    @Override
710
    public FLayer createLayer(String layerName, DataStore dataStore)
711
            throws LoadLayerException {
712
        return this.createLayer(layerName, dataStore, null);
713
    }
714

    
715

    
716
    @Override
717
    public FLayer createLayer(String layerName, CreateLayerParameters parameters) throws LoadLayerException {
718
        try {
719
            DataManager dataManager = DALLocator.getDataManager();
720
            DataStoreParameters dataParameters = parameters.getDataParameters();
721
            DataStore dataStore = dataManager.openStore(
722
                    dataParameters.getDataStoreName(), 
723
                    dataParameters
724
            );
725
            return this.createLayer(layerName, dataStore, parameters);
726
        } catch (Exception e) {
727
            throw new LoadLayerException(layerName, e);
728
        }
729
    }    
730
    
731
    @Override
732
    public FLayer createLayer(String layerName, DataStore dataStore, CreateLayerParameters parameters) throws LoadLayerException {
733
        try {
734
            boolean useCache = false;
735
            ICoordTrans coordTrans = null;
736
            IProjection projection = (IProjection) dataStore.getDynValue(FeatureStore.METADATA_CRS);
737
            
738
            if( parameters!=null ) {
739
                if( parameters.getDataParameters()!=dataStore.getParameters() ) {
740
                    throw new IllegalArgumentException("The dataStore parameters are not the same of the store pased to create layer.");
741
                }
742
                useCache = parameters.useCache();
743
                
744
                coordTrans = parameters.getCoordTrans();
745
                // TODO: Aqui comprobacion de que si hay transformacion es adecuada
746
                // para la proyeccion del store.
747
            }
748
            
749
            if( useCache ) {
750
                DataStoreProviderFactory factory = dataStore.getProviderFactory();
751
                if( factory.isTiledSupported() != DataStoreProviderFactory.NO ) {
752
                    if( !factory.getClass().getSimpleName().equals("TileProviderFactory")) {
753
                        DataManager dataManager = DALLocator.getDataManager();
754
                        DynObject tileParameters = dataManager.createStoreParameters("TileCache");
755
                        File cacheFolder;
756
                        FoldersManager folderManager = ToolsLocator.getFoldersManager();
757
                        File applicationHome = folderManager.get("ApplicationHome");
758
                        if( applicationHome==null ) {
759
                            cacheFolder = folderManager.getTemporaryFile("gvsig_rcache");
760
                        } else {
761
                            cacheFolder = new File(applicationHome, "gvsig_rcache");
762
                        }
763
                        if (tileParameters.getDynClass().getDynField("rootFolder") != null) {
764
                            tileParameters.setDynValue("rootFolder", cacheFolder);
765
                        }
766
                        try {
767
                            dataStore.useCache("TileCache", tileParameters);
768
                        } catch (DataException e) {
769
                            LOGGER.warn("Can't cache the layer.", e);
770
                        }
771
                    }
772
                }
773
            }
774
            
775
            Class<? extends FLayer> layerClass = this.getLayerClassFromDataStoreClass(dataStore.getClass());
776
            if (layerClass == null) {
777
                throw new CantRetrieveLayerByStoreException(layerName, dataStore.getName());
778
            }
779
            FLayer layer;
780
            try {
781
                layer = (FLayer) layerClass.newInstance();
782
            } catch (InstantiationException | IllegalAccessException e) {
783
                throw new LoadLayerException(layerName, e);
784
            }
785

    
786
            layer.setName(layerName);
787
            ((SingleLayer) layer).setDataStore(dataStore);
788
            if (projection != null) {
789
                layer.setProjection(projection);
790
                if( coordTrans != null ) {
791
                    layer.setCoordTrans(coordTrans);
792
                }
793
            }
794
            layer.load();
795
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
796
        } catch (Exception e) {
797
            throw new LoadLayerException(layerName, e);
798
        }
799
    }
800

    
801
    @Override
802
    public ILegend getLegend(DataStore dataStore) {
803
        ILegend legend = null;
804
        ResourcesStorage resourcesStorage = dataStore.getResourcesStorage();
805
        if( resourcesStorage!=null ) {
806
            Resource resource = resourcesStorage.getResource(SymbolManager.LEGEND_FILE_EXTENSION.substring(1));
807
            try {
808
                if ((resource != null) && (resource.exists())) {
809
                    PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
810
                    InputStream is = resource.asInputStream();
811
                    legend = (ILegend) persistenceManager.getObject(is);
812
                    is.close();
813
                }
814
            } catch (Exception e) {
815
                LOGGER.warn("Can't loasd legend", e);
816
            } finally {
817
                IOUtils.closeQuietly(resource);
818
            }
819
        }
820
        //If the legend is null, next option is to check if the store has the getLegend method
821
        if (legend == null) {
822
            try {
823
                legend = (ILegend) dataStore.invokeDynMethod("getLegend", null);
824
            } catch (DynMethodNotSupportedException e) {
825
                LOGGER.debug("This store {} does not provide a legend.",
826
                        dataStore.getName());
827
            } catch (DynMethodException e) {
828
                LOGGER.warn(
829
                        "Can't load the specific legend provided for the store {}.",
830
                        dataStore.getName(), e);
831
            }
832
        }
833

    
834
        //If legend is null, last step is just try to create the legend by default
835
        if (legend == null) {
836
            if( dataStore instanceof FeatureStore ) {
837
                FeatureType featureType;
838
                try {
839
                    featureType = (((FeatureStore) dataStore).getDefaultFeatureType());
840
                    int indexGeom = featureType.getDefaultGeometryAttributeIndex();
841
                    if (indexGeom < 0) {
842
                        throw new IllegalArgumentException("The layer don't has a geometry column.");
843
                    }
844
                    int typeShape = featureType.getAttributeDescriptor(indexGeom).getGeometryType();
845
                    legend = createDefaultVectorLegend(typeShape);
846
                } catch (DataException e) {
847
                    LOGGER.warn("Error getting the default feature type", e);
848
                }
849
                
850
            } else if( dataStore instanceof RasterStore ) {
851
                RasterStore rasterStore = (RasterStore) dataStore;
852
                List<BandDescriptor> bands = rasterStore.getBandDescriptors();
853
                legend = createDefaultRasterLegend(bands);
854
            }
855
        }
856

    
857
        if( legend instanceof RasterLegend ) {
858
            RasterLegend rasterLegend = (RasterLegend) legend;
859
            RasterStore rasterStore = (RasterStore) dataStore;
860
            ColorInterpretation colorInterpretation = rasterLegend.getColorInterpretation();
861
            if (colorInterpretation.isPalette()) {
862
                rasterLegend.addColorTableOperation(colorInterpretation, 0);
863
            } else {
864
                rasterLegend.addLinearStretchEnhancementOperationIfNeeded(
865
                        colorInterpretation, 
866
                        rasterStore.getBandDescriptors(), 
867
                        0);
868
            }
869
            if (colorInterpretation.hasAnyHSLBand()) {
870
                rasterLegend.addHSLToRGBOperation(colorInterpretation);
871
            } else if (colorInterpretation.hasAnyCMYKBand()) {
872
                rasterLegend.addCMYKToRGBOperation(colorInterpretation);
873
            } else if (colorInterpretation.hasAnyYCBCRBand()) {
874
              //TODO: Not implemented yet, meanwhile do nothing
875
    //                legend.addYCBCRToRGBOperation(colorInterpretation);
876
            }        
877
        }
878
        return legend;
879
    }
880

    
881
    @Override
882
    public ILabelingStrategy getLabelingStrategy(DataStore dataStore) {
883
        ILabelingStrategy labelingStrategy = null;
884

    
885
        ResourcesStorage resourcesStorage = dataStore.getResourcesStorage();
886
        if( resourcesStorage!=null ) {
887
            Resource resource = resourcesStorage.getResource(SymbolManager.LABELINGSTRATEGY_FILE_EXTENSION.substring(1));
888
            try {
889
                if ((resource != null) && (resource.exists())) {
890
                    PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
891
                    InputStream is = resource.asInputStream();
892
                    labelingStrategy = (ILabelingStrategy) persistenceManager.getObject(is);
893
                    is.close();
894
                }
895
            } catch (Exception e) {
896
                LOGGER.warn("Can't load Label strategy", e);
897
            } finally {
898
                IOUtils.closeQuietly(resource);
899
            }
900
        }
901

    
902
        //If the legend is null, next option is to check if the store has the getLabeling method
903
        if (labelingStrategy == null) {
904
            try {
905
                labelingStrategy
906
                        = (ILabelingStrategy) dataStore.invokeDynMethod("getLabeling",
907
                                null);
908
            } catch (DynMethodNotSupportedException e1) {
909
                labelingStrategy = null;
910
            } catch (DynMethodException e1) {
911
                LOGGER.error("Can't load the specific labeling strategy provided for the datastore {}.",
912
                        dataStore.getName(),
913
                        e1);
914
            }
915
        }
916

    
917
        return labelingStrategy;
918
    }
919

    
920
    private Object call(Object instance, String methodName, Class[] signature, Object[] params) {
921
        try {
922
            Method method = instance.getClass().getMethod(methodName, signature);
923
            if (method == null) {
924
                return null;
925
            }
926
            Object value = method.invoke(instance, params);
927
            return value;
928
        } catch (Exception ex) {
929
            return null;
930
        }
931
    }
932

    
933
    @Override
934
    public void registerIconLayer(String storeProviderName, String iconName) {
935
        if (storeProviderName == null || iconName == null) {
936
            LOGGER.info("registerIconLayer, storeProviderName or iconName are null");
937
            return;
938
        }
939
        String storeName = storeProviderName.trim().toLowerCase();
940
        if (storeName.length() == 0 || iconName.trim().length() == 0) {
941
            LOGGER.info("registerIconLayer, invalid storeProviderName or iconName");
942
            return;
943
        }
944
        iconLayers.put(storeName, iconName);
945
        notifyObservers(REGISTER_ICON_LAYER, storeName, iconName);
946
    }
947

    
948
        @Override
949
    public String getIconLayer(DataStore store) {
950
        try {
951
            return this.getIconLayer(store.getProviderName());
952
        } catch (Throwable th){
953
            return "layer-icon";
954
        }
955
    }
956

    
957
    @Override
958
    public String getIconLayer(String providerName) {
959
                String name = null;
960
                try {
961
                        name = (String) iconLayers.get(providerName.trim().toLowerCase());
962
                } catch(Throwable th) {
963
                        // Do nothing
964
                }
965
                if( StringUtils.isEmpty(name) ) {
966
                        name = "layer-icon";
967
                }
968
        return name;
969
    }
970

    
971
    /* (non-Javadoc)
972
     * @see org.gvsig.fmap.mapcontext.MapContextManager#getDefaultCRS()
973
     */
974
    @Override
975
    public IProjection getDefaultCRS() {
976
        IProjection crs = CRSFactory.getCRS("EPSG:4326");
977
        return (IProjection) notifyObservers(GET_DEFAULT_CRS, crs).getValue();
978
    }
979

    
980
    public Notification notifyLoadMapContext(MapContext mapContext) {
981
        return this.observableHelper.notifyObservers(this, LOAD_MAPCONTEXT, mapContext);
982
    }
983

    
984
    public Notification notifyLoadLayer(FLayer layer) {
985
        return this.observableHelper.notifyObservers(this, LOAD_LAYER, layer);
986
    }
987

    
988
    @Override
989
    public void addObserver(Observer o) {
990
        this.observableHelper.addObserver(o);
991
    }
992

    
993
    @Override
994
    public void deleteObserver(Observer o) {
995
        this.observableHelper.deleteObserver(o);
996
    }
997

    
998
    @Override
999
    public void deleteObservers() {
1000
        this.observableHelper.deleteObservers();
1001
    }
1002

    
1003
    protected Notification notifyObservers(String type, Object value) {
1004
        return this.observableHelper.notifyObservers(this, type, value);
1005
    }
1006

    
1007
    protected Notification notifyObservers(String type, Object value1, Object value2) {
1008
        return this.observableHelper.notifyObservers(this, type, value1, value2);
1009
    }
1010

    
1011
    protected Notification notifyObservers(String type, Object value1, Object value2, Object value3) {
1012
        return this.observableHelper.notifyObservers(this, type, value1, value2, value3);
1013
    }
1014

    
1015
    @Override
1016
    public File getColorTableLibraryFolder() {
1017
        if (this.colorTableLibraryFolder == null) {
1018
            // Provide a default value to the location for the color
1019
            // table library.
1020
            String colorTableLibraryPath = System.getProperty("user.home")
1021
                    + File.separator
1022
                    + "gvSIG"
1023
                    + File.separator
1024
                    + "colortable";
1025
            this.colorTableLibraryFolder = new File(colorTableLibraryPath);
1026
        }
1027
        return this.colorTableLibraryFolder;
1028
    }
1029

    
1030
    @Override
1031
    public void setColorTableLibraryFolder(File colorTableLibraryFolder) {
1032
        this.colorTableLibraryFolder = colorTableLibraryFolder;
1033
    }
1034

    
1035
    @Override
1036
    public LayerInformationBuilder createLayerInformationBuilder() {
1037
        return new DefaultLayerInformationBuilder();
1038
    }
1039

    
1040

    
1041
}