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

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

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

    
116
    private static final Logger LOGGER = LoggerFactory
117
            .getLogger(DefaultMapContextManager.class);
118

    
119
    private static final double DEFAULT_SYMBOL_TRANSPARENCY = 0.6;
120

    
121
    private Class drawerClazz = DefaultMapContextDrawer.class;
122

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

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

    
127
    private final Map<String, Map<Class<ILegend>,Class<ILegendWriter>>> legendWriters = new LinkedHashMap<>();
128
    
129
    private final Map<Object,Class<? extends FLayer>> layerClassFromStoreClass = new HashMap<>();
130

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

    
133
    private String defaultVectorLegend;
134

    
135
    private final ObservableHelper observableHelper = new ObservableHelper();
136

    
137
    private File colorTableLibraryFolder = null;
138
    private String defaultRasterLegend;
139

    
140
    @Override
141
    public MapContext createMapContext() {
142
        MapContext mapcontext = new MapContext(new ViewPort());
143
        return (MapContext) notifyObservers(CREATE_MAPCONTEXT, mapcontext).getValue();
144
    }
145

    
146
    @Override
147
    public SymbolManager getSymbolManager() {
148
        return MapContextLocator.getSymbolManager();
149
    }
150

    
151
    private SymbolPreferences getSymbolPreferences() {
152
        return getSymbolManager().getSymbolPreferences();
153
    }
154

    
155
    @Override
156
    public String getSymbolLibraryPath() {
157
        return getSymbolPreferences().getSymbolLibraryPath();
158
    }
159

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

    
165
    @Override
166
    public void resetSymbolLibraryPath() {
167
        getSymbolPreferences().resetSymbolLibraryPath();
168
    }
169

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

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

    
180
    @Override
181
    public Font getDefaultSymbolFont() {
182
        return getSymbolPreferences().getDefaultSymbolFont();
183
    }
184

    
185
    public String getSymbolFileExtension() {
186
        return getSymbolPreferences().getSymbolFileExtension();
187
    }
188

    
189
    @Override
190
    public boolean isDefaultSymbolFillColorAleatory() {
191
        return getSymbolPreferences().isDefaultSymbolFillColorAleatory();
192
    }
193

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

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

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

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

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

    
219
    @Override
220
    public void setDefaultSymbolFillColor(Color defaultSymbolFillColor) {
221
        getSymbolPreferences().setDefaultSymbolFillColor(defaultSymbolFillColor);
222
    }
223

    
224
    @Override
225
    public void setDefaultSymbolFillColorAleatory(
226
            boolean defaultSymbolFillColorAleatory) {
227
        getSymbolPreferences().setDefaultSymbolFillColorAleatory(
228
                defaultSymbolFillColorAleatory);
229
    }
230

    
231
    @Override
232
    public void setDefaultSymbolFont(Font defaultSymbolFont) {
233
        getSymbolPreferences().setDefaultSymbolFont(defaultSymbolFont);
234
    }
235

    
236
    public void setSymbolFileExtension(String extension) {
237
        getSymbolPreferences().setSymbolFileExtension(extension);
238
    }
239

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

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

    
252
    @Override
253
    public int getDefaultCartographicSupportReferenceSystem() {
254
        return getSymbolPreferences().getDefaultCartographicSupportReferenceSystem();
255
    }
256

    
257
    @Override
258
    public void setDefaultCartographicSupportReferenceSystem(
259
            int defaultCartographicSupportReferenceSystem) {
260
        getSymbolPreferences().setDefaultCartographicSupportReferenceSystem(
261
                defaultCartographicSupportReferenceSystem);
262
    }
263

    
264
    @Override
265
    public MapContextDrawer createMapContextDrawerInstance(Class drawerClazz)
266
            throws MapContextException {
267
        return createMapContextDrawerInstance(drawerClazz, "NONE");
268
    }
269

    
270
    @Override
271
    public MapContextDrawer createDefaultMapContextDrawerInstance()
272
            throws MapContextException {
273

    
274
        return createMapContextDrawerInstance(drawerClazz, "default");
275
    }
276

    
277
    private MapContextDrawer createMapContextDrawerInstance(Class drawerClazz,
278
            String name) throws RegisteredClassInstantiationException {
279
        try {
280
            MapContextDrawer drawer = (MapContextDrawer) drawerClazz.newInstance();
281
            notifyObservers(CREATE_MAPCONTEXT_DRAWER, drawer);
282
            return drawer;
283
        } catch (Exception ex) {
284
            throw new RegisteredClassInstantiationException(
285
                    MapContextDrawer.class, drawerClazz, name, ex);
286
        }
287
    }
