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

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

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

    
113
    private static final Logger LOGGER = LoggerFactory
114
            .getLogger(DefaultMapContextManager.class);
115

    
116
    private Class drawerClazz = DefaultMapContextDrawer.class;
117

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

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

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

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

    
128
    private String defaultVectorLegend;
129

    
130
    private final ObservableHelper observableHelper = new ObservableHelper();
131

    
132
    private File colorTableLibraryFolder = null;
133
    private String defaultRasterLegend;
134

    
135
    @Override
136
    public MapContext createMapContext() {
137
        MapContext mapcontext = new MapContext(new ViewPort());
138
        return (MapContext) notifyObservers(CREATE_MAPCONTEXT, mapcontext).getValue();
139
    }
140

    
141
    @Override
142
    public SymbolManager getSymbolManager() {
143
        return MapContextLocator.getSymbolManager();
144
    }
145

    
146
    private SymbolPreferences getSymbolPreferences() {
147
        return getSymbolManager().getSymbolPreferences();
148
    }
149

    
150
    @Override
151
    public String getSymbolLibraryPath() {
152
        return getSymbolPreferences().getSymbolLibraryPath();
153
    }
154

    
155
    @Override
156
    public void setSymbolLibraryPath(String symbolLibraryPath) {
157
        getSymbolPreferences().setSymbolLibraryPath(symbolLibraryPath);
158
    }
159

    
160
    @Override
161
    public void resetSymbolLibraryPath() {
162
        getSymbolPreferences().resetSymbolLibraryPath();
163
    }
164

    
165
    @Override
166
    public Color getDefaultSymbolColor() {
167
        return getSymbolPreferences().getDefaultSymbolColor();
168
    }
169

    
170
    @Override
171
    public Color getDefaultSymbolFillColor() {
172
        return getSymbolPreferences().getDefaultSymbolFillColor();
173
    }
174

    
175
    @Override
176
    public Font getDefaultSymbolFont() {
177
        return getSymbolPreferences().getDefaultSymbolFont();
178
    }
179

    
180
    public String getSymbolFileExtension() {
181
        return getSymbolPreferences().getSymbolFileExtension();
182
    }
183

    
184
    @Override
185
    public boolean isDefaultSymbolFillColorAleatory() {
186
        return getSymbolPreferences().isDefaultSymbolFillColorAleatory();
187
    }
188

    
189
    @Override
190
    public void resetDefaultSymbolColor() {
191
        getSymbolPreferences().resetDefaultSymbolColor();
192
    }
193

    
194
    @Override
195
    public void resetDefaultSymbolFillColor() {
196
        getSymbolPreferences().resetDefaultSymbolFillColor();
197
    }
198

    
199
    @Override
200
    public void resetDefaultSymbolFillColorAleatory() {
201
        getSymbolPreferences().resetDefaultSymbolFillColorAleatory();
202
    }
203

    
204
    @Override
205
    public void resetDefaultSymbolFont() {
206
        getSymbolPreferences().resetDefaultSymbolFont();
207
    }
208

    
209
    @Override
210
    public void setDefaultSymbolColor(Color defaultSymbolColor) {
211
        getSymbolPreferences().setDefaultSymbolColor(defaultSymbolColor);
212
    }
213

    
214
    @Override
215
    public void setDefaultSymbolFillColor(Color defaultSymbolFillColor) {
216
        getSymbolPreferences().setDefaultSymbolFillColor(defaultSymbolFillColor);
217
    }
218

    
219
    @Override
220
    public void setDefaultSymbolFillColorAleatory(
221
            boolean defaultSymbolFillColorAleatory) {
222
        getSymbolPreferences().setDefaultSymbolFillColorAleatory(
223
                defaultSymbolFillColorAleatory);
224
    }
225

    
226
    @Override
227
    public void setDefaultSymbolFont(Font defaultSymbolFont) {
228
        getSymbolPreferences().setDefaultSymbolFont(defaultSymbolFont);
229
    }
230

    
231
    public void setSymbolFileExtension(String extension) {
232
        getSymbolPreferences().setSymbolFileExtension(extension);
233
    }
234

    
235
    @Override
