src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/property/SingleMapNodeProperty.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 138,163 ****
*
* The target will be set to a {@link Map}.
*/
private final Loader itemsLoader = new Loader(false) {
! private ThreadLocal<BeanT> target = new ThreadLocal<BeanT>();
! private ThreadLocal<ValueT> map = new ThreadLocal<ValueT>();
! private int depthCounter = 0; // needed to clean ThreadLocals
@Override
public void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
// create or obtain the Map object
try {
! target.set((BeanT)state.prev.target);
! map.set(acc.get(target.get()));
! depthCounter++;
! if(map.get() == null) {
! map.set(ClassFactory.create(mapImplClass));
! }
! map.get().clear();
! state.target = map.get();
} catch (AccessorException e) {
// recover from error by setting a dummy Map that receives and discards the values
handleGenericException(e,true);
state.target = new HashMap();
}
--- 138,164 ----
*
* The target will be set to a {@link Map}.
*/
private final Loader itemsLoader = new Loader(false) {
! private ThreadLocal<Stack<BeanT>> target = new ThreadLocal<Stack<BeanT>>();
! private ThreadLocal<Stack<ValueT>> map = new ThreadLocal<Stack<ValueT>>();
@Override
public void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
// create or obtain the Map object
try {
! BeanT target = (BeanT) state.prev.target;
! ValueT mapValue = acc.get(target);
! if(mapValue == null)
! mapValue = ClassFactory.create(mapImplClass);
! else
! mapValue.clear();
!
! Stack.push(this.target, target);
! Stack.push(map, mapValue);
! state.target = mapValue;
} catch (AccessorException e) {
// recover from error by setting a dummy Map that receives and discards the values
handleGenericException(e,true);
state.target = new HashMap();
}
*** 165,179 ****
@Override
public void leaveElement(State state, TagName ea) throws SAXException {
super.leaveElement(state, ea);
try {
! acc.set(target.get(), map.get());
! if (--depthCounter == 0) {
! target.remove();
! map.remove();
! }
} catch (AccessorException ex) {
handleGenericException(ex,true);
}
}
--- 166,176 ----
@Override
public void leaveElement(State state, TagName ea) throws SAXException {
super.leaveElement(state, ea);
try {
! acc.set(Stack.pop(target), Stack.pop(map));
} catch (AccessorException ex) {
handleGenericException(ex,true);
}
}
*** 287,292 ****
--- 284,321 ----
public Accessor getElementPropertyAccessor(String nsUri, String localName) {
if(tagName.equals(nsUri,localName))
return acc;
return null;
}
+
+ private static final class Stack<T> {
+ private Stack<T> parent;
+ private T value;
+
+ private Stack(Stack<T> parent, T value) {
+ this.parent = parent;
+ this.value = value;
+ }
+
+ private Stack(T value) {
+ this.value = value;
+ }
+
+ private static <T> void push(ThreadLocal<Stack<T>> holder, T value) {
+ Stack<T> parent = holder.get();
+ if (parent == null)
+ holder.set(new Stack<T>(value));
+ else
+ holder.set(new Stack<T>(parent, value));
+ }
+
+ private static <T> T pop(ThreadLocal<Stack<T>> holder) {
+ Stack<T> current = holder.get();
+ if (current.parent == null)
+ holder.remove();
+ else
+ holder.set(current.parent);
+ return current.value;
+ }
+
+ }
}