288

    
289
    @Override
290
    public void setDefaultMapContextDrawer(Class drawerClazz)
291
            throws MapContextException {
292

    
293
        validateMapContextDrawer(drawerClazz);
294
        this.drawerClazz = drawerClazz;
295
        notifyObservers(SET_MAPCONTEXT_DRAWER, drawerClazz);
296
    }
297

    
298
    @Override
299
    public void validateMapContextDrawer(Class drawerClazz)
300
            throws MapContextException {
301
        if (!MapContextDrawer.class.isAssignableFrom(drawerClazz)) {
302
            throw new InvalidRegisteredClassException(MapContextDrawer.class,
303
                    drawerClazz, "UNKNOWN");
304
        }
305
    }
306

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

    
319
    @Override
320
    public String getDefaultVectorLegend() {
321
        return defaultVectorLegend;
322
    }
323

    
324
    @Override
325
    public void setDefaultVectorLegend(String defaultVectorLegend) {
326
        this.defaultVectorLegend = defaultVectorLegend;
327
    }
328

    
329
    @Override
330
    public String getDefaultRasterLegend() {
331
        return defaultRasterLegend;
332
    }
333

    
334
    @Override
335
    public void setDefaultRasterLegend(String defaultRasterLegend) {
336
        this.defaultRasterLegend = defaultRasterLegend;
337
    }
338
    
339
    @Override
340
    public void registerLegend(String legendName, Class legendClass)
341
            throws MapContextRuntimeException {
342

    
343
        if (legendClass == null || !ILegend.class.isAssignableFrom(legendClass)) {
344
            throw new InvalidRegisteredClassException(ILegend.class,
345
                    legendClass, legendName);
346
        }
347

    
348
        legends.put(legendName, legendClass);
349
        notifyObservers(REGISTER_LEGEND, legendName, legendClass);
350
    }
351

    
352
    @Override
353
    public ILegend createLegend(String legendName)
354
            throws MapContextRuntimeException {
355
        Class legendClass = (Class) legends.get(legendName);
356

    
357
        if (legendClass != null) {
358
            try {
359
                ILegend legend = (ILegend) legendClass.newInstance();
360
                return (ILegend) notifyObservers(CREATE_LEGEND, legend).getValue();
361
            } catch (InstantiationException | IllegalAccessException e) {
362
                throw new RegisteredClassInstantiationException(ILegend.class,
363
                        legendClass, legendName, e);
364
            }
365
        }
366
        return null;
367
    }
368

    
369
    @Override
370
    public IVectorLegend createDefaultVectorLegend(int shapeType)
371
            throws MapContextRuntimeException {
372
        try {
373
            // Create legend
374
            IVectorLegend legend
375
                    = (IVectorLegend) createLegend(getDefaultVectorLegend());
376
            if (legend == null) {
377
                return null;
378
            }
379
            // Set legend values
380
            legend.setShapeType(shapeType);
381
            ISymbol symbol = getSymbolManager().createSymbol(shapeType);
382
            if (symbol == null) {
383
                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.";
384
                throw new RuntimeException(msg);
385
            } 
386
            if( symbol instanceof TransparencySupport && (
387
                    GeometryUtils.isSubtype(Geometry.TYPES.SURFACE,shapeType) ||
388
                    GeometryUtils.isSubtype(Geometry.TYPES.MULTISURFACE,shapeType) )
389
                ) {
390
                ((TransparencySupport)symbol).setTransparency(DEFAULT_SYMBOL_TRANSPARENCY);
391
            }
392
            legend.setDefaultSymbol(symbol);
393
            return legend;
394
        } catch (Exception e) {
395
            throw new MapContextRuntimeException(e);
396
        }
397
    }
398

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

    
433
    // =============================================================
434
    // Legend reading/writing
435

    
436
    private Map<Class<ILegend>,Class<ILegendWriter>> getLegendWritersForFormat(String format) {
437
        synchronized(legendWriters) {
438
            return legendWriters.get(format);
439
        }
440
    }
441

    
442
    private Class<ILegendReader> getLegendReaderForFormat(String format) {
443
        synchronized(legendReaders) {
444
            return legendReaders.get(format);
445
        }
446
    }
447

    
448
    @Override
