Package org.structr.common

Source Code of org.structr.common.ValidationHelper

/**
* Copyright (C) 2010-2014 Morgner UG (haftungsbeschränkt)
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.common;

import java.util.Arrays;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.structr.common.error.ChronologicalOrderToken;
import org.structr.common.error.EmptyPropertyToken;
import org.structr.common.error.ErrorBuffer;
import org.structr.common.error.FrameworkException;
import org.structr.common.error.MatchToken;
import org.structr.common.error.RangeToken;
import org.structr.common.error.TooShortToken;
import org.structr.common.error.UniqueToken;
import org.structr.common.error.ValueToken;
import org.structr.core.GraphObject;
import org.structr.core.Result;
import org.structr.core.app.StructrApp;
import org.structr.core.entity.AbstractNode;
import org.structr.core.graph.NodeInterface;
import org.structr.core.graph.RelationshipInterface;
import org.structr.core.property.GenericProperty;
import org.structr.core.property.PropertyKey;

/**
* Defines helper methods for property validation.
*
* @author Christian Morgner
*/
public class ValidationHelper {

  private static final PropertyKey UnknownType = new GenericProperty("unknown type");
 
  // ----- public static methods -----
  /**
   * Checks whether the value for the given property key of the given node
   * has at least the given length.
   *
   * @param node the node
   * @param key the property key whose value should be checked
   * @param minLength the min length
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkStringMinLength(final GraphObject node, final PropertyKey<String> key, final int minLength, final ErrorBuffer errorBuffer) {

    String value = node.getProperty(key);
    String type  = node.getType();

    if (StringUtils.isNotBlank(value)) {

      if (value.length() >= minLength) {

        return false;

      }

      errorBuffer.add(type, new TooShortToken(key, minLength));

      return true;

    }

    errorBuffer.add(type, new EmptyPropertyToken(key));

    return true;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is a non-empty string.
   *
   * @param node the node
   * @param key the property key
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkStringNotBlank(final GraphObject node, final PropertyKey<String> key, final ErrorBuffer errorBuffer) {

    String type  = node.getType();

    if (StringUtils.isNotBlank(node.getProperty(key))) {

      return false;

    }

    errorBuffer.add(type, new EmptyPropertyToken(key));

    return true;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is a non-empty string.
   *
   * @param node the node
   * @param key the property key
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkPropertyNotNull(final GraphObject node, final PropertyKey key, final ErrorBuffer errorBuffer) {
   
    String type  = node.getType();

    if (key == null) {
      errorBuffer.add(type, new EmptyPropertyToken(UnknownType));
      return true;
    }

    Object value = node.getProperty(key);

    if (value != null) {

      if (value instanceof Iterable) {

        if (((Iterable) value).iterator().hasNext()) {

          return false;

        }

      } else {

        return false;

      }

    }

    errorBuffer.add(type, new EmptyPropertyToken(key));

    return true;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is non null and of type Date.
   *
   * @param node the node
   * @param key the property key
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkDate(final GraphObject node, final PropertyKey<Date> key, final ErrorBuffer errorBuffer) {

    Date date     = node.getProperty(key);
    String type   = node.getType();
    boolean error = false;

    if ((date == null) || ((date != null) && (date.getTime() == 0))) {

      errorBuffer.add(type, new EmptyPropertyToken(key));
      error = true;

    }

    return error;
  }


  /**
   * Checks whether the Date values for the two given property keys are
   * in chronological order, i.e. the Date of key1 lies before the one of
   * key2.
   *
   * @param node the node
   * @param key1 the first Date key
   * @param key2 the second Date key
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkDatesChronological(final GraphObject node, final PropertyKey<Date> key1, final PropertyKey<Date> key2, final ErrorBuffer errorBuffer) {

    Date date1    = node.getProperty(key1);
    Date date2    = node.getProperty(key2);
    String type   = node.getType();
    boolean error = false;

    error |= checkDate(node, key1, errorBuffer);
    error |= checkDate(node, key2, errorBuffer);

    if ((date1 != null) && (date2 != null) &&!date1.before(date2)) {

      errorBuffer.add(type, new ChronologicalOrderToken(key1, key2));

      error = true;

    }

    return error;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is one of the values array.
   *
   * @param node the node
   * @param key the property key
   * @param values the values to check against
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkStringInArray(final GraphObject node, final PropertyKey<String> key, final String[] values, final ErrorBuffer errorBuffer) {

    String type  = node.getType();

    if (StringUtils.isNotBlank(node.getProperty(key))) {

      if (Arrays.asList(values).contains(node.getProperty(key))) {

        return false;

      }

    }

    errorBuffer.add(type, new ValueToken(key, values));

    return true;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is a valid enum value of the given type.
   *
   * @param node the node
   * @param key the property key
   * @param enumType the enum type to check against
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkStringInEnum(final GraphObject node, final PropertyKey<? extends Enum> key, Class<? extends Enum> enumType, final ErrorBuffer errorBuffer) {
   
    return checkStringInEnum(node.getType(), node, key, enumType, errorBuffer);
  }
 
  /**
   * Checks whether the value of the given property key of the given node
   * if not null and matches the given regular expression.
   *
   * @param node
   * @param key
   * @param expression
   * @param errorBuffer
   * @return true if string matches expression
   */
  public static boolean checkStringMatchesRegex(final GraphObject node, final PropertyKey<String> key, final String expression, final ErrorBuffer errorBuffer) {

    String value = node.getProperty(key);
    boolean matches = value != null && value.matches(expression);
   
    if (!matches) {
      errorBuffer.add(node.getType(), new MatchToken(key, value, expression));
    }
   
    return matches;
   
  }
 
