1 /* 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. 4 * 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 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.bind.v2.runtime.unmarshaller; 27 28 import com.sun.xml.internal.bind.api.AccessorException; 29 import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor; 30 import com.sun.xml.internal.bind.v2.runtime.reflect.Lister; 31 32 import org.xml.sax.SAXException; 33 34 /** 35 * Holds the information about packing scope. 36 * 37 * <p> 38 * When no packing is started yet, all the fields should be set to null. 39 * 40 * @author Kohsuke Kawaguchi 41 */ 42 public final class Scope<BeanT,PropT,ItemT,PackT> { 43 44 public final UnmarshallingContext context; 45 46 private BeanT bean; 47 private Accessor<BeanT,PropT> acc; 48 private PackT pack; 49 private Lister<BeanT,PropT,ItemT,PackT> lister; 50 Scope(UnmarshallingContext context)51 Scope(UnmarshallingContext context) { 52 this.context = context; 53 } 54 55 /** 56 * Returns true if this scope object is filled by a packing in progress. 57 */ hasStarted()58 public boolean hasStarted() { 59 return bean!=null; 60 } 61 62 /** 63 * Initializes all the fields to null. 64 */ reset()65 public void reset() { 66 if(bean==null) { 67 // already initialized 68 assert clean(); 69 return; 70 } 71 72 bean = null; 73 acc = null; 74 pack = null; 75 lister = null; 76 } 77 78 /** 79 * Finishes up the current packing in progress (if any) and 80 * resets this object. 81 */ finish()82 public void finish() throws AccessorException { 83 if(hasStarted()) { 84 lister.endPacking(pack,bean,acc); 85 reset(); 86 } 87 assert clean(); 88 } 89 clean()90 private boolean clean() { 91 return bean==null && acc==null && pack==null && lister==null; 92 } 93 94 /** 95 * Adds a new item to this packing scope. 96 */ add( Accessor<BeanT,PropT> acc, Lister<BeanT,PropT,ItemT,PackT> lister, ItemT value)97 public void add( Accessor<BeanT,PropT> acc, Lister<BeanT,PropT,ItemT,PackT> lister, ItemT value) throws SAXException{ 98 try { 99 if(!hasStarted()) { 100 this.bean = (BeanT)context.getCurrentState().getTarget(); 101 this.acc = acc; 102 this.lister = lister; 103 this.pack = lister.startPacking(bean,acc); 104 } 105 106 lister.addToPack(pack,value); 107 } catch (AccessorException e) { 108 Loader.handleGenericException(e,true); 109 // recover from this error by ignoring future items. 110 this.lister = Lister.getErrorInstance(); 111 this.acc = Accessor.getErrorInstance(); 112 } 113 } 114 115 /** 116 * Starts the packing scope, without adding any item. 117 * 118 * This allows us to return an empty pack, thereby allowing the user 119 * to distinguish empty array vs null array. 120 */ start( Accessor<BeanT,PropT> acc, Lister<BeanT,PropT,ItemT,PackT> lister)121 public void start( Accessor<BeanT,PropT> acc, Lister<BeanT,PropT,ItemT,PackT> lister) throws SAXException{ 122 try { 123 if(!hasStarted()) { 124 this.bean = (BeanT)context.getCurrentState().getTarget(); 125 this.acc = acc; 126 this.lister = lister; 127 this.pack = lister.startPacking(bean,acc); 128 } 129 } catch (AccessorException e) { 130 Loader.handleGenericException(e,true); 131 // recover from this error by ignoring future items. 132 this.lister = Lister.getErrorInstance(); 133 this.acc = Accessor.getErrorInstance(); 134 } 135 } 136 } 137