449
    public List<String> getLegendReadingFormats() {
450
        synchronized(legendReaders) {
451
            List<String> resp = new ArrayList();
452
            resp.addAll(legendReaders.keySet());
453
            return resp;
454
        }
455
    }
456

    
457
    @Override
458
    public List<String> getLegendWritingFormats() {
459
        synchronized(legendWriters) {
460
            List<String> resp = new ArrayList();
461
            resp.addAll(legendWriters.keySet());
462
            return resp;
463
        }
464
    }
465
    
466
    @Override
467
    public void registerLegendReader(String format, Class readerClass)
468
            throws MapContextRuntimeException {
469
        if (readerClass == null
470
                || !ILegendReader.class.isAssignableFrom(readerClass)) {
471
            throw new InvalidRegisteredClassException(ILegendReader.class,
472
                    readerClass, format);
473
        }
474
        synchronized (legendReaders) {
475
            legendReaders.put(format, readerClass);
476
        }
477
        notifyObservers(REGISTER_LEGEND_READER, format, readerClass);
478
    }
479

    
480
    @Override
481
    public void registerLegendWriter(Class legendClass, String format,
482
            Class writerClass) throws MapContextRuntimeException {
483
        if (writerClass == null || legendClass == null
484
                || !ILegendWriter.class.isAssignableFrom(writerClass)
485
                || !ILegend.class.isAssignableFrom(legendClass)) {
486

    
487
            throw new InvalidRegisteredClassException(ILegendWriter.class,
488
                    writerClass, format.concat("-").concat(
489
                            legendClass == null ? "Null" : legendClass.getName()));
490
        }
491

    
492
        synchronized (legendWriters) {
493
            Map<Class<ILegend>, Class<ILegendWriter>> legendWriterOfFormat = legendWriters.get(format);
494
            if (legendWriterOfFormat == null) {
495
                legendWriterOfFormat = new LinkedHashMap();
496
                legendWriters.put(format, legendWriterOfFormat);
497
            }
498
            legendWriterOfFormat.put(legendClass, writerClass);
499
        }
500
        notifyObservers(REGISTER_LEGEND_WRITER, format, writerClass);
501
    }
502

    
503
    @Override
504
    public ILegendReader createLegendReader(String format)
505
            throws MapContextRuntimeException {
506
        Class<ILegendReader> legendReaderClazz = getLegendReaderForFormat(format);
507

    
508
        if (legendReaderClazz != null) {
509
            try {
510
                ILegendReader reader = (ILegendReader) legendReaderClazz.newInstance();
511
                return (ILegendReader) notifyObservers(CREATE_LEGEND_READER, reader).getValue();
512
            } catch (InstantiationException|IllegalAccessException e) {
513
                throw new RegisteredClassInstantiationException(
514
                        ILegendReader.class, legendReaderClazz, format, e);
515
            }
516
        }
517
        return null;
518
    }
519

    
520
    @Override
521
    public ILegendWriter createLegendWriter(Class legendClass, String format)
522
            throws MapContextRuntimeException {
523

    
524
        if (legendClass == null || format == null) {
525
            return null;
526
        }
527

    
528
        Map<Class<ILegend>, Class<ILegendWriter>> legendFormatWriters = getLegendWritersForFormat(format);
529

    
530
        if (legendFormatWriters != null) {
531
            Class<ILegendWriter> legendWriterClazz = legendFormatWriters.get(legendClass);
532
            if (legendWriterClazz != null) {
533
                /*
534
                 * Found exact match
535
                 */
536
                try {
537
                    ILegendWriter writer = (ILegendWriter) legendWriterClazz.newInstance();
538
                    return (ILegendWriter) notifyObservers(CREATE_LEGEND_READER, writer).getValue();
539
                } catch (InstantiationException|IllegalAccessException e) {
540
                    throw new RegisteredClassInstantiationException(
541
                            ILegendWriter.class, 
542
                            legendWriterClazz,
543
                            format.concat("-").concat(legendClass.getName()), 
544
                            e
545
                    );
546
                }
547
            } else {
548
                /*
549
                 * Trying to find superclass/superinterface of parameter
550
                 */
551
                try {
552
                    return getSuperClassLegendWriter(legendFormatWriters, legendClass);
553
                } catch (Exception exc) {
554
                    throw new MapContextRuntimeException(exc);
555
                }
556
            }
557
        }
558
        return null;
559
    }
560

    
561
    private ILegendWriter getSuperClassLegendWriter(Map<Class<ILegend>, Class<ILegendWriter>> clsToWtr, Class<ILegend> legclass)