236
    public int getDefaultCartographicSupportMeasureUnit() {
237
        return getSymbolPreferences().getDefaultCartographicSupportMeasureUnit();
238
    }
239

    
240
    @Override
241
    public void setDefaultCartographicSupportMeasureUnit(
242
            int defaultCartographicSupportMeasureUnit) {
243
        getSymbolPreferences().setDefaultCartographicSupportMeasureUnit(
244
                defaultCartographicSupportMeasureUnit);
245
    }
246

    
247
    @Override
248
    public int getDefaultCartographicSupportReferenceSystem() {
249
        return getSymbolPreferences().getDefaultCartographicSupportReferenceSystem();
250
    }
251

    
252
    @Override
253
    public void setDefaultCartographicSupportReferenceSystem(
254
            int defaultCartographicSupportReferenceSystem) {
255
        getSymbolPreferences().setDefaultCartographicSupportReferenceSystem(
256
                defaultCartographicSupportReferenceSystem);
257
    }
258

    
259
    @Override
260
    public MapContextDrawer createMapContextDrawerInstance(Class drawerClazz)
261
            throws MapContextException {
262
        return createMapContextDrawerInstance(drawerClazz, "NONE");
263
    }
264

    
265
    @Override
266
    public MapContextDrawer createDefaultMapContextDrawerInstance()
267
            throws MapContextException {
268

    
269
        return createMapContextDrawerInstance(drawerClazz, "default");
270
    }
271

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

    
284
    @Override
285
    public void setDefaultMapContextDrawer(Class drawerClazz)
286
            throws MapContextException {
287

    
288
        validateMapContextDrawer(drawerClazz);
289
        this.drawerClazz = drawerClazz;
290
        notifyObservers(SET_MAPCONTEXT_DRAWER, drawerClazz);
291
    }
292

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

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

    
314
    @Override
315
    public String getDefaultVectorLegend() {
316
        return defaultVectorLegend;
317
    }
318

    
319
    @Override
320
    public void setDefaultVectorLegend(String defaultVectorLegend) {
321
        this.defaultVectorLegend = defaultVectorLegend;
322
    }
323

    
324
    @Override
325
    public String getDefaultRasterLegend() {
326
        return defaultRasterLegend;
327
    }
328

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

    
338
        if (legendClass == null || !ILegend.class.isAssignableFrom(legendClass)) {
339
            throw new InvalidRegisteredClassException(ILegend.class,
340
                    legendClass, legendName);
341
        }
342

    
343
        legends.put(legendName, legendClass);
344
        notifyObservers(REGISTER_LEGEND, legendName, legendClass);
345
    }
346

    
347
    @Override
348
    public ILegend createLegend(String legendName)
