예제 #1
0
 /**
  * Set the default values for the non defined fields.
  *
  * @param model the model which has its default fields set.
  * @throws IllegalAccessException if the underlying fields are inaccessible
  * @throws Exception In case the field cannot be parsed
  */
 private void setDefaultValuesForFields(final Map<String, Object> model)
     throws IllegalAccessException, Exception {
   // Set the default values, if defined
   for (int i = 1; i <= dataFields.size(); i++) {
     Field field = annotatedFields.get(i);
     field.setAccessible(true);
     DataField dataField = dataFields.get(i);
     Object modelField = model.get(field.getDeclaringClass().getName());
     if (field.get(modelField) == null && !dataField.defaultValue().isEmpty()) {
       Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField);
       Object value = format.parse(dataField.defaultValue());
       field.set(modelField, value);
     }
   }
 }
예제 #2
0
  public void bind(List<String> tokens, Map<String, Object> model, int line) throws Exception {

    int pos = 1;
    int counterMandatoryFields = 0;

    for (String data : tokens) {

      // Get DataField from model
      DataField dataField = dataFields.get(pos);
      ObjectHelper.notNull(
          dataField, "No position " + pos + " defined for the field: " + data + ", line: " + line);

      if (dataField.trim()) {
        data = data.trim();
      }

      if (dataField.required()) {
        // Increment counter of mandatory fields
        ++counterMandatoryFields;

        // Check if content of the field is empty
        // This is not possible for mandatory fields
        if (data.equals("")) {
          throw new IllegalArgumentException(
              "The mandatory field defined at the position "
                  + pos
                  + " is empty for the line: "
                  + line);
        }
      }

      // Get Field to be setted
      Field field = annotatedFields.get(pos);
      field.setAccessible(true);

      if (LOG.isDebugEnabled()) {
        LOG.debug("Pos: {}, Data: {}, Field type: {}", new Object[] {pos, data, field.getType()});
      }

      // Create format object to format the field
      Format<?> format = FormatFactory.getFormat(field.getType(), getLocale(), dataField);

      // field object to be set
      Object modelField = model.get(field.getDeclaringClass().getName());

      // format the data received
      Object value = null;

      if (!data.equals("")) {
        try {
          value = format.parse(data);
        } catch (FormatException ie) {
          throw new IllegalArgumentException(
              ie.getMessage() + ", position: " + pos + ", line: " + line, ie);
        } catch (Exception e) {
          throw new IllegalArgumentException(
              "Parsing error detected for field defined at the position: "
                  + pos
                  + ", line: "
                  + line,
              e);
        }
      } else {
        if (!dataField.defaultValue().isEmpty()) {
          value = format.parse(dataField.defaultValue());
        } else {
          value = getDefaultValueForPrimitive(field.getType());
        }
      }

      field.set(modelField, value);

      ++pos;
    }

    LOG.debug("Counter mandatory fields: {}", counterMandatoryFields);

    if (counterMandatoryFields < numberMandatoryFields) {
      throw new IllegalArgumentException("Some mandatory fields are missing, line: " + line);
    }

    if (pos < totalFields) {
      setDefaultValuesForFields(model);
    }
  }
