src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/UnmarshallingContext.java

changeset 707
31893650acaf
parent 650
121e938cb9c3
child 760
e530533619ec
equal deleted inserted replaced
706:1e9d08d74c48 707:31893650acaf
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this 7 * published by the Free Software Foundation. Oracle designates this
33 import java.util.HashMap; 33 import java.util.HashMap;
34 import java.util.Iterator; 34 import java.util.Iterator;
35 import java.util.List; 35 import java.util.List;
36 import java.util.Map; 36 import java.util.Map;
37 import java.util.concurrent.Callable; 37 import java.util.concurrent.Callable;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
40 38
41 import javax.xml.XMLConstants; 39 import javax.xml.XMLConstants;
42 import javax.xml.bind.JAXBElement; 40 import javax.xml.bind.JAXBElement;
43 import javax.xml.bind.UnmarshalException; 41 import javax.xml.bind.UnmarshalException;
44 import javax.xml.bind.Unmarshaller; 42 import javax.xml.bind.Unmarshaller;
196 */ 194 */
197 public final class State { 195 public final class State {
198 /** 196 /**
199 * Loader that owns this element. 197 * Loader that owns this element.
200 */ 198 */
201 public Loader loader; 199 private Loader loader;
202 /** 200 /**
203 * Once {@link #loader} is completed, this receiver 201 * Once {@link #loader} is completed, this receiver
204 * receives the result. 202 * receives the result.
205 */ 203 */
206 public Receiver receiver; 204 private Receiver receiver;
207 205
208 public Intercepter intercepter; 206 private Intercepter intercepter;
209
210 207
211 /** 208 /**
212 * Object being unmarshalled by this {@link #loader}. 209 * Object being unmarshalled by this {@link #loader}.
213 */ 210 */
214 public Object target; 211 private Object target;
215 212
216 /** 213 /**
217 * Hack for making JAXBElement unmarshalling work. 214 * Hack for making JAXBElement unmarshalling work.
218 * 215 *
219 * <p> 216 * <p>
238 * Yes, I know this is a hack, and no, I'm not proud of it. 235 * Yes, I know this is a hack, and no, I'm not proud of it.
239 * 236 *
240 * @see ElementBeanInfoImpl.IntercepterLoader#startElement(State, TagName) 237 * @see ElementBeanInfoImpl.IntercepterLoader#startElement(State, TagName)
241 * @see ElementBeanInfoImpl.IntercepterLoader#intercept(State, Object) 238 * @see ElementBeanInfoImpl.IntercepterLoader#intercept(State, Object)
242 */ 239 */
243 public Object backup; 240 private Object backup;
244 241
245 /** 242 /**
246 * Number of {@link UnmarshallingContext#nsBind}s declared thus far. 243 * Number of {@link UnmarshallingContext#nsBind}s declared thus far.
247 * (The value of {@link UnmarshallingContext#nsLen} when this state is pushed. 244 * (The value of {@link UnmarshallingContext#nsLen} when this state is pushed.
248 */ 245 */
254 * This should be set by either a parent {@link Loader} when 251 * This should be set by either a parent {@link Loader} when
255 * {@link Loader#childElement(State, TagName)} is called 252 * {@link Loader#childElement(State, TagName)} is called
256 * or by a child {@link Loader} when 253 * or by a child {@link Loader} when
257 * {@link Loader#startElement(State, TagName)} is called. 254 * {@link Loader#startElement(State, TagName)} is called.
258 */ 255 */
259 public String elementDefaultValue; 256 private String elementDefaultValue;
260 257
261 /** 258 /**
262 * {@link State} for the parent element 259 * {@link State} for the parent element
263 * 260 *
264 * {@link State} objects form a doubly linked list. 261 * {@link State} objects form a doubly linked list.
265 */ 262 */
266 public State prev; 263 private State prev;
267 private State next; 264 private State next;
268 265
269 public boolean nil = false; 266 private boolean nil = false;
267
268 /**
269 * specifies that we are working with mixed content
270 */
271 private boolean mixed = false;
270 272
271 /** 273 /**
272 * Gets the context. 274 * Gets the context.
273 */ 275 */
274 public UnmarshallingContext getContext() { 276 public UnmarshallingContext getContext() {
278 @SuppressWarnings("LeakingThisInConstructor") 280 @SuppressWarnings("LeakingThisInConstructor")
279 private State(State prev) { 281 private State(State prev) {
280 this.prev = prev; 282 this.prev = prev;
281 if (prev!=null) { 283 if (prev!=null) {
282 prev.next = this; 284 prev.next = this;
285 if (prev.mixed) // parent is in mixed mode
286 this.mixed = true;
283 } 287 }
284 } 288 }
285 289
286 private void push() { 290 private void push() {
287 if (logger.isLoggable(Level.FINEST)) { 291 if (logger.isLoggable(Level.FINEST)) {
288 logger.log(Level.FINEST, "State.push"); 292 logger.log(Level.FINEST, "State.push");
289 } 293 }
290 if (next==null) { 294 if (next==null) {
291 assert current == this; 295 assert current == this;
292 allocateMoreStates(); 296 next = new State(this);
293 } 297 }
294 nil = false; 298 nil = false;
295 State n = next; 299 State n = next;
296 n.numNsDecl = nsLen; 300 n.numNsDecl = nsLen;
297 current = n; 301 current = n;
302 logger.log(Level.FINEST, "State.pop"); 306 logger.log(Level.FINEST, "State.pop");
303 } 307 }
304 assert prev!=null; 308 assert prev!=null;
305 loader = null; 309 loader = null;
306 nil = false; 310 nil = false;
311 mixed = false;
307 receiver = null; 312 receiver = null;
308 intercepter = null; 313 intercepter = null;
309 elementDefaultValue = null; 314 elementDefaultValue = null;
310 target = null; 315 target = null;
311 current = prev; 316 current = prev;
317 next = null;
318 }
319
320 public boolean isMixed() {
321 return mixed;
322 }
323
324 public Object getTarget() {
325 return target;
326 }
327
328 public void setLoader(Loader loader) {
329 if (loader instanceof StructureLoader) // set mixed mode
330 mixed = !((StructureLoader)loader).getBeanInfo().hasElementOnlyContentModel();
331 this.loader = loader;
332 }
333
334 public void setReceiver(Receiver receiver) {
335 this.receiver = receiver;
336 }
337
338 public State getPrev() {
339 return prev;
340 }
341
342 public void setIntercepter(Intercepter intercepter) {
343 this.intercepter = intercepter;
344 }
345
346 public void setBackup(Object backup) {
347 this.backup = backup;
348 }
349
350 public void setTarget(Object target) {
351 this.target = target;
352 }
353
354 public Object getBackup() {
355 return backup;
356 }
357
358 public boolean isNil() {
359 return nil;
360 }
361
362 public void setNil(boolean nil) {
363 this.nil = nil;
364 }
365
366 public Loader getLoader() {
367 return loader;
368 }
369
370 public String getElementDefaultValue() {
371 return elementDefaultValue;
372 }
373
374 public void setElementDefaultValue(String elementDefaultValue) {
375 this.elementDefaultValue = elementDefaultValue;
312 } 376 }
313 } 377 }
314 378
315 /** 379 /**
316 * Stub to the user-specified factory method. 380 * Stub to the user-specified factory method.
346 */ 410 */
347 public UnmarshallingContext( UnmarshallerImpl _parent, AssociationMap assoc) { 411 public UnmarshallingContext( UnmarshallerImpl _parent, AssociationMap assoc) {
348 this.parent = _parent; 412 this.parent = _parent;
349 this.assoc = assoc; 413 this.assoc = assoc;
350 this.root = this.current = new State(null); 414 this.root = this.current = new State(null);
351 allocateMoreStates();
352 } 415 }
353 416
354 public void reset(InfosetScanner scanner,boolean isInplaceMode, JaxBeanInfo expectedType, IDResolver idResolver) { 417 public void reset(InfosetScanner scanner,boolean isInplaceMode, JaxBeanInfo expectedType, IDResolver idResolver) {
355 this.scanner = scanner; 418 this.scanner = scanner;
356 this.isInplaceMode = isInplaceMode; 419 this.isInplaceMode = isInplaceMode;
391 } catch (Exception e) { 454 } catch (Exception e) {
392 handleError(e); 455 handleError(e);
393 } 456 }
394 457
395 return null; 458 return null;
396 }
397
398 /**
399 * Allocates a few more {@link State}s.
400 *
401 * Allocating multiple {@link State}s at once allows those objects
402 * to be allocated near each other, which reduces the working set
403 * of CPU. It improves the chance the relevant data is in the cache.
404 */
405 private void allocateMoreStates() {
406 // this method should be used only when we run out of a state.
407 assert current.next==null;
408
409 State s = current;
410 for (int i=0; i<8; i++) {
411 s = new State(s);
412 }
413 } 459 }
414 460
415 public void clearStates() { 461 public void clearStates() {
416 State last = current; 462 State last = current;
417 while (last.next != null) last = last.next; 463 while (last.next != null) last = last.next;
513 current.loader.startElement(current,tagName); 559 current.loader.startElement(current,tagName);
514 } 560 }
515 561
516 @Override 562 @Override
517 public void text(CharSequence pcdata) throws SAXException { 563 public void text(CharSequence pcdata) throws SAXException {
518 State cur = current;
519 pushCoordinator(); 564 pushCoordinator();
520 try { 565 try {
521 if(cur.elementDefaultValue!=null) { 566 if (current.elementDefaultValue != null) {
522 if(pcdata.length()==0) { 567 if (pcdata.length() == 0) {
523 // send the default value into the unmarshaller instead 568 // send the default value into the unmarshaller instead
524 pcdata = cur.elementDefaultValue; 569 pcdata = current.elementDefaultValue;
525 } 570 }
526 } 571 }
527 cur.loader.text(cur,pcdata); 572 current.loader.text(current, pcdata);
528 } finally { 573 } finally {
529 popCoordinator(); 574 popCoordinator();
530 } 575 }
531 } 576 }
532 577

mercurial