562
            throws Exception {
563

    
564
        Iterator kiter = clsToWtr.keySet().iterator();
565
        Object oitem;
566
        Class<ILegendWriter> citem;
567
        while (kiter.hasNext()) {
568
            oitem = kiter.next();
569
            if (oitem instanceof Class) {
570
                citem = (Class) oitem;
571
                if (citem.isAssignableFrom(legclass)) {
572
                    /*
573
                     * Found superclass/superinterface
574
                     */
575
                    citem = clsToWtr.get(oitem);
576
                    return (ILegendWriter) citem.newInstance();
577
                }
578
            }
579
        }
580
        /*
581
         * No superclass/superinterface found
582
         */
583
        return null;
584
    }
585

    
586
    // =============================================================
587

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

    
595
    @Override
596
    public IMultiLayerSymbol createMultiLayerSymbol(String symbolName)
597
            throws MapContextRuntimeException {
598
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(symbolName);
599
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
600
    }
601

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

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

    
616
    @Override
617
    public ISymbol createSymbol(String symbolName, Color color)
618
            throws MapContextRuntimeException {
619
        ISymbol symbol = getSymbolManager().createSymbol(symbolName, color);
620
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
621
    }
622

    
623
    @Override
624
    public ISymbol createSymbol(String symbolName)
625
            throws MapContextRuntimeException {
626
        ISymbol symbol = getSymbolManager().createSymbol(symbolName);
627
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
628
    }
629

    
630
    @Override
631
    public IWarningSymbol getWarningSymbol(String message, String symbolDesc,
632
            int symbolDrawExceptionType) throws MapContextRuntimeException {
633
        return getSymbolManager().getWarningSymbol(message, symbolDesc,
634
                symbolDrawExceptionType);
635
    }
636

    
637
    public ISymbol[] loadSymbols(File folder, FileFilter filter)
638
            throws SymbolException {
639
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder, filter);
640
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
641
    }
642

    
643
    public ISymbol[] loadSymbols(File folder) throws SymbolException {
644
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder);
645
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
646
    }
647

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

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

    
663
    @Override
664
    public void registerSymbol(String symbolName, Class symbolClass)
665
            throws MapContextRuntimeException {
666
        getSymbolManager().registerSymbol(symbolName, symbolClass);
667
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass);
668
    }
669

    
670
    @Override
671
    public void registerSymbol(String symbolName, int[] shapeTypes,
672
            Class symbolClass) throws MapContextException {
673
        getSymbolManager().registerSymbol(symbolName, shapeTypes, symbolClass);
674
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass, shapeTypes);
675
    }
676

    
677
    public void saveSymbol(ISymbol symbol, String fileName, File folder,
678
            boolean overwrite) throws SymbolException {
679
        getSymbolManager().saveSymbol(symbol, fileName, folder, overwrite);
680
    }
681

    
682
    public void saveSymbol(ISymbol symbol, String fileName, File folder)
683
            throws SymbolException {
684
        getSymbolManager().saveSymbol(symbol, fileName, folder);
685
    }
686

    
687
    @Override
688
    public boolean registerLayer(
689
        Class theClass,
690
        Class<? extends FLayer> layerClass) 
691
    {
692
        this.layerClassFromStoreClass.put(theClass, layerClass);
693
        return true;
694
    }    
695

    
696
    @Override
697
    public boolean registerLayer(Factory<FLayer> factory) {
698
        this.layerClassFromStoreClass.put(factory, null);
699
        return true;
700
    }
701
    
702
    private FLayer newLayer(DataStore dataStore) {
703
        for (Map.Entry<Object, Class<? extends FLayer>> entry : layerClassFromStoreClass.entrySet()) {
704
            Object  currentKey = entry.getKey();
705
            if( currentKey instanceof Factory ) {
706
                Factory<FLayer> factory = (Factory<FLayer>) currentKey;
707
                FLayer layer = factory.create(dataStore.getParameters(), dataStore);
708
                if( layer != null ) {
709
                    return layer;
710
                }
711
            }
712
        }
713
        return null;
714
    }
715
    
