예제 #1
0
 /**
  * given a list of objects returns the objects either in a DataList, or, if they are PathSpecs
  * (projections), encode them and return a String.
  */
 private static Object coerceList(List<?> values, Class<?> elementClass, ProtocolVersion version) {
   assert values != null;
   DataList dataList = new DataList();
   for (Object value : values) {
     if (value != null) {
       dataList.add(paramToDataObject(value, elementClass, version));
     }
   }
   return dataList;
 }
예제 #2
0
 /**
  * This method trims doc (1st arg) according to projected (2nd arg), which may have been modified
  * by projection. This method works in-place, meaning that the doc may be mutated.
  */
 private static void trim(DataMap doc, DataMap projected) {
   DataMap toAddDoc = new DataMap();
   Set<String> fields = doc.keySet();
   List<String> toRemoveDoc = new ArrayList<String>(fields.size());
   for (String f : fields) {
     Object v = doc.get(f);
     if (f.equals(PatchConstants.DELETE_COMMAND)) {
       DataList deletedFields = (DataList) v;
       DataList filteredDeleteFields = new DataList();
       for (Object patchDeleteField : deletedFields) {
         if (projected.containsKey(patchDeleteField)) {
           filteredDeleteFields.add(patchDeleteField);
         }
       }
       toRemoveDoc.add(f);
       if (!filteredDeleteFields.isEmpty()) {
         toAddDoc.put(PatchConstants.DELETE_COMMAND, filteredDeleteFields);
       }
     } else if (f.equals(PatchConstants.SET_COMMAND)) {
       DataMap setFields = (DataMap) v;
       Set<String> setFieldNames = setFields.keySet();
       List<String> toRemove = new LinkedList<String>();
       DataMap filteredSetFields = new DataMap();
       for (String setFieldName : setFieldNames) {
         if (projected.containsKey(setFieldName)) {
           filteredSetFields.put(setFieldName, projected.get(setFieldName));
         }
         toRemove.add(setFieldName);
       }
       for (String fieldToRemove : toRemove) {
         setFields.remove(fieldToRemove);
         if (filteredSetFields.containsKey(fieldToRemove)) {
           setFields.put(fieldToRemove, filteredSetFields.get(fieldToRemove));
         }
       }
       if (setFields.isEmpty()) {
         toRemoveDoc.add(f);
       }
     } else if (v instanceof DataMap) {
       if (projected.containsKey(f)) {
         trim((DataMap) v, (DataMap) projected.get(f));
       } else {
         toRemoveDoc.add(f);
       }
     }
   }
   // apply changes to doc
   for (String f : toRemoveDoc) {
     doc.remove(f);
   }
   for (String f : toAddDoc.keySet()) {
     doc.put(f, toAddDoc.get(f));
   }
 }
예제 #3
0
  @SuppressWarnings("unchecked")
  public <ArrayTemplate extends AbstractArrayTemplate<E>, E extends Number> void testNumberArray(
      Class<ArrayTemplate> templateClass,
      ArrayDataSchema schema,
      List<E> castTo,
      List<? extends Number> castFrom)
      throws InstantiationException, IllegalAccessException {
    // test insert non-native, converted to element type on set
    ArrayTemplate array1 = templateClass.newInstance();
    array1.addAll((List<E>) castFrom);
    for (int i = 0; i < castTo.size(); ++i) {
      assertEquals(castTo.get(i), array1.get(i));
      assertEquals(array1.data().get(i), castTo.get(i));
    }

    // test underlying is non-native, convert on get to element type on get.
    DataList dataList2 = new DataList(castFrom);
    ArrayTemplate array2 = DataTemplateUtil.wrap(dataList2, schema, templateClass);
    for (int i = 0; i < castTo.size(); ++i) {
      assertSame(dataList2.get(i), castFrom.get(i));
      assertEquals(castTo.get(i), array2.get(i));
    }
  }
