Coverage Report - org.apache.johnzon.core.JsonInMemoryParser
 
Classes in this File Line Coverage Branch Coverage Complexity
JsonInMemoryParser
59%
22/37
45%
10/22
3,35
JsonInMemoryParser$1
100%
1/1
N/A
3,35
JsonInMemoryParser$ArrayIterator
84%
21/25
66%
8/12
3,35
JsonInMemoryParser$ObjectIterator
84%
28/33
75%
12/16
3,35
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements. See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership. The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License. You may obtain a copy of the License at
 9  
  *
 10  
  * http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied. See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.johnzon.core;
 20  
 
 21  
 import java.math.BigDecimal;
 22  
 import java.util.Iterator;
 23  
 import java.util.Map;
 24  
 import java.util.NoSuchElementException;
 25  
 
 26  
 import javax.json.JsonArray;
 27  
 import javax.json.JsonNumber;
 28  
 import javax.json.JsonObject;
 29  
 import javax.json.JsonString;
 30  
 import javax.json.JsonValue;
 31  
 import javax.json.JsonValue.ValueType;
 32  
 import javax.json.stream.JsonLocation;
 33  
 import javax.json.stream.JsonParser;
 34  
 
 35  32
 class JsonInMemoryParser implements JsonParser {
 36  
 
 37  2
     private final SimpleStack<Iterator<Event>> stack = new SimpleStack<Iterator<Event>>();
 38  
 
 39  
     private Event currentEvent;
 40  
     private JsonValue currentValue;
 41  
 
 42  10
     private class ArrayIterator implements Iterator<Event> {
 43  
 
 44  
         private final Iterator<JsonValue> aentries;
 45  2
         private Boolean end = null;
 46  
 
 47  2
         public ArrayIterator(final JsonArray ja) {
 48  2
             aentries = ja.iterator();
 49  
 
 50  2
         }
 51  
 
 52  
         @Override
 53  
         public boolean hasNext() {
 54  0
             return !Boolean.TRUE.equals(end);
 55  
         }
 56  
 
 57  
         @Override
 58  
         public Event next() {
 59  
 
 60  10
             if (end == null) {
 61  2
                 end = Boolean.FALSE;
 62  2
                 return Event.START_ARRAY;
 63  8
             } else if (!aentries.hasNext()) {
 64  
 
 65  2
                 if (!stack.isEmpty()) {
 66  2
                     stack.pop();
 67  
                 }
 68  
 
 69  2
                 end = Boolean.TRUE;
 70  
 
 71  2
                 return Event.END_ARRAY;
 72  
             } else {
 73  
 
 74  6
                 final JsonValue val = aentries.next();
 75  
 
 76  6
                 final ValueType vt = val.getValueType();
 77  
 
 78  6
                 if (vt == ValueType.OBJECT) {
 79  1
                     stack.push(new ObjectIterator((JsonObject) val));
 80  1
                     return stack.peek().next();
 81  
 
 82  5
                 } else if (vt == ValueType.ARRAY) {
 83  0
                     stack.push(new ArrayIterator((JsonArray) val));
 84  0
                     return stack.peek().next();
 85  
 
 86  
                 } else {
 87  5
                     currentValue = val;
 88  5
                     return getEvent(vt);
 89  
                 }
 90  
             }
 91  
 
 92  
         }
 93  
 
 94  
         @Override
 95  
         public void remove() {
 96  0
             throw new UnsupportedOperationException();
 97  
 
 98  
         }
 99  
 
 100  
     }
 101  
 
 102  12
     private class ObjectIterator implements Iterator<Event> {
 103  
 
 104  
         private final Iterator<Map.Entry<String, JsonValue>> oentries;
 105  
         private JsonValue jsonValue;
 106  2
         private Boolean end = null;
 107  
 
 108  2
         public ObjectIterator(final JsonObject jo) {
 109  2
             oentries = jo.entrySet().iterator();
 110  
 
 111  2
         }
 112  
 
 113  
         @Override
 114  
         public boolean hasNext() {
 115  0
             return !Boolean.TRUE.equals(end);
 116  
         }
 117  
 
 118  
         @Override
 119  
         public Event next() {
 120  
 
 121  12
             if (end == null) {
 122  2
                 end = Boolean.FALSE;
 123  2
                 return Event.START_OBJECT;
 124  10
             } else if (jsonValue == null && !oentries.hasNext()) {
 125  
 
 126  2
                 if (!stack.isEmpty()) {
 127  2
                     stack.pop();
 128  
                 }
 129  
 
 130  2
                 end = Boolean.TRUE;
 131  
 
 132  2
                 return Event.END_OBJECT;
 133  8
             } else if (jsonValue == null) {
 134  
 
 135  4
                 final Map.Entry<String, JsonValue> tmp = oentries.next();
 136  4
                 jsonValue = tmp.getValue();
 137  4
                 currentValue = new JsonStringImpl(tmp.getKey());
 138  4
                 return Event.KEY_NAME;
 139  
 
 140  
             } else {
 141  
 
 142  4
                 final ValueType vt = jsonValue.getValueType();
 143  
 
 144  4
                 if (vt == ValueType.OBJECT) {
 145  0
                     stack.push(new ObjectIterator((JsonObject) jsonValue));
 146  0
                     jsonValue = null;
 147  0
                     return stack.peek().next();
 148  
 
 149  4
                 } else if (vt == ValueType.ARRAY) {
 150  1
                     stack.push(new ArrayIterator((JsonArray) jsonValue));
 151  1
                     jsonValue = null;
 152  1
                     return stack.peek().next();
 153  
 
 154  
                 } else {
 155  
 
 156  3
                     final Event ret = getEvent(vt);
 157  3
                     currentValue = jsonValue;
 158  3
                     jsonValue = null;
 159  3
                     return ret;
 160  
                 }
 161  
 
 162  
             }
 163  
 
 164  
         }
 165  
 
 166  
         @Override
 167  
         public void remove() {
 168  0
             throw new UnsupportedOperationException();
 169  
 
 170  
         }
 171  
 
 172  
     }
 173  
 
 174  
     private static Event getEvent(final ValueType value) {
 175  
 
 176  1
         switch (value) {
 177  
         case NUMBER:
 178  5
             return Event.VALUE_NUMBER;
 179  
         case STRING:
 180  3
             return Event.VALUE_STRING;
 181  
         case FALSE:
 182  0
             return Event.VALUE_FALSE;
 183  
         case NULL:
 184  0
             return Event.VALUE_NULL;
 185  
         case TRUE:
 186  0
             return Event.VALUE_TRUE;
 187  
         default:
 188  0
             throw new IllegalArgumentException(value + " not supported");
 189  
 
 190  
         }
 191  
 
 192  
     }
 193  
 
 194  1
     JsonInMemoryParser(final JsonObject object) {
 195  1
         stack.push(new ObjectIterator(object));
 196  1
     }
 197  
 
 198  1
     JsonInMemoryParser(final JsonArray array) {
 199  1
         stack.push(new ArrayIterator(array));
 200  1
     }
 201  
 
 202  
     @Override
 203  
     public boolean hasNext() {
 204  42
         return !stack.isEmpty();
 205  
     }
 206  
 
 207  
     @Override
 208  
     public Event next() {
 209  
 
 210  20
         if (!hasNext()) {
 211  0
             throw new NoSuchElementException();
 212  
         }
 213  
 
 214  20
         currentEvent = stack.peek().next();
 215  
 
 216  20
         return currentEvent;
 217  
     }
 218  
 
 219  
     @Override
 220  
     public String getString() {
 221  7
         if (currentEvent != Event.KEY_NAME && currentEvent != Event.VALUE_STRING) {
 222  0
             throw new IllegalStateException("String is for numbers and strings");
 223  
         }
 224  7
         return JsonString.class.cast(currentValue).getString();
 225  
     }
 226  
 
 227  
     @Override
 228  
     public boolean isIntegralNumber() {
 229  1
         if (currentEvent != Event.VALUE_NUMBER) {
 230  0
             throw new IllegalStateException("isIntegralNumber is for numbers");
 231  
         }
 232  1
         return JsonNumber.class.cast(currentValue).isIntegral();
 233  
     }
 234  
 
 235  
     @Override
 236  
     public int getInt() {
 237  5
         if (currentEvent != Event.VALUE_NUMBER) {
 238  0
             throw new IllegalStateException("getInt is for numbers");
 239  
         }
 240  5
         return JsonNumber.class.cast(currentValue).intValue();
 241  
     }
 242  
 
 243  
     @Override
 244  
     public long getLong() {
 245  0
         if (currentEvent != Event.VALUE_NUMBER) {
 246  0
             throw new IllegalStateException("getLong is for numbers");
 247  
         }
 248  0
         return JsonNumber.class.cast(currentValue).longValue();
 249  
     }
 250  
 
 251  
     @Override
 252  
     public BigDecimal getBigDecimal() {
 253  0
         if (currentEvent != Event.VALUE_NUMBER) {
 254  0
             throw new IllegalStateException("getBigDecimal is for numbers");
 255  
         }
 256  0
         return JsonNumber.class.cast(currentValue).bigDecimalValue();
 257  
     }
 258  
 
 259  
     @Override
 260  
     public JsonLocation getLocation() { // no location for in memory parsers
 261  0
         return JsonLocationImpl.UNKNOWN_LOCATION;
 262  
     }
 263  
 
 264  
     @Override
 265  
     public void close() {
 266  
         // no-op
 267  1
     }
 268  
 
 269  
 }