349
            throws MapContextRuntimeException {
350
        Class legendClass = (Class) legends.get(legendName);
351

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

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

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

    
422
    // =============================================================
423
    // Legend reading/writing
424

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

    
431
    private Class<ILegendReader> getLegendReaderForFormat(String format) {
432
        synchronized(legendReaders) {
433
            return legendReaders.get(format);
434
        }
435
    }
436

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

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

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

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

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

    
492
    @Override
493
    public ILegendReader createLegendReader(String format)
494
            throws MapContextRuntimeException {
495
        Class<ILegendReader> legendReaderClazz = getLegendReaderForFormat(format);
496

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

    
509
    @Override
510
    public ILegendWriter createLegendWriter(Class legendClass, String format)
511
            throws MapContextRuntimeException {
512

    
513
        if (legendClass == null || format == null) {
514
            return null;
515
        }
516

    
517
        Map<Class<ILegend>, Class<ILegendWriter>> legendFormatWriters = getLegendWritersForFormat(format);
518

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

    
550
    private ILegendWriter getSuperClassLegendWriter(Map<Class<ILegend>, Class<ILegendWriter>> clsToWtr, Class<ILegend> legclass)
551
            throws Exception {
552

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

    
575
    // =============================================================
576

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

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

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

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

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

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

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

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

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

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

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

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

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

    
666
    public void saveSymbol(ISymbol symbol, String fileName, File folder,
667
            boolean overwrite) throws SymbolException {
668
        getSymbolManager().saveSymbol(symbol, fileName, folder, overwrite);
669
    }
670

    
671
    public void saveSymbol(ISymbol symbol, String fileName, File folder)
672
            throws SymbolException {
673
        getSymbolManager().saveSymbol(symbol, fileName, folder);
674
    }
675

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

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

    
722

    
723
    @Override
724
    public FLayer createLayer(String layerName, CreateLayerParameters parameters) throws LoadLayerException {
725
        try {
726
            DataManager dataManager = DALLocator.getDataManager();
727
            DataStoreParameters dataParameters = parameters.getDataParameters();
728
            DataFactory sf = dataManager.getStoreFactory(dataParameters);
729
            
730
            if( sf==null 
731
                    || !StringUtils.equalsIgnoreCase(sf.getName(), "FeatureStore") 
732
                    || parameters.getCoordTrans()!=null 
733
                    || parameters.useCache() 
734
                    || parameters.isVisible()
735
                ) {
736
                DataStore dataStore = dataManager.openStore(
737
                        dataParameters.getProviderName(), 
738
                        dataParameters
739
                );
740
                return this.createLayer(layerName, dataStore, parameters);
741
            }
742
            Class<? extends FLayer> layerClass = this.getLayerClassFromDataStoreClass(FeatureStore.class);
743
            if (layerClass == null) {
744
                throw new CantRetrieveLayerByStoreException(layerName, FeatureStore.class.getName());
745
            }
746
            FLayer layer;
747
            try {
748
                layer = (FLayer) layerClass.newInstance();
749
            } catch (InstantiationException | IllegalAccessException e) {
750
                throw new LoadLayerException(layerName, e);
751
            }
752

    
753
            layer.setName(layerName);
754
            layer.setVisible(false);
755
            ((FLyrVect) layer).setDataStoreParameters(dataParameters);
756
            layer.load();
757
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
758
            
759
        } catch (Exception e) {
760
            throw new LoadLayerException(layerName, e);
761
        }
762
    }    
763
    
764
    @Override
765
    public FLayer createLayer(String layerName, DataStore dataStore, CreateLayerParameters parameters) throws LoadLayerException {
766
        try {
767
            boolean useCache = false;
768
            ICoordTrans coordTrans = null;
769
            IProjection projection = (IProjection) dataStore.getDynValue(FeatureStore.METADATA_CRS);
770
            
771
            if( parameters!=null ) {
772
                if( parameters.getDataParameters()!=dataStore.getParameters() ) {
773
                    throw new IllegalArgumentException("The dataStore parameters are not the same of the store pased to create layer.");
774
                }
775
                useCache = parameters.useCache();
776
                
777
                coordTrans = parameters.getCoordTrans();
778
                // TODO: Aqui comprobacion de que si hay transformacion es adecuada
779
                // para la proyeccion del store.
780
            }
781
            
782
            if( useCache ) {
783
                DataStoreProviderFactory factory = dataStore.getProviderFactory();
784
                if( factory.isTiledSupported() != DataStoreProviderFactory.NO ) {
785
                    if( !factory.getClass().getSimpleName().equals("TileProviderFactory")) {
786
                        DataManager dataManager = DALLocator.getDataManager();
787
                        DynObject tileParameters = dataManager.createStoreParameters("TileCache");
788
                        File cacheFolder;
789
                        FoldersManager folderManager = ToolsLocator.getFoldersManager();
790
                        File applicationHome = folderManager.get("ApplicationHome");
791
                        if( applicationHome==null ) {
792
                            cacheFolder = folderManager.getTemporaryFile("gvsig_rcache");
793
                        } else {
794
                            cacheFolder = new File(applicationHome, "gvsig_rcache");
795
                        }
796
                        if (tileParameters.getDynClass().getDynField("rootFolder") != null) {
797
                            tileParameters.setDynValue("rootFolder", cacheFolder);
798
                        }
799
                        try {
800
                            dataStore.useCache("TileCache", tileParameters);
801
                        } catch (DataException e) {
802
                            LOGGER.warn("Can't cache the layer.", e);
803
                        }
804
                    }
805
                }
806
            }
807
            
808
            Class<? extends FLayer> layerClass = this.getLayerClassFromDataStoreClass(dataStore.getClass());
809
            if (layerClass == null) {
810
                throw new CantRetrieveLayerByStoreException(layerName, dataStore.getName());
811
            }
812
            FLayer layer;
813
            try {
814
                layer = (FLayer) layerClass.newInstance();
815
            } catch (InstantiationException | IllegalAccessException e) {
816
                throw new LoadLayerException(layerName, e);
817
            }
818

    
819
            layer.setName(layerName);
820
            ((SingleLayer) layer).setDataStore(dataStore);
821
            if (projection != null) {
822
                layer.setProjection(projection);
823
                if( coordTrans != null ) {
824
                    layer.setCoordTrans(coordTrans);
825
                }
826
            }
827
            layer.load();
828
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
829
        } catch (Exception e) {
830
            throw new LoadLayerException(layerName, e);
831
        }
832
    }
833

    
834
    @Override
835
    public ILegend getLegend(DataStore dataStore) {
836
        ILegend legend = null;
837
        ResourcesStorage resourcesStorage = null;
838
        try {
839
            resourcesStorage = dataStore.getResourcesStorage();
840
            if( resourcesStorage!=null ) {
841
                Resource resource = resourcesStorage.getResource(SymbolManager.LEGEND_FILE_EXTENSION.substring(1));
842
                try {
843
                    if ((resource != null) && (resource.exists())) {
844
                        PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
845
                        InputStream is = resource.asInputStream();
846
                        legend = (ILegend) persistenceManager.getObject(is);
847
                        is.close();
848
                    }
849
                } catch (Exception e) {
850
                    LOGGER.warn("Can't loasd legend", e);
851
                } finally {
852
                    IOUtils.closeQuietly(resource);
853
                }
854
            }
855
        } finally {
856
            DisposeUtils.disposeQuietly(resourcesStorage);
857
        }
858
        //If the legend is null, next option is to check if the store has the getLegend method
859
        if (legend == null) {
860
            try {
861
                legend = (ILegend) dataStore.invokeDynMethod("getLegend", null);
862
            } catch (DynMethodNotSupportedException e) {
863
                LOGGER.debug("This store {} does not provide a legend.",
864
                        dataStore.getName());
865
            } catch (DynMethodException e) {
866
                LOGGER.warn(
867
                        "Can't load the specific legend provided for the store {}.",
868
                        dataStore.getName(), e);
869
            }
870
        }
871

    
872
        //If legend is null, last step is just try to create the legend by default
873
        if (legend == null) {
874
            if( dataStore instanceof FeatureStore ) {
875
                FeatureType featureType;
876
                try {
877
                    featureType = (((FeatureStore) dataStore).getDefaultFeatureType());
878
                    int indexGeom = featureType.getDefaultGeometryAttributeIndex();
879
                    if (indexGeom < 0) {
880
                        throw new IllegalArgumentException("The layer don't has a geometry column.");
881
                    }
882
                    int typeShape = featureType.getAttributeDescriptor(indexGeom).getGeometryType();
883
                    legend = createDefaultVectorLegend(typeShape);
884
                } catch (DataException e) {
885
                    LOGGER.warn("Error getting the default feature type", e);
886
                }
887
                
888
            } else if( dataStore instanceof RasterStore ) {
889
                RasterStore rasterStore = (RasterStore) dataStore;
890
                List<BandDescriptor> bands = rasterStore.getBandDescriptors();
891
                legend = createDefaultRasterLegend(bands);
892
            }
893
        }
894

    
895
        if( legend instanceof RasterLegend ) {
896
            RasterLegend rasterLegend = (RasterLegend) legend;
897
            RasterStore rasterStore = (RasterStore) dataStore;
898
            ColorInterpretation colorInterpretation = rasterLegend.getColorInterpretation();
899
            if (colorInterpretation.isPalette()) {
900
                rasterLegend.addColorTableOperation(colorInterpretation, 0);
901
            } else {
902
                rasterLegend.addLinearStretchEnhancementOperationIfNeeded(
903
                        colorInterpretation, 
904
                        rasterStore.getBandDescriptors(), 
905
                        0);
906
            }
907
            if (colorInterpretation.hasAnyHSLBand()) {
908
                rasterLegend.addHSLToRGBOperation(colorInterpretation);
909
            } else if (colorInterpretation.hasAnyCMYKBand()) {
910
                rasterLegend.addCMYKToRGBOperation(colorInterpretation);
911
            } else if (colorInterpretation.hasAnyYCBCRBand()) {
912
              //TODO: Not implemented yet, meanwhile do nothing
913
    //                legend.addYCBCRToRGBOperation(colorInterpretation);
914
            }        
915
        }
916
        return legend;
917
    }
918

    
919
    @Override
920
    public ILabelingStrategy getLabelingStrategy(DataStore dataStore) {
921
        ILabelingStrategy labelingStrategy = null;
922

    
923
        ResourcesStorage resourcesStorage = dataStore.getResourcesStorage();
924
        if( resourcesStorage!=null ) {
925
            Resource resource = resourcesStorage.getResource(SymbolManager.LABELINGSTRATEGY_FILE_EXTENSION.substring(1));
926
            try {
927
                if ((resource != null) && (resource.exists())) {
928
                    PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
929
                    InputStream is = resource.asInputStream();
930
                    labelingStrategy = (ILabelingStrategy) persistenceManager.getObject(is);
931
                    is.close();
932
                }
933
            } catch (Exception e) {
934
                LOGGER.warn("Can't load Label strategy", e);
935
            } finally {
936
                IOUtils.closeQuietly(resource);
937
            }
938
        }
939

    
940
        //If the legend is null, next option is to check if the store has the getLabeling method
941
        if (labelingStrategy == null) {
942
            try {
943
                labelingStrategy
944
                        = (ILabelingStrategy) dataStore.invokeDynMethod("getLabeling",
945
                                null);
946
            } catch (DynMethodNotSupportedException e1) {
947
                labelingStrategy = null;
948
            } catch (DynMethodException e1) {
949
                LOGGER.error("Can't load the specific labeling strategy provided for the datastore {}.",
950
                        dataStore.getName(),
951
                        e1);
952
            }
953
        }
954

    
955
        return labelingStrategy;
956
    }
957

    
958
    private Object call(Object instance, String methodName, Class[] signature, Object[] params) {
959
        try {
960
            Method method = instance.getClass().getMethod(methodName, signature);
961
            if (method == null) {
962
                return null;
963
            }
964
            Object value = method.invoke(instance, params);
965
            return value;
966
        } catch (Exception ex) {
967
            return null;
968
        }
969
    }
970

    
971
    @Override
972
    public void registerIconLayer(String storeProviderName, String iconName) {
973
        if (storeProviderName == null || iconName == null) {
974
            LOGGER.info("registerIconLayer, storeProviderName or iconName are null");
975
            return;
976
        }
977
        String storeName = storeProviderName.trim().toLowerCase();
978
        if (storeName.length() == 0 || iconName.trim().length() == 0) {
979
            LOGGER.info("registerIconLayer, invalid storeProviderName or iconName");
980
            return;
981
        }
982
        iconLayers.put(storeName, iconName);
983
        notifyObservers(REGISTER_ICON_LAYER, storeName, iconName);
984
    }
985

    
986
        @Override
987
    public String getIconLayer(DataStore store) {
988
        try {
989
            return this.getIconLayer(store.getProviderName());
990
        } catch (Throwable th){
991
            return "layer-icon";
992
        }
993
    }
994

    
995
    @Override
996
    public String getIconLayer(String providerName) {
997
                String name = null;
998
                try {
999
                        name = (String) iconLayers.get(providerName.trim().toLowerCase());
1000
                } catch(Throwable th) {
1001
                        // Do nothing
1002
                }
1003
                if( StringUtils.isEmpty(name) ) {
1004
                        name = "layer-icon";
1005
                }
1006
        return name;
1007
    }
1008

    
1009
    /* (non-Javadoc)
1010
     * @see org.gvsig.fmap.mapcontext.MapContextManager#getDefaultCRS()
1011
     */
1012
    @Override
1013
    public IProjection getDefaultCRS() {
1014
        IProjection crs = CRSFactory.getCRS("EPSG:4326");
1015
        return (IProjection) notifyObservers(GET_DEFAULT_CRS, crs).getValue();
1016
    }
1017

    
1018
    public Notification notifyLoadMapContext(MapContext mapContext) {
1019
        return this.observableHelper.notifyObservers(this, LOAD_MAPCONTEXT, mapContext);
1020
    }
1021

    
1022
    public Notification notifyLoadLayer(FLayer layer) {
1023
        return this.observableHelper.notifyObservers(this, LOAD_LAYER, layer);
1024
    }
1025

    
1026
    @Override
1027
    public void addObserver(Observer o) {
1028
        this.observableHelper.addObserver(o);
1029
    }
1030

    
1031
    @Override
1032
    public void deleteObserver(Observer o) {
1033
        this.observableHelper.deleteObserver(o);
1034
    }
1035

    
1036
    @Override
1037
    public void deleteObservers() {
1038
        this.observableHelper.deleteObservers();
1039
    }
1040

    
1041
    protected Notification notifyObservers(String type, Object value) {
1042
        return this.observableHelper.notifyObservers(this, type, value);
1043
    }
1044

    
1045
    protected Notification notifyObservers(String type, Object value1, Object value2) {
1046
        return this.observableHelper.notifyObservers(this, type, value1, value2);
1047
    }
1048

    
1049
    protected Notification notifyObservers(String type, Object value1, Object value2, Object value3) {
1050
        return this.observableHelper.notifyObservers(this, type, value1, value2, value3);
1051
    }
1052

    
1053
    @Override
1054
    public File getColorTableLibraryFolder() {
1055
        if (this.colorTableLibraryFolder == null) {
1056
            // Provide a default value to the location for the color
1057
            // table library.
1058
            String colorTableLibraryPath = System.getProperty("user.home")
1059
                    + File.separator
1060
                    + "gvSIG"
1061
                    + File.separator
1062
                    + "colortable";
1063
            this.colorTableLibraryFolder = new File(colorTableLibraryPath);
1064
        }
1065
        return this.colorTableLibraryFolder;
1066
    }
1067

    
1068
    @Override
1069
    public void setColorTableLibraryFolder(File colorTableLibraryFolder) {
1070
        this.colorTableLibraryFolder = colorTableLibraryFolder;
1071
    }
1072

    
1073
    @Override
1074
    public LayerInformationBuilder createLayerInformationBuilder() {
1075
        return new DefaultLayerInformationBuilder();
1076
    }
1077

    
1078
    @Override
1079
    public Icon getIcon(int geometryType, boolean withSelection) {
1080
        try {
1081
            String name;
1082
            switch (geometryType) {
1083
                case Geometry.TYPES.LINE:
1084
                    name = "layer-type-line";
1085
                    break;
1086
                case Geometry.TYPES.POINT:
1087
                    name = "layer-type-point";
1088
                    break;
1089
                case Geometry.TYPES.POLYGON:
1090
                    name = "layer-type-polygon";
1091
                    break;
1092
                case Geometry.TYPES.MULTILINE:
1093
                    name = "layer-type-multiline";
1094
                    break;
1095
                case Geometry.TYPES.MULTIPOINT:
1096
                    name = "layer-type-multipoint";
1097
                    break;
1098
                case Geometry.TYPES.MULTIPOLYGON:
1099
                    name = "layer-type-multipolygon";
1100
                    break;
1101
                case Geometry.TYPES.GEOMETRY:
1102
                    name = "layer-type-mix";
1103
                    break;
1104
                default:
1105
                    return null;
1106
            }
1107
            if (withSelection) {
1108
                name = name + "-sel";
1109
            }
1110
            name = name + ".png";
1111
            URL url = this.getClass().getResource("/layertypes/" + name);
1112
            if (url == null) {
1113
                return null;
1114
            }
1115
            Icon icon = new ImageIcon(url);
1116
            return icon;
1117
        } catch (Exception ex) {
1118
            return null;
1119
        }
1120
    }
1121

    
1122
}