/**
* 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.yoko.bindings.corba;
import java.lang.reflect.Constructor;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.schemas.yoko.bindings.corba.Anonsequence;
import org.apache.schemas.yoko.bindings.corba.CaseType;
import org.apache.schemas.yoko.bindings.corba.Enum;
import org.apache.schemas.yoko.bindings.corba.Enumerator;
import org.apache.schemas.yoko.bindings.corba.Sequence;
import org.apache.schemas.yoko.bindings.corba.Union;
import org.apache.schemas.yoko.bindings.corba.Unionbranch;
import org.apache.yoko.bindings.corba.types.CorbaAnyHandler;
import org.apache.yoko.bindings.corba.types.CorbaArrayHandler;
import org.apache.yoko.bindings.corba.types.CorbaEnumHandler;
import org.apache.yoko.bindings.corba.types.CorbaExceptionHandler;
import org.apache.yoko.bindings.corba.types.CorbaFixedHandler;
import org.apache.yoko.bindings.corba.types.CorbaObjectHandler;
import org.apache.yoko.bindings.corba.types.CorbaObjectReferenceHandler;
import org.apache.yoko.bindings.corba.types.CorbaPrimitiveHandler;
import org.apache.yoko.bindings.corba.types.CorbaSequenceHandler;
import org.apache.yoko.bindings.corba.types.CorbaStructHandler;
import org.apache.yoko.bindings.corba.types.CorbaUnionHandler;
import org.omg.CORBA.Any;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.InputStream;
public class CorbaObjectReader {
private static final Logger LOG = LogUtils.getL7dLogger(CorbaObjectReader.class);
private InputStream stream;
public CorbaObjectReader(InputStream inStream) {
stream = inStream;
}
public void read(CorbaObjectHandler obj) throws CorbaBindingException {
switch (obj.getTypeCode().kind().value()) {
case TCKind._tk_boolean:
((CorbaPrimitiveHandler)obj).setValue(this.readBoolean());
break;
case TCKind._tk_char:
Character charValue = this.readChar();
((CorbaPrimitiveHandler)obj).setValue(charValue);
break;
case TCKind._tk_wchar:
((CorbaPrimitiveHandler)obj).setValue(this.readWChar());
break;
case TCKind._tk_octet:
Byte octetValue = this.readOctet();
((CorbaPrimitiveHandler)obj).setValue(octetValue);
break;
case TCKind._tk_short:
((CorbaPrimitiveHandler)obj).setValue(this.readShort());
break;
case TCKind._tk_ushort:
((CorbaPrimitiveHandler)obj).setValue(this.readUShort());
break;
case TCKind._tk_long:
((CorbaPrimitiveHandler)obj).setValue(this.readLong());
break;
case TCKind._tk_ulong:
((CorbaPrimitiveHandler)obj).setValue(this.readULong());
break;
case TCKind._tk_longlong:
((CorbaPrimitiveHandler)obj).setValue(this.readLongLong());
break;
case TCKind._tk_ulonglong:
((CorbaPrimitiveHandler)obj).setValue(this.readULongLong());
break;
case TCKind._tk_float:
((CorbaPrimitiveHandler)obj).setValue(this.readFloat());
break;
case TCKind._tk_double:
((CorbaPrimitiveHandler)obj).setValue(this.readDouble());
break;
case TCKind._tk_string:
((CorbaPrimitiveHandler)obj).setValue(this.readString());
break;
case TCKind._tk_wstring:
((CorbaPrimitiveHandler)obj).setValue(this.readWString());
break;
case TCKind._tk_any:
((CorbaAnyHandler)obj).setValue(this.readAny());
break;
// Now for the complex types
case TCKind._tk_array:
this.readArray(obj);
break;
case TCKind._tk_sequence:
this.readSequence(obj);
break;
case TCKind._tk_struct:
this.readStruct(obj);
break;
case TCKind._tk_enum:
this.readEnum(obj);
break;
case TCKind._tk_except:
this.readException(obj);
break;
case TCKind._tk_fixed:
this.readFixed(obj);
break;
case TCKind._tk_union:
this.readUnion(obj);
break;
case TCKind._tk_objref:
this.readObjectReference(obj);
break;
default:
// TODO: Provide Implementation. Do we throw an exception.
}
}
// -- primitive types --
public Boolean readBoolean() throws CorbaBindingException {
try {
return new Boolean(stream.read_boolean());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read boolean");
throw new CorbaBindingException("CorbaObjectReader: readBoolean MARSHAL exception", ex);
}
}
public Character readChar() throws CorbaBindingException {
try {
return new Character(stream.read_char());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read character");
throw new CorbaBindingException("CorbaObjectReader: readChar MARSHAL exception", ex);
}
}
public Character readWChar() throws CorbaBindingException {
try {
return new Character(stream.read_wchar());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read wide character");
throw new CorbaBindingException("CorbaObjectReader: readWChar MARSHAL exception", ex);
}
}
public Byte readOctet() throws CorbaBindingException {
try {
return new Byte(stream.read_octet());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read octet");
throw new CorbaBindingException("CorbaObjectReader: readOctet MARSHAL exception", ex);
}
}
public Short readShort() throws CorbaBindingException {
try {
return new Short(stream.read_short());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read short");
throw new CorbaBindingException("CorbaObjectReader: readShort MARSHAL exception", ex);
}
}
public Integer readUShort() throws CorbaBindingException {
try {
Integer result = new Integer(stream.read_ushort());
if (result < 0) {
result = (result - Short.MIN_VALUE) - Short.MIN_VALUE;
}
return result;
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read unsigned short");
throw new CorbaBindingException("CorbaObjectReader: readUShort MARSHAL exception", ex);
}
}
public Integer readLong() throws CorbaBindingException {
try {
return new Integer(stream.read_long());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read long");
throw new CorbaBindingException("CorbaObjectReader: readLong MARSHAL exception", ex);
}
}
public BigInteger readULong() throws CorbaBindingException {
try {
return new BigInteger(stream.read_ulong() + "");
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read unsigned long");
throw new CorbaBindingException("CorbaObjectReader: readULong MARSHAL exception", ex);
}
}
public Long readLongLong() throws CorbaBindingException {
try {
return new Long(stream.read_longlong());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read long long");
throw new CorbaBindingException("CorbaObjectReader: readLongLong MARSHAL exception", ex);
}
}
public BigInteger readULongLong() throws CorbaBindingException {
try {
return new BigInteger(stream.read_ulonglong() + "");
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read unsigned long long");
throw new CorbaBindingException("CorbaObjectReader: readULongLong MARSHAL exception", ex);
}
}
public Float readFloat() throws CorbaBindingException {
try {
return new Float(stream.read_float());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read float");
throw new CorbaBindingException("CorbaObjectReader: readFloat MARSHAL exception", ex);
}
}
public Double readDouble() throws CorbaBindingException {
try {
return new Double(stream.read_double());
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read double");
throw new CorbaBindingException("CorbaObjectReader: readDouble MARSHAL exception", ex);
}
}
public String readString() throws CorbaBindingException {
try {
return stream.read_string();
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read string");
throw new CorbaBindingException("CorbaObjectReader: readString MARSHAL exception", ex);
}
}
public String readWString() throws CorbaBindingException {
try {
return stream.read_wstring();
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read wide string");
throw new CorbaBindingException("CorbaObjectReader: readWString MARSHAL exception", ex);
}
}
public Any readAny() throws CorbaBindingException {
try {
return stream.read_any();
} catch (org.omg.CORBA.MARSHAL ex) {
LOG.log(Level.SEVERE, "CorbaObjectReader: could not read any");
throw new CorbaBindingException("CorbaObjectReader: readAny MARSHAL exception", ex);
}
}
// -- complex types --
public void readEnum(CorbaObjectHandler obj) throws CorbaBindingException {
int enumIndex = stream.read_long();
Enum enumType = (Enum) obj.getType();
List<Enumerator> enumerators = enumType.getEnumerator();
CorbaEnumHandler enumObj = (CorbaEnumHandler)obj;
enumObj.setValue(enumerators.get(enumIndex).getValue());
}
public void readStruct(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaStructHandler structObj = (CorbaStructHandler)obj;
List<CorbaObjectHandler> structMembers = structObj.getMembers();
for (int i = 0; i < structMembers.size(); ++i) {
this.read(structMembers.get(i));
}
}
public void readException(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaExceptionHandler exceptObj = (CorbaExceptionHandler)obj;
List<CorbaObjectHandler> exceptElements = exceptObj.getMembers();
String exceptId = stream.read_string();
exceptObj.setId(exceptId);
for (int i = 0; i < exceptElements.size(); ++i) {
this.read(exceptElements.get(i));
}
}
public void readFixed(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaFixedHandler fixedHandler = (CorbaFixedHandler)obj;
long scale = fixedHandler.getScale();
java.math.BigDecimal fixedValue = stream.read_fixed().movePointLeft((int)scale);
fixedHandler.setValue(fixedValue);
}
public void readUnion(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaUnionHandler unionHandler = (CorbaUnionHandler)obj;
Union unionType = (Union)unionHandler.getType();
List<Unionbranch> branches = unionType.getUnionbranch();
CorbaObjectHandler discriminator = unionHandler.getDiscriminator();
if (branches.size() > 0) {
this.read(discriminator);
String discLabel = null;
if (discriminator.getTypeCodeKind().value() == TCKind._tk_enum) {
discLabel = ((CorbaEnumHandler)discriminator).getValue();
} else {
discLabel = ((CorbaPrimitiveHandler)discriminator).getDataFromValue();
}
// Now find the label in the union to get the right case
Unionbranch defaultBranch = null;
boolean caseFound = false;
for (Iterator<Unionbranch> branchIter = branches.iterator(); branchIter.hasNext();) {
Unionbranch branch = branchIter.next();
if (branch.isSetDefault() && branch.isDefault()) {
defaultBranch = branch;
}
List<CaseType> cases = branch.getCase();
for (Iterator<CaseType> caseIter = cases.iterator(); caseIter.hasNext();) {
CaseType c = caseIter.next();
if (c.getLabel().equalsIgnoreCase(discLabel)) {
CorbaObjectHandler branchObj = unionHandler.getBranchByName(branch.getName());
this.read(branchObj);
unionHandler.setValue(branch.getName(), branchObj);
caseFound = true;
break;
}
}
if (caseFound) {
break;
}
}
// If we never find a case that matches the value of the discriminiator, then we must have
// found the default case.
if (!caseFound && defaultBranch != null) {
CorbaObjectHandler branchObj = unionHandler.getBranchByName(defaultBranch.getName());
this.read(branchObj);
unionHandler.setValue(defaultBranch.getName(), branchObj);
}
}
}
public void readArray(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaArrayHandler arrayObj = (CorbaArrayHandler)obj;
List<CorbaObjectHandler> arrayElements = arrayObj.getElements();
for (int i = 0; i < arrayElements.size(); ++i) {
this.read(arrayElements.get(i));
}
}
public void readSequence(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaSequenceHandler sequenceObj = (CorbaSequenceHandler)obj;
List<CorbaObjectHandler> seqElements = sequenceObj.getElements();
int length = stream.read_ulong();
long bound = 0;
if (obj.getType() instanceof Anonsequence) {
Anonsequence anonSeqType = (Anonsequence) obj.getType();
bound = anonSeqType.getBound();
} else {
Sequence seqType = (Sequence) obj.getType();
bound = seqType.getBound();
}
if (bound == 0) {
seqElements.clear();
// No predefined elements means an unbounded sequence. Use the template element
// to construct each object that is in the input stream.
CorbaObjectHandler template = sequenceObj.getTemplateElement();
Class<?> templateClass = template.getClass();
// we know that we are after the 4 parameter version of the constructor
Class[] paramClasses = new Class[4];
Object[] params = new Object[4];
paramClasses[0] = QName.class;
params[0] = template.getName();
paramClasses[1] = QName.class;
params[1] = template.getIdlType();
paramClasses[2] = TypeCode.class;
params[2] = template.getTypeCode();
paramClasses[3] = Object.class;
params[3] = template.getType();
Constructor templateConstructor = null;
try {
templateConstructor = templateClass.getConstructor(paramClasses);
} catch (java.lang.NoSuchMethodException ex) {
throw new CorbaBindingException("Exception while reading unbounded sequence", ex);
}
for (int i = 0; i < length; ++i) {
CorbaObjectHandler seqElement = null;
try {
seqElement = (CorbaObjectHandler)templateConstructor.newInstance(params);
// A special case arises if we have a unbounded sequence of unbounded sequences. We
// need to obtain the template object so that all nested unbounded sequences can be
// correctly constructed.
if (template instanceof CorbaSequenceHandler) {
CorbaSequenceHandler templateSeq = (CorbaSequenceHandler)template;
((CorbaSequenceHandler)seqElement).
setTemplateElement(templateSeq.getTemplateElement());
}
} catch (java.lang.Exception ex) {
throw new CorbaBindingException("Unable to instantiate sequence element", ex);
}
read(seqElement);
sequenceObj.addElement(seqElement);
}
} else {
// We have a bounded sequence and the object should already be pre-built
for (int i = 0; i < length; ++i) {
read(seqElements.get(i));
}
}
}
public void readObjectReference(CorbaObjectHandler obj) throws CorbaBindingException {
CorbaObjectReferenceHandler objRefObj = (CorbaObjectReferenceHandler)obj;
org.omg.CORBA.Object objRef = stream.read_Object();
objRefObj.setReference(objRef);
}
}