Пример #1
0
  /**
   * Parse JSON text into java object from the input source.
   *
   * @param in
   * @param containerFactory - Use this factory to createyour own JSON object and JSON array
   *     containers.
   * @return Instance of the following: org.json.simple.JSONObject, org.json.simple.JSONArray,
   *     java.lang.String, java.lang.Number, java.lang.Boolean, null
   * @throws IOException
   * @throws ParseException
   */
  public Object parse(Reader in, ContainerFactory containerFactory)
      throws IOException, ParseException {
    reset(in);
    LinkedList statusStack = new LinkedList();
    LinkedList valueStack = new LinkedList();

    try {
      do {
        nextToken();
        switch (status) {
          case S_INIT:
            switch (token.type) {
              case Yytoken.TYPE_VALUE:
                status = S_IN_FINISHED_VALUE;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(token.value);
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(createObjectContainer(containerFactory));
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(createArrayContainer(containerFactory));
                break;
              default:
                status = S_IN_ERROR; // inner switch
            }
            break;

          case S_IN_FINISHED_VALUE:
            if (token.type == Yytoken.TYPE_EOF) return valueStack.removeFirst();
            else
              throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);

          case S_IN_OBJECT:
            switch (token.type) {
              case Yytoken.TYPE_COMMA:
                break;
              case Yytoken.TYPE_VALUE:
                if (token.value instanceof String) {
                  String key = (String) token.value;
                  valueStack.addFirst(key);
                  status = S_PASSED_PAIR_KEY;
                  statusStack.addFirst(new Integer(status));
                } else {
                  status = S_IN_ERROR;
                }
                break;
              case Yytoken.TYPE_RIGHT_BRACE:
                if (valueStack.size() > 1) {
                  statusStack.removeFirst();
                  valueStack.removeFirst();
                  status = peekStatus(statusStack);
                } else {
                  status = S_IN_FINISHED_VALUE;
                }
                break;
              default:
                status = S_IN_ERROR;
                break; // inner switch
            }
            break;

          case S_PASSED_PAIR_KEY:
            switch (token.type) {
              case Yytoken.TYPE_COLON:
                break;
              case Yytoken.TYPE_VALUE:
                statusStack.removeFirst();
                String key = (String) valueStack.removeFirst();
                Map parent = (Map) valueStack.getFirst();
                parent.put(key, token.value);
                status = peekStatus(statusStack);
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                statusStack.removeFirst();
                key = (String) valueStack.removeFirst();
                parent = (Map) valueStack.getFirst();
                List newArray = createArrayContainer(containerFactory);
                parent.put(key, newArray);
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(newArray);
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                statusStack.removeFirst();
                key = (String) valueStack.removeFirst();
                parent = (Map) valueStack.getFirst();
                Map newObject = createObjectContainer(containerFactory);
                parent.put(key, newObject);
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(newObject);
                break;
              default:
                status = S_IN_ERROR;
            }
            break;

          case S_IN_ARRAY:
            switch (token.type) {
              case Yytoken.TYPE_COMMA:
                break;
              case Yytoken.TYPE_VALUE:
                List val = (List) valueStack.getFirst();
                val.add(token.value);
                break;
              case Yytoken.TYPE_RIGHT_SQUARE:
                if (valueStack.size() > 1) {
                  statusStack.removeFirst();
                  valueStack.removeFirst();
                  status = peekStatus(statusStack);
                } else {
                  status = S_IN_FINISHED_VALUE;
                }
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                val = (List) valueStack.getFirst();
                Map newObject = createObjectContainer(containerFactory);
                val.add(newObject);
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(newObject);
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                val = (List) valueStack.getFirst();
                List newArray = createArrayContainer(containerFactory);
                val.add(newArray);
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                valueStack.addFirst(newArray);
                break;
              default:
                status = S_IN_ERROR; // inner switch
            }
            break;
          case S_IN_ERROR:
            throw new ParseException(
                getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); // switch
        }
        if (status == S_IN_ERROR) {
          throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
        }
      } while (token.type != Yytoken.TYPE_EOF);
    } catch (IOException ie) {
      throw ie;
    }

    throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
  }