예제 #4
0
  public <ArrayTemplate extends AbstractArrayTemplate<E>, E> void testArray(
      Class<ArrayTemplate> templateClass, ArrayDataSchema schema, List<E> input, List<E> adds)
      throws InstantiationException, IllegalAccessException {
    // out.println("Testing " + templateClass.getName() + " " + schema.toString());

    // constructors and addAll
    ArrayTemplate array1 = templateClass.newInstance();
    array1.addAll(input);
    assertEquals(input, array1);

    /*
    Constructor[] constructors = templateClass.getConstructors();
    for (Constructor c : constructors)
    {
      out.println(c);
    }
    */
    try {
      int size = input.size();

      // constructor(int capacity)
      Constructor<ArrayTemplate> capacityConstructor = templateClass.getConstructor(int.class);
      ArrayTemplate array = capacityConstructor.newInstance(input.size());
      assertEquals(array, Collections.emptyList());
      array.addAll(input);
      assertEquals(input, array);
      array.clear();
      assertEquals(size, input.size());

      // constructor(Collection<E>)
      Constructor<ArrayTemplate> collectionConstructor =
          templateClass.getConstructor(Collection.class);
      array = collectionConstructor.newInstance(input);
      assertEquals(input, array);
      array.clear();
      assertEquals(size, input.size());

      // constructor(DataList)
      Constructor<ArrayTemplate> dataListConstructor = templateClass.getConstructor(DataList.class);
      array = dataListConstructor.newInstance(array1.data());
      assertEquals(array1, array);
      assertEquals(input, array);
      array.clear();
      assertEquals(array1, array);
    } catch (Exception e) {
      assertSame(e, null);
    }

    // test wrapping
    array1.clear();
    array1.addAll(input);
    DataList dataList2 = new DataList();
    ArrayTemplate array2 =
        DataTemplateUtil.wrap(dataList2, schema, templateClass); // with schema arg
    for (E e : input) {
      if (e instanceof DataTemplate) {
        dataList2.add(((DataTemplate<?>) e).data());
      } else if (e instanceof Enum) {
        dataList2.add(e.toString());
      } else {
        dataList2.add(e);
      }
    }
    assertEquals(array1, array2);
    ArrayTemplate array2a = DataTemplateUtil.wrap(dataList2, templateClass); // without schema arg
    assertEquals(array1, array2a);
    assertSame(array2.data(), array2a.data());

    // schema()
    ArrayDataSchema schema1 = array1.schema();
    assertTrue(schema1 != null);
    assertEquals(schema1.getType(), DataSchema.Type.ARRAY);
    assertEquals(schema1, schema);

    // add(E element), get(int index)
    ArrayTemplate array3 = templateClass.newInstance();
    for (int i = 0; i < adds.size(); ++i) {
      E value = adds.get(i);
      assertTrue(array3.add(value));
      assertEquals(array3.get(i), value);
      assertSame(array3.get(i), value);
      assertTrue(array3.toString().contains(value.toString()));
    }
    assertEquals(array3, adds);

    // add(int index, E element), get(int index)
    ArrayTemplate array4 = templateClass.newInstance();
    for (int i = 0; i < adds.size(); ++i) {
      E value = adds.get(adds.size() - i - 1);
      array4.add(0, value);
      assertEquals(array4.get(0), value);
      assertSame(array4.get(0), value);
    }
    assertEquals(array4, adds);

    // clear(), isEmpty(), size()
    assertEquals(array4.size(), adds.size());
    assertFalse(array4.isEmpty());
    array4.clear();
    assertTrue(array4.isEmpty());
    assertEquals(array4.size(), 0);

    // equals()
    array4.clear();
    array4.addAll(input);
    assertTrue(array4.equals(array4));
    assertTrue(array4.equals(input));
    assertFalse(array4.equals(null));
    assertFalse(array4.equals(adds));
    for (int i = 0; i <= input.size(); ++i) {
      List<E> subList = input.subList(0, i);
      ArrayTemplate a = templateClass.newInstance();
      a.addAll(subList);
      if (i == input.size()) {
        assertTrue(array4.equals(subList));
        assertTrue(array4.equals(a));
      } else {
        assertFalse(array4.equals(subList));
        assertFalse(array4.equals(a));
      }
    }

    // hashcode()
    ArrayTemplate array5 = templateClass.newInstance();
    array5.addAll(input);
    assertEquals(array5.hashCode(), array5.data().hashCode());
    array5.addAll(adds);
    assertEquals(array5.hashCode(), array5.data().hashCode());
    array5.clear();
    int lastHash = 0;
    for (int i = 0; i < input.size(); ++i) {
      array5.add(input.get(i));
      int newHash = array5.hashCode();
      if (i > 0) {
        assertFalse(newHash == lastHash);
      }
      lastHash = newHash;
    }

    // indexOf(Object o), lastIndexOf(Object o)
    ArrayTemplate array6 = templateClass.newInstance();
    array6.addAll(adds);
    for (E e : adds) {
      assertEquals(array6.indexOf(e), adds.indexOf(e));
      assertEquals(array6.lastIndexOf(e), adds.lastIndexOf(e));
    }

    // remove(int index), subList(int fromIndex, int toIndex)
    ArrayTemplate array7 = templateClass.newInstance();
    array7.addAll(input);
    ArrayTemplate array8 = templateClass.newInstance();
    array8.addAll(input);
    for (int i = 0; i < input.size(); ++i) {
      array7.remove(0);
      assertEquals(array7, input.subList(i + 1, input.size()));
      assertEquals(array7, array8.subList(i + 1, input.size()));
    }

    // removeRange(int fromIndex, int toIndex), subList(int fromIndex, int toIndex)
    for (int from = 0; from < input.size(); ++from) {
      for (int to = from + 1; to <= input.size(); ++to) {
        ArrayTemplate arrayRemove = templateClass.newInstance();
        arrayRemove.addAll(input);
        InternalList<E> reference = new InternalList<E>(input);
        arrayRemove.removeRange(from, to);
        reference.removeRange(from, to);
        assertEquals(reference, arrayRemove);
      }
    }

    // set(int index, E element)
    ArrayTemplate array9 = templateClass.newInstance();
    array9.addAll(input);
    InternalList<E> reference9 = new InternalList<E>(input);
    for (int i = 0; i < input.size() / 2; ++i) {
      int k = input.size() - i - 1;
      E lo = array9.get(i);
      E hi = array9.get(k);
      E hiPrev = array9.set(k, lo);
      E loPrev = array9.set(i, hi);
      E refHiPrev = reference9.set(k, lo);
      E refLoPrev = reference9.set(i, hi);
      assertEquals(hiPrev, refHiPrev);
      assertEquals(loPrev, refLoPrev);
      assertEquals(array9.get(i), reference9.get(i));
      assertEquals(array9.get(k), reference9.get(k));
    }

    // clone
    Exception exc = null;
    ArrayTemplate array10 = templateClass.newInstance();
    array10.addAll(input);
    try {
      exc = null;
      @SuppressWarnings("unchecked")
      ArrayTemplate array10Clone = (ArrayTemplate) array10.clone();
      assertEquals(array10Clone, array10);
      assertTrue(array10Clone != array10);
      array10Clone.remove(0);
      assertEquals(array10Clone.size(), array10.size() - 1);
      assertFalse(array10Clone.equals(array10));
      assertTrue(array10.containsAll(array10Clone));
      array10.remove(0);
      assertEquals(array10Clone, array10);
    } catch (CloneNotSupportedException e) {
      exc = e;
    }
    assert (exc == null);

    // contains
    for (int i = 0; i < input.size(); ++i) {
      ArrayTemplate array = templateClass.newInstance();
      E v = input.get(i);
      array.add(v);
      for (int k = 0; k < input.size(); ++k) {
        if (k == i) assertTrue(array.contains(v));
        else assertFalse(array.contains(input.get(k)));
      }
    }

    // containsAll
    ArrayTemplate arrayContainsAll = templateClass.newInstance();
    arrayContainsAll.addAll(input);
    arrayContainsAll.addAll(adds);
    InternalList<E> referenceContainsAll = new InternalList<E>(input);
    referenceContainsAll.addAll(adds);
    for (int from = 0; from < arrayContainsAll.size(); ++from) {
      for (int to = from + 1; to <= arrayContainsAll.size(); ++to) {
        boolean testResult = arrayContainsAll.containsAll(referenceContainsAll.subList(from, to));
        boolean referenceResult =
            referenceContainsAll.containsAll(referenceContainsAll.subList(from, to));
        assertEquals(testResult, referenceResult);
        assertTrue(testResult);
        assertTrue(referenceResult);
      }
      boolean testResult2 =
          arrayContainsAll.subList(from, arrayContainsAll.size()).containsAll(referenceContainsAll);
      boolean referenceResult2 =
          referenceContainsAll
              .subList(from, arrayContainsAll.size())
              .containsAll(referenceContainsAll);
      // out.println("from " + from + " test " + testResult2 + " ref " + referenceResult2);
      assertEquals(testResult2, referenceResult2);
    }

    // removeAll
    InternalList<E> referenceListRemoveAll = new InternalList<E>(input);
    referenceListRemoveAll.addAll(adds);
    for (int from = 0; from < referenceListRemoveAll.size(); ++from) {
      for (int to = from + 1; to <= referenceListRemoveAll.size(); ++to) {
        ArrayTemplate arrayRemoveAll = templateClass.newInstance();
        arrayRemoveAll.addAll(referenceListRemoveAll);
        InternalList<E> referenceRemoveAll = new InternalList<E>(referenceListRemoveAll);

        boolean testResult = arrayRemoveAll.removeAll(referenceListRemoveAll.subList(from, to));
        boolean referenceResult =
            referenceRemoveAll.removeAll(referenceListRemoveAll.subList(from, to));
        // out.println("from " + from + " to " + to + " test " + testResult + " " + arrayRemoveAll +
        // " ref " + referenceResult + " " + referenceRemoveAll);
        assertEquals(arrayRemoveAll, referenceRemoveAll);
        assertEquals(testResult, referenceResult);
        assertTrue(testResult);
        assertTrue(referenceResult);
      }
    }

    // retainAll
    InternalList<E> referenceListRetainAll = new InternalList<E>(input);
    referenceListRetainAll.addAll(adds);
    for (int from = 0; from < referenceListRetainAll.size(); ++from) {
      for (int to = from + 1; to <= referenceListRetainAll.size(); ++to) {
        ArrayTemplate arrayRetainAll = templateClass.newInstance();
        arrayRetainAll.addAll(referenceListRetainAll);
        InternalList<E> referenceRetainAll = new InternalList<E>(referenceListRetainAll);

        boolean testResult = arrayRetainAll.removeAll(referenceListRetainAll.subList(from, to));
        boolean referenceResult =
            referenceRetainAll.removeAll(referenceListRetainAll.subList(from, to));
        // out.println("from " + from + " to " + to + " test " + testResult + " " + arrayRetainAll +
        // " ref " + referenceResult + " " + referenceRetainAll);
        assertEquals(arrayRetainAll, referenceRetainAll);
        assertEquals(testResult, referenceResult);
        assertTrue(testResult);
        assertTrue(referenceResult);
      }
    }

    // Iterator
    ArrayTemplate arrayIt = templateClass.newInstance();
    arrayIt.addAll(input);
    arrayIt.addAll(adds);
    for (Iterator<E> it = arrayIt.iterator(); it.hasNext(); ) {
      it.next();
      it.remove();
    }
    assertTrue(arrayIt.isEmpty());

    // ListIterator hasNext, hasPrevious, next, previous
    ArrayTemplate arrayListIt = templateClass.newInstance();
    arrayListIt.addAll(input);
    arrayListIt.addAll(adds);
    for (int i = 0; i <= arrayListIt.size(); ++i) {
      ListIterator<E> it = arrayListIt.listIterator(i);
      if (i > 0) {
        int save = it.nextIndex();
        assertTrue(it.hasPrevious());
        assertEquals(it.previous(), arrayListIt.get(i - 1));
        it.next();
        assertEquals(it.nextIndex(), save);
      } else {
        assertFalse(it.hasPrevious());
      }
      if (i < arrayListIt.size()) {
        int save = it.previousIndex();
        assertTrue(it.hasNext());
        assertEquals(it.next(), arrayListIt.get(i));
        it.previous();
        assertEquals(it.previousIndex(), save);
      } else {
        assertFalse(it.hasNext());
      }
      assertEquals(it.nextIndex(), i);
      assertEquals(it.previousIndex(), i - 1);
    }

    // ListIterator remove
    for (ListIterator<E> it = arrayListIt.listIterator(); it.hasNext(); ) {
      it.next();
      it.remove();
    }
    assertTrue(arrayListIt.isEmpty());

    // ListIterator add
    arrayListIt.clear();
    {
      ListIterator<E> it = arrayListIt.listIterator();
      for (E e : adds) {
        it.add(e);
      }
    }
    assertEquals(arrayListIt, adds);

    // ListIterator set
    for (int i = 0; i < adds.size(); ++i) {
      ListIterator<E> it = arrayListIt.listIterator(i);
      it.next();
      E value = adds.get(adds.size() - i - 1);
      it.set(value);
    }
    for (int i = 0; i < adds.size(); ++i) {
      E value = adds.get(adds.size() - i - 1);
      assertEquals(arrayListIt.get(i), value);
    }
  }
