Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / filter / RasterFilterListManager.java @ 17884

History | View | Annotate | Download (13 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.grid.filter;
20

    
21
import java.lang.reflect.Constructor;
22
import java.lang.reflect.InvocationTargetException;
23
import java.util.ArrayList;
24
import java.util.Iterator;
25
import java.util.Map.Entry;
26
import java.util.regex.Matcher;
27
import java.util.regex.Pattern;
28

    
29
import org.gvsig.raster.util.RasterUtilities;
30
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
31
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
32
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
33

    
34
/*
35
 * TODO: FUNCIONALIDAD: Anulada las estad?sticas. Hay que incluirlas de nuevo.
36
 */
37
/**
38
 * Esta clase es de la parte cliente y es la encargada de la gesti?n de la pila
39
 * de filtros. Cada tipo de filtro o conjunto de tipos de filtro deben tener un
40
 * gestor que implementa IRasterFilterManager. Esos gestores deben registrarse
41
 * en esta clase con la funci?n addClassListManager. Este registro puede hacerse
42
 * desde esta misma clase o desde una extensi?n. Un cliente que desee aplicar un
43
 * filtro deber? introducirlo en la lista usando para ello las funciones que su
44
 * manager de filtros le ofrece. Adem?s se encarga de otras funciones como la
45
 * conversi?n de un filtro a cadena de Strings y la recuperaci?n desde cadena de
46
 * Strings y el control de tipos de la salida de un raster de la lista con la
47
 * entrada del siguiente filtro.
48
 *
49
 * @author Nacho Brodin (nachobrodin@gmail.com)
50
 */
51
public class RasterFilterListManager {
52
        protected RasterFilterList        rasterFilterList = null;
53
        private boolean                                debug = false;
54
        protected ArrayList                        filterList = null;
55
        private ArrayList                        managers = new ArrayList();
56

    
57
        /**
58
         * Constructor
59
         * @param filterStack
60
         */
61
        public RasterFilterListManager(RasterFilterList filterStack) {
62
                this.rasterFilterList = filterStack;
63

    
64
                // Cargamos el manager con los gestores de drivers registrados
65

    
66
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
67
                ExtensionPoint extensionPoint = (ExtensionPoint) extensionPoints.get("RasterFilter");
68
                if (extensionPoint == null)
69
                        return;
70
                Iterator iterator = extensionPoint.entrySet().iterator();
71
                while (iterator.hasNext()) {
72
                        Entry entry = (Entry) iterator.next();
73
                        if (entry != null) {
74
                                Class RasterClass = (Class) entry.getValue();
75
                                Object obj = RasterFilterListManager.loadClass(RasterClass, this);
76
                                if (obj != null)
77
                                        managers.add(obj);
78
                        }
79
                }
80
        }
81

    
82
        /**
83
         * Controla que los tipos de los filtros de la pila sean correctos, es decir,
84
         * que el tipo de salida de un filtro de salida coincida con el tipo de la
85
         * entrada del siguiente. En caso de no ser as? crea el filtro de tipo
86
         * adecuado y lo sustituye en el no coincidente. Esto es necesario ya que en
87
         * la eliminaci?n de filtros puede quedarse en inconsistencia de tipos.
88
         */
89
        public void controlTypes() throws FilterTypeException {
90
                ArrayList exceptions = new ArrayList();
91
                for (int i = 0; i < rasterFilterList.lenght(); i++) {
92
                        String classFilter = null, packageFilter = null, oldClass = null;
93
                        try {
94
                                RasterFilter rf = rasterFilterList.get(i);
95
                                if (rf == null)
96
                                        return;
97
                                classFilter = rf.getClass().toString();
98
                                packageFilter = classFilter.substring(classFilter.indexOf(" ") + 1, classFilter.lastIndexOf("."));
99
                                oldClass = classFilter.substring(classFilter.lastIndexOf(".") + 1, classFilter.length());
100
                        } catch (ArrayIndexOutOfBoundsException ex) {
101
                                return;
102
                        } catch (NullPointerException ex) {
103
                                return;
104
                        }
105

    
106
                        // Para el primer filtro comprobamos con el tipo de dato de entrada a la pila
107
                        if (i == 0) {
108
                                if (rasterFilterList.getInitDataType() != rasterFilterList.get(i).getInRasterDataType()) {
109
                                        Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i).getInRasterDataType()));
110
                                        Matcher m = p.matcher(oldClass);
111
                                        String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.getInitDataType()));
112
                                        String strPackage = packageFilter + "." + newClass;
113

    
114
                                        renewFilterFromControlTypes(strPackage, i, exceptions);
115
                                }
116

    
117
                                // Desde el filtro 2 en adelante se compara la salida de uno con la entrada del siguiente
118
                        } else {
119
                                if (rasterFilterList.get(i - 1).getOutRasterDataType() != rasterFilterList.get(i).getInRasterDataType()) {
120
                                        Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i).getInRasterDataType()));
121
                                        Matcher m = p.matcher(oldClass);
122
                                        String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getOutRasterDataType()));
123
                                        String strPackage = packageFilter + "." + newClass;
124
                                        
