/** Unit test to check for regression of [JACKSON-18]. */
  public void testSmallNumbers() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode root = mapper.createArrayNode();
    for (int i = -20; i <= 20; ++i) {
      JsonNode n = root.numberNode(i);
      root.add(n);
      // Hmmh. Not sure why toString() won't be triggered otherwise...
      assertEquals(String.valueOf(i), n.toString());
    }

    // Loop over 2 different serialization methods
    for (int type = 0; type < 2; ++type) {
      StringWriter sw = new StringWriter();
      if (type == 0) {
        JsonGenerator gen = new JsonFactory().createGenerator(sw);
        root.serialize(gen, null);
        gen.close();
      } else {
        mapper.writeValue(sw, root);
      }

      String doc = sw.toString();
      JsonParser p = new JsonFactory().createParser(new StringReader(doc));

      assertEquals(JsonToken.START_ARRAY, p.nextToken());
      for (int i = -20; i <= 20; ++i) {
        assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
        assertEquals(i, p.getIntValue());
        assertEquals("" + i, p.getText());
      }
      assertEquals(JsonToken.END_ARRAY, p.nextToken());
      p.close();
    }
  }
Exemplo n.º 2
0
 private TwitterEntry read(JsonParser jp) throws IOException {
   // First: verify that we got "Json Object":
   if (jp.nextToken() != JsonToken.START_OBJECT) {
     throw new IOException("Expected data to start with an Object");
   }
   TwitterEntry result = new TwitterEntry();
   // Iterate over object fields:
   while (jp.nextToken() != JsonToken.END_OBJECT) {
     String fieldName = jp.getCurrentName();
     // Let's move to value
     jp.nextToken();
     if (fieldName.equals("id")) {
       result.setId(jp.getLongValue());
     } else if (fieldName.equals("text")) {
       result.setText(jp.getText());
     } else if (fieldName.equals("fromUserId")) {
       result.setFromUserId(jp.getIntValue());
     } else if (fieldName.equals("toUserId")) {
       result.setToUserId(jp.getIntValue());
     } else if (fieldName.equals("languageCode")) {
       result.setLanguageCode(jp.getText());
     } else {
       // ignore, or signal error
       throw new IOException("Unrecognized field '" + fieldName + "'");
     }
   }
   jp.close(); // important to close both parser and underlying File reader
   return result;
 }
Exemplo n.º 3
0
 private void _testSurrogates(JsonFactory f, boolean checkText) throws IOException {
   byte[] json = "{\"text\":\"\uD83D\uDE03\"}".getBytes("UTF-8");
   // first
   JsonParser jp = f.createParser(json);
   assertToken(JsonToken.START_OBJECT, jp.nextToken());
   assertToken(JsonToken.FIELD_NAME, jp.nextToken());
   if (checkText) {
     assertEquals("text", jp.getText());
   }
   assertToken(JsonToken.VALUE_STRING, jp.nextToken());
   if (checkText) {
     assertEquals("\uD83D\uDE03", jp.getText());
   }
   assertToken(JsonToken.END_OBJECT, jp.nextToken());
 }
  public void testUtf8Issue462() throws Exception {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    IOContext ioc = new IOContext(new BufferRecycler(), bytes, true);
    JsonGenerator gen = new UTF8JsonGenerator(ioc, 0, null, bytes);
    String str = "Natuurlijk is alles gelukt en weer een tevreden klant\uD83D\uDE04";
    int length = 4000 - 38;

    for (int i = 1; i <= length; ++i) {
      gen.writeNumber(1);
    }
    gen.writeString(str);
    gen.flush();
    gen.close();

    // Also verify it's parsable?
    JsonFactory f = new JsonFactory();
    JsonParser p = f.createParser(bytes.toByteArray());
    for (int i = 1; i <= length; ++i) {
      assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
      assertEquals(1, p.getIntValue());
    }
    assertToken(JsonToken.VALUE_STRING, p.nextToken());
    assertEquals(str, p.getText());
    assertNull(p.nextToken());
    p.close();
  }
 protected String _valueDesc() {
   try {
     return _desc(_parser.getText());
   } catch (Exception e) {
     return "[N/A]";
   }
 }
