public void testSetDefineOpenContent() throws Exception {
   rootDataObject.set("addressOpenContent", childDataObject);
   Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
   assertNotNull(openProp);
   assertTrue(openProp.isOpenContent());
   assertTrue(openProp.isContainment());
   assertFalse(openProp.isMany());
   assertEquals(childDataObject.getType(), openProp.getType());
 }
 public void testSetDefineOpenContentSimple() throws Exception {
   rootDataObject.set("stringOpenContent", "someString");
   Property openProp = rootDataObject.getInstanceProperty("stringOpenContent");
   assertNotNull(openProp);
   assertTrue(openProp.isOpenContent());
   assertFalse(openProp.isContainment());
   assertFalse(openProp.isMany());
   assertEquals(SDOConstants.SDO_STRING, openProp.getType());
 }
 public void testSetDefineOpenContentSimple2() throws Exception {
   BigInteger value = new BigInteger("123");
   rootDataObject.set("stringOpenContent", value);
   Property openProp = rootDataObject.getInstanceProperty("stringOpenContent");
   assertNotNull(openProp);
   assertTrue(openProp.isOpenContent());
   assertFalse(openProp.isContainment());
   assertFalse(openProp.isMany());
   assertEquals(SDOConstants.SDO_INTEGER, openProp.getType());
 }
 public void testSetDefineOpenContentManyProperty() throws Exception {
   List value = new ArrayList();
   value.add(childDataObject);
   rootDataObject.set("addressOpenContent", value);
   Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
   assertNotNull(openProp);
   assertTrue(openProp.isOpenContent());
   assertTrue(openProp.isContainment());
   assertTrue(openProp.isMany());
   assertEquals(childDataObject.getType(), openProp.getType());
 }
  /**
   * Check if position exists, then either acquire value through position or directly.
   *
   * @param propertyName the name of property of the caller
   * @param position the index of values to be accessed
   * @param caller the DataObject containing property with the passed in property name
   * @return the values to be accessed
   */
  private Object getObjectByFragment(String propertyName, int position, DataObject caller) {
    Property prop = caller.getInstanceProperty(propertyName);
    if (prop == null) {
      return null;
    }

    if (prop.isMany() && position > -1) {
      return caller.getList(prop).get(position);
    } else {
      return caller.get(prop);
    }
  }
 /**
  * INTERNAL: Used during XML Unmarshal.
  *
  * @param dataObject
  * @param property
  * @param cs
  * @return
  */
 private Object getValue(SDODataObject dataObject, Property property, SDOChangeSummary cs) {
   if (cs != null) {
     Object returnValue = cs.getPropertyInternal(dataObject, property);
     if (property.isMany()) {
       if (cs.getOriginalElements().containsKey(returnValue)) {
         // are we using the cast to List as a sort of instance check that would throw a CCE?
         return cs.getOriginalElements().get(returnValue);
       }
     }
     return returnValue;
   }
   return dataObject.get(property); // get the value of current property
 }
  public void testSetDefineOpenContentManySimpleProperty() throws Exception {
    List value = new ArrayList();
    value.add(new Integer(4));
    rootDataObject.set("addressOpenContent", value);
    Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
    assertNotNull(openProp);
    assertTrue(openProp.isOpenContent());
    assertFalse(openProp.isContainment());
    assertTrue(openProp.isMany());
    assertEquals(SDOConstants.SDO_INTOBJECT, openProp.getType());

    assertTrue(rootDataObject.isSet("addressOpenContent"));
    rootDataObject.unset("addressOpenContent");
    assertFalse(rootDataObject.isSet("addressOpenContent"));
  }
  public void testSetDefineOpenContentManyPropertyContainmentChild() throws Exception {
    SDOType typeType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.TYPE);

    List value = new ArrayList();
    Type addressSDOType = typeHelper.getType("my.uri", "address");
    DataObject childDataObjectContainment = dataFactory.create(addressSDOType);

    DataObject someOther = dataFactory.create(typeType);
    someOther.set("name", "someOther");
    someOther.set("uri", "my.uri");
    addProperty(someOther, "test", addressSDOType, true, false, true);
    Type someOtherParentType = typeHelper.define(someOther);
    DataObject someOtherParentDO = dataFactory.create(someOtherParentType);
    someOtherParentDO.set("test", childDataObjectContainment);

    value.add(childDataObjectContainment);
    rootDataObject.set("addressOpenContent", value);
    Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
    assertNotNull(openProp);
    assertTrue(openProp.isOpenContent());
    assertFalse(openProp.isContainment());
    assertTrue(openProp.isMany());
    assertEquals(childDataObject.getType(), openProp.getType());
  }
  /**
   * Access the DataObject value by using the fragment containing query informations.
   *
   * @param frag one string fragment in the path
   * @param openBracketIndex the index of open bracket in a fragment
   * @param closeBracketIndex the index of close bracket in a fragment
   * @param equalsignIndex the index of equalsign in string fragment quoted by brackets
   * @param caller the DataObject that passes the path information in
   * @param callerProperty the name of the property
   * @return the DataObject as value of the property having name as the above callerProperty
   */
  private DataObject getDataObjectFromQuery(
      String frag,
      int openBracketIndex,
      int closeBracketIndex,
      int equalsignIndex,
      DataObject caller,
      String callerProperty) {
    try {
      // trim off any whitespace for property names
      String propertyNameOfQryDataObject =
          frag.substring(openBracketIndex + 1, equalsignIndex + openBracketIndex).trim();
      List objects = caller.getList(caller.getInstanceProperty(callerProperty));
      String query = frag.substring(equalsignIndex + openBracketIndex + 1, closeBracketIndex);
      String value = null;
      int firstQuoteIndex = query.indexOf('\'');
      int lastQuoteIndex = query.lastIndexOf('\'');
      if ((firstQuoteIndex == -1)
          && (lastQuoteIndex == -1)) { // !! note: case: [number=1'23'] is assume not to happen !!
        firstQuoteIndex = query.indexOf("\"");
        lastQuoteIndex = query.lastIndexOf("\"");
      }
      if ((firstQuoteIndex != -1)
          && (lastQuoteIndex != -1)
          && (firstQuoteIndex < lastQuoteIndex)) { // quoted string existed
        value = query.substring(firstQuoteIndex + 1, lastQuoteIndex);
      } else {
        // if the value is not enclosed on quotes, trim off any whitespace
        value = query.trim();
      }
      Iterator iterObjects = objects.iterator();
      Object queryValue = value;
      Object actualValue = null;
      while (iterObjects.hasNext()) {
        DataObject cur = (DataObject) iterObjects.next();
        Property p = cur.getInstanceProperty(propertyNameOfQryDataObject);
        if (p != null) {
          try {
            queryValue =
                XMLConversionManager.getDefaultXMLManager()
                    .convertObject(queryValue, p.getType().getInstanceClass());
          } catch (ConversionException e) {
            // do nothing, skip
          }

          if (!p.isMany()) {
            actualValue = cur.get(p);
            if (actualValue.equals(queryValue)) {
              return cur;
            }
          } else { // case p is many type
            List values = cur.getList(p);
            Iterator iterValues = values.iterator();

            while (iterValues.hasNext()) {
              actualValue = iterValues.next();
              if (actualValue.equals(queryValue)) {
                return cur;
              }
            }
          }
        }
      }

      return null;
    } catch (IllegalArgumentException e) {
      return null;
    }
  }
  /**
   * Converts the given value from bytes based on data type and cardinality information for the
   * given property. For 'many' or multi-valued properties, if the SDO Java type for the property is
   * not already String, the value is first converted from a String using the SDO conversion which
   * uses java.util.Arrays formatting, resulting in an array of primitive types. For non 'many' or
   * singular properties, only the HBase Bytes utility is used.
   *
   * @param targetProperty the property
   * @param value the bytes value
   * @return the converted object
   * @throws IllegalArgumentException if the given property is not a data type property
   */
  public Object fromBytes(Property targetProperty, byte[] value) {
    Object result = null;

    if (!targetProperty.getType().isDataType())
      throw new IllegalArgumentException(
          "property " + targetProperty.toString() + " is not a datatype property");

    DataType targetDataType = DataType.valueOf(targetProperty.getType().getName());

    switch (targetDataType) {
        // Data types stored as String bytes in HBase
      case String:
      case Strings:
      case URI:
      case Month:
      case MonthDay:
      case Day:
      case Time:
      case Year:
      case YearMonth:
      case YearMonthDay:
      case Duration:
        String resultStr = Bytes.toString(value);
        result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
        break;
      case Date:
        resultStr = Bytes.toString(value);
        result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
        break;
      case DateTime:
        // NOTE: remember datetime is a String Java representation in SDO 2.1
        resultStr = Bytes.toString(value);
        result = DataConverter.INSTANCE.fromString(targetProperty, resultStr);
        break;

        // Data types stored by directly converting from primitive types to bytes in HBase.
        // TODO: for these data types determine if there is a way to "delimit" multiple values yet
        // not take the extra and expensive step of first converting to delimited String.
      case Decimal:
        if (!targetProperty.isMany()) result = Bytes.toBigDecimal(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Bytes:
        if (!targetProperty.isMany()) result = value; // already bytes
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Byte:
        if (!targetProperty.isMany()) {
          // NOTE: no toByte method as would expect as there is opposite method, see below
          // e.g. Bytes.toByte(value);
          if (value != null) {
            if (value.length > 2)
              log.warn(
                  "truncating "
                      + String.valueOf(value.length)
                      + " length byte array for target data type 'byte'");
            result = value[0];
          }
        } else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Boolean:
        if (!targetProperty.isMany()) result = Bytes.toBoolean(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Character:
        if (!targetProperty.isMany()) result = Character.valueOf(Bytes.toString(value).charAt(0));
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Double:
        if (!targetProperty.isMany()) result = Bytes.toDouble(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Float:
        if (!targetProperty.isMany()) result = Bytes.toFloat(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Int:
        if (!targetProperty.isMany()) result = Bytes.toInt(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Integer:
        if (!targetProperty.isMany()) result = new BigInteger(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Long:
        if (!targetProperty.isMany()) result = Bytes.toLong(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Short:
        if (!targetProperty.isMany()) result = Bytes.toShort(value);
        else result = DataConverter.INSTANCE.fromString(targetProperty, Bytes.toString(value));
        break;
      case Object:
        // FIXME: custom serialization?
      default:
        result = Bytes.toString(value);
        break;
    }

    return result;
  }
  /**
   * Converts the given value to bytes based on data type and cardinality information for the given
   * property. For 'many' or multi-valued properties, if the SDO Java type for the property is not
   * already String, the value is first converted to String using the SDO conversion which uses
   * java.util.Arrays formatting. For non 'many' or singular properties, only the HBase Bytes
   * utility is used.
   *
   * @param sourceProperty the source property
   * @param value the value
   * @return the bytes
   * @throws IllegalArgumentException if the given property is not a data type property
   */
  public byte[] toBytes(Property sourceProperty, Object value) {
    byte[] result;

    if (!sourceProperty.getType().isDataType())
      throw new IllegalArgumentException(
          "property " + sourceProperty.toString() + " is not a datatype property");
    DataType dataType = DataType.valueOf(sourceProperty.getType().getName());

    switch (dataType) {
        // Data types stored as String bytes in HBase
      case String:
      case Strings:
      case URI:
      case Month:
      case MonthDay:
      case Day:
      case Time:
      case Year:
      case YearMonth:
      case YearMonthDay:
      case Date:
      case Duration:
        String resultStr = DataConverter.INSTANCE.toString(sourceProperty, value);
        result = Bytes.toBytes(resultStr);
        break;
      case DateTime:
        resultStr = DataConverter.INSTANCE.toString(sourceProperty, value);
        result = Bytes.toBytes(resultStr);
        break;
        // Data types stored by directly converting from primitive types to bytes in HBase. When
        // the given property is a 'many' property, the value is first converted to String so
        // can be delimited.
      case Decimal:
        if (!sourceProperty.isMany()) {
          BigDecimal resultDecimal =
              DataConverter.INSTANCE.toDecimal(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultDecimal);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Bytes:
        if (!sourceProperty.isMany()) {
          byte[] resultBytes = DataConverter.INSTANCE.toBytes(sourceProperty.getType(), value);
          result = resultBytes;
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Byte:
        if (!sourceProperty.isMany()) {
          byte resultByte = DataConverter.INSTANCE.toByte(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultByte);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Boolean:
        if (!sourceProperty.isMany()) {
          boolean resultBool = DataConverter.INSTANCE.toBoolean(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultBool);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Character:
        if (!sourceProperty.isMany()) {
          resultStr = DataConverter.INSTANCE.toString(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultStr);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Double:
        if (!sourceProperty.isMany()) {
          double resultDouble = DataConverter.INSTANCE.toDouble(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultDouble);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Float:
        if (!sourceProperty.isMany()) {
          float resultFloat = DataConverter.INSTANCE.toFloat(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultFloat);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Int:
        if (!sourceProperty.isMany()) {
          int resultInt = DataConverter.INSTANCE.toInt(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultInt);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Integer:
        if (!sourceProperty.isMany()) {
          BigInteger resultInteger =
              DataConverter.INSTANCE.toInteger(sourceProperty.getType(), value);
          result = resultInteger.toByteArray();
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Long:
        if (!sourceProperty.isMany()) {
          long resultLong = DataConverter.INSTANCE.toLong(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultLong);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Short:
        if (!sourceProperty.isMany()) {
          short resultShort = DataConverter.INSTANCE.toShort(sourceProperty.getType(), value);
          result = Bytes.toBytes(resultShort);
        } else {
          String strResult = DataConverter.INSTANCE.toString(sourceProperty, value);
          result = Bytes.toBytes(strResult);
        }
        break;
      case Object:
        // FIXME: do we serialize objects in some custom format for hbase
      default:
        resultStr = DataConverter.INSTANCE.toString(sourceProperty.getType(), value);
        result = Bytes.toBytes(resultStr);
        break;
    }
    return result;
  }