125
                                        renewFilterFromControlTypes(strPackage.trim(), i, exceptions);
126
                                }
127
                        }
128
                }
129

    
130
                if (exceptions.size() > 0)
131
                        throw new FilterTypeException("");
132

    
133
                if (debug)
134
                        rasterFilterList.show();
135
        }
136
        
137
        /**
138
         * Reemplaza un filtro segun su nombre a la lista de filtros, util para cambiar
139
         * el tipo de datos de un filtro en la pila de filtros.
140
         * @param nameFilter
141
         * @param pos
142
         * @param exceptions
143
         */
144
        private void renewFilterFromControlTypes(String nameFilter, int pos, ArrayList exceptions) {
145
                try {
146
                        RasterFilter newFilter = RasterFilter.createFilter(nameFilter);
147
                        newFilter.params = rasterFilterList.get(pos).params;
148
                        if (newFilter.params.get("filterName") != null)
149
                                newFilter.setName((String) newFilter.params.get("filterName"));
150
                        else
151
                                newFilter.setName(rasterFilterList.get(pos).getName());
152
                        rasterFilterList.replace(newFilter, pos);
153
                } catch (FilterTypeException e) {
154
                        exceptions.add(e);
155
                }
156
        }
157
        
158
        /**
159
         * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en
160
         * la pila y false si no lo est?.
161
         * @param filter Tipo de filtro a comprobar
162
         * @return true si est? en la pila y false si no lo est?
163
         */
164
        public boolean isActive(String name) {
165
                return rasterFilterList.isActive(name);
166
        }
167

    
168
        /**
169
         * Elimina los filtros de la pila de un determinado tipo
170
         *
171
         * @param type Tipo de filtro a eliminar
172
         * @throws FilterTypeException 
173
         */
174
        public void removeFilter(String name) throws FilterTypeException {
175
                rasterFilterList.remove(name);
176
                this.controlTypes();
177
        }
178

    
179
        public ArrayList getStringsFromFilterList() {
180
                filterList = new ArrayList();
181
                for (int i = 0; i < rasterFilterList.lenght(); i++) {
182
                        RasterFilter rf = rasterFilterList.get(i);
183

    
184
                        // Se recorren todos los managers registrados comprobando si corresponde a
185
                        // la clase del filtro
186
                        for (int j = 0; j < managers.size(); j++)
187
                                filterList = ((IRasterFilterListManager) managers.get(j)).getStringsFromFilterList(filterList, rf);
188
                }
189

    
190
                return filterList;
191
        }
192

    
193
        /*
194
         * (non-Javadoc)
195
         * @see org.gvsig.raster.grid.filter.IRasterFilterListManager#createStackFromStrings(java.util.ArrayList, java.lang.String, int)
196
         */
197
        public int createStackFromStrings(ArrayList filters, String fil, int filteri) {
198
                return filteri;
199
        }
200

    
201
        /**
202
         * Crea una pila de filtros a partir de un Array de Strings. Cada elemento del array debe
203
         * tener la forma elemento=valor.
204
         * @param filters
205
         * @throws FilterTypeException 
206
         */
207
        public void createFilterListFromStrings(ArrayList f) throws FilterTypeException {
208
                createFilterListFromStrings(f, new Integer(0));
209
        }
210

    
211
        /**
212
         * Crea una pila de filtros a partir de un Array de Strings. Cada elemento del array debe
213
         * tener la forma elemento=valor.
214
         * @param pos Posici?n desde la cual se empieza a analizar.
215
         * @param filters
216
         * @throws FilterTypeException 
217
         */
218
        private void createFilterListFromStrings(ArrayList f, Integer pos) throws FilterTypeException {
219
                ArrayList filters = (ArrayList) f.clone();
220
                rasterFilterList.clear();
221

    
222
                int filteri = pos.intValue();
223

    
224
                // Busca un filtro activo y despu?s todas las propiedades que necesita ese
225
                // filtro para ser creado. Una vez las tiene a?ade en la pila el tipo de
226
                // filtro.
227
                while ((filters.size() > 0) && (filteri < filters.size())) {
228
                        String fil = (String) filters.get(filteri);
229

    
230
                        for (int j = 0; j < managers.size(); j++) {
231
                                try {
232
                                        filteri = ((IRasterFilterListManager) managers.get(j)).createFilterListFromStrings(filters, fil, filteri);
233
                                } catch (NullPointerException e) {
234
                                }
235
                        }
236

    
237
                        filteri++;
238
                }
239
        }
240

    
241
        /**
242
         * Obtiene el elemento de una cadena de la forma elemento=valor
243
         * @param cadena
244
         * @return
245
         */
246
        public static String getElem(String cadena) {
247
                if (cadena != null) {
248
                        return cadena.substring(0, cadena.indexOf("="));
249
                } else {
250
                        return null;
251
                }
252
        }
253

    
254
        /**
255
         * Obtiene el valor de una cadena de la forma elemento=valor
256
         * @param cadena
257
         * @return
258
         */
259
        public static String getValue(String cadena) {
260
                if (cadena != null) {
261
                        return cadena.substring(cadena.indexOf("=") + 1, cadena.length());
262
                } else {
263
                        return null;
264
                }
265
        }
