1.1 --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/property/SingleMapNodeProperty.java Thu Sep 26 10:43:28 2013 -0700 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/property/SingleMapNodeProperty.java Fri Oct 04 16:21:34 2013 +0100 1.3 @@ -140,22 +140,23 @@ 1.4 */ 1.5 private final Loader itemsLoader = new Loader(false) { 1.6 1.7 - private ThreadLocal<BeanT> target = new ThreadLocal<BeanT>(); 1.8 - private ThreadLocal<ValueT> map = new ThreadLocal<ValueT>(); 1.9 - private int depthCounter = 0; // needed to clean ThreadLocals 1.10 + private ThreadLocal<Stack<BeanT>> target = new ThreadLocal<Stack<BeanT>>(); 1.11 + private ThreadLocal<Stack<ValueT>> map = new ThreadLocal<Stack<ValueT>>(); 1.12 1.13 @Override 1.14 public void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException { 1.15 // create or obtain the Map object 1.16 try { 1.17 - target.set((BeanT)state.prev.target); 1.18 - map.set(acc.get(target.get())); 1.19 - depthCounter++; 1.20 - if(map.get() == null) { 1.21 - map.set(ClassFactory.create(mapImplClass)); 1.22 - } 1.23 - map.get().clear(); 1.24 - state.target = map.get(); 1.25 + BeanT target = (BeanT) state.prev.target; 1.26 + ValueT mapValue = acc.get(target); 1.27 + if(mapValue == null) 1.28 + mapValue = ClassFactory.create(mapImplClass); 1.29 + else 1.30 + mapValue.clear(); 1.31 + 1.32 + Stack.push(this.target, target); 1.33 + Stack.push(map, mapValue); 1.34 + state.target = mapValue; 1.35 } catch (AccessorException e) { 1.36 // recover from error by setting a dummy Map that receives and discards the values 1.37 handleGenericException(e,true); 1.38 @@ -167,11 +168,7 @@ 1.39 public void leaveElement(State state, TagName ea) throws SAXException { 1.40 super.leaveElement(state, ea); 1.41 try { 1.42 - acc.set(target.get(), map.get()); 1.43 - if (--depthCounter == 0) { 1.44 - target.remove(); 1.45 - map.remove(); 1.46 - } 1.47 + acc.set(Stack.pop(target), Stack.pop(map)); 1.48 } catch (AccessorException ex) { 1.49 handleGenericException(ex,true); 1.50 } 1.51 @@ -289,4 +286,36 @@ 1.52 return acc; 1.53 return null; 1.54 } 1.55 + 1.56 + private static final class Stack<T> { 1.57 + private Stack<T> parent; 1.58 + private T value; 1.59 + 1.60 + private Stack(Stack<T> parent, T value) { 1.61 + this.parent = parent; 1.62 + this.value = value; 1.63 + } 1.64 + 1.65 + private Stack(T value) { 1.66 + this.value = value; 1.67 + } 1.68 + 1.69 + private static <T> void push(ThreadLocal<Stack<T>> holder, T value) { 1.70 + Stack<T> parent = holder.get(); 1.71 + if (parent == null) 1.72 + holder.set(new Stack<T>(value)); 1.73 + else 1.74 + holder.set(new Stack<T>(parent, value)); 1.75 + } 1.76 + 1.77 + private static <T> T pop(ThreadLocal<Stack<T>> holder) { 1.78 + Stack<T> current = holder.get(); 1.79 + if (current.parent == null) 1.80 + holder.remove(); 1.81 + else 1.82 + holder.set(current.parent); 1.83 + return current.value; 1.84 + } 1.85 + 1.86 + } 1.87 }