blob: 2ad131021d30806791f6dfb069ead26299a2144e [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.BindingTypeName;
import org.apache.xmlbeans.impl.binding.bts.WrappedArrayType;
import org.apache.xmlbeans.impl.marshal.util.collections.Accumulator;
import org.apache.xmlbeans.impl.marshal.util.collections.AccumulatorFactory;
import javax.xml.namespace.QName;
import java.lang.reflect.Array;
final class WrappedArrayRuntimeBindingType
extends RuntimeBindingType
{
private final WrappedArrayType wrappedArrayType;
private ItemProperty elementProperty;
WrappedArrayRuntimeBindingType(WrappedArrayType binding_type)
throws XmlException
{
super(binding_type);
wrappedArrayType = binding_type;
}
void accept(RuntimeTypeVisitor visitor)
throws XmlException
{
visitor.visit(this);
}
public void initialize(RuntimeBindingTypeTable typeTable,
BindingLoader bindingLoader)
throws XmlException
{
final BindingTypeName item_type_name = wrappedArrayType.getItemType();
assert item_type_name != null;
final BindingType item_type = bindingLoader.getBindingType(item_type_name);
if (item_type == null) {
final String msg = "unable to lookup " + item_type_name +
" from type " + wrappedArrayType;
throw new XmlException(msg);
}
final RuntimeBindingType item_rtt =
typeTable.createRuntimeType(item_type, bindingLoader);
elementProperty =
new ItemProperty(this, wrappedArrayType.getItemName(),
item_rtt,
wrappedArrayType.isItemNillable());
}
boolean hasElementChildren()
{
return true;
}
ItemProperty getElementProperty()
{
assert elementProperty != null;
return elementProperty;
}
protected Object createIntermediary(UnmarshalResult context)
{
return AccumulatorFactory.createAccumulator(getJavaType(),
elementProperty.getElementClass());
}
protected Object createIntermediary(UnmarshalResult context,
Object actual_object)
{
//cannot modify the length of an array once it is created...
final String e = "factories not supported for array types: " +
getBindingType();
throw new UnsupportedOperationException(e);
}
protected Object getFinalObjectFromIntermediary(Object inter,
UnmarshalResult context)
throws XmlException
{
Accumulator acc = (Accumulator)inter;
return acc.getFinalArray();
}
boolean isObjectFromIntermediateIdempotent()
{
return false;
}
static final class ItemProperty
extends RuntimeBindingProperty
{
private final QName itemName;
private final RuntimeBindingType itemType;
private final boolean nillable;
ItemProperty(RuntimeBindingType containing_type,
QName item_name,
RuntimeBindingType item_type,
boolean nillable)
throws XmlException
{
super(containing_type);
itemName = item_name;
itemType = item_type;
this.nillable = nillable;
}
Class getElementClass()
{
return itemType.getJavaType();
}
RuntimeBindingType getRuntimeBindingType()
{
return itemType;
}
RuntimeBindingType getActualRuntimeType(Object property_value,
MarshalResult result)
throws XmlException
{
return result.determineRuntimeBindingType(itemType, property_value);
}
QName getName()
{
return itemName;
}
public void fill(Object inter, Object prop_obj)
throws XmlException
{
Accumulator acc = (Accumulator)inter;
acc.append(prop_obj);
}
protected void fillPlaceholder(Object inter)
{
Accumulator acc = (Accumulator)inter;
acc.appendDefault();
}
//non index properties can return unsupported...
protected int getSize(Object inter)
{
Accumulator acc = (Accumulator)inter;
return acc.size();
}
protected void fill(Object final_obj, int index, Object prop_val)
{
assert final_obj != null;
assert !(final_obj instanceof Accumulator);
//TODO: fix case for collections. Can only work with List types
assert final_obj.getClass().isArray();
Array.set(final_obj, index, prop_val);
}
Object getValue(Object parentObject, MarshalResult result)
throws XmlException
{
throw new UnsupportedOperationException("use 3 arg getValue");
}
Object getValue(Object parentObject, MarshalResult result, int item_index)
throws XmlException
{
return Array.get(parentObject, item_index);
}
boolean isSet(Object parentObject, MarshalResult result)
throws XmlException
{
throw new UnsupportedOperationException("use 3 arg isSet");
}
boolean isSet(Object parentObject, MarshalResult result, int item_index)
throws XmlException
{
if (nillable) return true;
if (itemType.isJavaPrimitive()) return true;
//TODO: consider isSet for array elements?
return getValue(parentObject, result, item_index) != null;
}
boolean isMultiple()
{
return true;
}
boolean isNillable()
{
return nillable;
}
String getLexicalDefault()
{
return null;
}
}
}