예제 #3
0
  /**
   * Generate a table containing the data formatted and sorted with their position/offset If the
   * model is Ordered than a key is created combining the annotation @Section and Position of the
   * field If a relation @OneToMany is defined, than we iterate recursively through this function
   * The result is placed in the Map<Integer, List> results
   */
  private void generateCsvPositionMap(
      Class<?> clazz, Object obj, Map<Integer, List<String>> results) throws Exception {

    String result = "";

    for (Field field : clazz.getDeclaredFields()) {

      field.setAccessible(true);

      DataField datafield = field.getAnnotation(DataField.class);

      if (datafield != null) {

        if (obj != null) {

          // Retrieve the format, pattern and precision associated to the type
          Class<?> type = field.getType();

          // Create format
          Format<?> format = FormatFactory.getFormat(type, getLocale(), datafield);

          // Get field value
          Object value = field.get(obj);

          result = formatString(format, value);

          if (datafield.trim()) {
            result = result.trim();
          }

          if (datafield.clip() && result.length() > datafield.length()) {
            result = result.substring(0, datafield.length());
          }

          if (LOG.isDebugEnabled()) {
            LOG.debug(
                "Value to be formatted: {}, position: {}, and its formatted value: {}",
                new Object[] {value, datafield.pos(), result});
          }

        } else {
          result = "";
        }

        Integer key;

        if (isMessageOrdered() && obj != null) {

          // Generate a key using the number of the section
          // and the position of the field
          Integer key1 = sections.get(obj.getClass().getName());
          Integer key2 = datafield.position();
          Integer keyGenerated = generateKey(key1, key2);

          if (LOG.isDebugEnabled()) {
            LOG.debug("Key generated: {}, for section: {}", String.valueOf(keyGenerated), key1);
          }

          key = keyGenerated;

        } else {
          key = datafield.pos();
        }

        if (!results.containsKey(key)) {
          List<String> list = new LinkedList<String>();
          list.add(result);
          results.put(key, list);
        } else {
          List<String> list = results.get(key);
          list.add(result);
        }
      }

      OneToMany oneToMany = field.getAnnotation(OneToMany.class);
      if (oneToMany != null) {

        // Set global variable
        // Will be used during generation of CSV
        isOneToMany = true;

        List<?> list = (List<?>) field.get(obj);
        if (list != null) {

          Iterator<?> it = list.iterator();
          while (it.hasNext()) {
            Object target = it.next();
            generateCsvPositionMap(target.getClass(), target, results);
          }

        } else {

          // Call this function to add empty value
          // in the table
          generateCsvPositionMap(field.getClass(), null, results);
        }
      }
    }
  }
/**
 * Unit test for {@link JsonJacksonFormat}
 *
 * @author [email protected] Jeffrey Damick
 */
public class JsonJacksonFormatTest {
  // since jackson doesn't append spaces after the colon...
  private static final String unknownFieldsText =
      TestUtil.readTextFromFile("json_format_unknown_fields_data.txt").replaceAll(": ", ":");

  private static final String bogusJson =
      "{\"default_string\":\"!@##&*)&*(&*&*&*\"}{))_+__+$$(((((((((((((((()!?:\">\"}";
  private static final String validJson =
      "{\"default_string\":\"!@##&*)&*(&*&*&*\\\"}{))_+__+$$(((((((((((((((()!?:\\\">\"}";
  private FormatFactory formatFactory = new FormatFactory();
  private ProtobufFormatter formatter = formatFactory.createFormatter(Formatter.JSON_JACKSON);

  @Before
  public void setup() {
    formatter.setDefaultCharset(Charset.forName("UTF-8"));
  }

  @Test
  public void testStackOverflow() throws Exception {
    TestAllTypes bd =
        TestAllTypes.newBuilder().setDefaultBytes(ByteString.copyFrom(new byte[1024])).build();
    String jsonText = formatter.printToString(bd);
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    formatter.merge(TextUtils.toInputStream(jsonText), builder);
  }

  @Test
  public void testUnknown() throws Exception {
    TestAllTypes allTypes =
        TestAllTypes.newBuilder()
            .setDefaultInt32(123)
            .setOptionalInt64(456l)
            .setOptionalString("foo")
            .setOptionalImportMessage(ImportMessage.newBuilder().setD(123))
            .build();
    String javaText = formatter.printToString(allTypes);
    // System.out.println(javaText);
    assertEquals("json doesn't match", unknownFieldsText, javaText);

    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    formatter.merge(TextUtils.toInputStream(javaText), builder);
    assertEquals(allTypes, builder.build());
  }

  @Test
  public void testMoreUnknown() throws Exception {
    UnknownFieldSet unknownGroupLevel2 =
        UnknownFieldSet.newBuilder()
            .addField(16, UnknownFieldSet.Field.newBuilder().addVarint(566667).build())
            .build();

    UnknownFieldSet unknownGroup =
        UnknownFieldSet.newBuilder()
            .addField(11, UnknownFieldSet.Field.newBuilder().addVarint(566667).build())
            .addField(15, UnknownFieldSet.Field.newBuilder().addGroup(unknownGroupLevel2).build())
            .build();

    ByteString bs = ByteString.copyFromUtf8("testUnknown");
    OneString data =
        OneString.newBuilder()
            .setUnknownFields(
                UnknownFieldSet.newBuilder()
                    .addField(5, UnknownFieldSet.Field.newBuilder().addFixed32(999).build())
                    .addField(6, UnknownFieldSet.Field.newBuilder().addGroup(unknownGroup).build())
                    .addField(7, UnknownFieldSet.Field.newBuilder().addLengthDelimited(bs).build())
                    .build())
            .setData("12345")
            .build();

    String javaText = formatter.printToString(data);
    // System.out.println(javaText);
    OneString.Builder builder = OneString.newBuilder();
    formatter.merge(TextUtils.toInputStream(javaText), builder);
    assertEquals(data.getData(), builder.build().getData());
  }