Пример #2
0
  /**
   * Stream processing of JSON text.
   *
   * @see ContentHandler
   * @param in
   * @param contentHandler
   * @param isResume - Indicates if it continues previous parsing operation. If set to true, resume
   *     parsing the old stream, and parameter 'in' will be ignored. If this method is called for
   *     the first time in this instance, isResume will be ignored.
   * @throws IOException
   * @throws ParseException
   */
  public void parse(Reader in, ContentHandler contentHandler, boolean isResume)
      throws IOException, ParseException {
    if (!isResume) {
      reset(in);
      handlerStatusStack = new LinkedList();
    } else {
      if (handlerStatusStack == null) {
        isResume = false;
        reset(in);
        handlerStatusStack = new LinkedList();
      }
    }

    LinkedList statusStack = handlerStatusStack;

    try {
      do {
        switch (status) {
          case S_INIT:
            contentHandler.startJSON();
            nextToken();
            switch (token.type) {
              case Yytoken.TYPE_VALUE:
                status = S_IN_FINISHED_VALUE;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.primitive(token.value)) return;
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startObject()) return;
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startArray()) return;
                break;
              default:
                status = S_IN_ERROR; // inner switch
            }
            break;

          case S_IN_FINISHED_VALUE:
            nextToken();
            if (token.type == Yytoken.TYPE_EOF) {
              contentHandler.endJSON();
              status = S_END;
              return;
            } else {
              status = S_IN_ERROR;
              throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
            }

          case S_IN_OBJECT:
            nextToken();
            switch (token.type) {
              case Yytoken.TYPE_COMMA:
                break;
              case Yytoken.TYPE_VALUE:
                if (token.value instanceof String) {
                  String key = (String) token.value;
                  status = S_PASSED_PAIR_KEY;
                  statusStack.addFirst(new Integer(status));
                  if (!contentHandler.startObjectEntry(key)) return;
                } else {
                  status = S_IN_ERROR;
                }
                break;
              case Yytoken.TYPE_RIGHT_BRACE:
                if (statusStack.size() > 1) {
                  statusStack.removeFirst();
                  status = peekStatus(statusStack);
                } else {
                  status = S_IN_FINISHED_VALUE;
                }
                if (!contentHandler.endObject()) return;
                break;
              default:
                status = S_IN_ERROR;
                break; // inner switch
            }
            break;

          case S_PASSED_PAIR_KEY:
            nextToken();
            switch (token.type) {
              case Yytoken.TYPE_COLON:
                break;
              case Yytoken.TYPE_VALUE:
                statusStack.removeFirst();
                status = peekStatus(statusStack);
                if (!contentHandler.primitive(token.value)) return;
                if (!contentHandler.endObjectEntry()) return;
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                statusStack.removeFirst();
                statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startArray()) return;
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                statusStack.removeFirst();
                statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startObject()) return;
                break;
              default:
                status = S_IN_ERROR;
            }
            break;

          case S_IN_PAIR_VALUE:
            statusStack.removeFirst();
            status = peekStatus(statusStack);
            if (!contentHandler.endObjectEntry()) return;
            break;
            /*
             * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
             * therefore delay consuming token until next round.
             */

          case S_IN_ARRAY:
            nextToken();
            switch (token.type) {
              case Yytoken.TYPE_COMMA:
                break;
              case Yytoken.TYPE_VALUE:
                if (!contentHandler.primitive(token.value)) return;
                break;
              case Yytoken.TYPE_RIGHT_SQUARE:
                if (statusStack.size() > 1) {
                  statusStack.removeFirst();
                  status = peekStatus(statusStack);
                } else {
                  status = S_IN_FINISHED_VALUE;
                }
                if (!contentHandler.endArray()) return;
                break;
              case Yytoken.TYPE_LEFT_BRACE:
                status = S_IN_OBJECT;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startObject()) return;
                break;
              case Yytoken.TYPE_LEFT_SQUARE:
                status = S_IN_ARRAY;
                statusStack.addFirst(new Integer(status));
                if (!contentHandler.startArray()) return;
                break;
              default:
                status = S_IN_ERROR; // inner switch
            }
            break;

          case S_END:
            return;

          case S_IN_ERROR:
            throw new ParseException(
                getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); // switch
        }
        if (status == S_IN_ERROR) {
          throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
        }
      } while (token.type != Yytoken.TYPE_EOF);
    } catch (IOException ie) {
      status = S_IN_ERROR;
      throw ie;
    } catch (ParseException pe) {
      status = S_IN_ERROR;
      throw pe;
    } catch (RuntimeException re) {
      status = S_IN_ERROR;
      throw re;
    } catch (Error e) {
      status = S_IN_ERROR;
      throw e;
    }

    status = S_IN_ERROR;
    throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
  }