Exemplo n.º 6
0
 protected DateTime parseLocal(JsonParser jp) throws IOException, JsonProcessingException {
   String str = jp.getText().trim();
   if (str.length() == 0) { // [JACKSON-360]
     return null;
   }
   return _localDateTimeFormat.parseDateTime(str);
 }
  @Override
  public Collection<String> deserialize(
      JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException {
    // Ok: must point to START_ARRAY
    if (!jp.isExpectedStartArrayToken()) {
      return handleNonArray(jp, ctxt, result);
    }

    if (_valueDeserializer != null) {
      return deserializeUsingCustom(jp, ctxt, result, _valueDeserializer);
    }
    JsonToken t;

    while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
      String value;
      if (t == JsonToken.VALUE_STRING) {
        value = jp.getText();
      } else if (t == JsonToken.VALUE_NULL) {
        value = null;
      } else {
        value = _parseString(jp, ctxt);
      }
      result.add(value);
    }
    return result;
  }
Exemplo n.º 8
0
 @Override
 public ReadablePeriod deserialize(JsonParser jp, DeserializationContext ctxt)
     throws IOException, JsonProcessingException {
   // TODO: perhaps support array of numbers...
   // if (jp.isExpectedStartArrayToken()) { ]
   switch (jp.getCurrentToken()) {
     case VALUE_NUMBER_INT: // assume it's millisecond count
       return new Period(jp.getLongValue());
     case VALUE_STRING:
       return new Period(jp.getText());
   }
   throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "expected JSON Number or String");
 }
  /** This is the trickiest thing to handle, since property we are looking for may be anywhere... */
  @Override
  public Object deserializeTypedFromObject(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    // but first, sanity check to ensure we have START_OBJECT or FIELD_NAME
    JsonToken t = jp.getCurrentToken();
    if (t == JsonToken.START_OBJECT) {
      t = jp.nextToken();
    } else if (t != JsonToken.FIELD_NAME) {
      throw ctxt.wrongTokenException(
          jp,
          JsonToken.START_OBJECT,
          "need JSON Object to contain As.PROPERTY type information (for class "
              + baseTypeName()
              + ")");
    }
    // Ok, let's try to find the property. But first, need token buffer...
    TokenBuffer tb = null;

    for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
      String name = jp.getCurrentName();
      jp.nextToken(); // to point to the value
      if (_propertyName.equals(name)) { // gotcha!
        JsonDeserializer<Object> deser = _findDeserializer(ctxt, jp.getText());
        // deserializer should take care of closing END_OBJECT as well
        if (tb != null) {
          jp = JsonParserSequence.createFlattened(tb.asParser(jp), jp);
        }
        /* Must point to the next value; tb had no current, jp
         * pointed to VALUE_STRING:
         */
        jp.nextToken(); // to skip past String value
        // deserializer should take care of closing END_OBJECT as well
        return deser.deserialize(jp, ctxt);
      }
      if (tb == null) {
        tb = new TokenBuffer(null);
      }
      tb.writeFieldName(name);
      tb.copyCurrentStructure(jp);
    }
    // Error if we get here...
    throw ctxt.wrongTokenException(
        jp,
        JsonToken.FIELD_NAME,
        "missing property '"
            + _propertyName
            + "' that is to contain type id  (for class "
            + baseTypeName()
            + ")");
  }