716
    private Class<? extends FLayer> getLayerClass(
717
            Class keyClass) {
718
        Class<? extends FLayer> layerClass = this.layerClassFromStoreClass.get(keyClass);
719
        if( layerClass!=null ) {
720
            return layerClass;
721
        }
722
        for (Map.Entry<Object, Class<? extends FLayer>> entry : layerClassFromStoreClass.entrySet()) {
723
            Object  currentKey = entry.getKey();
724
            if( currentKey instanceof Class ) {
725
                Class  currentKeyClass = (Class) currentKey;
726
                layerClass = entry.getValue();
727
                if( currentKeyClass.isAssignableFrom(keyClass) ) {
728
                    return layerClass;
729
                }
730
            }
731
        }
732
        return null;
733
    }
734
    
735
    @Override
736
    public FLayer createLayer(String layerName, DataStoreParameters dataParameters)
737
            throws LoadLayerException {
738
        try {
739
            DataManager dataManager = DALLocator.getDataManager();
740
            DataStore dataStore = dataManager.openStore(
741
                    dataParameters.getDataStoreName(), 
742
                    dataParameters
743
            );
744
            return this.createLayer(layerName, dataStore, null);
745
        } catch (Exception e) {
746
            throw new LoadLayerException(layerName, e);
747
        }
748
    }
749

    
750
    @Override
751
    public FLayer createLayer(String layerName, DataStore dataStore)
752
            throws LoadLayerException {
753
        return this.createLayer(layerName, dataStore, null);
754
    }
755

    
756

    
757
    @Override
758
    public FLayer createLayer(String layerName, CreateLayerParameters parameters) throws LoadLayerException {
759
        try {
760
            DataManager dataManager = DALLocator.getDataManager();
761
            DataStoreParameters dataParameters = parameters.getDataParameters();
762
            DataFactory sf = dataManager.getStoreFactory(dataParameters);
763
            
764
            if( sf==null 
765
                    || !StringUtils.equalsIgnoreCase(sf.getName(), "FeatureStore") 
766
                    || parameters.getCoordTrans()!=null 
767
                    || parameters.useCache() 
768
                    || parameters.isVisible()
769
                ) {
770
                DataStore dataStore = dataManager.openStore(
771
                        dataParameters.getProviderName(), 
772
                        dataParameters
773
                );
774
                return this.createLayer(layerName, dataStore, parameters);
775
            }
776
            Class<? extends FLayer> layerClass = this.getLayerClass(FeatureStore.class);
777
            if (layerClass == null) {
778
                throw new CantRetrieveLayerByStoreException(layerName, FeatureStore.class.getName());
779
            }
780
            FLayer layer;
781
            try {
782
                layer = (FLayer) layerClass.newInstance();
783
            } catch (InstantiationException | IllegalAccessException e) {
784
                throw new LoadLayerException(layerName, e);
785
            }
786

    
787
            layer.setName(layerName);
788
            layer.setVisible(false);
789
            ((FLyrVect) layer).setDataStoreParameters(dataParameters);
790
            layer.load();
791
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
792
            
793
        } catch (Exception e) {
794
            throw new LoadLayerException(layerName, e);
795
        }
796
    }    
797
    
798
    @Override
