Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / operations / DefaultOperationList.java @ 8800

History | View | Annotate | Download (17.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2017 gvSIG Association
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., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.raster.lib.buffer.impl.operations;
24

    
25
import java.util.ArrayList;
26
import java.util.Collection;
27
import java.util.HashSet;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.ListIterator;
31
import java.util.Set;
32

    
33
import org.apache.commons.lang3.StringUtils;
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.raster.lib.buffer.api.Buffer;
38
import org.gvsig.raster.lib.buffer.api.BufferLocator;
39
import org.gvsig.raster.lib.buffer.api.OperationManager;
40
import org.gvsig.raster.lib.buffer.api.exceptions.BufferOperationException;
41
import org.gvsig.raster.lib.buffer.api.operations.InvalidLookupParametersException;
42
import org.gvsig.raster.lib.buffer.api.operations.InvalidLookupParametersException.Problem;
43
import org.gvsig.raster.lib.buffer.api.operations.Operation;
44
import org.gvsig.raster.lib.buffer.api.operations.OperationFactory;
45
import org.gvsig.raster.lib.buffer.api.operations.OperationFactory.Applicable;
46
import org.gvsig.raster.lib.buffer.api.operations.OperationList;
47
import org.gvsig.raster.lib.buffer.api.operations.OperationListEntry;
48
import org.gvsig.raster.lib.buffer.api.operations.OperationListNotification;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.dynobject.DynClass;
51
import org.gvsig.tools.dynobject.DynField;
52
import org.gvsig.tools.dynobject.DynField_v2;
53
import org.gvsig.tools.dynobject.DynObject;
54
import org.gvsig.tools.dynobject.DynStruct;
55
import org.gvsig.tools.observer.impl.BaseWeakReferencingObservable;
56
import org.gvsig.tools.persistence.PersistenceManager;
57
import org.gvsig.tools.persistence.PersistentState;
58
import org.gvsig.tools.persistence.exception.PersistenceException;
59

    
60

    
61
/**
62
 * @author fdiaz
63
 *
64
 */
65
public class DefaultOperationList extends BaseWeakReferencingObservable implements OperationList {
66

    
67
    private static final Logger LOG = LoggerFactory.getLogger(DefaultOperationList.class);
68

    
69
    /**
70
     * Persistence definition name
71
     */
72
    public static final String PERSISTENT_NAME = "OperationListPersistence";
73
    /**
74
     * Description of persistence definition
75
     */
76
    public static final String PERSISTENT_DESCRIPTION = "Persistence definition of operation list";
77

    
78
    private final static String OPERATIONS_PERSISTENCE_FIELD = "operations";
79

    
80

    
81
    private List<OperationListEntry> operations;
82

    
83
    private DynObject defaultParameters = null;
84

    
85
    /**
86
     *
87
     */
88
    public DefaultOperationList() {
89
        this.operations = new ArrayList<OperationListEntry>();
90
    }
91

    
92
    @Override
93
    public int size() {
94
        return this.operations.size();
95
    }
96

    
97
    @Override
98
    public boolean isEmpty() {
99
        return this.operations.isEmpty();
100
    }
101

    
102
    @Override
103
    public boolean contains(Object o) {
104
        return this.operations.contains(o);
105
    }
106

    
107
    @Override
108
    public Iterator<OperationListEntry> iterator() {
109
        return this.operations.iterator();
110
    }
111

    
112
    @Override
113
    public Object[] toArray() {
114
        return this.operations.toArray();
115
    }
116

    
117
    @Override
118
    public <T> T[] toArray(T[] a) {
119
        return this.operations.toArray(a);
120
    }
121

    
122
    @Override
123
    public boolean add(OperationListEntry e) {
124
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
125
        boolean result = this.operations.add(e);
126
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRY, new Object[] {
127
            oldOperations, this.operations }));
128

    
129
        return result;
130
    }
131

    
132
    @Override