Exemplo n.º 10
0
  public ArtistImpl(JsonParser parser) throws JsonParseException, IOException {
    if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
      if (parser.getCurrentToken() == JsonToken.VALUE_NULL) return;
      throw new IOException(
          "Expected data to start with an Object. Found " + parser.getCurrentToken());
    }

    while (parser.nextToken() != JsonToken.END_OBJECT) {
      String fName = parser.getCurrentName();
      parser.nextToken();

      if (fName.equals("id")) id = parser.getLongValue();
      else if (fName.equals("name")) name = parser.getText();
      else if (fName.equals("eventDescription")) description = parser.getText();
      else if (fName.equals("urlOfficialWebsite")) siteUrl = JFlyUtils.parseURL(parser.getText());
      else if (fName.equals("urlMySpace")) myspaceUrl = JFlyUtils.parseURL(parser.getText());
      else if (fName.equals("urlFacebook")) facebookUrl = JFlyUtils.parseURL(parser.getText());
      else if (fName.equals("twitterScreenName")) twitterScreenName = parser.getText();
      else if (fName.equals("urlAudio")) audioUrl = JFlyUtils.parseURL(parser.getText());
      else if (fName.equals("urlPurchaseMusic")) purchaseUrl = JFlyUtils.parseURL(parser.getText());
      else if (fName.equals("embedAudio")) audioHtml = parser.getText();
      else if (fName.equals("embedVideo")) videoHtml = parser.getText();
      else if (fName.equals("idMobileFriendly")) mobileFriendly = parser.getBooleanValue();
      else if (fName.equals("images")) {
        if (parser.getCurrentToken().equals(JsonToken.START_ARRAY)) {
          while (parser.nextToken() != JsonToken.END_ARRAY) {
            images.add(new ImageMetaImpl(parser));
          }
        }
      } else if (fName.equals("youtubeVideos")) {
        if (parser.getCurrentToken().equals(JsonToken.START_ARRAY)) {
          while (parser.nextToken() != JsonToken.END_ARRAY) {
            youTubeVideos.add(new YouTubeMetaImpl(parser));
          }
        }
      } else if (parser.getCurrentToken() == JsonToken.START_OBJECT
          || parser.getCurrentToken() == JsonToken.START_ARRAY) {
        parser.skipChildren();
      }
    } // end while
  }
