Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / org.gvsig.desktop.library / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / operations / DefaultOperationList.java @ 43864

History | View | Annotate | Download (18 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.dispose.DisposeUtils;
51
import org.gvsig.tools.dynobject.DynClass;
52
import org.gvsig.tools.dynobject.DynField;
53
import org.gvsig.tools.dynobject.DynField_v2;
54
import org.gvsig.tools.dynobject.DynObject;
55
import org.gvsig.tools.dynobject.DynStruct;
56
import org.gvsig.tools.observer.impl.BaseWeakReferencingObservable;
57
import org.gvsig.tools.persistence.PersistenceManager;
58
import org.gvsig.tools.persistence.PersistentState;
59
import org.gvsig.tools.persistence.exception.PersistenceException;
60
import org.gvsig.tools.task.TaskStatus;
61

    
62

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

    
69
    private static final Logger LOG = LoggerFactory.getLogger(DefaultOperationList.class);
70

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

    
80
    private final static String OPERATIONS_PERSISTENCE_FIELD = "operations";
81

    
82

    
83
    private List<OperationListEntry> operations;
84

    
85
    private DynObject defaultParameters = null;
86

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

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

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

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

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

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

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

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

    
131
        return result;
132
    }
133

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
306

    
307
    @Override
308
    public void removeIfExists(String name) {
309
        int removed = 0;
310
        int size = this.size();
311
        for (Iterator<OperationListEntry> iterator = this.iterator(); iterator.hasNext();) {
312
            OperationListEntry entry = (OperationListEntry) iterator.next();
313
            Operation operation = entry.getOperation();
314
            if (operation.getFactory().getName().equals(name)) {
315
                iterator.remove();
316
                removed++;
317
            }
318
        }
319
        if(this.size()!=size-removed){
320
            LOG.warn("NO SE HAN ELIMINADO CORRECTAMENTE LAS ENTRADAS DE LA OPERATION_LIST.");
321
        }
322
    }
323
    
324
    @Override
325
    public Object getParameterValue(String name) {
326
        int size = operations.size();
327
        return getParameterValue(name, size);
328
    }
329

    
330
    private Object getParameterValue(String name, int index) {
331
        if(index<0){
332
            index = this.operations.size()+index;
333
        }
334
        ListIterator<OperationListEntry> iterator = operations.listIterator(index);
335

    
336
        Object result = null;
337
        while (iterator.hasPrevious()) {
338
            OperationListEntry operationListEntry = (OperationListEntry) iterator.previous();
339
            if (operationListEntry != null && operationListEntry.isActive()) {
340
                DynObject parameters = operationListEntry.getParameters();
341
                if (parameters.getDynClass().getDynField(name) != null) {
342
                    result = parameters.getDynValue(name);
343
                    break;
344
                }
345
            } else {
346
                LOG.warn("***** THE ENTRY IS NULL *****");
347
            }
348
        }
349
        if(result == null && defaultParameters!=null){
350
            if (defaultParameters.getDynClass().getDynField(name) != null) {
351
                result = defaultParameters.getDynValue(name);
352
            }
353
        }
354
        return result;
355
    }
356

    
357
    @Override
358
    public void saveToState(PersistentState state) throws PersistenceException {
359
        state.set(OPERATIONS_PERSISTENCE_FIELD, this.operations);
360

    
361
    }
362

    
363
    @Override
364
    public void loadFromState(PersistentState state) throws PersistenceException {
365
        this.operations = new ArrayList<>();
366

    
367
        Iterator it = state.getIterator(OPERATIONS_PERSISTENCE_FIELD);
368
        while(it.hasNext()) {
369
            OperationListEntry operationListEntry = (OperationListEntry) it.next();
370
            this.add(operationListEntry);
371
        }
372
    }
373

    
374
    public static void registerPersistence() {
375
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
376
        DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
377
        if (definition == null) {
378
            definition =
379
                manager.addDefinition(DefaultOperationList.class, PERSISTENT_NAME,
380
                    PERSISTENT_DESCRIPTION, null, null);
381
            definition.addDynFieldList(OPERATIONS_PERSISTENCE_FIELD).setMandatory(false).setClassOfItems(OperationListEntry.class);
382
        }
383
    }
384

    
385
    public List<String> getAvailableParameterNames() {
386
        Set<String> result = new HashSet<>();
387
        for (OperationListEntry operationListEntry : operations) {
388
            DynObject parameters = operationListEntry.getParameters();
389
            DynField[] dynFields = parameters.getDynClass().getDynFields();
390
            for (int i = 0; i < dynFields.length; i++) {
391
                result.add(dynFields[i].getName());
392
            }
393
        }
394
        if (this.defaultParameters != null) {
395
            DynField[] dynFields = this.defaultParameters.getDynClass().getDynFields();
396
            for (DynField dynField : dynFields) {
397
                result.add(dynField.getName());
398
            }
399
        }
400
        return new ArrayList<>(result);
401
    }
402

    
403
    @Override
404
    public void setDefaultParameters(DynObject parameters) {
405
        this.defaultParameters = parameters;
406
    }
407

    
408
    @Override
409
    public void validateLookupParameters() throws InvalidLookupParametersException {
410
        List<Problem> problems = new ArrayList<>();
411
//        InvalidLookupParametersException exception = new InvalidLookupParametersException(problems);
412

    
413
        ListIterator<OperationListEntry> iterator = operations.listIterator();
414

    
415
        int i = operations.size();
416
        while (iterator.hasPrevious()) {
417
            OperationListEntry operationListEntry = (OperationListEntry) iterator.previous();
418
            Operation operation = operationListEntry.getOperation();
419
            DynObject parameters = operationListEntry.getParameters();
420
            OperationFactory factory = operation.getFactory();
421
            if (operationListEntry.isActive()) {
422
                DynClass paramsDefinition = parameters.getDynClass();
423
                DynField[] fields = paramsDefinition.getDynFields();
424
                for (DynField field1 : fields) {
425
                    DynField_v2 field = (DynField_v2) field1;
426
                    String name = operationListEntry.getLookpupParameterName(field.getName());
427
                    if( !StringUtils.isEmpty(name) ) {
428
                        name = (String) field.getTags().get("lookupParameter");
429
                    }
430
                    if( !StringUtils.isEmpty(name) ) {
431
                        if( getParameterValue(name, i) == null){
432
                            Problem problem = new Problem(factory.getName(), field.getName(), name);
433
                            problems.add(problem);
434
                        }
435
                    }
436
                }
437
            }
438
            i--;
439
        }
440
        if(!problems.isEmpty()){
441
            throw new InvalidLookupParametersException(problems);
442
        }
443
    }
444

    
445
    private ArrayList<OperationListEntry> cloneOperations() {
446
        ArrayList<OperationListEntry> clonedOperations = null;
447
        if (operations != null) {
448
            try {
449
                clonedOperations = new ArrayList(operations.size());
450
                for (int i = 0; i < operations.size(); i++) {
451
                    clonedOperations.add((OperationListEntry) operations.get(i).clone());
452
                }
453
            } catch (CloneNotSupportedException e) {
454
                LOG.warn("Can't clone operation list", e);
455
            }
456
        }
457
        return clonedOperations;
458
    }
459

    
460
    @Override
461
    public Object clone() throws CloneNotSupportedException {
462
        OperationList cloned = new DefaultOperationList();
463

    
464
        if (operations != null) {
465
            for (int i = 0; i < operations.size(); i++) {
466
                cloned.add((OperationListEntry) operations.get(i).clone());
467
            }
468
        }
469

    
470
        return cloned;
471
    }
472
}