117 * A Map property can never be ID.
118 */
119 public String getIdValue(BeanT bean) {
120 return null;
121 }
122
123 public PropertyKind getKind() {
124 return PropertyKind.MAP;
125 }
126
127 public void buildChildElementUnmarshallers(UnmarshallerChain chain, QNameMap<ChildLoader> handlers) {
128 keyLoader = keyBeanInfo.getLoader(chain.context,true);
129 valueLoader = valueBeanInfo.getLoader(chain.context,true);
130 handlers.put(tagName,new ChildLoader(itemsLoader,null));
131 }
132
133 private Loader keyLoader;
134 private Loader valueLoader;
135
136 /**
137 * Handles <items> and </items>.
138 *
139 * The target will be set to a {@link Map}.
140 */
141 private final Loader itemsLoader = new Loader(false) {
142
143 private ThreadLocal<Stack<BeanT>> target = new ThreadLocal<Stack<BeanT>>();
144 private ThreadLocal<Stack<ValueT>> map = new ThreadLocal<Stack<ValueT>>();
145
146 @Override
147 public void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
148 // create or obtain the Map object
149 try {
150 BeanT target = (BeanT) state.getPrev().getTarget();
151 ValueT mapValue = acc.get(target);
152 if(mapValue == null)
153 mapValue = ClassFactory.create(mapImplClass);
154 else
155 mapValue.clear();
156
157 Stack.push(this.target, target);
173 handleGenericException(ex,true);
174 }
175 }
176
177 @Override
178 public void childElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
179 if(ea.matches(entryTag)) {
180 state.setLoader(entryLoader);
181 } else {
182 super.childElement(state,ea);
183 }
184 }
185
186 @Override
187 public Collection<QName> getExpectedChildElements() {
188 return Collections.singleton(entryTag.toQName());
189 }
190 };
191
192 /**
193 * Handles <entry> and </entry>.
194 *
195 * The target will be set to a {@link Map}.
196 */
197 private final Loader entryLoader = new Loader(false) {
198 @Override
199 public void startElement(UnmarshallingContext.State state, TagName ea) {
200 state.setTarget(new Object[2]); // this is inefficient
201 }
202
203 @Override
204 public void leaveElement(UnmarshallingContext.State state, TagName ea) {
205 Object[] keyValue = (Object[])state.getTarget();
206 Map map = (Map) state.getPrev().getTarget();
207 map.put(keyValue[0],keyValue[1]);
208 }
209
210 @Override
211 public void childElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
212 if(ea.matches(keyTag)) {
213 state.setLoader(keyLoader);
|
117 * A Map property can never be ID.
118 */
119 public String getIdValue(BeanT bean) {
120 return null;
121 }
122
123 public PropertyKind getKind() {
124 return PropertyKind.MAP;
125 }
126
127 public void buildChildElementUnmarshallers(UnmarshallerChain chain, QNameMap<ChildLoader> handlers) {
128 keyLoader = keyBeanInfo.getLoader(chain.context,true);
129 valueLoader = valueBeanInfo.getLoader(chain.context,true);
130 handlers.put(tagName,new ChildLoader(itemsLoader,null));
131 }
132
133 private Loader keyLoader;
134 private Loader valueLoader;
135
136 /**
137 * Handles {@code <items>} and {@code </items>}.
138 *
139 * The target will be set to a {@link Map}.
140 */
141 private final Loader itemsLoader = new Loader(false) {
142
143 private ThreadLocal<Stack<BeanT>> target = new ThreadLocal<Stack<BeanT>>();
144 private ThreadLocal<Stack<ValueT>> map = new ThreadLocal<Stack<ValueT>>();
145
146 @Override
147 public void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
148 // create or obtain the Map object
149 try {
150 BeanT target = (BeanT) state.getPrev().getTarget();
151 ValueT mapValue = acc.get(target);
152 if(mapValue == null)
153 mapValue = ClassFactory.create(mapImplClass);
154 else
155 mapValue.clear();
156
157 Stack.push(this.target, target);
173 handleGenericException(ex,true);
174 }
175 }
176
177 @Override
178 public void childElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
179 if(ea.matches(entryTag)) {
180 state.setLoader(entryLoader);
181 } else {
182 super.childElement(state,ea);
183 }
184 }
185
186 @Override
187 public Collection<QName> getExpectedChildElements() {
188 return Collections.singleton(entryTag.toQName());
189 }
190 };
191
192 /**
193 * Handles {@code <entry>} and {@code </entry>}.
194 *
195 * The target will be set to a {@link Map}.
196 */
197 private final Loader entryLoader = new Loader(false) {
198 @Override
199 public void startElement(UnmarshallingContext.State state, TagName ea) {
200 state.setTarget(new Object[2]); // this is inefficient
201 }
202
203 @Override
204 public void leaveElement(UnmarshallingContext.State state, TagName ea) {
205 Object[] keyValue = (Object[])state.getTarget();
206 Map map = (Map) state.getPrev().getTarget();
207 map.put(keyValue[0],keyValue[1]);
208 }
209
210 @Override
211 public void childElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
212 if(ea.matches(keyTag)) {
213 state.setLoader(keyLoader);
|