package com.sun.xml.internal.bind.v2.runtime;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import com.sun.xml.internal.bind.api.AccessorException;
import com.sun.xml.internal.bind.v2.model.core.PropertyKind;
import com.sun.xml.internal.bind.v2.model.runtime.RuntimeElementInfo;
import com.sun.xml.internal.bind.v2.model.runtime.RuntimePropertyInfo;
import com.sun.xml.internal.bind.v2.runtime.property.Property;
import com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory;
import com.sun.xml.internal.bind.v2.runtime.property.UnmarshallerChain;
import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.ChildLoader;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Discarder;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Intercepter;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.TagName;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
import com.sun.xml.internal.bind.v2.util.QNameMap;
import org.xml.sax.SAXException;
public final class ElementBeanInfoImpl extends JaxBeanInfo<JAXBElement> {
private Loader loader;
private final Property property;
private final QName tagName;
public final Class expectedType;
private final Class scope;
private final Constructor<? extends JAXBElement> constructor;
ElementBeanInfoImpl(JAXBContextImpl grammar, RuntimeElementInfo rei) {
super(grammar,rei,(Class<JAXBElement>)rei.getType(),true,false,true);
this.property = PropertyFactory.create(grammar,rei.getProperty());
tagName = rei.getElementName();
expectedType = (Class) Utils.REFLECTION_NAVIGATOR.erasure(rei.getContentInMemoryType());
scope = rei.getScope()==null ? JAXBElement.GlobalScope.class : rei.getScope().getClazz();
Class type = (Class) Utils.REFLECTION_NAVIGATOR.erasure(rei.getType());
if(type==JAXBElement.class)
constructor = null;
else {
try {
constructor = type.getConstructor(expectedType);
} catch (NoSuchMethodException e) {
NoSuchMethodError x = new NoSuchMethodError("Failed to find the constructor for " + type + " with " + expectedType);
x.initCause(e);
throw x;
}
}
}
protected ElementBeanInfoImpl(final JAXBContextImpl grammar) {
super(grammar,null,JAXBElement.class,true,false,true);
tagName = null;
expectedType = null;
scope = null;
constructor = null;
this.property = new Property<JAXBElement>() {
public void reset(JAXBElement o) {
throw new UnsupportedOperationException();
}
public void serializeBody(JAXBElement e, XMLSerializer target, Object outerPeer) throws SAXException, IOException, XMLStreamException {
Class scope = e.getScope();
if(e.isGlobalScope()) scope = null;
QName n = e.getName();
ElementBeanInfoImpl bi = grammar.getElement(scope,n);
if(bi==null) {
JaxBeanInfo tbi;
try {
tbi = grammar.getBeanInfo(e.getDeclaredType(),true);
} catch (JAXBException x) {
target.reportError(null,x);
return;
}
Object value = e.getValue();
target.startElement(n.getNamespaceURI(),n.getLocalPart(),n.getPrefix(),null);
if(value==null) {
target.writeXsiNilTrue();
} else {
target.childAsXsiType(value,"value",tbi, false);
}
target.endElement();
} else {
try {
bi.property.serializeBody(e,target,e);
} catch (AccessorException x) {
target.reportError(null,x);
}
}
}
public void serializeURIs(JAXBElement o, XMLSerializer target) {
}
public boolean hasSerializeURIAction() {
return false;
}
public String getIdValue(JAXBElement o) {
return null;
}
public PropertyKind getKind() {
return PropertyKind.ELEMENT;
}
public void buildChildElementUnmarshallers(UnmarshallerChain chain, QNameMap<ChildLoader> handlers) {
}
public Accessor getElementPropertyAccessor(String nsUri, String localName) {
throw new UnsupportedOperationException();
}
public void wrapUp() {
}
public RuntimePropertyInfo getInfo() {
return property.getInfo();
}
public boolean isHiddenByOverride() {
return false;
}
public void setHiddenByOverride(boolean hidden) {
throw new UnsupportedOperationException("Not supported on jaxbelements.");
}
public String getFieldName() {
return null;
}
};
}
private final class IntercepterLoader extends Loader implements Intercepter {
private final Loader core;
public IntercepterLoader(Loader core) {
this.core = core;
}
@Override
public final void startElement(UnmarshallingContext.State state, TagName ea) throws SAXException {
state.setLoader(core);
state.setIntercepter(this);
Object child;
UnmarshallingContext context = state.getContext();
child = context.getOuterPeer();
if(child!=null && jaxbType!=child.getClass())
child = null;
if(child!=null)
reset((JAXBElement)child,context);
if(child==null)
child = context.createInstance(ElementBeanInfoImpl.this);
fireBeforeUnmarshal(ElementBeanInfoImpl.this, child, state);
context.recordOuterPeer(child);
UnmarshallingContext.State p = state.getPrev();
p.setBackup(p.getTarget());
p.setTarget(child);
core.startElement(state,ea);
}
public Object intercept(UnmarshallingContext.State state, Object o) throws SAXException {
JAXBElement e = (JAXBElement)state.getTarget();
state.setTarget(state.getBackup());
state.setBackup(null);
if (state.isNil()) {
e.setNil(true);
state.setNil(false);
}
if(o!=null)
e.setValue(o);
fireAfterUnmarshal(ElementBeanInfoImpl.this, e, state);
return e;
}
}
public String getElementNamespaceURI(JAXBElement e) {
return e.getName().getNamespaceURI();
}
public String getElementLocalName(JAXBElement e) {
return e.getName().getLocalPart();
}
public Loader getLoader(JAXBContextImpl context, boolean typeSubstitutionCapable) {
if(loader==null) {
UnmarshallerChain c = new UnmarshallerChain(context);
QNameMap<ChildLoader> result = new QNameMap<ChildLoader>();
property.buildChildElementUnmarshallers(c,result);
if(result.size()==1)
this.loader = new IntercepterLoader(result.getOne().getValue().loader);
else
this.loader = Discarder.INSTANCE;
}
return loader;
}
public final JAXBElement createInstance(UnmarshallingContext context) throws IllegalAccessException, InvocationTargetException, InstantiationException {
return createInstanceFromValue(null);
}
public final JAXBElement createInstanceFromValue(Object o) throws IllegalAccessException, InvocationTargetException, InstantiationException {
if(constructor==null)
return new JAXBElement(tagName,expectedType,scope,o);
else
return constructor.newInstance(o);
}
public boolean reset(JAXBElement e, UnmarshallingContext context) {
e.setValue(null);
return true;
}
public String getId(JAXBElement e, XMLSerializer target) {
Object o = e.getValue();
if(o instanceof String)
return (String)o;
else
return null;
}
public void serializeBody(JAXBElement element, XMLSerializer target) throws SAXException, IOException, XMLStreamException {
try {
property.serializeBody(element,target,null);
} catch (AccessorException x) {
target.reportError(null,x);
}
}
public void serializeRoot(JAXBElement e, XMLSerializer target) throws SAXException, IOException, XMLStreamException {
serializeBody(e,target);
}
public void serializeAttributes(JAXBElement e, XMLSerializer target) {
}
public void serializeURIs(JAXBElement e, XMLSerializer target) {
}
public final Transducer<JAXBElement> getTransducer() {
return null;
}
@Override
public void wrapUp() {
super.wrapUp();
property.wrapUp();
}
@Override
public void link(JAXBContextImpl grammar) {
super.link(grammar);
getLoader(grammar,true);
}
}