예제 #5
0
  @SuppressWarnings("unchecked")
  public <ArrayTemplate extends AbstractArrayTemplate<E>, E> void testArrayBadInput(
      Class<ArrayTemplate> templateClass,
      ArrayDataSchema schema,
      List<E> good,
      List<Object> badInput,
      List<Object> badOutput)
      throws InstantiationException, IllegalAccessException {
    Exception exc = null;
    ArrayTemplate arrayTemplateBad = templateClass.newInstance();
    DataList badDataList = new DataList();
    ArrayTemplate badWrappedArrayTemplate =
        DataTemplateUtil.wrap(badDataList, schema, templateClass);

    List<E> badIn = (List<E>) badInput;

    // add(E element)
    for (E o : badIn) {
      try {
        exc = null;
        arrayTemplateBad.add(o);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(o == null || exc instanceof ClassCastException);
      assertTrue(o != null || exc instanceof NullPointerException);
    }

    // add(int index, E element)
    for (Object o : badIn) {
      try {
        exc = null;
        arrayTemplateBad.add(0, (E) o);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(o == null || exc instanceof ClassCastException);
      assertTrue(o != null || exc instanceof NullPointerException);
    }

    // addAll(Collection<E> c)
    try {
      exc = null;
      arrayTemplateBad.addAll(badIn);
    } catch (Exception e) {
      exc = e;
    }
    assertTrue(exc != null);
    assertTrue(exc instanceof ClassCastException);

    // set(int index, E element)
    arrayTemplateBad.addAll(good);
    assertTrue(arrayTemplateBad.size() > 1);
    for (Object o : badIn) {
      try {
        exc = null;
        arrayTemplateBad.set(0, (E) o);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(o == null || exc instanceof ClassCastException);
      assertTrue(o != null || exc instanceof NullPointerException);
    }

    // listIterator add
    for (Object o : badIn) {
      try {
        exc = null;
        ListIterator<E> it = arrayTemplateBad.listIterator(0);
        it.add((E) o);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(o == null || exc instanceof ClassCastException);
      assertTrue(o != null || exc instanceof NullPointerException);
    }

    // listIterator set
    for (Object o : badIn) {
      try {
        exc = null;
        ListIterator<E> it = arrayTemplateBad.listIterator(0);
        it.next();
        it.set((E) o);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(o == null || exc instanceof ClassCastException);
      assertTrue(o != null || exc instanceof NullPointerException);
    }

    badDataList.clear();
    badDataList.addAll(badOutput);
    badWrappedArrayTemplate = DataTemplateUtil.wrap(badDataList, schema, templateClass);

    // Get returns bad
    for (int i = 0; i < badWrappedArrayTemplate.size(); ++i) {
      try {
        exc = null;
        badWrappedArrayTemplate.get(i);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }

    // Set returns bad
    badDataList.clear();
    badDataList.addAll(badOutput);
    assertEquals(badWrappedArrayTemplate.size(), badOutput.size());
    for (int i = 0; i < badWrappedArrayTemplate.size(); ++i) {
      try {
        exc = null;
        badWrappedArrayTemplate.set(i, good.get(0));
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }

    // Remove returns bad
    badDataList.clear();
    badDataList.addAll(badOutput);
    assertEquals(badWrappedArrayTemplate.size(), badOutput.size());
    for (int i = 0; i < badWrappedArrayTemplate.size(); ++i) {
      try {
        exc = null;
        badWrappedArrayTemplate.remove(0);
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }

    // Iterator returns bad
    for (Object o : badOutput) {
      badDataList.clear();
      badDataList.add(o);
      try {
        exc = null;
        badWrappedArrayTemplate.iterator().next();
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }

    // ListIterator returns bad
    for (Object o : badOutput) {
      badDataList.clear();
      badDataList.add(o);
      try {
        exc = null;
        badWrappedArrayTemplate.listIterator().next();
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }
    for (Object o : badOutput) {
      badDataList.clear();
      badDataList.add(o);
      try {
        exc = null;
        badWrappedArrayTemplate.listIterator(badWrappedArrayTemplate.size()).previous();
      } catch (Exception e) {
        exc = e;
      }
      assertTrue(exc != null);
      assertTrue(exc instanceof TemplateOutputCastException);
    }
  }
예제 #6
0
    private Object translate(Object value, DataSchema dataSchema, Schema avroSchema) {
      AvroOverride avroOverride = getAvroOverride(dataSchema);
      if (avroOverride != null) {
        return avroOverride
            .getCustomDataTranslator()
            .dataToAvroGeneric(this, value, dataSchema, avroSchema);
      }

      DataSchema dereferencedDataSchema = dataSchema.getDereferencedDataSchema();
      DataSchema.Type type = dereferencedDataSchema.getType();
      Object result;
      switch (type) {
        case NULL:
          if (value != Data.NULL) {
            appendMessage("value must be null for null schema");
            result = BAD_RESULT;
            break;
          }
          result = null;
          break;
        case BOOLEAN:
          result = ((Boolean) value).booleanValue();
          break;
        case INT:
          result = ((Number) value).intValue();
          break;
        case LONG:
          result = ((Number) value).longValue();
          break;
        case FLOAT:
          result = ((Number) value).floatValue();
          break;
        case DOUBLE:
          result = ((Number) value).doubleValue();
          break;
        case STRING:
          result = new Utf8((String) value);
          break;
        case BYTES:
          result = ByteBuffer.wrap(translateBytes(value));
          break;
        case ENUM:
          String enumValue = value.toString();
          EnumDataSchema enumDataSchema = (EnumDataSchema) dereferencedDataSchema;
          if (enumDataSchema.getSymbols().contains(enumValue) == false) {
            appendMessage(
                "enum value %1$s not one of %2$s", enumValue, enumDataSchema.getSymbols());
            result = BAD_RESULT;
            break;
          }
          result = _avroAdapter.createEnumSymbol(avroSchema, enumValue);
          break;
        case FIXED:
          byte[] bytes = translateBytes(value);
          FixedDataSchema fixedDataSchema = (FixedDataSchema) dereferencedDataSchema;
          if (fixedDataSchema.getSize() != bytes.length) {
            appendMessage(
                "ByteString size %1$d != FixedDataSchema size %2$d",
                bytes.length, fixedDataSchema.getSize());
            result = null;
            break;
          }
          GenericData.Fixed fixed = new GenericData.Fixed(avroSchema);
          fixed.bytes(bytes);
          result = fixed;
          break;
        case MAP:
          DataMap map = (DataMap) value;
          DataSchema valueDataSchema = ((MapDataSchema) dereferencedDataSchema).getValues();
          Schema valueAvroSchema = avroSchema.getValueType();
          Map<String, Object> avroMap = new HashMap<String, Object>(map.size());
          for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            _path.addLast(key);
            Object entryAvroValue = translate(entry.getValue(), valueDataSchema, valueAvroSchema);
            _path.removeLast();
            avroMap.put(key, entryAvroValue);
          }
          result = avroMap;
          break;
        case ARRAY:
          DataList list = (DataList) value;
          DataSchema elementDataSchema = ((ArrayDataSchema) dereferencedDataSchema).getItems();
          Schema elementAvroSchema = avroSchema.getElementType();
          GenericData.Array<Object> avroList =
              new GenericData.Array<Object>(list.size(), avroSchema);
          for (int i = 0; i < list.size(); i++) {
            _path.addLast(i);
            Object entryAvroValue = translate(list.get(i), elementDataSchema, elementAvroSchema);
            _path.removeLast();
            avroList.add(entryAvroValue);
          }
          result = avroList;
          break;
        case RECORD:
          map = (DataMap) value;
          RecordDataSchema recordDataSchema = (RecordDataSchema) dereferencedDataSchema;
          GenericData.Record avroRecord = new GenericData.Record(avroSchema);
          for (RecordDataSchema.Field field : recordDataSchema.getFields()) {
            String fieldName = field.getName();
            DataSchema fieldDataSchema = field.getType();
            Schema.Field avroField = avroSchema.getField(fieldName);
            if (avroField == null) {
              // field present in input but there is no field for it in Avro schema.
              // TODO: Whether and how to indicate this condition to clients.
              continue;
            }
            _path.addLast(fieldName);
            Schema fieldAvroSchema = avroField.schema();
            Object fieldValue = map.get(fieldName);
            boolean isOptional = field.getOptional();
            if (isOptional) {
              if (fieldDataSchema.getDereferencedType() != DataSchema.Type.UNION) {
                if (fieldValue == null) {
                  fieldValue = Data.NULL;
                  fieldDataSchema = DataSchemaConstants.NULL_DATA_SCHEMA;
                }
                Map.Entry<String, Schema> fieldAvroEntry =
                    findUnionMember(fieldDataSchema, fieldAvroSchema);
                if (fieldAvroEntry == null) {
                  _path.removeLast();
                  continue;
                }
                fieldAvroSchema = fieldAvroEntry.getValue();
              } else {
                // already a union
                if (fieldValue == null) {
                  // field is not present
                  fieldValue = Data.NULL;
                  fieldDataSchema = DataSchemaConstants.NULL_DATA_SCHEMA;
                }
              }
            } else {
              if (fieldValue == null) {
                appendMessage("required field is absent");
                _path.removeLast();
                continue;
              }
            }
            Object fieldAvroValue = translate(fieldValue, fieldDataSchema, fieldAvroSchema);
            avroRecord.put(fieldName, fieldAvroValue);
            _path.removeLast();
          }
          result = avroRecord;
          break;
        case UNION:
          UnionDataSchema unionDataSchema = (UnionDataSchema) dereferencedDataSchema;
          String key;
          Object memberValue;
          if (value == Data.NULL) {
            key = DataSchemaConstants.NULL_TYPE;
            memberValue = Data.NULL;
          } else {
            map = (DataMap) value;
            Map.Entry<String, Object> entry = map.entrySet().iterator().next();
            key = entry.getKey();
            memberValue = entry.getValue();
          }
          DataSchema memberDataSchema = unionDataSchema.getType(key);
          Map.Entry<String, Schema> memberAvroEntry = findUnionMember(memberDataSchema, avroSchema);
          if (memberAvroEntry == null) {
            result = BAD_RESULT;
            break;
          }
          Schema memberAvroSchema = memberAvroEntry.getValue();
          _path.addLast(memberAvroEntry.getKey());
          Object memberAvroValue = translate(memberValue, memberDataSchema, memberAvroSchema);
          _path.removeLast();
          result = memberAvroValue;
          break;
        default:
          appendMessage("schema type unknown %1$s", dereferencedDataSchema.getType());
          result = BAD_RESULT;
          break;
      }
      return result;
    }
예제 #7
0
    private Object translate(Object value, DataSchema dataSchema, Schema avroSchema) {
      AvroOverride avroOverride = getAvroOverride(dataSchema);
      if (avroOverride != null) {
        return avroOverride
            .getCustomDataTranslator()
            .avroGenericToData(this, value, avroSchema, dataSchema);
      }

      DataSchema dereferencedDataSchema = dataSchema.getDereferencedDataSchema();
      DataSchema.Type type = dereferencedDataSchema.getType();
      Object result;
      switch (type) {
        case NULL:
          if (value != null) {
            appendMessage("value must be null for null schema");
            result = BAD_RESULT;
            break;
          }
          result = Data.NULL;
          break;
        case BOOLEAN:
          result = ((Boolean) value).booleanValue();
          break;
        case INT:
          result = ((Number) value).intValue();
          break;
        case LONG:
          result = ((Number) value).longValue();
          break;
        case FLOAT:
          result = ((Number) value).floatValue();
          break;
        case DOUBLE:
          result = ((Number) value).doubleValue();
          break;
        case STRING:
          result = value.toString();
          break;
        case BYTES:
          ByteBuffer byteBuffer = (ByteBuffer) value;
          ByteString byteString = ByteString.copy(byteBuffer);
          byteBuffer.rewind();
          result = byteString;
          break;
        case ENUM:
          String enumValue = value.toString();
          EnumDataSchema enumDataSchema = (EnumDataSchema) dereferencedDataSchema;
          if (enumDataSchema.getSymbols().contains(enumValue) == false) {
            appendMessage(
                "enum value %1$s not one of %2$s", enumValue, enumDataSchema.getSymbols());
            result = BAD_RESULT;
            break;
          }
          result = enumValue;
          break;
        case FIXED:
          GenericFixed fixed = (GenericFixed) value;
          byte[] fixedBytes = fixed.bytes();
          FixedDataSchema fixedDataSchema = (FixedDataSchema) dereferencedDataSchema;
          if (fixedDataSchema.getSize() != fixedBytes.length) {
            appendMessage(
                "GenericFixed size %1$d != FixedDataSchema size %2$d",
                fixedBytes.length, fixedDataSchema.getSize());
            result = BAD_RESULT;
            break;
          }
          byteString = ByteString.copy(fixedBytes);
          result = byteString;
          break;
        case MAP:
          @SuppressWarnings("unchecked")
          Map<?, Object> map = (Map<?, Object>) value;
          DataSchema valueDataSchema = ((MapDataSchema) dereferencedDataSchema).getValues();
          Schema valueAvroSchema = avroSchema.getValueType();
          DataMap dataMap = new DataMap(map.size());
          for (Map.Entry<?, Object> entry : map.entrySet()) {
            String key = entry.getKey().toString();
            _path.addLast(key);
            Object entryValue = translate(entry.getValue(), valueDataSchema, valueAvroSchema);
            _path.removeLast();
            dataMap.put(key, entryValue);
          }
          result = dataMap;
          break;
        case ARRAY:
          GenericArray<?> list = (GenericArray<?>) value;
          DataSchema elementDataSchema = ((ArrayDataSchema) dereferencedDataSchema).getItems();
          Schema elementAvroSchema = avroSchema.getElementType();
          DataList dataList = new DataList(list.size());
          for (int i = 0; i < list.size(); i++) {
            _path.addLast(i);
            Object entryValue = translate(list.get(i), elementDataSchema, elementAvroSchema);
            _path.removeLast();
            dataList.add(entryValue);
          }
          result = dataList;
          break;
        case RECORD:
          GenericRecord record = (GenericRecord) value;
          RecordDataSchema recordDataSchema = (RecordDataSchema) dereferencedDataSchema;
          dataMap = new DataMap(avroSchema.getFields().size());
          for (RecordDataSchema.Field field : recordDataSchema.getFields()) {
            String fieldName = field.getName();
            Object fieldValue = record.get(fieldName);
            // fieldValue could be null if the Avro schema does not contain the named field or
            // the field is present with a null value. In either case we do not add a value
            // to the translated DataMap. We do not consider optional/required/default here
            // either (i.e. it is not an error if a required field is missing); the user can
            // later call ValidateDataAgainstSchema with various
            // settings for RequiredMode to obtain the desired behaviour.
            if (fieldValue == null) {
              continue;
            }
            boolean isOptional = field.getOptional();
            DataSchema fieldDataSchema = field.getType();
            Schema fieldAvroSchema = avroSchema.getField(fieldName).schema();
            if (isOptional && (fieldDataSchema.getDereferencedType() != DataSchema.Type.UNION)) {
              // Avro schema should be union with 2 types: null and the field's type.
              Map.Entry<String, Schema> fieldAvroEntry =
                  findUnionMember(fieldDataSchema, fieldAvroSchema);
              if (fieldAvroEntry == null) {
                continue;
              }
              fieldAvroSchema = fieldAvroEntry.getValue();
            }
            _path.addLast(fieldName);
            dataMap.put(fieldName, translate(fieldValue, fieldDataSchema, fieldAvroSchema));
            _path.removeLast();
          }
          result = dataMap;
          break;
        case UNION:
          UnionDataSchema unionDataSchema = (UnionDataSchema) dereferencedDataSchema;
          Map.Entry<DataSchema, Schema> memberSchemas =
              findUnionMemberSchema(value, unionDataSchema, avroSchema);
          if (memberSchemas == null) {
            result = BAD_RESULT;
            break;
          }
          if (value == null) {
            // schema must be "null" schema
            result = Data.NULL;
          } else {
            DataSchema memberDataSchema = memberSchemas.getKey();
            Schema memberAvroSchema = memberSchemas.getValue();
            String key = memberDataSchema.getUnionMemberKey();
            dataMap = new DataMap(1);
            _path.addLast(key);
            dataMap.put(key, translate(value, memberDataSchema, memberAvroSchema));
            _path.removeLast();
            result = dataMap;
          }
          break;
        default:
          appendMessage("schema type unknown %1$s", dereferencedDataSchema.getType());
          result = BAD_RESULT;
          break;
      }
      return result;
    }
예제 #8
0
  /**
   * Build a method argument from a request parameter that is an array
   *
   * @param context {@link ResourceContext}
   * @param param {@link Parameter}
   * @return argument value in the correct type
   */
  private static Object buildArrayArgument(
      final ResourceContext context, final Parameter<?> param) {
    final Object convertedValue;
    if (DataTemplate.class.isAssignableFrom(param.getItemType())) {
      final DataList itemsList = (DataList) context.getStructuredParameter(param.getName());
      convertedValue = Array.newInstance(param.getItemType(), itemsList.size());
      int j = 0;
      for (Object paramData : itemsList) {
        final DataTemplate<?> itemsElem =
            DataTemplateUtil.wrap(paramData, param.getItemType().asSubclass(DataTemplate.class));

        ValidateDataAgainstSchema.validate(
            itemsElem.data(),
            itemsElem.schema(),
            new ValidationOptions(
                RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT, CoercionMode.STRING_TO_PRIMITIVE));

        Array.set(convertedValue, j++, itemsElem);
      }
    } else {
      final List<String> itemStringValues = context.getParameterValues(param.getName());
      ArrayDataSchema parameterSchema = null;
      if (param.getDataSchema() instanceof ArrayDataSchema) {
        parameterSchema = (ArrayDataSchema) param.getDataSchema();
      } else {
        throw new RoutingException(
            "An array schema is expected.", HttpStatus.S_400_BAD_REQUEST.getCode());
      }

      convertedValue = Array.newInstance(param.getItemType(), itemStringValues.size());
      int j = 0;
      for (String itemStringValue : itemStringValues) {
        if (itemStringValue == null) {
          throw new RoutingException(
              "Parameter '" + param.getName() + "' cannot contain null values",
              HttpStatus.S_400_BAD_REQUEST.getCode());
        }
        try {
          Array.set(
              convertedValue,
              j++,
              ArgumentUtils.convertSimpleValue(
                  itemStringValue, parameterSchema.getItems(), param.getItemType()));
        } catch (NumberFormatException e) {
          Class<?> targetClass =
              DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(
                  parameterSchema.getItems().getDereferencedType());
          // thrown from Integer.valueOf or Long.valueOf
          throw new RoutingException(
              String.format(
                  "Array parameter '%s' value '%s' must be of type '%s'",
                  param.getName(), itemStringValue, targetClass.getName()),
              HttpStatus.S_400_BAD_REQUEST.getCode());
        } catch (IllegalArgumentException e) {
          // thrown from Enum.valueOf
          throw new RoutingException(
              String.format(
                  "Array parameter '%s' value '%s' is invalid", param.getName(), itemStringValue),
              HttpStatus.S_400_BAD_REQUEST.getCode());
        } catch (TemplateRuntimeException e) {
          // thrown from DataTemplateUtil.coerceOutput
          throw new RoutingException(
              String.format(
                  "Array parameter '%s' value '%s' is invalid. Reason: %s",
                  param.getName(), itemStringValue, e.getMessage()),
              HttpStatus.S_400_BAD_REQUEST.getCode());
        }
      }
    }

    return convertedValue;
  }