001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.bind.v2.runtime.unmarshaller;
027:
028: import com.sun.xml.internal.bind.api.AccessorException;
029: import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor;
030: import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
031:
032: import org.xml.sax.SAXException;
033:
034: /**
035: * Holds the information about packing scope.
036: *
037: * <p>
038: * When no packing is started yet, all the fields should be set to null.
039: *
040: * @author Kohsuke Kawaguchi
041: */
042: public final class Scope<BeanT, PropT, ItemT, PackT> {
043:
044: public final UnmarshallingContext context;
045:
046: private BeanT bean;
047: private Accessor<BeanT, PropT> acc;
048: private PackT pack;
049: private Lister<BeanT, PropT, ItemT, PackT> lister;
050:
051: Scope(UnmarshallingContext context) {
052: this .context = context;
053: }
054:
055: /**
056: * Returns true if this scope object is filled by a packing in progress.
057: */
058: public boolean hasStarted() {
059: return bean != null;
060: }
061:
062: /**
063: * Initializes all the fields to null.
064: */
065: public void reset() {
066: if (bean == null) {
067: // already initialized
068: assert clean();
069: return;
070: }
071:
072: bean = null;
073: acc = null;
074: pack = null;
075: lister = null;
076: }
077:
078: /**
079: * Finishes up the current packing in progress (if any) and
080: * resets this object.
081: */
082: public void finish() throws AccessorException {
083: if (hasStarted()) {
084: lister.endPacking(pack, bean, acc);
085: reset();
086: }
087: assert clean();
088: }
089:
090: private boolean clean() {
091: return bean == null && acc == null && pack == null
092: && lister == null;
093: }
094:
095: /**
096: * Adds a new item to this packing scope.
097: */
098: public void add(Accessor<BeanT, PropT> acc,
099: Lister<BeanT, PropT, ItemT, PackT> lister, ItemT value)
100: throws SAXException {
101: try {
102: if (!hasStarted()) {
103: this .bean = (BeanT) context.getCurrentState().target;
104: this .acc = acc;
105: this .lister = lister;
106: this .pack = lister.startPacking(bean, acc);
107: }
108:
109: lister.addToPack(pack, value);
110: } catch (AccessorException e) {
111: Loader.handleGenericException(e, true);
112: // recover from this error by ignoring future items.
113: this.lister = Lister.ERROR;
114: this.acc = Accessor.ERROR;
115: }
116: }
117: }
|