|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 package org.chromium.sdk.internal.protocolparser.dynamicimpl; |
|
6 |
|
7 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; |
|
8 import org.json.simple.JSONObject; |
|
9 |
|
10 /** |
|
11 * A parser that generates dynamic proxy implementation of JsonType interface |
|
12 * for a {@link JSONObject}. |
|
13 * It creates dynamic proxy instance in 2 steps. First {@link #parseValue(Object, ObjectData)} |
|
14 * outputs {@link ObjectData}, which gets stored in field storage array. Later, when we are |
|
15 * about to return the value to a user, it is converted to a dynamic proxy instance by |
|
16 * {@link #VALUE_FINISHER} converter. We have to store an intermediate value for easier data |
|
17 * manipulation (dynamic proxy does not have any interfaces that we could make use of). |
|
18 */ |
|
19 class JsonTypeParser<T> extends SlowParser<ObjectData> { |
|
20 private final RefToType<T> refToType; |
|
21 private final boolean isNullable; |
|
22 private final boolean isSubtyping; |
|
23 |
|
24 JsonTypeParser(RefToType<T> refToType, boolean isNullable, boolean isSubtyping) { |
|
25 this.refToType = refToType; |
|
26 this.isNullable = isNullable; |
|
27 this.isSubtyping = isSubtyping; |
|
28 } |
|
29 |
|
30 RefToType<T> getType() { |
|
31 return refToType; |
|
32 } |
|
33 |
|
34 @Override |
|
35 public ObjectData parseValue(Object value, ObjectData thisData) |
|
36 throws JsonProtocolParseException { |
|
37 if (isNullable && value == null) { |
|
38 return null; |
|
39 } |
|
40 if (value == null) { |
|
41 throw new JsonProtocolParseException("null input"); |
|
42 } |
|
43 TypeHandler<T> typeHandler = refToType.get(); |
|
44 if (isSubtyping) { |
|
45 return typeHandler.parse(value, thisData); |
|
46 } else { |
|
47 return typeHandler.parseRootImpl(value); |
|
48 } |
|
49 } |
|
50 |
|
51 @Override |
|
52 public FieldLoadedFinisher getValueFinisher() { |
|
53 return VALUE_FINISHER; |
|
54 } |
|
55 |
|
56 @Override |
|
57 public JsonTypeParser<?> asJsonTypeParser() { |
|
58 return this; |
|
59 } |
|
60 |
|
61 public boolean isSubtyping() { |
|
62 return isSubtyping; |
|
63 } |
|
64 |
|
65 private static final FieldLoadedFinisher VALUE_FINISHER = new FieldLoadedFinisher() { |
|
66 @Override |
|
67 Object getValueForUser(Object cachedValue) { |
|
68 if (cachedValue == null) { |
|
69 return null; |
|
70 } |
|
71 ObjectData data = (ObjectData) cachedValue; |
|
72 return data.getProxy(); |
|
73 } |
|
74 }; |
|
75 } |