799
    public FLayer createLayer(String layerName, DataStore dataStore, CreateLayerParameters parameters) throws LoadLayerException {
800
        try {
801
            boolean useCache = false;
802
            ICoordTrans coordTrans = null;
803
            IProjection projection = (IProjection) dataStore.getDynValue(FeatureStore.METADATA_CRS);
804
            
805
            if( parameters!=null ) {
806
                if( parameters.getDataParameters()!=dataStore.getParameters() ) {
807
                    throw new IllegalArgumentException("The dataStore parameters are not the same of the store pased to create layer.");
808
                }
809
                useCache = parameters.useCache();
810
                
811
                coordTrans = parameters.getCoordTrans();
812
                // TODO: Aqui comprobacion de que si hay transformacion es adecuada
813
                // para la proyeccion del store.
814
            }
815
            
816
            if( useCache ) {
817
                DataStoreProviderFactory factory = dataStore.getProviderFactory();
818
                if( factory.isTiledSupported() != DataStoreProviderFactory.NO ) {
819
                    if( !factory.getClass().getSimpleName().equals("TileProviderFactory")) {
820
                        DataManager dataManager = DALLocator.getDataManager();
821
                        DynObject tileParameters = dataManager.createStoreParameters("TileCache");
822
                        File cacheFolder;
823
                        FoldersManager folderManager = ToolsLocator.getFoldersManager();
824
                        File applicationHome = folderManager.get("ApplicationHome");
825
                        if( applicationHome==null ) {
826
                            cacheFolder = folderManager.getTemporaryFile("gvsig_rcache");
827
                        } else {
828
                            cacheFolder = new File(applicationHome, "gvsig_rcache");
829
                        }
830
                        if (tileParameters.getDynClass().getDynField("rootFolder") != null) {
831
                            tileParameters.setDynValue("rootFolder", cacheFolder);
832
                        }
833
                        try {
834
                            dataStore.useCache("TileCache", tileParameters);
835
                        } catch (DataException e) {
836
                            LOGGER.warn("Can't cache the layer.", e);
837
                        }
838
                    }
839
                }
840
            }
841
            FLayer layer = this.newLayer(dataStore);
842
            if( layer == null ) {
843
                Class<? extends FLayer> layerClass = this.getLayerClass(dataStore.getParameters().getClass());
844
                if (layerClass == null) {
845
                    layerClass = this.getLayerClass(dataStore.getProviderFactory().getClass());
846
                    if (layerClass == null) {
847
                        layerClass = this.getLayerClass(dataStore.getClass());
848
                    }
849
                    if (layerClass == null) {
850
                        throw new CantRetrieveLayerByStoreException(layerName, dataStore.getName());
851
                    }
852
                }
853
                try {
854
                    layer = (FLayer) layerClass.newInstance();
855
                } catch (InstantiationException | IllegalAccessException e) {
856
                    throw new LoadLayerException(layerName, e);
857
                }
858
            }
859
            layer.setName(layerName);
860
            ((SingleLayer) layer).setDataStore(dataStore);
861
            if (projection != null) {
862
                layer.setProjection(projection);
863
                if( coordTrans != null ) {
864
                    layer.setCoordTrans(coordTrans);
865
                }
866
            }
867
            layer.load();
868
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
869
        } catch (Exception e) {
870
            throw new LoadLayerException(layerName, e);
871
        }
872
    }
873

    
874
    @Override
875
    public ILegend getLegend(DataStore dataStore) {
876
        ILegend legend = null;
877
        ResourcesStorage resourcesStorage = null;
878
        try {
879
            resourcesStorage = dataStore.getResourcesStorage();
880
            if( resourcesStorage!=null ) {
881
                Resource resource = resourcesStorage.getResource(SymbolManager.LEGEND_FILE_EXTENSION.substring(1));
882
                try {
883
                    if ((resource != null) && (resource.exists())) {
884
                        PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
885
                        InputStream is = resource.asInputStream();
886
                        legend = (ILegend) persistenceManager.getObject(is);
887
                        is.close();
888
                    }
889
                } catch (Exception e) {
890
                    LOGGER.warn("Can't loasd legend", e);
891
                } finally {
892
                    IOUtils.closeQuietly(resource);
893
                }
894
            }
895
        } finally {
896
            DisposeUtils.disposeQuietly(resourcesStorage);
897
        }
898
        //If the legend is null, next option is to check if the store has the getLegend method
899
        if (legend == null) {
900
            try {
901
                legend = (ILegend) dataStore.invokeDynMethod("getLegend", null);
902
            } catch (DynMethodNotSupportedException e) {
903
                LOGGER.debug("This store {} does not provide a legend.",
904
                        dataStore.getName());
905
            } catch (DynMethodException e) {
906
                LOGGER.warn(
907
                        "Can't load the specific legend provided for the store {}.",
908
                        dataStore.getName(), e);
909
            }
910
        }
911

    
912
        //If legend is null, last step is just try to create the legend by default
913
        if (legend == null) {
914
            if( dataStore instanceof FeatureStore ) {
915
                FeatureType featureType;
916
                try {
917
                    featureType = (((FeatureStore) dataStore).getDefaultFeatureType());
918
                    int indexGeom = featureType.getDefaultGeometryAttributeIndex();
919
                    if (indexGeom < 0) {
920
                        throw new IllegalArgumentException("The layer don't has a geometry column.");
921
                    }
922
                    int typeShape = featureType.getAttributeDescriptor(indexGeom).getGeometryType();
923
                    legend = createDefaultVectorLegend(typeShape);
924
                } catch (DataException e) {
925
                    LOGGER.warn("Error getting the default feature type", e);
926
                }
927
                
928
            } else if( dataStore instanceof RasterStore ) {
929
                RasterStore rasterStore = (RasterStore) dataStore;
930
                List<BandDescriptor> bands = rasterStore.getBandDescriptors();
931
                legend = createDefaultRasterLegend(bands);
932
            }
933
        }
934

    
935
        if( legend instanceof RasterLegend ) {
936
            RasterLegend rasterLegend = (RasterLegend) legend;
937
            RasterStore rasterStore = (RasterStore) dataStore;
938
            ColorInterpretation colorInterpretation = rasterLegend.getColorInterpretation();
939
            if (colorInterpretation.isPalette()) {
940
                rasterLegend.addColorTableOperation(colorInterpretation, 0);
941
            } else {
942
                rasterLegend.addLinearStretchEnhancementOperationIfNeeded(
943
                        colorInterpretation, 
944
                        rasterStore.getBandDescriptors(), 
945
                        0);
946
            }
947
            if (colorInterpretation.hasAnyHSLBand()) {
948
                rasterLegend.addHSLToRGBOperation(colorInterpretation);
949
            } else if (colorInterpretation.hasAnyCMYKBand()) {
950
                rasterLegend.addCMYKToRGBOperation(colorInterpretation);
951
            } else if (colorInterpretation.hasAnyYCBCRBand()) {
952
              //TODO: Not implemented yet, meanwhile do nothing
953
    //                legend.addYCBCRToRGBOperation(colorInterpretation);
954
            }        
955
        }
956
        return legend;
957
    }
