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

History | View | Annotate | Download (41.5 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.net.URL;
33
import java.util.ArrayList;
34
import java.util.HashMap;
35
import java.util.Iterator;
36
import java.util.LinkedHashMap;
37
import java.util.List;
38
import java.util.Map;
39
import javax.swing.Icon;
40
import javax.swing.ImageIcon;
41
import org.apache.commons.io.IOUtils;
42
import org.apache.commons.lang3.StringUtils;
43
import org.cresques.cts.ICoordTrans;
44

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

    
103
/**
104
 * Default implementation of the {@link MapContextManager}.
105
 *
106
 */
107
@SuppressWarnings("UseSpecificCatch")
108
public class DefaultMapContextManager implements MapContextManager {
109

    
110
    private static final Logger LOGGER = LoggerFactory
111
            .getLogger(DefaultMapContextManager.class);
112

    
113
    private Class drawerClazz = DefaultMapContextDrawer.class;
114

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

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

    
119
    private final Map<String, Map<Class<ILegend>,Class<ILegendWriter>>> legendWriters = new LinkedHashMap<>();
120
    
121
    private final Map<Class<? extends DataStore>,Class<? extends FLayer>> layerClassFromStoreClass = new HashMap<>();
122

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

    
125
    private String defaultVectorLegend;
126

    
127
    private final ObservableHelper observableHelper = new ObservableHelper();
128

    
129
    private File colorTableLibraryFolder = null;
130
    private String defaultRasterLegend;
131

    
132
    @Override
133
    public MapContext createMapContext() {
134
        MapContext mapcontext = new MapContext(new ViewPort());
135
        return (MapContext) notifyObservers(CREATE_MAPCONTEXT, mapcontext).getValue();
136
    }
137

    
138
    @Override
139
    public SymbolManager getSymbolManager() {
140
        return MapContextLocator.getSymbolManager();
141
    }
142

    
143
    private SymbolPreferences getSymbolPreferences() {
144
        return getSymbolManager().getSymbolPreferences();
145
    }
146

    
147
    @Override
148
    public String getSymbolLibraryPath() {
149
        return getSymbolPreferences().getSymbolLibraryPath();
150
    }
151

    
152
    @Override
153
    public void setSymbolLibraryPath(String symbolLibraryPath) {
154
        getSymbolPreferences().setSymbolLibraryPath(symbolLibraryPath);
155
    }
156

    
157
    @Override
158
    public void resetSymbolLibraryPath() {
159
        getSymbolPreferences().resetSymbolLibraryPath();
160
    }
161

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

    
167
    @Override
168
    public Color getDefaultSymbolFillColor() {
169
        return getSymbolPreferences().getDefaultSymbolFillColor();
170
    }
171

    
172
    @Override
173
    public Font getDefaultSymbolFont() {
174
        return getSymbolPreferences().getDefaultSymbolFont();
175
    }
176

    
177
    public String getSymbolFileExtension() {
178
        return getSymbolPreferences().getSymbolFileExtension();
179
    }
180

    
181
    @Override
182
    public boolean isDefaultSymbolFillColorAleatory() {
183
        return getSymbolPreferences().isDefaultSymbolFillColorAleatory();
184
    }
185

    
186
    @Override
187
    public void resetDefaultSymbolColor() {
188
        getSymbolPreferences().resetDefaultSymbolColor();
189
    }
190

    
191
    @Override
192
    public void resetDefaultSymbolFillColor() {
193
        getSymbolPreferences().resetDefaultSymbolFillColor();
194
    }
195

    
196
    @Override
197
    public void resetDefaultSymbolFillColorAleatory() {
198
        getSymbolPreferences().resetDefaultSymbolFillColorAleatory();
199
    }
200

    
201
    @Override
202
    public void resetDefaultSymbolFont() {
203
        getSymbolPreferences().resetDefaultSymbolFont();
204
    }
205

    
206
    @Override
207
    public void setDefaultSymbolColor(Color defaultSymbolColor) {
208
        getSymbolPreferences().setDefaultSymbolColor(defaultSymbolColor);
209
    }
210

    
211
    @Override
212
    public void setDefaultSymbolFillColor(Color defaultSymbolFillColor) {
213
        getSymbolPreferences().setDefaultSymbolFillColor(defaultSymbolFillColor);
214
    }
215

    
216
    @Override
217
    public void setDefaultSymbolFillColorAleatory(
218
            boolean defaultSymbolFillColorAleatory) {
219
        getSymbolPreferences().setDefaultSymbolFillColorAleatory(
220
                defaultSymbolFillColorAleatory);
221
    }
222

    
223
    @Override
224
    public void setDefaultSymbolFont(Font defaultSymbolFont) {
225
        getSymbolPreferences().setDefaultSymbolFont(defaultSymbolFont);
226
    }
227

    
228
    public void setSymbolFileExtension(String extension) {
229
        getSymbolPreferences().setSymbolFileExtension(extension);
230
    }
231

    
232
    @Override
233
    public int getDefaultCartographicSupportMeasureUnit() {
234
        return getSymbolPreferences().getDefaultCartographicSupportMeasureUnit();
235
    }
236

    
237
    @Override
238
    public void setDefaultCartographicSupportMeasureUnit(
239
            int defaultCartographicSupportMeasureUnit) {
240
        getSymbolPreferences().setDefaultCartographicSupportMeasureUnit(
241
                defaultCartographicSupportMeasureUnit);
242
    }
243

    
244
    @Override
245
    public int getDefaultCartographicSupportReferenceSystem() {
246
        return getSymbolPreferences().getDefaultCartographicSupportReferenceSystem();
247
    }
248

    
249
    @Override
250
    public void setDefaultCartographicSupportReferenceSystem(
251
            int defaultCartographicSupportReferenceSystem) {
252
        getSymbolPreferences().setDefaultCartographicSupportReferenceSystem(
253
                defaultCartographicSupportReferenceSystem);
254
    }
255

    
256
    @Override
257
    public MapContextDrawer createMapContextDrawerInstance(Class drawerClazz)
258
            throws MapContextException {
259
        return createMapContextDrawerInstance(drawerClazz, "NONE");
260
    }
261

    
262
    @Override
263
    public MapContextDrawer createDefaultMapContextDrawerInstance()
264
            throws MapContextException {
265

    
266
        return createMapContextDrawerInstance(drawerClazz, "default");
267
    }
268

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

    
281
    @Override
282
    public void setDefaultMapContextDrawer(Class drawerClazz)
283
            throws MapContextException {
284

    
285
        validateMapContextDrawer(drawerClazz);
286
        this.drawerClazz = drawerClazz;
287
        notifyObservers(SET_MAPCONTEXT_DRAWER, drawerClazz);
288
    }
289

    
290
    @Override
291
    public void validateMapContextDrawer(Class drawerClazz)
292
            throws MapContextException {
293
        if (!MapContextDrawer.class.isAssignableFrom(drawerClazz)) {
294
            throw new InvalidRegisteredClassException(MapContextDrawer.class,
295
                    drawerClazz, "UNKNOWN");
296
        }
297
    }
298

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

    
311
    @Override
312
    public String getDefaultVectorLegend() {
313
        return defaultVectorLegend;
314
    }
315

    
316
    @Override
317
    public void setDefaultVectorLegend(String defaultVectorLegend) {
318
        this.defaultVectorLegend = defaultVectorLegend;
319
    }
320

    
321
    @Override
322
    public String getDefaultRasterLegend() {
323
        return defaultRasterLegend;
324
    }
325

    
326
    @Override
327
    public void setDefaultRasterLegend(String defaultRasterLegend) {
328
        this.defaultRasterLegend = defaultRasterLegend;
329
    }
330
    
331
    @Override
332
    public void registerLegend(String legendName, Class legendClass)
333
            throws MapContextRuntimeException {
334

    
335
        if (legendClass == null || !ILegend.class.isAssignableFrom(legendClass)) {
336
            throw new InvalidRegisteredClassException(ILegend.class,
337
                    legendClass, legendName);
338
        }
339

    
340
        legends.put(legendName, legendClass);
341
        notifyObservers(REGISTER_LEGEND, legendName, legendClass);
342
    }
343

    
344
    @Override
345
    public ILegend createLegend(String legendName)
346
            throws MapContextRuntimeException {
347
        Class legendClass = (Class) legends.get(legendName);
348

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

    
361
    @Override
362
    public IVectorLegend createDefaultVectorLegend(int shapeType)
363
            throws MapContextRuntimeException {
364
        try {
365
            // Create legend
366
            IVectorLegend legend
367
                    = (IVectorLegend) createLegend(getDefaultVectorLegend());
368
            if (legend == null) {
369
                return null;
370
            }
371
            // Set legend values
372
            legend.setShapeType(shapeType);
373
            ISymbol symbol = getSymbolManager().createSymbol(shapeType);
374
            if (symbol == null) {
375
                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.";
376
                throw new RuntimeException(msg);
377
            }
378
            legend.setDefaultSymbol(symbol);
379
            return legend;
380
        } catch (Exception e) {
381
            throw new MapContextRuntimeException(e);
382
        }
383
    }
384

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

    
419
    // =============================================================
420
    // Legend reading/writing
421

    
422
    private Map<Class<ILegend>,Class<ILegendWriter>> getLegendWritersForFormat(String format) {
423
        synchronized(legendWriters) {
424
            return legendWriters.get(format);
425
        }
426
    }
427

    
428
    private Class<ILegendReader> getLegendReaderForFormat(String format) {
429
        synchronized(legendReaders) {
430
            return legendReaders.get(format);
431
        }
432
    }
433

    
434
    @Override
435
    public List<String> getLegendReadingFormats() {
436
        synchronized(legendReaders) {
437
            List<String> resp = new ArrayList();
438
            resp.addAll(legendReaders.keySet());
439
            return resp;
440
        }
441
    }
442

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

    
466
    @Override
467
    public void registerLegendWriter(Class legendClass, String format,
468
            Class writerClass) throws MapContextRuntimeException {
469
        if (writerClass == null || legendClass == null
470
                || !ILegendWriter.class.isAssignableFrom(writerClass)
471
                || !ILegend.class.isAssignableFrom(legendClass)) {
472

    
473
            throw new InvalidRegisteredClassException(ILegendWriter.class,
474
                    writerClass, format.concat("-").concat(
475
                            legendClass == null ? "Null" : legendClass.getName()));
476
        }
477

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

    
489
    @Override
490
    public ILegendReader createLegendReader(String format)
491
            throws MapContextRuntimeException {
492
        Class<ILegendReader> legendReaderClazz = getLegendReaderForFormat(format);
493

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

    
506
    @Override
507
    public ILegendWriter createLegendWriter(Class legendClass, String format)
508
            throws MapContextRuntimeException {
509

    
510
        if (legendClass == null || format == null) {
511
            return null;
512
        }
513

    
514
        Map<Class<ILegend>, Class<ILegendWriter>> legendFormatWriters = getLegendWritersForFormat(format);
515

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

    
547
    private ILegendWriter getSuperClassLegendWriter(Map<Class<ILegend>, Class<ILegendWriter>> clsToWtr, Class<ILegend> legclass)
548
            throws Exception {
549

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

    
572
    // =============================================================
573

    
574
    @Override
575
    public IMultiLayerSymbol createMultiLayerSymbol(int shapeType)
576
            throws MapContextRuntimeException {
577
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(shapeType);
578
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
579
    }
580

    
581
    @Override
582
    public IMultiLayerSymbol createMultiLayerSymbol(String symbolName)
583
            throws MapContextRuntimeException {
584
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(symbolName);
585
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
586
    }
587

    
588
    @Override
589
    public ISymbol createSymbol(int shapeType, Color color)
590
            throws MapContextRuntimeException {
591
        ISymbol symbol = getSymbolManager().createSymbol(shapeType, color);
592
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
593
    }
594

    
595
    @Override
596
    public ISymbol createSymbol(int shapeType)
597
            throws MapContextRuntimeException {
598
        ISymbol symbol = getSymbolManager().createSymbol(shapeType);
599
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
600
    }
601

    
602
    @Override
603
    public ISymbol createSymbol(String symbolName, Color color)
604
            throws MapContextRuntimeException {
605
        ISymbol symbol = getSymbolManager().createSymbol(symbolName, color);
606
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
607
    }
608

    
609
    @Override
610
    public ISymbol createSymbol(String symbolName)
611
            throws MapContextRuntimeException {
612
        ISymbol symbol = getSymbolManager().createSymbol(symbolName);
613
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
614
    }
615

    
616
    @Override
617
    public IWarningSymbol getWarningSymbol(String message, String symbolDesc,
618
            int symbolDrawExceptionType) throws MapContextRuntimeException {
619
        return getSymbolManager().getWarningSymbol(message, symbolDesc,
620
                symbolDrawExceptionType);
621
    }
622

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

    
629
    public ISymbol[] loadSymbols(File folder) throws SymbolException {
630
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder);
631
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
632
    }
633

    
634
    @Override
635
    public void registerMultiLayerSymbol(String symbolName, Class symbolClass)
636
            throws MapContextRuntimeException {
637
        getSymbolManager().registerMultiLayerSymbol(symbolName, symbolClass);
638
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass);
639
    }
640

    
641
    @Override
642
    public void registerMultiLayerSymbol(String symbolName, int[] shapeTypes,
643
            Class symbolClass) throws MapContextRuntimeException {
644
        getSymbolManager().registerMultiLayerSymbol(symbolName, shapeTypes,
645
                symbolClass);
646
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass, shapeTypes);
647
    }
648

    
649
    @Override
650
    public void registerSymbol(String symbolName, Class symbolClass)
651
            throws MapContextRuntimeException {
652
        getSymbolManager().registerSymbol(symbolName, symbolClass);
653
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass);
654
    }
655

    
656
    @Override
657
    public void registerSymbol(String symbolName, int[] shapeTypes,
658
            Class symbolClass) throws MapContextException {
659
        getSymbolManager().registerSymbol(symbolName, shapeTypes, symbolClass);
660
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass, shapeTypes);
661
    }
662

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

    
668
    public void saveSymbol(ISymbol symbol, String fileName, File folder)
669
            throws SymbolException {
670
        getSymbolManager().saveSymbol(symbol, fileName, folder);
671
    }
672

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

    
713
    @Override
714
    public FLayer createLayer(String layerName, DataStore dataStore)
715
            throws LoadLayerException {
716
        return this.createLayer(layerName, dataStore, null);
717
    }
718

    
719

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

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

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

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

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

    
885
    @Override
886
    public ILabelingStrategy getLabelingStrategy(DataStore dataStore) {
887
        ILabelingStrategy labelingStrategy = null;
888

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

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

    
921
        return labelingStrategy;
922
    }
923

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

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

    
952
        @Override
953
    public String getIconLayer(DataStore store) {
954
        try {
955
            return this.getIconLayer(store.getProviderName());
956
        } catch (Throwable th){
957
            return "layer-icon";
958
        }
959
    }
960

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

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

    
984
    public Notification notifyLoadMapContext(MapContext mapContext) {
985
        return this.observableHelper.notifyObservers(this, LOAD_MAPCONTEXT, mapContext);
986
    }
987

    
988
    public Notification notifyLoadLayer(FLayer layer) {
989
        return this.observableHelper.notifyObservers(this, LOAD_LAYER, layer);
990
    }
991

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

    
997
    @Override
998
    public void deleteObserver(Observer o) {
999
        this.observableHelper.deleteObserver(o);
1000
    }
1001

    
1002
    @Override
1003
    public void deleteObservers() {
1004
        this.observableHelper.deleteObservers();
1005
    }
1006

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

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

    
1015
    protected Notification notifyObservers(String type, Object value1, Object value2, Object value3) {
1016
        return this.observableHelper.notifyObservers(this, type, value1, value2, value3);
1017
    }
1018

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

    
1034
    @Override
1035
    public void setColorTableLibraryFolder(File colorTableLibraryFolder) {
1036
        this.colorTableLibraryFolder = colorTableLibraryFolder;
1037
    }
1038

    
1039
    @Override
1040
    public LayerInformationBuilder createLayerInformationBuilder() {
1041
        return new DefaultLayerInformationBuilder();
1042
    }
1043

    
1044
    @Override
1045
    public Icon getIcon(int geometryType, boolean withSelection) {
1046
        try {
1047
            String name;
1048
            switch (geometryType) {
1049
                case Geometry.TYPES.LINE:
1050
                    name = "layer-type-line";
1051
                    break;
1052
                case Geometry.TYPES.POINT:
1053
                    name = "layer-type-point";
1054
                    break;
1055
                case Geometry.TYPES.POLYGON:
1056
                    name = "layer-type-polygon";
1057
                    break;
1058
                case Geometry.TYPES.MULTILINE:
1059
                    name = "layer-type-multiline";
1060
                    break;
1061
                case Geometry.TYPES.MULTIPOINT:
1062
                    name = "layer-type-multipoint";
1063
                    break;
1064
                case Geometry.TYPES.MULTIPOLYGON:
1065
                    name = "layer-type-multipolygon";
1066
                    break;
1067
                case Geometry.TYPES.GEOMETRY:
1068
                    name = "layer-type-mix";
1069
                    break;
1070
                default:
1071
                    return null;
1072
            }
1073
            if (withSelection) {
1074
                name = name + "-sel";
1075
            }
1076
            name = name + ".png";
1077
            URL url = this.getClass().getResource("/layertypes/" + name);
1078
            if (url == null) {
1079
                return null;
1080
            }
1081
            Icon icon = new ImageIcon(url);
1082
            return icon;
1083
        } catch (Exception ex) {
1084
            return null;
1085
        }
1086
    }
1087

    
1088
}