133
    public boolean remove(Object o) {
134
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
135
        boolean result = this.operations.remove(o);
136
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.REMOVED_ENTRY, new Object[] {
137
            oldOperations, this.operations }));
138
        return result;
139
    }
140

    
141
    @Override
142
    public boolean containsAll(Collection<?> c) {
143
        return this.operations.containsAll(c);
144
    }
145

    
146
    @Override
147
    public boolean addAll(Collection<? extends OperationListEntry> c) {
148
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
149
        boolean result = this.operations.addAll(c);
150
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRIES, new Object[] {
151
            oldOperations, this.operations }));
152
        return result;
153
    }
154

    
155
    @Override
156
    public boolean addAll(int index, Collection<? extends OperationListEntry> c) {
157
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
158
        boolean result = this.operations.addAll(index, c);
159
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRIES, new Object[] {
160
            oldOperations, this.operations }));
161
        return result;
162
    }
163

    
164
    @Override
165
    public boolean removeAll(Collection<?> c) {
166
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
167
        boolean result = this.operations.removeAll(c);
168
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.REMOVED_ENTRIES, new Object[] {
169
            oldOperations, this.operations }));
170
        return result;
171
    }
172

    
173
    @Override
174
    public boolean retainAll(Collection<?> c) {
175
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
176
        boolean result = this.operations.retainAll(c);
177
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.RETAINED_ENTRIES, new Object[] {
178
            oldOperations, this.operations }));
179
        return result;
180
    }
181

    
182
    @Override
183
    public void clear() {
184
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
185
        this.operations.clear();
186
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.CLEAR_ENTRIES, new Object[] {
187
            oldOperations, this.operations }));
188
    }
189

    
190
    @Override
191
    public OperationListEntry get(int index) {
192
        return this.operations.get(index);
193
    }
194

    
195
    @Override
196
    public OperationListEntry set(int index, OperationListEntry element) {
197
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
198
        OperationListEntry result = this.operations.set(index, element);
199
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.SETTED_ENTRY, new Object[] {
200
            oldOperations, this.operations }));
201
        return result;
202
    }
203

    
204
    @Override
205
    public void add(int index, OperationListEntry element) {
206
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
207
        if(index<0){
208
            index = this.operations.size()+index;
209
        }
210
        this.operations.add(index, element);
211
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRY, new Object[] {
212
            oldOperations, this.operations }));
213
    }
214

    
215
    @Override
216
    public OperationListEntry remove(int index) {
217
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
218
        OperationListEntry result = this.operations.remove(index);
219
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.REMOVED_ENTRY, new Object[] {
220
            oldOperations, this.operations }));
221
        return result;
222
    }
223

    
224
    @Override
225
    public int indexOf(Object o) {
226
        return this.operations.indexOf(o);
227
    }
228

    
229
    @Override
230
    public int lastIndexOf(Object o) {
231
        return this.operations.lastIndexOf(o);
232
    }
233

    
234
    @Override
235
    public ListIterator<OperationListEntry> listIterator() {
236
        return this.operations.listIterator();
237
    }
238

    
239
    @Override
240
    public ListIterator<OperationListEntry> listIterator(int index) {
241
        return this.operations.listIterator(index);
242
    }
243

    
244
    @Override
245
    public List<OperationListEntry> subList(int fromIndex, int toIndex) {
246
        return this.operations.subList(fromIndex, toIndex);
247
    }
248

    
249
    @Override
