Revision 46010 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/JDBCHelperBase.java

View differences:

JDBCHelperBase.java
31 31
import java.util.ArrayList;
32 32
import java.util.HashSet;
33 33
import java.util.List;
34
import java.util.function.Predicate;
34 35
import org.apache.commons.io.IOUtils;
35 36
import org.apache.commons.lang3.ArrayUtils;
36 37
import org.apache.commons.lang3.StringUtils;
37 38
import org.apache.commons.lang3.mutable.MutableBoolean;
38 39
import org.gvsig.expressionevaluator.Code;
40
import org.gvsig.expressionevaluator.Expression;
39 41
import org.gvsig.expressionevaluator.ExpressionBuilder;
42
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_$$CONSTANT;
43
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_$$IDENTIFIER;
40 44
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
41 45
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
42 46
import org.gvsig.expressionevaluator.Function;
......
48 52
import org.gvsig.fmap.dal.SQLBuilder;
49 53
import org.gvsig.fmap.dal.exception.DataException;
50 54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
51 56
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
52 58
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
53 59
import org.gvsig.fmap.dal.feature.FeatureType;
54 60
import org.gvsig.fmap.dal.feature.ForeingKey;
......
85 91
import org.gvsig.tools.evaluator.Evaluator;
86 92
import org.gvsig.tools.exception.BaseException;
87 93
import org.gvsig.tools.exception.NotYetImplemented;
94
import org.gvsig.tools.visitor.FilteredVisitable;
88 95
import org.gvsig.tools.visitor.VisitCanceledException;
89 96
import org.gvsig.tools.visitor.Visitor;
90 97
import org.slf4j.Logger;
......
237 244
  }
238 245

  
239 246
  @Override
247
  @SuppressWarnings("Convert2Lambda")
240 248
  public boolean supportFilter(final FeatureType type, Evaluator filter) {
241 249
    if (filter == null) {
242 250
      // No hay que filtrar nada, asi que se p?ede.
243 251
      return true;
244 252
    }
245 253
    String sql = filter.getSQL();
246
    return this.supportExpression(type, sql);
247
  }
248
  
249
  @Override
250
  public boolean supportExpression(final FeatureType type, String sql) {
251
    // No podemos filtrar cuando:
252
    // - Hay una subquery especificada en los parametros 
253
    // - Si hay un filtro y el getSQL devuelbe null.
254
    // - Si se esta usando alguna funcion no-sql en el getSQL
255
    // - Si se estan usando funciones OGC y no soportamos funciones espaciales
256
    // - Si se esta usando algun campo calculado en la expresion de filtro.
257
    // 
258
    // Un proveedor especifico podria sobreescribir el metodo,
259
    // para hilar mas fino al comprobar si soporta el filtro o no.
260
    //
261

  
262
    if (this.useSubquery()) {
263
      // Se esta usando una subquery en los parametros de acceso a la
264
      // BBDD, asi que no podemos filtrar.
265
      return false;
266
    } 
267 254
    if (StringUtils.isEmpty(sql)) {
268 255
      // Hay un filtro, pero la SQL es null, con lo que no podemos
269 256
      // filtrar por el.
270 257
      return false;
271 258
    }
259
    return this.supportExpression(type, sql);
260
  }
261
  
262
    @Override
263
    @SuppressWarnings("Convert2Lambda")