  /**
   * Checks whether the value for the given property key of the given node
   * is a valid enum value of the given type. In case of an error, the
   * type identifiery in typeString is used for the error message.
   *
   * @param typeString
   * @param node the node
   * @param key the property key
   * @param enumType the enum type to check against
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkStringInEnum(final String typeString, final GraphObject node, final PropertyKey<? extends Enum> key, Class<? extends Enum> enumType, final ErrorBuffer errorBuffer) {

    Enum value = node.getProperty(key);
    Enum[] values = enumType.getEnumConstants();

    for (Enum v : values) {

      if (v.equals(value)) {
        return false;
      }

    }

    errorBuffer.add(typeString, new ValueToken(key, values));

    return true;
  }

  /**
   * Checks whether the value for the given property key of the given node
   * is null OR one of the values given in the values array.
   *
   * @param node the node
   * @param key the property key
   * @param values the values array
   * @param errorBuffer the error buffer
   *
   * @return true if there is an error checking the given node
   */
  public static boolean checkNullOrStringInArray(final GraphObject node, final PropertyKey<String> key, String[] values, final ErrorBuffer errorBuffer) {

    String value = node.getProperty(key);
    String type  = node.getType();

    if(value == null) {
      return false;
    }

    if (StringUtils.isNotBlank(node.getProperty(key))) {

      if (Arrays.asList(values).contains(node.getProperty(key))) {

        return false;

      }

    }

    errorBuffer.add(type, new ValueToken(key, values));

    return true;
  }
 
  public static boolean checkIntegerInRangeError(final GraphObject node, final PropertyKey<Integer> key, final String range, final ErrorBuffer errorBuffer) {

    // we expect expression to have the following format:
    // - "[" or "]" followed by a number (including negative values
    // - a comma (must exist)
    // - a number (including negative values followed by "[" or "]"

    final int length        = range.length();
    final String leftBound  = range.substring(0, 1);
    final String rightBound = range.substring(length-1, length);
    final String[] parts    = range.substring(1, length-1).split("[,]+");
    final String type       = node.getType();

    if (parts.length == 2) {

      final String leftPart   = parts[0].trim();
      final String rightPart  = parts[1].trim();
      final int left          = Integer.parseInt(leftPart);
      final int right         = Integer.parseInt(rightPart);
      final Integer value     = node.getProperty(key);

      // do not check for non-null values, ignore (silently succeed)
      if (value != null) {

        // result
        boolean inRange         = true;

        if ("[".equals(leftBound)) {
          inRange &= value.intValue() >= left;
        } else {
          inRange &= value.intValue() > left;
        }

        if ("]".equals(rightBound)) {
          inRange &= value.intValue() <= right;
        } else {
          inRange &= value.intValue() < right;
        }

        if (!inRange) {
         
          errorBuffer.add(type, new RangeToken(key, range));
        }

        return !inRange;
      }
     
    }
   
    // no error
    return false;
  }
 