250
    public Buffer execute(Buffer buffer) throws BufferOperationException {
251
        Buffer tmpBuffer = buffer;
252
        int i=0;
253
        for (Iterator<OperationListEntry> iterator = operations.iterator(); iterator.hasNext();) {
254
            OperationListEntry operationListEntry = (OperationListEntry) iterator.next();
255
            Operation operation = operationListEntry.getOperation();
256
            DynObject parameters = operationListEntry.getParameters();
257
            OperationFactory factory = operation.getFactory();
258
            if (operationListEntry.isActive()) {
259
                if (factory.isApplicable(tmpBuffer).equals(Applicable.NO)) {
260
                    throw new IllegalArgumentException("The operation is not applicable to the input buffer");
261
                }
262
                DynClass paramsDefinition = parameters.getDynClass();
263
                DynField[] fields = paramsDefinition.getDynFields();
264
                for (int j = 0; j < fields.length; j++) {
265
                    DynField_v2 field = (DynField_v2) fields[j];
266
                    String name = operationListEntry.getLookpupParameterName(field.getName());
267
                    if( !StringUtils.isEmpty(name) ) {
268
                        name = (String) field.getTags().get("lookupParameter");
269
                    }
270
                    if( !StringUtils.isEmpty(name) ) {
271
                        parameters.setDynValue(field.getName(), getParameterValue(name, i));
272
                    }
273
                }
274
                tmpBuffer = operation.execute(tmpBuffer, parameters);
275
            }
276
            i++;
277
        }
278
        return tmpBuffer;
279
    }
280

    
281
    @Override
282
    public void add(Operation operation, DynObject parameters) {
283
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
284
        OperationManager operationManager = ((OperationManager)BufferLocator.getBufferManager());
285
        OperationListEntry entry = operationManager.createOperationListEntry(operation, parameters);
286
        this.operations.add(entry);
287
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRY, new Object[] {
288
            oldOperations, this.operations }));
289
    }
290

    
291
    @Override
292
    public void add(int index, Operation operation, DynObject parameters) {
293
        ArrayList<OperationListEntry> oldOperations = this.cloneOperations();
294
        OperationManager operationManager = ((OperationManager)BufferLocator.getBufferManager());
295
        OperationListEntry entry = operationManager.createOperationListEntry(operation, parameters);
296
        this.operations.add(index, entry);
297
        this.notifyObservers(new DefaultOperationListNotification(OperationListNotification.ADDED_ENTRY, new Object[] {
298
            oldOperations, this.operations }));
299
    }
300

    
301
    @Override
302
    public Object getParameterValue(String name) {
303
        return getParameterValue(name, operations.size());
304
    }
305

    
306
    private Object getParameterValue(String name, int index) {
307
        if(index<0){
308
            index = this.operations.size()+index;
309
        }
310
        ListIterator<OperationListEntry> iterator = operations.listIterator(index);
311

    
312
        Object result = null;
313
        while (iterator.hasPrevious()) {
314
            OperationListEntry operationListEntry = (OperationListEntry) iterator.previous();
315
            if (operationListEntry != null && operationListEntry.isActive()) {
316
                DynObject parameters = operationListEntry.getParameters();
317
                if (parameters.getDynClass().getDynField(name) != null) {
318
                    result = parameters.getDynValue(name);
319
                    break;
320
                }
321
            } else {
322
                LOG.warn("***** THE ENTRY IS NULL *****");
323
            }
324
        }
325
        if(result == null && defaultParameters!=null){
326
            if (defaultParameters.getDynClass().getDynField(name) != null) {
327
                result = defaultParameters.getDynValue(name);
328
            }
329
        }
330
        return result;
331
    }
332

    
333
    @Override
334
    public void saveToState(PersistentState state) throws PersistenceException {
335
        state.set(OPERATIONS_PERSISTENCE_FIELD, this.operations);
336

    
337
    }
338

    
339
    @Override
340
    public void loadFromState(PersistentState state) throws PersistenceException {
341
        this.operations = new ArrayList<OperationListEntry>();
342

    
343
        Iterator it = state.getIterator(OPERATIONS_PERSISTENCE_FIELD);
344
        while(it.hasNext()) {
345
            OperationListEntry operationListEntry = (OperationListEntry) it.next();
346
            this.add(operationListEntry);
347
        }
348
    }