958

    
959
    @Override
960
    public ILabelingStrategy getLabelingStrategy(DataStore dataStore) {
961
        ILabelingStrategy labelingStrategy = null;
962

    
963
        ResourcesStorage resourcesStorage = dataStore.getResourcesStorage();
964
        if( resourcesStorage!=null ) {
965
            Resource resource = resourcesStorage.getResource(SymbolManager.LABELINGSTRATEGY_FILE_EXTENSION.substring(1));
966
            try {
967
                if ((resource != null) && (resource.exists())) {
968
                    PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
969
                    InputStream is = resource.asInputStream();
970
                    labelingStrategy = (ILabelingStrategy) persistenceManager.getObject(is);
971
                    is.close();
972
                }
973
            } catch (Exception e) {
974
                LOGGER.warn("Can't load Label strategy", e);
975
            } finally {
976
                IOUtils.closeQuietly(resource);
977
            }
978
        }
979

    
980
        //If the legend is null, next option is to check if the store has the getLabeling method
981
        if (labelingStrategy == null) {
982
            try {
983
                labelingStrategy
984
                        = (ILabelingStrategy) dataStore.invokeDynMethod("getLabeling",
985
                                null);
986
            } catch (DynMethodNotSupportedException e1) {
987
                labelingStrategy = null;
988
            } catch (DynMethodException e1) {
989
                LOGGER.error("Can't load the specific labeling strategy provided for the datastore {}.",
990
                        dataStore.getName(),
991
                        e1);
992
            }
993
        }
994

    
995
        return labelingStrategy;
996
    }
997

    
998
    private Object call(Object instance, String methodName, Class[] signature, Object[] params) {
999
        try {
1000
            Method method = instance.getClass().getMethod(methodName, signature);
1001
            if (method == null) {
1002
                return null;
1003
            }
1004
            Object value = method.invoke(instance, params);
1005
            return value;
1006
        } catch (Exception ex) {
1007
            return null;
1008
        }
1009
    }
1010

    
1011
    @Override
1012
    public void registerIconLayer(String storeProviderName, String iconName) {
1013
        if (storeProviderName == null || iconName == null) {
1014
            LOGGER.info("registerIconLayer, storeProviderName or iconName are null");
1015
            return;
1016
        }
1017
        String storeName = storeProviderName.trim().toLowerCase();
1018
        if (storeName.length() == 0 || iconName.trim().length() == 0) {
1019
            LOGGER.info("registerIconLayer, invalid storeProviderName or iconName");
1020
            return;
1021
        }
1022
        iconLayers.put(storeName, iconName);
1023
        notifyObservers(REGISTER_ICON_LAYER, storeName, iconName);
1024
    }
1025

    
1026
        @Override
1027
    public String getIconLayer(DataStore store) {
1028
        try {
1029
            return this.getIconLayer(store.getProviderName());
1030
        } catch (Throwable th){
1031
            return "layer-icon";
1032
        }
1033
    }
1034

    
1035
    @Override
1036
    public String getIconLayer(String providerName) {
1037
                String name = null;
1038
                try {
1039
                        name = (String) iconLayers.get(providerName.trim().toLowerCase());
1040
                } catch(Throwable th) {
1041
                        // Do nothing
1042
                }
1043
                if( StringUtils.isEmpty(name) ) {
1044
                        name = "layer-icon";
1045
                }
1046
        return name;
1047
    }