264
    public boolean supportExpression(final FeatureType type, String sql) {
265
        // La expression no es valida si:
266
        // - Hay una subquery especificada en los parametros 
267
        // - Si la sql es null.
268
        // - Si se esta usando alguna funcion no-sql en el getSQL
269
        // - Si se esta invocando a metodos de un objeto
270
        // - Si se estan usando funciones OGC y no soportamos funciones espaciales
271
        // - Si se esta usando algun campo calculado en la expresion de filtro.
272
        // 
273
        // Un proveedor especifico podria sobreescribir el metodo,
274
        // para hilar mas fino al comprobar si soporta el filtro o no.
275
        //
272 276

  
273
    // Ahora vamos a comprobar que las funciones que se usan son 
274
    // compatibles sql, y que no se usan funciones OGC si el 
275
    // proveedor dice que no soporta funciones espaciales.
276
    // Tambien comprobaremos que el filtro no usa ningun campo calculado.
277
    final MutableBoolean isCompatible = new MutableBoolean(true);
278
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
279
    Code code = manager.compile(sql);
280
    SymbolTable symbolTable = manager.createSymbolTable();
281
    code.link(symbolTable);
282
    try {
283
      code.accept(new Visitor() {
284
        @Override
285
        public void visit(Object code_obj) throws VisitCanceledException, BaseException {
286
          Code code = (Code) code_obj;
287
          switch (code.code()) {
288
            case Code.CALLABLE:
289
              Code.Callable caller = (Code.Callable) code;
290
              if (!supportCaller(caller)) {
291
                isCompatible.setValue(false);
292
                throw new VisitCanceledException();
293
              }
294
              break;
277
        if (StringUtils.isEmpty(sql)) {
278
            return false;
279
        }
295 280

  
296
            case Code.IDENTIFIER:
297
              Code.Identifier identifier = (Code.Identifier) code;
298
              if (type != null) {
299
                FeatureAttributeDescriptor attrdesc = type.getAttributeDescriptor(identifier.name());
300
                if (attrdesc != null) {
301
                  if (attrdesc.isComputed()) {
302
                    isCompatible.setValue(false);
303
                    throw new VisitCanceledException();
304
                  }
281
        if (this.useSubquery()) {
282
            // Se esta usando una subquery en los parametros de acceso a la
283
            // BBDD, asi que no podemos filtrar.
284
            return false;
285
        }
286

  
287
        // Ahora vamos a comprobar que las funciones que se usan son 
288
        // compatibles sql, y que no se usan funciones OGC si el 
289
        // proveedor dice que no soporta funciones espaciales.
290
        // Tambien comprobaremos que el filtro no usa ningun campo calculado.
291
        final MutableBoolean isCompatible = new MutableBoolean(true);
292
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
293
        Code code = manager.compile(sql);
294
        SymbolTable symbolTable = manager.createSymbolTable();
295
        code.link(symbolTable);
296
        try {
297
            code.accept(new Visitor() {
298
                @Override
299
                public void visit(Object code_obj) throws VisitCanceledException, BaseException {
300
                    Code code1 = (Code) code_obj;
301
                    switch (code1.code()) {
302
                        case Code.CALLABLE:
303
                            Code.Callable caller = (Code.Callable) code1;
304
                            if (!supportCaller(caller)) {
305
                                isCompatible.setValue(false);
306
                                throw new VisitCanceledException();
307
                            }
308
                            break;
309
                        case Code.METHOD:
310
                            isCompatible.setValue(false);
311
                            throw new VisitCanceledException();
312
                        case Code.IDENTIFIER:
313
                            Code.Identifier identifier = (Code.Identifier) code1;
314
                            if (type != null) {
315
                                FeatureAttributeDescriptor attrdesc = type.getAttributeDescriptor(identifier.name());
316
                                if (attrdesc != null) {
317
                                    if (attrdesc.isComputed()) {
318
                                        FeatureAttributeEmulator emulator = attrdesc.getFeatureAttributeEmulator();
319
                                        if (!(emulator instanceof FeatureAttributeEmulatorExpression)) {
320
                                            isCompatible.setValue(false);
321
                                            throw new VisitCanceledException();
322
                                        }
323
                                        Expression expr = ((FeatureAttributeEmulatorExpression) emulator).getExpression();
324
                                        if (!supportExpression(type, expr.getPhrase())) {
325
                                            isCompatible.setValue(false);
326
                                            throw new VisitCanceledException();
327
                                        }
328
                                    }
329
                                }
330
                            }
331
                            break;
332
                    }
305 333
                } 
306
              }
307
              break;
308
          }
334
            }, new Predicate<FilteredVisitable>() {
335
                @Override
336
                public boolean test(FilteredVisitable code0) {
337
                    if (code0 instanceof Code.Callable) {
338
                        String name = ((Code.Callable) code0).name();
339
                        return StringUtils.equalsIgnoreCase(name, FUNCTION_$$CONSTANT)
340
                                || StringUtils.equalsIgnoreCase(name, FUNCTION_$$IDENTIFIER);
341
                    }
342
                    return false;
343
                }
344
            });
345

  
346
        } catch (VisitCanceledException ex) {
347
            // Do nothing
348
        } catch (Exception ex) {
349
            LOGGER.warn("Can't calculate if is SQL compatible.", ex);
309 350
        }
310
      });
311 351

  
312
    } catch (VisitCanceledException ex) {
313
      // Do nothing
314
    } catch (Exception ex) {
315
      LOGGER.warn("Can't calculate if is SQL compatible.", ex);
352
        return isCompatible.booleanValue();
316 353
    }
317 354

  
318
    return isCompatible.booleanValue();
319
  }
320

  
321 355
  @Override
322 356
  public boolean supportOrder(FeatureType type, FeatureQueryOrder order) {
323 357
    if (this.useSubquery()) {
......
657 691
    replaceExistsFunction(sqlbuilder, type, extra_column_names);
658 692
  }
659 693

  
694
  @SuppressWarnings("Convert2Lambda")
660 695
  private void replaceExistsFunction(
661 696
          SQLBuilder sqlbuilder,
662 697
          FeatureType type,
......
716 751
    }
717 752
  }
718 753

  
754
  @SuppressWarnings("Convert2Lambda")
719 755
  protected void replaceForeingValueFunction(
720 756
          SQLBuilder sqlbuilder,
721 757
          FeatureType type,
......
815 851
      // Para las columnas que puedan dar conflicto se prepara un reemplazo 
816 852
      // de estas que tenga el nombre de tabla.
817 853
      for (ExpressionBuilder.Variable variable : sqlbuilder.variables()) {
818
        if (variable instanceof SQLBuilderBase.ColumnBase) {
854
        if (variable == null || variable instanceof SQLBuilderBase.ColumnBase) {
819 855
          continue;
820 856
        }
821 857
        for (String foreingName : foreing_value_args) {

Also available in: Unified diff