  @Test
  public void testInvalidJson() throws Exception {
    TestAllTypes msg =
        TestAllTypes.newBuilder()
            .setDefaultString("!@##&*)&*(&*&*&*\"}{))_+__+$$(((((((((((((((()!?:\">")
            .build();
    String javaText = formatter.printToString(msg);
    // System.out.println(javaText);
    assertEquals(javaText, validJson);

    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    try {
      formatter.merge(TextUtils.toInputStream(bogusJson), builder);
      fail("Expect parsing error due to malformed JSON");
    } catch (Exception e) {
      // good
    }
  }

  @Test
  public void testStringValueContainsSurrogatePair() throws Exception {
    String testString = new String(Character.toChars(0x1D11E));

    OneString msg = OneString.newBuilder().setData(testString).build();
    String json = formatter.printToString(msg);
    // Assert that the surrogate pair was encoded

    assertEquals("{\"data\":\"\\uD834\\uDD1E\"}", json);

    // Assert that we can read the string back into a msg
    OneString.Builder builder = OneString.newBuilder();
    formatter.merge(TextUtils.toInputStream(json), builder);
    assertEquals(msg, builder.build());
  }

  @Test
  public void testStringValueContainsControlCharacters() throws Exception {
    char[] ctrlChars = new char[0x001F + 1];
    for (char c = 0; c < 0x001F + 1; c++) {
      ctrlChars[c] = c;
    }
    String testString = new String(ctrlChars);
    OneString msg = OneString.newBuilder().setData(testString).build();
    String json = formatter.printToString(msg);

    // Assert that we can read the string back into a msg
    OneString.Builder builder = OneString.newBuilder();
    formatter.merge(TextUtils.toInputStream(json), builder);
    OneString item = builder.build();
    assertEquals(msg, item);
    assertTrue(Arrays.equals(ctrlChars, item.getData().toCharArray()));
  }

  @Test
  public void testStringValueContainsCharactersThatShouldBeEscaped() throws Exception {
    // input string is \"'
    String testString = "\\\"'";
    OneString msg = OneString.newBuilder().setData(testString).build();
    String json = formatter.printToString(msg);
    // Assert that reverse-solidus and double quotes where escaped using a reverse-solidus

    // Expected string is {"name": "\\\"'"}
    assertEquals("{\"data\":\"\\\\\\\"\'\"}", json);

    // Assert that we can read the string back into a msg
    OneString.Builder builder = OneString.newBuilder();
    formatter.merge(TextUtils.toInputStream(json), builder);
    assertEquals(msg, builder.build());
  }

  @Test
  public void testNestedExtension() throws Exception {
    ExtensionRegistry registry = ExtensionRegistry.newInstance();
    UnittestProto.registerAllExtensions(registry);

    UnittestProto.TestAllExtensions tae =
        UnittestProto.TestAllExtensions.newBuilder()
            .setExtension(TestNestedExtension.test, "aTest")
            .build();
    String output = formatter.printToString(tae);

    UnittestProto.TestAllExtensions.Builder builder = UnittestProto.TestAllExtensions.newBuilder();
    formatter.merge(TextUtils.toInputStream(output), registry, builder);
    String value = builder.build().getExtension(TestNestedExtension.test);
    assertEquals("aTest", value);
  }

  @Test
  public void testChineseCharacters() throws Exception {
    String data = "検索jan5検索[email protected]";
    String testString = "{\"data\":\"" + data + "\"}";

    OneString.Builder builder = OneString.newBuilder();
    formatter.merge(TextUtils.toInputStream(testString, Charset.forName("UTF-8")), builder);
    OneString msg = builder.build();

    // System.out.println(msg.getData());

    assertEquals(data, msg.getData());
  }
}