Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.cxf.aegis.type.basic.ArrayType Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cxf.aegis.type.basic;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.cxf.aegis.Context;
import org.apache.cxf.aegis.DatabindingException;
import org.apache.cxf.aegis.type.Type;
import org.apache.cxf.aegis.type.TypeUtil;
import org.apache.cxf.aegis.xml.MessageReader;
import org.apache.cxf.aegis.xml.MessageWriter;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaSequence;
/**
* An ArrayType.
*
* @author Dan Diephouse
*/
public class ArrayType extends Type {
private static final Logger LOG = LogUtils.getL7dLogger(ArrayType.class);
private QName componentName;
private long minOccurs;
private long maxOccurs = Long.MAX_VALUE;
private boolean flat;
public ArrayType() {
}
@Override
public Object readObject(MessageReader reader, Context context) throws DatabindingException {
try {
Collection values = readCollection(reader, context);
return makeArray(getComponentType().getTypeClass(), values);
} catch (IllegalArgumentException e) {
throw new DatabindingException("Illegal argument.", e);
}
}
protected Collection createCollection() {
return new ArrayList();
}
protected Collection readCollection(MessageReader reader, Context context) throws DatabindingException {
Collection values = createCollection();
while (reader.hasMoreElementReaders()) {
MessageReader creader = reader.getNextElementReader();
Type compType = TypeUtil.getReadType(creader.getXMLStreamReader(), context.getGlobalContext(),
getComponentType());
if (creader.isXsiNil()) {
values.add(null);
creader.readToEnd();
} else {
values.add(compType.readObject(creader, context));
}
// check max occurs
int size = values.size();
if (size > maxOccurs) {
throw new DatabindingException("The number of elements in " + getSchemaType()
+ " exceeds the maximum of " + maxOccurs);
}
}
// check min occurs
if (values.size() < minOccurs) {
throw new DatabindingException("The number of elements in " + getSchemaType()
+ " does not meet the minimum of " + minOccurs);
}
return values;
}
@SuppressWarnings("unchecked")
protected Object makeArray(Class arrayType, Collection values) {
int i;
int n;
Object array = null;
if (Integer.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Integer.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Long.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Long.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Short.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Short.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Double.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Double.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Float.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Float.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Byte.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Byte.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Boolean.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Boolean.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
} else if (Character.TYPE.equals(arrayType)) {
Object[] objects = values.toArray();
array = Array.newInstance(Character.TYPE, objects.length);
for (i = 0, n = objects.length; i < n; i++) {
Array.set(array, i, objects[i]);
}
}
return array == null ? values.toArray((Object[])Array.newInstance(getComponentType().getTypeClass(),
values.size())) : array;
}
@Override
public void writeObject(Object values, MessageWriter writer,
Context context) throws DatabindingException {
boolean forceXsiWrite = false;
if (values == null) {
return;
}
Type type = getComponentType();
if (type == null) {
throw new DatabindingException("Couldn't find type for array.");
}
if (XmlSchemaConstants.ANY_TYPE_QNAME.equals(type.getSchemaType())) {
forceXsiWrite = true;
}
String ns = null;
if (type.isAbstract()) {
ns = getSchemaType().getNamespaceURI();
} else {
ns = type.getSchemaType().getNamespaceURI();
}
String name = type.getSchemaType().getLocalPart();
Class arrayType = type.getTypeClass();
boolean oldXsiWrite = context.getGlobalContext().isWriteXsiTypes();
try {
if (forceXsiWrite) {
context.getGlobalContext().setWriteXsiTypes(true);
}
int i;
int n;
if (Object.class.isAssignableFrom(arrayType)) {
Object[] objects = (Object[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(objects[i], writer, context, type, name, ns);
}
} else if (Integer.TYPE.equals(arrayType)) {
int[] objects = (int[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Integer(objects[i]), writer, context, type, name, ns);
}
} else if (Long.TYPE.equals(arrayType)) {
long[] objects = (long[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Long(objects[i]), writer, context, type, name, ns);
}
} else if (Short.TYPE.equals(arrayType)) {
short[] objects = (short[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Short(objects[i]), writer, context, type, name, ns);
}
} else if (Double.TYPE.equals(arrayType)) {
double[] objects = (double[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Double(objects[i]), writer, context, type, name, ns);
}
} else if (Float.TYPE.equals(arrayType)) {
float[] objects = (float[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Float(objects[i]), writer, context, type, name, ns);
}
} else if (Byte.TYPE.equals(arrayType)) {
byte[] objects = (byte[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Byte(objects[i]), writer, context, type, name, ns);
}
} else if (Boolean.TYPE.equals(arrayType)) {
boolean[] objects = (boolean[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(Boolean.valueOf(objects[i]), writer, context, type, name, ns);
}
} else if (Character.TYPE.equals(arrayType)) {
char[] objects = (char[])values;
for (i = 0, n = objects.length; i < n; i++) {
writeValue(new Character(objects[i]), writer, context, type, name, ns);
}
}
} finally {
context.getGlobalContext().setWriteXsiTypes(oldXsiWrite);
}
}
protected void writeValue(Object value, MessageWriter writer, Context context, Type type, String name,
String ns) throws DatabindingException {
type = TypeUtil.getWriteType(context.getGlobalContext(), value, type);
MessageWriter cwriter;
if (type.isWriteOuter()) {
cwriter = writer.getElementWriter(name, ns);
} else {
cwriter = writer;
}
if (value == null && type.isNillable()) {
cwriter.writeXsiNil();
} else {
type.writeObject(value, cwriter, context);
}
if (type.isWriteOuter()) {
cwriter.close();
}
}
@Override
public void writeSchema(XmlSchema root) {
if (hasDefinedArray(root)) {
return;
}
XmlSchemaComplexType complex = new XmlSchemaComplexType(root);
complex.setName(getSchemaType().getLocalPart());
root.addType(complex);
root.getItems().add(complex);
XmlSchemaSequence seq = new XmlSchemaSequence();
complex.setParticle(seq);
Type componentType = getComponentType();
XmlSchemaElement element = new XmlSchemaElement();
element.setName(componentType.getSchemaType().getLocalPart());
element.setSchemaTypeName(componentType.getSchemaType());
seq.getItems().add(element);
if (componentType.isNillable()) {
element.setNillable(true);
}
element.setMinOccurs(getMinOccurs());
element.setMaxOccurs(getMaxOccurs());
}
/**
* Since both an Array and a List can have the same type definition, double check that there isn't already
* a defined type already.
*
* @param root
* @return
*/
private boolean hasDefinedArray(XmlSchema root) {
return root.getTypeByName(getSchemaType().getLocalPart()) != null;
}
/**
* We need to write a complex type schema for Beans, so return true.
*
* @see org.apache.cxf.aegis.type.Type#isComplex()
*/
@Override
public boolean isComplex() {
return true;
}
public QName getComponentName() {
return componentName;
}
public void setComponentName(QName componentName) {
this.componentName = componentName;
}
/**
* @see org.apache.cxf.aegis.type.Type#getDependencies()
*/
@Override
public Set getDependencies() {
Set deps = new HashSet();
deps.add(getComponentType());
return deps;
}
/**
* Get the Type
of the elements in the array.
*
* @return
*/
public Type getComponentType() {
Class compType = getTypeClass().getComponentType();
Type type;
if (componentName == null) {
type = getTypeMapping().getType(compType);
} else {
type = getTypeMapping().getType(componentName);
// We couldn't find the type the user specified. One is created
// below instead.
if (type == null) {
LOG.finest("Couldn't find array component type " + componentName + ". Creating one instead.");
}
}
if (type == null) {
type = getTypeMapping().getTypeCreator().createType(compType);
getTypeMapping().register(type);
}
return type;
}
public long getMaxOccurs() {
return maxOccurs;
}
public void setMaxOccurs(long maxOccurs) {
this.maxOccurs = maxOccurs;
}
public long getMinOccurs() {
return minOccurs;
}
public void setMinOccurs(long minOccurs) {
this.minOccurs = minOccurs;
}
public boolean isFlat() {
return flat;
}
public void setFlat(boolean flat) {
setWriteOuter(!flat);
this.flat = flat;
}
@Override
public boolean hasMaxOccurs() {
return true;
}
@Override
public boolean hasMinOccurs() {
return true;
}
}