266

    
267
        /**
268
         * Convierte un rango contenido en una array doble en una cadena de strings
269
         * para poder salvar a xml
270
         * @param rang
271
         * @return
272
         */
273
        /*private String rangeToString(int[][] rang) {
274
                StringBuffer rangoStr = new StringBuffer();
275

276
                if (rang != null) {
277
                        for (int i = 0; i < rang.length; i++) {
278
                                rangoStr.append(String.valueOf(rang[i][0]) + ":");
279
                                rangoStr.append(String.valueOf(rang[i][1]) + ":");
280
                        }
281

282
                        String r = rangoStr.toString();
283

284
                        if (r.endsWith(":")) {
285
                                r = r.substring(0, r.length() - 1);
286
                        }
287

288
                        return r;
289
                } else {
290
                        return null;
291
                }
292
        }*/
293

    
294
        /**
295
         * Convierte una cadena en una lista de rangos numericos para poder asignar
296
         * transparencias a la imagen
297
         * @param rang
298
         * @return
299
         */
300
        /*private int[][] stringToRange(String rang) {
301
                if ((rang != null) && !rang.equals("null")) {
302
                        ArrayList lista = new ArrayList();
303
                        StringTokenizer tokenizer = new StringTokenizer(rang, ":");
304

305
                        while (tokenizer.hasMoreTokens())
306
                                lista.add(tokenizer.nextToken());
307

308
                        int[][] intervalos = new int[(int) (lista.size() / 2)][2];
309

310
                        for (int i = 0; i < lista.size(); i = i + 2) {
311
                                intervalos[i / 2][0] = Integer.valueOf((String) lista.get(i)).intValue();
312
                                intervalos[i / 2][1] = Integer.valueOf((String) lista.get(i + 1)).intValue();
313
                        }
314

315
                        return intervalos;
316
                } else {
317
                        return null;
318
                }
319
        }*/
320

    
321
        /**
322
         * Obtiene la lista de filtros
323
         * @return RasterFilterList
324
         */
325
        public RasterFilterList getFilterList() {
326
                return rasterFilterList;
327
        }
328

    
329
        /**
330
         * Carga una clase pasada por par?metro. Como argumento del constructor de la
331
         * clase se pasar? un RasterFilterStackManager. Esto es usado para instanciar
332
         * los gestores de filtros registrados
333
         * @param clase Clase a instanciar
334
         * @param stackManager Par?metro del constructor de la clase a instanciar
335
         * @return Objeto que corresponde a la instancia de la clase pasada.
336
         */
337
        public static Object loadClass(Class clase, RasterFilterListManager stackManager) {
338
                Object obj = null;
339
                Class[] args = { RasterFilterListManager.class };
340
                try {
341
                        Constructor hazNuevo = clase.getConstructor(args);
342
                        Object[] args2 = { stackManager };
343
                        obj = hazNuevo.newInstance(args2);
344
                } catch (SecurityException e) {
345
                        e.printStackTrace();
346
                } catch (NoSuchMethodException e) {
347
                        e.printStackTrace();
348
                } catch (IllegalArgumentException e) {
349
                        e.printStackTrace();
350
                } catch (InstantiationException e) {
351
                        e.printStackTrace();
352
                } catch (IllegalAccessException e) {
353
                        e.printStackTrace();
354
                } catch (InvocationTargetException e) {
355
                        e.printStackTrace();
356
                }
357
                return obj;
358
        }
359

    
360
        /**
361
         * Obtiene el manager registrado a partir de la clase
362
         * @return
363
         */
364
        public IRasterFilterListManager getManagerByClass(Class c) {
365
                for (int j = 0; j < managers.size(); j++) {
366
                        if (managers.get(j).getClass().equals(c))
367
                                return (IRasterFilterListManager) managers.get(j);
368
                }
369
                return null;
370
        }
371

    
372
        /**
373
         * Obtiene el manager registrado a partir de la clase de un filtro
374
         * @return
375
         */
376
        public IRasterFilterListManager getManagerByFilterClass(Class c) {
377
                for (int i = 0; i < managers.size(); i++)
378
                        for (int j = 0; j < ((IRasterFilterListManager) managers.get(i)).getRasterFilterList().size(); j++)
379
                                if (((IRasterFilterListManager) managers.get(i)).getRasterFilterList().get(j).equals(c))
380
                                        return (IRasterFilterListManager) managers.get(i);
381
                return null;
382
        }
383

    
384
        /*
385
         * (non-Javadoc)
386
         * @see org.gvsig.raster.grid.filter.IRasterFilterListManager#getRasterFilterList()
387
         */
388
        public ArrayList getRasterFilterList() {
389
                ArrayList filters = new ArrayList();
390
                for (int i = 0; i < managers.size(); i++) {
391
                        ArrayList auxFilters = ((IRasterFilterListManager) managers.get(i)).getRasterFilterList();
392
                        for (int j = 0; j < auxFilters.size(); j++) {
393
                                filters.add(auxFilters.get(j));
394
                        }
395
                }
396
                return filters;
397
        }
398
}