Exemplo n.º 11
0
 @SuppressWarnings("unchecked")
 @Override
 public T deserialize(JsonParser jp, DeserializationContext ctxt)
     throws IOException, JsonProcessingException {
   JsonToken t = jp.getCurrentToken();
   if (t == JsonToken.VALUE_NUMBER_INT) {
     return (T) new DateTime(jp.getLongValue(), DateTimeZone.UTC);
   }
   if (t == JsonToken.VALUE_STRING) {
     String str = jp.getText().trim();
     if (str.length() == 0) { // [JACKSON-360]
       return null;
     }
     return (T) new DateTime(str, DateTimeZone.UTC);
   }
   throw ctxt.mappingException(getValueClass());
 }
 private final String[] handleNonArray(JsonParser p, DeserializationContext ctxt)
     throws IOException {
   // implicit arrays from single values?
   boolean canWrap =
       (_unwrapSingle == Boolean.TRUE)
           || ((_unwrapSingle == null)
               && ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
   if (canWrap) {
     return new String[] {p.hasToken(JsonToken.VALUE_NULL) ? null : _parseString(p, ctxt)};
   }
   if (p.hasToken(JsonToken.VALUE_STRING)
       && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
     String str = p.getText();
     if (str.length() == 0) {
       return null;
     }
   }
   return (String[]) ctxt.handleUnexpectedToken(_valueClass, p);
 }
 protected final double _testRawDeser(int reps, byte[] json, ObjectReader reader)
     throws IOException {
   long start = System.nanoTime();
   final JsonFactory f = reader.getFactory();
   while (--reps >= 0) {
     JsonParser p = f.createParser(new ByteArrayInputStream(json));
     JsonToken t;
     while ((t = p.nextToken()) != null) {
       if (t == JsonToken.VALUE_STRING) {
         p.getText();
       } else if (t.isNumeric()) {
         p.getNumberValue();
       }
       ;
     }
     p.close();
   }
   hash = f.hashCode();
   return _msecsFromNanos(System.nanoTime() - start);
 }
 public void testSimpleArrayWrite() throws Exception {
   StringWriter sw = new StringWriter();
   JsonGenerator gen = new JsonFactory().createGenerator(sw);
   gen.writeStartArray();
   gen.writeNumber(13);
   gen.writeBoolean(true);
   gen.writeString("foobar");
   gen.writeEndArray();
   gen.close();
   String docStr = sw.toString();
   JsonParser jp = createParserUsingReader(docStr);
   assertEquals(JsonToken.START_ARRAY, jp.nextToken());
   assertEquals(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
   assertEquals(13, jp.getIntValue());
   assertEquals(JsonToken.VALUE_TRUE, jp.nextToken());
   assertEquals(JsonToken.VALUE_STRING, jp.nextToken());
   assertEquals("foobar", jp.getText());
   assertEquals(JsonToken.END_ARRAY, jp.nextToken());
   assertEquals(null, jp.nextToken());
   jp.close();
 }
 @Override
 public Object deserialize(JsonParser jp, DeserializationContext ctxt)
     throws IOException, JsonProcessingException {
   // couple of accepted types...
   Object value;
   if (_inputType == null) {
     value = jp.getText();
   } else if (_inputType == Integer.class) {
     value = Integer.valueOf(jp.getValueAsInt());
   } else if (_inputType == Long.class) {
     value = Long.valueOf(jp.getValueAsLong());
   } else {
     throw ctxt.mappingException(_enumClass);
   }
   try {
     return _factory.invoke(_enumClass, value);
   } catch (Exception e) {
     ClassUtil.unwrapAndThrowAsIAE(e);
   }
   return null;
 }
 @Override
 public JSONArray deserialize(JsonParser jp, DeserializationContext ctxt)
     throws IOException, JsonProcessingException {
   JSONArray array = new JSONArray();
   JsonToken t;
   while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
     switch (t) {
       case START_ARRAY:
         array.put(deserialize(jp, ctxt));
         continue;
       case START_OBJECT:
         array.put(JSONObjectDeserializer.instance.deserialize(jp, ctxt));
         continue;
       case VALUE_STRING:
         array.put(jp.getText());
         continue;
       case VALUE_NULL:
         array.put(JSONObject.NULL);
         continue;
       case VALUE_TRUE:
         array.put(Boolean.TRUE);
         continue;
       case VALUE_FALSE:
         array.put(Boolean.FALSE);
         continue;
       case VALUE_NUMBER_INT:
         array.put(jp.getNumberValue());
         continue;
       case VALUE_NUMBER_FLOAT:
         array.put(jp.getNumberValue());
         continue;
       case VALUE_EMBEDDED_OBJECT:
         array.put(jp.getEmbeddedObject());
         continue;
     }
     throw ctxt.mappingException("Urecognized or unsupported JsonToken type: " + t);
   }
   return array;
 }
  /**
   * Method that gets textual contents of the current token using available methods, and ensures
   * results are consistent, before returning them
   */
  protected String getAndVerifyText(JsonParser jp) throws IOException, JsonParseException {
    // Ok, let's verify other accessors
    int actLen = jp.getTextLength();
    char[] ch = jp.getTextCharacters();
    String str2 = new String(ch, jp.getTextOffset(), actLen);
    String str = jp.getText();

    if (str.length() != actLen) {
      fail(
          "Internal problem (jp.token == "
              + jp.getCurrentToken()
              + "): jp.getText().length() ['"
              + str
              + "'] == "
              + str.length()
              + "; jp.getTextLength() == "
              + actLen);
    }
    assertEquals("String access via getText(), getTextXxx() must be the same", str, str2);

    return str;
  }
  @Override
  public Enum<?> deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    JsonToken curr = jp.getCurrentToken();

    // Usually should just get string value:
    if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
      String name = jp.getText();
      Enum<?> result = _resolver.findEnum(name);
      if (result == null
          && !ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
        throw ctxt.weirdStringException(
            name, _resolver.getEnumClass(), "value not one of declared Enum instance names");
      }
      return result;
    }
    // But let's consider int acceptable as well (if within ordinal range)
    if (curr == JsonToken.VALUE_NUMBER_INT) {
      /* ... unless told not to do that. :-)
       * (as per [JACKSON-412]
       */
      if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
        throw ctxt.mappingException(
            "Not allowed to deserialize Enum value out of JSON number (disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow)");
      }

      int index = jp.getIntValue();
      Enum<?> result = _resolver.getEnum(index);
      if (result == null
          && !ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
        throw ctxt.weirdNumberException(
            Integer.valueOf(index),
            _resolver.getEnumClass(),
            "index value outside legal index range [0.." + _resolver.lastValidIndex() + "]");
      }
      return result;
    }
    throw ctxt.mappingException(_resolver.getEnumClass());
  }
 protected void verifyFieldName(JsonParser jp, String expName) throws IOException {
   assertEquals(expName, jp.getText());
   assertEquals(expName, jp.getCurrentName());
 }