1048

    
1049
    /* (non-Javadoc)
1050
     * @see org.gvsig.fmap.mapcontext.MapContextManager#getDefaultCRS()
1051
     */
1052
    @Override
1053
    public IProjection getDefaultCRS() {
1054
        IProjection crs = CRSFactory.getCRS("EPSG:4326");
1055
        return (IProjection) notifyObservers(GET_DEFAULT_CRS, crs).getValue();
1056
    }
1057

    
1058
    public Notification notifyLoadMapContext(MapContext mapContext) {
1059
        return this.observableHelper.notifyObservers(this, LOAD_MAPCONTEXT, mapContext);
1060
    }
1061

    
1062
    public Notification notifyLoadLayer(FLayer layer) {
1063
        return this.observableHelper.notifyObservers(this, LOAD_LAYER, layer);
1064
    }
1065

    
1066
    @Override
1067
    public void addObserver(Observer o) {
1068
        this.observableHelper.addObserver(o);
1069
    }
1070

    
1071
    @Override
1072
    public void deleteObserver(Observer o) {
1073
        this.observableHelper.deleteObserver(o);
1074
    }
1075

    
1076
    @Override
1077
    public void deleteObservers() {
1078
        this.observableHelper.deleteObservers();
1079
    }
1080

    
1081
    protected Notification notifyObservers(String type, Object value) {
1082
        return this.observableHelper.notifyObservers(this, type, value);
1083
    }
1084

    
1085
    protected Notification notifyObservers(String type, Object value1, Object value2) {
1086
        return this.observableHelper.notifyObservers(this, type, value1, value2);
1087
    }
1088

    
1089
    protected Notification notifyObservers(String type, Object value1, Object value2, Object value3) {
1090
        return this.observableHelper.notifyObservers(this, type, value1, value2, value3);
1091
    }
1092

    
1093
    @Override
1094
    public File getColorTableLibraryFolder() {
1095
        if (this.colorTableLibraryFolder == null) {
1096
            // Provide a default value to the location for the color
1097
            // table library.
1098
            String colorTableLibraryPath = System.getProperty("user.home")
1099
                    + File.separator
1100
                    + "gvSIG"
1101
                    + File.separator
1102
                    + "colortable";
1103
            this.colorTableLibraryFolder = new File(colorTableLibraryPath);
1104
        }
1105
        return this.colorTableLibraryFolder;
1106
    }
1107

    
1108
    @Override
1109
    public void setColorTableLibraryFolder(File colorTableLibraryFolder) {
1110
        this.colorTableLibraryFolder = colorTableLibraryFolder;
1111
    }
1112

    
1113
    @Override
1114
    public LayerInformationBuilder createLayerInformationBuilder() {
1115
        return new DefaultLayerInformationBuilder();
1116
    }
1117

    
1118
    @Override
1119
    public Icon getIcon(int geometryType, boolean withSelection) {
1120
        try {
1121
            String name;
1122
            switch (geometryType) {
1123
                case Geometry.TYPES.LINE:
1124
                    name = "layer-type-line";
1125
                    break;
1126
                case Geometry.TYPES.POINT:
1127
                    name = "layer-type-point";
1128
                    break;
1129
                case Geometry.TYPES.POLYGON:
1130
                    name = "layer-type-polygon";
1131
                    break;
1132
                case Geometry.TYPES.MULTILINE:
1133
                    name = "layer-type-multiline";
1134
                    break;
1135
                case Geometry.TYPES.MULTIPOINT:
1136
                    name = "layer-type-multipoint";
1137
                    break;
1138
                case Geometry.TYPES.MULTIPOLYGON:
1139
                    name = "layer-type-multipolygon";
1140
                    break;
1141
                case Geometry.TYPES.GEOMETRY:
1142
                    name = "layer-type-mix";
1143
                    break;
1144
                default:
1145
                    return null;
1146
            }
1147
            if (withSelection) {
1148
                name = name + "-sel";
1149
            }
1150
            name = name + ".png";
1151
            URL url = this.getClass().getResource("/layertypes/" + name);
1152
            if (url == null) {
1153
                return null;
1154
            }
1155
            Icon icon = new ImageIcon(url);
1156
            return icon;
1157
        } catch (Exception ex) {
1158
            return null;
1159
        }
1160
    }
1161

    
1162
}