Пример #3
0
 /**
  * Reset the parser to the initial state with a new character reader.
  *
  * @param in - The new character reader.
  * @throws IOException
  * @throws ParseException
  */
 public void reset(Reader in) {
   lexer.yyreset(in);
   reset();
 }
Пример #4
0
  @SuppressWarnings("unchecked")
  public void testDecode() throws Exception {
    System.out.println("=======decode=======");

    String s = "[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";
    Object obj = JSONValue.parse(s);
    JSONArray array = (JSONArray) obj;
    System.out.println("======the 2nd element of array======");
    System.out.println(array.get(1));
    System.out.println();
    assertEquals("{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}", array.get(1).toString());

    JSONObject obj2 = (JSONObject) array.get(1);
    System.out.println("======field \"1\"==========");
    System.out.println(obj2.get("1"));
    assertEquals("{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}", obj2.get("1").toString());

    s = "{}";
    obj = JSONValue.parse(s);
    assertEquals("{}", obj.toString());

    s = "[5,]";
    obj = JSONValue.parse(s);
    assertEquals("[5]", obj.toString());

    s = "[5,,2]";
    obj = JSONValue.parse(s);
    assertEquals("[5,2]", obj.toString());

    s = "[\"hello\\bworld\\\"abc\\tdef\\\\ghi\\rjkl\\n123\\u4e2d\"]";
    obj = JSONValue.parse(s);
    assertEquals("hello\bworld\"abc\tdef\\ghi\rjkl\n123中", ((List<Object>) obj).get(0).toString());

    JSONParser parser = new JSONParser();
    s = "{\"name\":";
    try {
      obj = parser.parse(s);
    } catch (ParseException pe) {
      assertEquals(ParseException.ERROR_UNEXPECTED_TOKEN, pe.getErrorType());
      assertEquals(8, pe.getPosition());
    }

    s = "{\"name\":}";
    try {
      obj = parser.parse(s);
    } catch (ParseException pe) {
      assertEquals(ParseException.ERROR_UNEXPECTED_TOKEN, pe.getErrorType());
      assertEquals(8, pe.getPosition());
    }

    s = "{\"name";
    try {
      obj = parser.parse(s);
    } catch (ParseException pe) {
      assertEquals(ParseException.ERROR_UNEXPECTED_TOKEN, pe.getErrorType());
      assertEquals(6, pe.getPosition());
    }

    s = "[[null, 123.45, \"a\\\tb c\"}, true]";
    try {
      parser.parse(s);
    } catch (ParseException pe) {
      assertEquals(24, pe.getPosition());
      System.out.println("Error at character position: " + pe.getPosition());
      switch (pe.getErrorType()) {
        case ParseException.ERROR_UNEXPECTED_TOKEN:
          System.out.println("Unexpected token: " + pe.getUnexpectedObject());
          break;
        case ParseException.ERROR_UNEXPECTED_CHAR:
          System.out.println("Unexpected character: " + pe.getUnexpectedObject());
          break;
        case ParseException.ERROR_UNEXPECTED_EXCEPTION:
          ((Exception) pe.getUnexpectedObject()).printStackTrace();
          break;
      }
    }

    s = "{\"first\": 123, \"second\": [4, 5, 6], \"third\": 789}";
    ContainerFactory containerFactory =
        new ContainerFactory() {
          public List<Object> creatArrayContainer() {
            return new LinkedList<Object>();
          }

          public Map<Object, Object> createObjectContainer() {
            return new LinkedHashMap<Object, Object>();
          }
        };

    try {
      Map<Object, Object> json = (Map<Object, Object>) parser.parse(s, containerFactory);
      Iterator<Map.Entry<Object, Object>> iter = json.entrySet().iterator();
      System.out.println("==iterate result==");
      while (iter.hasNext()) {
        Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iter.next();
        System.out.println(entry.getKey() + "=>" + entry.getValue());
      }

      System.out.println("==toJSONString()==");
      System.out.println(JSONValue.toJSONString(json));
      assertEquals(
          "{\"first\":123,\"second\":[4,5,6],\"third\":789}", JSONValue.toJSONString(json));
    } catch (ParseException pe) {
      pe.printStackTrace();
    }

    s = "{\"first\": 123, \"second\": [{\"s1\":{\"s11\":\"v11\"}}, 4, 5, 6], \"third\": 789}";
    ContentHandler myHandler =
        new ContentHandler() {

          public boolean endArray() throws ParseException {
            System.out.println("endArray()");
            return true;
          }

          public void endJSON() throws ParseException {
            System.out.println("endJSON()");
          }

          public boolean endObject() throws ParseException {
            System.out.println("endObject()");
            return true;
          }

          public boolean endObjectEntry() throws ParseException {
            System.out.println("endObjectEntry()");
            return true;
          }

          public boolean primitive(Object value) throws ParseException {
            System.out.println("primitive(): " + value);
            return true;
          }

          public boolean startArray() throws ParseException {
            System.out.println("startArray()");
            return true;
          }

          public void startJSON() throws ParseException {
            System.out.println("startJSON()");
          }

          public boolean startObject() throws ParseException {
            System.out.println("startObject()");
            return true;
          }

          public boolean startObjectEntry(String key) throws ParseException {
            System.out.println("startObjectEntry(), key:" + key);
            return true;
          }
        };
    try {
      parser.parse(s, myHandler);
    } catch (ParseException pe) {
      pe.printStackTrace();
    }

    class KeyFinder implements ContentHandler {
      private Object value;
      private boolean found = false;
      private boolean end = false;
      private String key;
      private String matchKey;

      public void setMatchKey(String matchKey) {
        this.matchKey = matchKey;
      }

      public Object getValue() {
        return value;
      }

      public boolean isEnd() {
        return end;
      }

      public void setFound(boolean found) {
        this.found = found;
      }

      public boolean isFound() {
        return found;
      }

      public void startJSON() throws ParseException, IOException {
        found = false;
        end = false;
      }

      public void endJSON() throws ParseException, IOException {
        end = true;
      }

      public boolean primitive(Object value) throws ParseException, IOException {
        if (key != null) {
          if (key.equals(matchKey)) {
            found = true;
            this.value = value;
            key = null;
            return false;
          }
        }
        return true;
      }

      public boolean startArray() throws ParseException, IOException {
        return true;
      }

      public boolean startObject() throws ParseException, IOException {
        return true;
      }

      public boolean startObjectEntry(String key) throws ParseException, IOException {
        this.key = key;
        return true;
      }

      public boolean endArray() throws ParseException, IOException {
        return false;
      }

      public boolean endObject() throws ParseException, IOException {
        return true;
      }

      public boolean endObjectEntry() throws ParseException, IOException {
        return true;
      }
    };

    s =
        "{\"first\": 123, \"second\": [{\"k1\":{\"id\":\"id1\"}}, 4, 5, 6, {\"id\": 123}], \"third\": 789, \"id\": null}";
    parser.reset();
    KeyFinder keyFinder = new KeyFinder();
    keyFinder.setMatchKey("id");
    int i = 0;
    try {
      while (!keyFinder.isEnd()) {
        parser.parse(s, keyFinder, true);
        if (keyFinder.isFound()) {
          i++;
          keyFinder.setFound(false);
          System.out.println("found id:");
          System.out.println(keyFinder.getValue());
          if (i == 1) assertEquals("id1", keyFinder.getValue());
          if (i == 2) {
            assertTrue(keyFinder.getValue() instanceof Number);
            assertEquals("123", String.valueOf(keyFinder.getValue()));
          }
          if (i == 3) assertTrue(null == keyFinder.getValue());
        }
      }
    } catch (ParseException pe) {
      pe.printStackTrace();
    }
  }