Exemplo n.º 20
0
 public final void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException {
   switch (jp.getCurrentToken()) {
     case START_OBJECT:
       writeStartObject();
       break;
     case END_OBJECT:
       writeEndObject();
       break;
     case START_ARRAY:
       writeStartArray();
       break;
     case END_ARRAY:
       writeEndArray();
       break;
     case FIELD_NAME:
       writeFieldName(jp.getCurrentName());
       break;
     case VALUE_STRING:
       if (jp.hasTextCharacters()) {
         writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength());
       } else {
         writeString(jp.getText());
       }
       break;
     case VALUE_NUMBER_INT:
       switch (jp.getNumberType()) {
         case INT:
           writeNumber(jp.getIntValue());
           break;
         case BIG_INTEGER:
           writeNumber(jp.getBigIntegerValue());
           break;
         default:
           writeNumber(jp.getLongValue());
       }
       break;
     case VALUE_NUMBER_FLOAT:
       switch (jp.getNumberType()) {
         case BIG_DECIMAL:
           writeNumber(jp.getDecimalValue());
           break;
         case FLOAT:
           writeNumber(jp.getFloatValue());
           break;
         default:
           writeNumber(jp.getDoubleValue());
       }
       break;
     case VALUE_TRUE:
       writeBoolean(true);
       break;
     case VALUE_FALSE:
       writeBoolean(false);
       break;
     case VALUE_NULL:
       writeNull();
       break;
     case VALUE_EMBEDDED_OBJECT:
       writeObject(jp.getEmbeddedObject());
       break;
     default:
       _cantHappen();
   }
 }