349

    
350
    public static void registerPersistence() {
351
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
352
        DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
353
        if (definition == null) {
354
            definition =
355
                manager.addDefinition(DefaultOperationList.class, PERSISTENT_NAME,
356
                    PERSISTENT_DESCRIPTION, null, null);
357
            definition.addDynFieldList(OPERATIONS_PERSISTENCE_FIELD).setMandatory(false).setClassOfItems(OperationListEntry.class);
358
        }
359
    }
360

    
361
    public List<String> getAvailableParameterNames() {
362
        Set<String> result = new HashSet<String>();
363
        for (Iterator<OperationListEntry> iterator = operations.iterator(); iterator.hasNext();) {
364
            OperationListEntry operationListEntry = (OperationListEntry) iterator.next();
365
            DynObject parameters = operationListEntry.getParameters();
366
            DynField[] dynFields = parameters.getDynClass().getDynFields();
367
            for (int i = 0; i < dynFields.length; i++) {
368
                result.add(dynFields[i].getName());
369
            }
370
        }
371
        if (this.defaultParameters != null) {
372
            DynField[] dynFields = this.defaultParameters.getDynClass().getDynFields();
373
            for (int i = 0; i < dynFields.length; i++) {
374
                result.add(dynFields[i].getName());
375
            }
376
        }
377
        return new ArrayList<String>(result);
378
    }
379

    
380
    @Override
381
    public void setDefaultParameters(DynObject parameters) {
382
        this.defaultParameters = parameters;
383
    }
384

    
385
    @Override
386
    public void validateLookupParameters() throws InvalidLookupParametersException {
387
        List<Problem> problems = new ArrayList<>();
388
        InvalidLookupParametersException exception = new InvalidLookupParametersException(problems);
389

    
390
        ListIterator<OperationListEntry> iterator = operations.listIterator();
391

    
392
        int i = operations.size();
393
        while (iterator.hasPrevious()) {
394
            OperationListEntry operationListEntry = (OperationListEntry) iterator.previous();
395
            Operation operation = operationListEntry.getOperation();
396
            DynObject parameters = operationListEntry.getParameters();
397
            OperationFactory factory = operation.getFactory();
398
            if (operationListEntry.isActive()) {
399
                DynClass paramsDefinition = parameters.getDynClass();
400
                DynField[] fields = paramsDefinition.getDynFields();
401
                for (int j = 0; j < fields.length; j++) {
402
                    DynField_v2 field = (DynField_v2) fields[j];
403
                    String name = operationListEntry.getLookpupParameterName(field.getName());
404
                    if( !StringUtils.isEmpty(name) ) {
405
                        name = (String) field.getTags().get("lookupParameter");
406
                    }
407
                    if( !StringUtils.isEmpty(name) ) {
408
                        if( getParameterValue(name, i) == null){
409
                            Problem problem = exception.new Problem(factory.getName(), field.getName(), name);
410
                            problems.add(problem);
411
                        }
412
                    }
413
                }
414
            }
415
            i--;
416
        }
417
        if(!problems.isEmpty()){
418
            throw new InvalidLookupParametersException(problems);
419
        }
420
        return;
421
    }
422

    
423
    private ArrayList<OperationListEntry> cloneOperations() {
424
        ArrayList<OperationListEntry> clonedOperations = null;
425
        if (operations != null) {
426
            try {
427
                clonedOperations = new ArrayList(operations.size());
428
                for (int i = 0; i < operations.size(); i++) {
429
                    clonedOperations.add((OperationListEntry) operations.get(i).clone());
430
                }
431
            } catch (CloneNotSupportedException e) {
432
                LOG.warn("Can't clone operation list", e);
433
            }
434
        }
435
        return clonedOperations;
436
    }
437

    
438
    @Override
439
    public Object clone() throws CloneNotSupportedException {
440
        OperationList cloned = new DefaultOperationList();
441

    
442
        if (operations != null) {
443
            for (int i = 0; i < operations.size(); i++) {
444
                cloned.add((OperationListEntry) operations.get(i).clone());
445
            }
446
        }
447

    
448
        return cloned;
449
    }
450
}