  public static boolean checkLongInRangeError(final GraphObject node, final PropertyKey<Long> key, final String range, final ErrorBuffer errorBuffer) {

    // we expect expression to have the following format:
    // - "[" or "]" followed by a number (including negative values
    // - a comma (must exist)
    // - a number (including negative values followed by "[" or "]"

    final int length        = range.length();
    final String leftBound  = range.substring(0, 1);
    final String rightBound = range.substring(length-1, length);
    final String[] parts    = range.substring(1, length-1).split("[,]+");
    final String type       = node.getType();

    if (parts.length == 2) {

      final String leftPart   = parts[0].trim();
      final String rightPart  = parts[1].trim();
      final long left         = Long.parseLong(leftPart);
      final long right        = Long.parseLong(rightPart);
      final Long value     = node.getProperty(key);

      // do not check for non-null values, ignore (silently succeed)
      if (value != null) {

        // result
        boolean inRange         = true;

        if ("[".equals(leftBound)) {
          inRange &= value.intValue() >= left;
        } else {
          inRange &= value.intValue() > left;
        }

        if ("]".equals(rightBound)) {
          inRange &= value.intValue() <= right;
        } else {
          inRange &= value.intValue() < right;
        }

        if (!inRange) {
         
          errorBuffer.add(type, new RangeToken(key, range));
        }

        return !inRange;
      }
     
    }
   
    // no error
    return false;
  }
 
  public static boolean checkDoubleInRangeError(final GraphObject node, final PropertyKey<Double> key, final String range, final ErrorBuffer errorBuffer) {

    // we expect expression to have the following format:
    // - "[" or "]" followed by a number (including negative values
    // - a comma (must exist)
    // - a number (including negative values followed by "[" or "]"

    final int length        = range.length();
    final String leftBound  = range.substring(0, 1);
    final String rightBound = range.substring(length-1, length);
    final String[] parts    = range.substring(1, length-1).split("[,]+");
    final String type       = node.getType();

    if (parts.length == 2) {

      final String leftPart  = parts[0].trim();
      final String rightPart = parts[1].trim();
      final double left      = Double.parseDouble(leftPart);
      final double right     = Double.parseDouble(rightPart);
      final Double value     = node.getProperty(key);

      // do not check for non-null values, ignore (silently succeed)
      if (value != null) {

        // result
        boolean inRange         = true;

        if ("[".equals(leftBound)) {
          inRange &= value.intValue() >= left;
        } else {
          inRange &= value.intValue() > left;
        }

        if ("]".equals(rightBound)) {
          inRange &= value.intValue() <= right;
        } else {
          inRange &= value.intValue() < right;
        }

        if (!inRange) {
         
          errorBuffer.add(type, new RangeToken(key, range));
        }
       
        return !inRange;
      }
     
    }
   
    // no error
    return false;
  }
 
  public static boolean checkPropertyUniquenessError(final GraphObject object, final PropertyKey key, final ErrorBuffer errorBuffer) {

    if (key != null) {

      final Object value         = object.getProperty(key);
      Result<GraphObject> result = null;
      boolean exists             = false;
      String id                  = null;

      try {

        if (object instanceof NodeInterface) {
         
          result = StructrApp.getInstance().nodeQuery(((NodeInterface)object).getClass()).and(key, value).getResult();
         
        } else {
         
          result = StructrApp.getInstance().relationshipQuery(((RelationshipInterface)object).getClass()).and(key, value).getResult();
         
        }
        exists = !result.isEmpty();

      } catch (FrameworkException fex) {

        fex.printStackTrace();

      }

      if (exists) {

        GraphObject foundNode = result.get(0);
        if (foundNode.getId() != object.getId()) {

          id = ((AbstractNode) result.get(0)).getUuid();

          errorBuffer.add(object.getType(), new UniqueToken(id, key, value));

          return true;
        }
      }
    }

    // no error
    return false;
  }
}
TOP

Related Classes of org.structr.common.ValidationHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.