Exemplo n.º 21
0
 @Override
 public CustomMap deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
   CustomMap result = new CustomMap();
   result.put("x", jp.getText());
   return result;
 }
  private Image readImage(JsonParser parser) throws IOException {
    boolean haveWidth = false;
    boolean haveHeight = false;
    Image image = new Image();
    if (parser.nextFieldName(FIELD_URI)) {
      image.uri = parser.nextTextValue();
      if (parser.nextFieldName(FIELD_TITLE)) {
        image.title = parser.nextTextValue();
        if (parser.nextFieldName(FIELD_WIDTH)) {
          image.width = parser.nextIntValue(-1);
          haveWidth = true;
          if (parser.nextFieldName(FIELD_HEIGHT)) {
            image.height = parser.nextIntValue(-1);
            haveHeight = true;
            if (parser.nextFieldName(FIELD_SIZE)) {
              image.size = Image.Size.valueOf(parser.nextTextValue());
              parser.nextToken();
              verifyCurrent(parser, JsonToken.END_OBJECT);
              return image;
            }
          }
        }
      }
    }

    for (; parser.getCurrentToken() == JsonToken.FIELD_NAME; parser.nextToken()) {
      String field = parser.getCurrentName();
      // read value token (or START_ARRAY)
      parser.nextToken();
      Integer I = fullFieldToIndex.get(field);
      if (I != null) {
        switch (I) {
          case FIELD_IX_URI:
            image.uri = parser.getText();
            continue;
          case FIELD_IX_TITLE:
            image.title = parser.getText();
            continue;
          case FIELD_IX_WIDTH:
            image.width = parser.getIntValue();
            haveWidth = true;
            continue;
          case FIELD_IX_HEIGHT:
            image.height = parser.getIntValue();
            haveHeight = true;
            continue;
          case FIELD_IX_SIZE:
            image.size = Image.Size.valueOf(parser.getText());
            continue;
        }
      }
      throw new IllegalStateException("Unexpected field '" + field + "'");
    }

    if (image.uri == null) throw new IllegalStateException("Missing field: " + FIELD_URI);
    if (!haveWidth) throw new IllegalStateException("Missing field: " + FIELD_WIDTH);
    if (!haveHeight) throw new IllegalStateException("Missing field: " + FIELD_HEIGHT);
    if (image.size == null) throw new IllegalStateException("Missing field: " + FIELD_SIZE);

    verifyCurrent(parser, JsonToken.END_OBJECT);

    return image;
  }
 @Override
 public OffsetTime deserialize(JsonParser parser, DeserializationContext context)
     throws IOException {
   if (parser.hasToken(JsonToken.VALUE_STRING)) {
     String string = parser.getText().trim();
     if (string.length() == 0) {
       return null;
     }
     try {
       return OffsetTime.parse(string, _formatter);
     } catch (DateTimeException e) {
       _rethrowDateTimeException(parser, context, e, string);
     }
   }
   if (!parser.isExpectedStartArrayToken()) {
     if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
       return (OffsetTime) parser.getEmbeddedObject();
     }
     throw context.wrongTokenException(parser, JsonToken.START_ARRAY, "Expected array or string.");
   }
   int hour = parser.nextIntValue(-1);
   if (hour == -1) {
     JsonToken t = parser.getCurrentToken();
     if (t == JsonToken.END_ARRAY) {
       return null;
     }
     if (t != JsonToken.VALUE_NUMBER_INT) {
       _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "hours");
     }
     hour = parser.getIntValue();
   }
   int minute = parser.nextIntValue(-1);
   if (minute == -1) {
     JsonToken t = parser.getCurrentToken();
     if (t == JsonToken.END_ARRAY) {
       return null;
     }
     if (t != JsonToken.VALUE_NUMBER_INT) {
       _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "minutes");
     }
     minute = parser.getIntValue();
   }
   int partialSecond = 0;
   int second = 0;
   if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
     second = parser.getIntValue();
     if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
       partialSecond = parser.getIntValue();
       if (partialSecond < 1_000
           && !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
         partialSecond *= 1_000_000; // value is milliseconds, convert it to nanoseconds
       }
       parser.nextToken();
     }
   }
   if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
     OffsetTime t =
         OffsetTime.of(hour, minute, second, partialSecond, ZoneOffset.of(parser.getText()));
     if (parser.nextToken() != JsonToken.END_ARRAY) {
       _reportWrongToken(parser, context, JsonToken.END_ARRAY, "timezone");
     }
     return t;
   }
   throw context.wrongTokenException(
       parser, JsonToken.VALUE_STRING, "Expected string for TimeZone after numeric values");
 }
 protected void verifyIntValue(JsonParser jp, long expValue) throws IOException {
   // First, via textual
   assertEquals(String.valueOf(expValue), jp.getText());
 }