diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp')
-rw-r--r-- | tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp | 4921 |
1 files changed, 4921 insertions, 0 deletions
diff --git a/tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp b/tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp new file mode 100644 index 0000000000..099269b237 --- /dev/null +++ b/tags/cpp-sdo-1.0.incubating-M3-RC1/runtime/core/src/commonj/sdo/DataObjectImpl.cpp @@ -0,0 +1,4921 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +#include "commonj/sdo/disable_warn.h" +#include "commonj/sdo/DataObjectImpl.h" + +#include "commonj/sdo/SDORuntimeException.h" + +#include "commonj/sdo/Property.h" +#include "commonj/sdo/Type.h" +#include "commonj/sdo/TypeList.h" +#include "commonj/sdo/Sequence.h" +#include "commonj/sdo/SequenceImpl.h" + +#include "commonj/sdo/PropertyList.h" + +#include "commonj/sdo/Logging.h" + +#include "commonj/sdo/TypeImpl.h" + +#include "commonj/sdo/ChangeSummaryImpl.h" +#include "commonj/sdo/DataFactoryImpl.h" +#include "commonj/sdo/SDOUtils.h" + +#include <string> +#include <stdio.h> +#include <stdlib.h> +using std::string; + + + + +namespace commonj{ +namespace sdo { + + /** + * RDO is an internal class holding a property value + */ + + rdo::rdo(unsigned int infirst, DataObjectImpl* insecond) + : first(infirst), second(insecond) + { + } + + rdo::rdo() + { + first = 0; + second = 0; + } + + rdo::rdo (const rdo& inrdo) + { + first = inrdo.first; + second = inrdo.second; + } + + rdo::~rdo() + { + } + +#define ASSERT_SETTABLE(property,primval) ASSERT_WRITABLE(*property, set##primval) + + /** DataObject + * DataObjects are the non-primitive members of a Data graph. + * + * A data object is a representation of some structured data. + * it is the fundamental component in the SDO (Service Data Objects) package. + * Data objects support reflection, path-based accesss, convenience creation + * and deletion methods,and the ability to be part of a data graph. + * Each data object holds its data as a series of properties. + * Properties can be accessed by name, property index, or using the property + * meta object itself. + * A data object can also contain references to other data objects, through + * reference-type properties. + * A data object has a series of convenience accessors for its properties. + * These methods either use a path (String), a property index, + * or the property's meta object itself, to identify the property. + * Some examples of the path-based accessors are as follows: + * DataObjectPtr company = ...; + * company->getString("name"); + * company->setString("name", "acme"); + * company->getString("department.0/name") + * .n indexes from 0. + * company->getString("department[1]/name") [] indexes from 1. + * company->getDataObject("department[number=123]") returns the department where number=123 + * company->getDataObject("..") returns the containing data object + * company->getDataObject("/") returns the root containing data object + * There are specific accessors for the primitive types and commonly used + * data types like String. + */ + + unsigned int DataObjectImpl::getBytes(const char* path, char* valptr , unsigned int max) + { + const SDOString pathObject(path); + unsigned int result = getBytes(pathObject, valptr, max); + return result; + } + + unsigned int DataObjectImpl::getString(const char* path, wchar_t* buf, unsigned int max) + { + return getString(SDOString(path), buf, max); + } + + // Convenience methods for string/bytes length + + unsigned int DataObjectImpl::getLength(const Property& p) + { + switch (p.getType().getTypeEnum()) { + case Type::BooleanType: + return BOOL_SIZE; + case Type::CharacterType: + case Type::ByteType: + return BYTE_SIZE; + case Type::ShortType: + case Type::IntegerType: + case Type::LongType: + return MAX_LONG_SIZE; + case Type::FloatType: + return MAX_FLOAT_SIZE; + case Type::DoubleType: + return MAX_DOUBLE_SIZE; + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::UriType: + case Type::StringType: + return getString(p,0,0); + case Type::BytesType: + return getBytes(p,0,0); + default: + return 0; + } + } + + unsigned int DataObjectImpl::getLength() + { + switch (getType().getTypeEnum()) { + case Type::BooleanType: + return BOOL_SIZE; + case Type::CharacterType: + case Type::ByteType: + return BYTE_SIZE; + case Type::ShortType: + case Type::IntegerType: + case Type::LongType: + return MAX_LONG_SIZE; + case Type::FloatType: + return MAX_FLOAT_SIZE; + case Type::DoubleType: + return MAX_DOUBLE_SIZE; + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::UriType: + case Type::StringType: + return getString(0,0); + case Type::BytesType: + return getBytes(0,0); + default: + return 0; + } + } + + unsigned int DataObjectImpl::getLength(const char* path) + { + return getLength(SDOString(path)); + } + + unsigned int DataObjectImpl::getLength(const SDOString& path) + { + DataObjectImpl* d; + SDOString spath; + DataObjectImpl::stripPath(path, spath); + SDOString prop = findPropertyContainer(spath, &d); + if (d != 0) { + if (prop.length() == 0) { + return 0; + } + else + { + const Property& p = d->getProperty(prop); + return getLength(p); + } + } + else + { + if (prop.length()) + { + const Property& p = getProperty(prop); + return getLength(p); + } + else + { + return 0; + } + } + } + + unsigned int DataObjectImpl::getLength(unsigned int index) + { + return getLength(getProperty(index)); + } + + // +++ + // Provide implementations for the getXXX(const char* path) methods. + // These are implemented by delegating the call + // to the corresponding getXXX(const SDOString& path) method. + + // getPrimitiveFromPath(Boolean,bool,false); + bool DataObjectImpl::getBoolean(const char* path) + { + return getBoolean(SDOString(path)); + } + + // getPrimitiveFromPath(Short,short,0); + short DataObjectImpl::getShort(const char* path) + { + return getShort(SDOString(path)); + } + + // getPrimitiveFromPath(Byte,char,0); + char DataObjectImpl::getByte(const char* path) + { + return getByte(SDOString(path)); + } + + // getPrimitiveFromPath(Character,wchar_t,0); + wchar_t DataObjectImpl::getCharacter(const char* path) + { + return getCharacter(SDOString(path)); + } + + // getPrimitiveFromPath(Date,const SDODate,0); + const SDODate DataObjectImpl::getDate(const char* path) + { + return getDate(SDOString(path)); + } + + // getPrimitiveFromPath(Double,long double,0.0); + long double DataObjectImpl::getDouble(const char* path) + { + return getDouble(SDOString(path)); + } + + // getPrimitiveFromPath(Float,float,0.0); + float DataObjectImpl::getFloat(const char* path) + { + return getFloat(SDOString(path)); + } + + // getPrimitiveFromPath(Integer,long,0); + long DataObjectImpl::getInteger(const char* path) + { + return getInteger(SDOString(path)); + } + + // getPrimitiveFromPath(Long,int64_t,0L); + int64_t DataObjectImpl::getLong(const char* path) + { + return getLong(SDOString(path)); + } + + // End of implementations for the getXXX(const char* path) methods. + // --- + + + // +++ + // Provide implementations for the setXXX(const char* path, XXX) methods. + // These are implemented by delegating the call + // to the corresponding setXXX(const SDOString& path, XXX) method. + + void DataObjectImpl::setBoolean(const char* path, bool b) + { + setBoolean(SDOString(path), b); + } + + void DataObjectImpl::setShort(const char* path, short s) + { + setShort(SDOString(path), s); + } + + void DataObjectImpl::setByte(const char* path, char c) + { + setByte(SDOString(path), c); + } + + void DataObjectImpl::setCharacter(const char* path, wchar_t c) + { + setCharacter(SDOString(path), c); + } + + void DataObjectImpl::setDate(const char* path, const SDODate d) + { + setDate(SDOString(path), d); + } + + void DataObjectImpl::setDouble(const char* path, long double d) + { + setDouble(SDOString(path), d); + } + + void DataObjectImpl::setFloat(const char* path, float f) + { + setFloat(SDOString(path), f); + } + + void DataObjectImpl::setInteger(const char* path, long i) + { + setInteger(SDOString(path), i); + } + + // setPrimitiveFromPath(Long,int64_t, int64_t); + // setPrimitiveFromPath(Integer,long, long); + // Depends on wordsize, see SDOString& variant below. + void DataObjectImpl::setLong(const char* path, /*long long*/ int64_t l) + { + setLong(SDOString(path), l); + } + + // End of implementations for the setXXX(const char* path, XXX) methods. + // --- + + + // open type support + + const PropertyImpl* DataObjectImpl::defineProperty(const SDOString& propname, + const Type& t) + { + openProperties.insert(openProperties.end(), + PropertyImpl(getType(), + propname, + (TypeImpl&)t, + false, + false, + true)); + DataFactory* df = factory; + ((DataFactoryImpl*)df)->addOpenProperty(PropertyImpl(getType(), + propname, + (TypeImpl&)t, + false, + false, + true)); + + return getPropertyImpl(propname); + } + + void DataObjectImpl::undefineProperty(unsigned int index) + { + if (index < openBase) return; + unsigned int point = index - openBase; + if (point >= openProperties.size()) return; + + // downgrade all the property settings above this one + + PropertyValueMap::iterator pit; + for (pit = PropertyValues.begin(); pit != PropertyValues.end();++pit) + { + if ((*pit).first > index) + { + if (getPropertyImpl((*pit).first)->isMany()) + { + DataObjectListImpl* dl = (*pit).second->getListImpl(); + if (dl != 0) dl->decrementPindex(); + } + (*pit).first-=1; + } + } + + // then remove this property from the list + + std::list<PropertyImpl>::iterator it = + openProperties.begin(); + for (unsigned int i=0;i<point;i++)++it; /* there must be a better way */ + + DataFactory* df = factory; + ((DataFactoryImpl*)df)->removeOpenProperty((*it).getName()); + + openProperties.erase(it); + + return; + } + + const PropertyImpl* DataObjectImpl::defineList(const char* propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "OpenDataObject"); + openProperties.insert( + openProperties.end(), PropertyImpl(getType(),propname, + (TypeImpl&)t, true, false, true)); + + DataFactory* df = factory; + ((DataFactoryImpl*)df)->addOpenProperty(PropertyImpl(getType(),propname, + (TypeImpl&)t, true, false, true)); + + return getPropertyImpl(propname); + } + + const PropertyImpl* DataObjectImpl::defineSDOValue(const SDOString& propname, + const SDOValue& sval) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, + sval.convertTypeEnumToString()); + return defineProperty(propname, t); + } + + const PropertyImpl* DataObjectImpl::defineBoolean(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Boolean"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineByte(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Byte"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineCharacter(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Character"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineString(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "String"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineBytes(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Bytes"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineShort(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Short"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineInteger(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Integer"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineLong(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Long"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineFloat(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Float"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineDouble(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Double"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineDate(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "Date"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineCString(const SDOString& propname) + { + const Type& t = factory->getType(Type::SDOTypeNamespaceURI, "String"); + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineDataObject(const SDOString& propname, + const Type& t) + { + return defineProperty(propname,t); + } + + const PropertyImpl* DataObjectImpl::defineDataObject(const char* propname, + const char* typeURI, const char* typeName) + { + const Type& t = factory->getType(typeURI, typeName); + return defineProperty(propname,t); + } + + void DataObjectImpl::setCString (unsigned int propertyIndex, const char* value) + { + setCString(propertyIndex, SDOString(value)); + } + + const char* DataObjectImpl::getCString (const char* path) + { + return getCString(SDOString(path)); + } + + void DataObjectImpl::setCString(const char* path, const char* value) + { + setCString(SDOString(path), SDOString(value)); + } + + void DataObjectImpl::setCString(const Property& property, const char* value) + { + setCString(property, SDOString(value)); + } + + // null support + + bool DataObjectImpl::isNull(const unsigned int propertyIndex) + { + validateIndex(propertyIndex); + if ((getProperty(propertyIndex).isMany())) + { + return false; + } + + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end();++i) + { + if ((*i).first == propertyIndex) + { + return (*i).second->isNull(); + } + } + return false; + } + + bool DataObjectImpl::isNull(const Property& property) + { + return isNull(getPropertyIndex(property)); + } + + bool DataObjectImpl::isNull(const char* path) + { + return isNull(SDOString(path)); + } + + bool DataObjectImpl::isNull(const SDOString& path) + { + DataObjectImpl *d = 0; + SDOString spath; + SDOString prop; + // char* spath = 0; + // char* prop = 0; + try { + DataObjectImpl::stripPath(path, spath); + prop = findPropertyContainer(spath, &d); + if (d != 0) { + if (prop.length() == 0) { + return d->isNull(); + } + else { + const Property& p = d->getProperty(prop); + return d->isNull(p); + } + } + return false; + } + catch (SDORuntimeException e) { + SDO_RETHROW_EXCEPTION("isNull",e); + } + } + + void DataObjectImpl::setNull(const unsigned int propertyIndex) + { + validateIndex(propertyIndex); + const Property& property = getProperty(propertyIndex); + if (property.isMany()) + { + string msg("Setting a list to null is not supported:"); + msg += property.getName(); + SDO_THROW_EXCEPTION("setNull", + SDOUnsupportedOperationException, + msg.c_str()); + } + + ASSERT_WRITABLE(property, setNull); + + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == propertyIndex) + { + logChange(propertyIndex); + (*i).second->setNull(); + return; + } + } + // The property was not set yet... + logChange(propertyIndex); + DataFactory* df = getDataFactory(); + DataObjectImpl* b = + new DataObjectImpl(df, getProperty(propertyIndex).getType()); + b->setContainer(this); + b->setApplicableChangeSummary(); + PropertyValues.push_back(rdo(propertyIndex,b)); + b->setNull(); + } + + void DataObjectImpl::setNull(const Property& property) + { + setNull(getPropertyIndexInternal(property)); + } + + void DataObjectImpl::setNull(const char* path) + { + setNull(SDOString(path)); + } + + void DataObjectImpl::setNull(const SDOString& path) + { + DataObjectImpl *d = 0; + SDOString spath; + SDOString prop; + size_t pc; + + try { + DataObjectImpl::stripPath(path, spath); + prop = findPropertyContainer(spath, &d); + if (d != 0) { + if (prop.length() == 0) { + try { + DataObjectImpl* cont = d->getContainerImpl(); + if (cont != 0) + { + pc = path.rfind('/'); // Find the last '/' in the path + if (pc != string::npos) + pc++; // pc is the index of the first character following the / + } + const Property& pcont = cont->getProperty(path.substr(pc)); + ASSERT_WRITABLE(pcont, setNull) + cont->logChange(pcont); + } + catch (SDORuntimeException&) + { + } + d->setNull(); + } + else { + const PropertyImpl* p = d->getPropertyImpl(prop); + if (p == 0) + { + if(d->getType().isOpenType()) + { + string msg("Cannot set unassigned open property to null:"); + msg += prop; + SDO_THROW_EXCEPTION("setNull", SDOUnsupportedOperationException, + msg.c_str()); + } + else + { + string msg("Property Not Found:"); + msg += prop; + SDO_THROW_EXCEPTION("setNull", SDOPropertyNotFoundException, + msg.c_str()); + } + } + ASSERT_SETTABLE(p, Null) + d->setNull((Property&)*p); + return; + } + } + return; + } + catch (SDORuntimeException e) { + SDO_RETHROW_EXCEPTION("setNull",e); + } + + } + + // getters and setters for a List data object + + DataObjectList& DataObjectImpl::getList(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + return(getList(SDOString())); + } + else + { + return(getList(SDOString(path))); + } + } + + DataObjectList& DataObjectImpl::getList(const SDOString& path) + { + DataObjectImpl *d; + SDOString spath; + + DataObjectImpl::stripPath(path, spath); + SDOString prop = findPropertyContainer(spath, &d); + + if (d != 0) { + if (prop.length() == 0) { + return d->getList(); + } + else { + const PropertyImpl* p = d->getPropertyImpl(prop); + if (p == 0 && d->getType().isOpenType()) + { + p = d->defineList(prop.c_str()); + } + if (p != 0) + { + return d->getList((Property&)*p); + } + } + } + + string msg("Invalid path:"); + msg += path; + SDO_THROW_EXCEPTION("getList",SDOPathNotFoundException, msg.c_str()); + } + + + DataObjectList& DataObjectImpl::getList(unsigned int propIndex) + { + return getList(getProperty(propIndex)); + } + + DataObjectList& DataObjectImpl::getList(const Property& p) + { + if (!p.isMany()) + { + PropertyImpl* pi = (PropertyImpl*)&p; + if (!pi->getTypeImpl()->isFromList()) + { + string msg("Get list not available on single valued property:"); + msg += p.getName(); + SDO_THROW_EXCEPTION("getList", SDOUnsupportedOperationException, + msg.c_str()); + } + } + + int propIndex = getPropertyIndexInternal(p); + DataObjectImpl* d = getDataObjectImpl(propIndex); + if (d == 0) { + // There is no list yet, so we need to create an + // empty data object to hold the list + DataFactory* df = getDataFactory(); + d = new DataObjectImpl(df, df->getType(Type::SDOTypeNamespaceURI,"DataObject")); + PropertyValues.push_back(rdo(propIndex, d)); + d->setContainer(this); + d->setApplicableChangeSummary(); + + DataObjectListImpl* list = new DataObjectListImpl(df,this, + propIndex,p.getType().getURI(),p.getType().getName()); + d->setList(list); + + } + return d->getList(); + } + + + + DataObjectList& DataObjectImpl::getList() + { + if (getTypeImpl().isFromList()) + { + return getList("values"); + } + return *listValue; + } + + DataObjectListImpl* DataObjectImpl::getListImpl() + { + if (getTypeImpl().isFromList()) + { + DataObjectList& dl = getList("values"); + return (DataObjectListImpl*)&dl; + } + return listValue; + } + + + + ///////////////////////////////////////////////////////////////////////////// + // Utilities + ///////////////////////////////////////////////////////////////////////////// + + + // get an index, or throw if the prop is not part of this DO + + unsigned int DataObjectImpl::getPropertyIndex(const Property& p) + { + const std::list<PropertyImpl*> props = getType().getPropertyListReference(); + + unsigned int i = 0; + for (std::list<PropertyImpl*>::const_iterator j = props.begin(); + j != props.end(); + j++, i++) + { + if (!strcmp((*j)->getName(), p.getName())) + { + return i; + } + } + if (getType().isOpenType()) + { + std::list<PropertyImpl>::iterator j; + int count = 0; + for (j = openProperties.begin() ; + j != openProperties.end() ; ++j) + { + if (!strcmp((*j).getName(),p.getName())) + { + return count+openBase; + } + count++; + } + } + string msg("Cannot find property:"); + msg += p.getName(); + SDO_THROW_EXCEPTION("getPropertyIndex", SDOPropertyNotFoundException, + msg.c_str()); + } + + /** + * This method is used internally to find the index of a + * property. If differs from the public getPropertyIndex method + * in that if the type of the containing object is open a new + * index is created. In the public version and error is thrown + */ + unsigned int DataObjectImpl::getPropertyIndexInternal(const Property& p) + { + unsigned int index; + + try + { + index = getPropertyIndex(p); + } + catch ( SDOPropertyNotFoundException e ) + { + // this could mean that this data object has an open + // type. getPropertyIndex fails in this case because it + // tries to access the index of the property + // and it doesn't exist because it hasn't been created yet. + // This new method is used where properties are being set + // based on existing property objects. This is likely to + // occur when a data object is being copied. In this case + // we want properties that are open to be copied also + // so we need to create the property and provide the index + if ( this->getType().isOpenType() ) + { + const Property *prop = NULL; + + // need to treat many valued properties specially + // because the property is a list rather than + // a single value + if ( p.isMany() ) + { + prop = defineList(p.getName()); + } + else + { + prop = defineProperty(p.getName(), p.getType()); + } + + index = getPropertyIndex(p); + } + else + { + throw e; + } + } + + return index; + } + + + const Property& DataObjectImpl::getProperty(unsigned int index) + { + PropertyImpl* pi = getPropertyImpl(index); + if (pi == 0) + { + string msg("Index out of range"); + SDO_THROW_EXCEPTION("getProperty", SDOIndexOutOfRangeException, + msg.c_str()); + } + return (Property&)*pi; + } + + /** + * See if the property currently exists + */ + + bool DataObjectImpl::hasProperty(const char* name) + { + return hasProperty(SDOString(name)); + } + + bool DataObjectImpl::hasProperty(const SDOString& name) + { + PropertyImpl* pi = getPropertyImpl(name); + if (pi == 0) return false; + return true; + } + + + PropertyImpl* DataObjectImpl::getPropertyImpl(unsigned int index) + { + // Cannot use getPropertyListReference because we will return a + // writeable PropertyImpl. + PropertyList props = getType().getProperties(); + if (index < props.size()) + { + return (PropertyImpl*)&props[index]; + } + + if (getType().isOpenType()) + { + if (index >= openBase && index - openBase < openProperties.size()) + { + std::list<PropertyImpl>::iterator j; + unsigned int val = 0; + j = openProperties.begin(); + while (val < index-openBase && j != openProperties.end()) + { + val++; + j++; + } + if (j != openProperties.end()) return &(*j); + } + } + return 0; + } + + + ////////////////////////////////////////////////////////////////////// + // TODO - this is rubbish, but gets us by until XPATH is done + // trip the path down to characters which I am going to + // recognise later (a-z, A-Z _ [ ] .) + ////////////////////////////////////////////////////////////////////// + + const char* DataObjectImpl::templateString = + " /abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=[]._#"; + + char* DataObjectImpl::stripPath(const char* path) + { + int pos = 0; + char* s = 0; + if (path == 0) return s; + + s = new char[strlen(path)+1]; + + for (unsigned int i=0;i < strlen(path); i++) + { + if (strchr(templateString,path[i]) != 0) { + s[pos++] = path[i]; + } + } + s[pos++] = 0; + return s; + } + + void DataObjectImpl::stripPath(const SDOString& path, SDOString& result) + { + result.erase(); + result.reserve(path.length()); + + size_t start = 0; + size_t position = path.find_first_not_of(templateString); + + while (position != string::npos) + { + result.append(path, start, (position - start)); + start = ++position; + position = path.find_first_not_of(templateString, position); + } + + result.append(path, start, string::npos); + + return; + } + + ////////////////////////////////////////////////////////////////////// + // Find a data object or return 0 if not found + ////////////////////////////////////////////////////////////////////// + DataObjectImpl* DataObjectImpl::findDataObject(const SDOString& token, long* index) + { + // name , name[int], name[x=y] name.int + size_t beginbrace = token.find('['); + size_t dot = token.find('.'); + size_t breaker = 0; + + if (dot != string::npos) + { + if (beginbrace != string::npos) + { + breaker = (beginbrace < dot) ? beginbrace : dot; + } + else + { + breaker = dot; + } + } + else + { + breaker = beginbrace; + } + + if (breaker == string::npos) + { + // its this object, and a property thereof + *index = -1; + const Property& p = getProperty(token); + return getDataObjectImpl(p); + } + + // We did find a breaker character. + const Property& p = getProperty(SDOString(token, 0, breaker)); + + breaker++; + + size_t endbrace = token.find(']'); + SDOString breakerStr = token.substr(breaker, (endbrace - breaker)); + // Search for the first occurence of an = sign starting at the previously + // identified "breaker" character and ending at the endbrace just found. We + // need to make a new SDOString to contain that substring. + + size_t eq = breakerStr.find('='); + + if (eq == string::npos) + { + // There is no "=" sign + unsigned int val = atoi(breakerStr.c_str()); + DataObjectList& list = getList(p); + + // The spec says that depts[1] is the first element, as is depts.0 + if (beginbrace != string::npos) val--; + + if (val >=0 && val < list.size()) + { + DataObject* dob = list[val]; + *index = val; + return (DataObjectImpl*)dob; + } + *index = -1; + return 0; + } + + // We did find an "=" sign. + SDOString PropertyName = breakerStr.substr(0, eq); + // breaker is now propname + eq++; + SDOString PropertyValue = breakerStr.substr(eq); + // eq is now propval + + DataObjectList& list = getList(p); + for (unsigned int li = 0 ; li < list.size() ; ++li) + { + // TODO comparison for double not ok + + const Type & t = list[li]->getType(); + const Property& p = list[li]->getProperty(PropertyName); + int ok = 0; + + switch (p.getTypeEnum()) + { + case Type::BooleanType: + { + // getCString will return "true" or "false" + if (!strcmp(PropertyValue.c_str(), list[li]->getCString(p))) ok = 1; + } + break; + + case Type::ByteType: + { + char cc = PropertyValue[0]; + // getByte return a char + if (cc == list[li]->getByte(p)) ok = 1; + } + break; + + case Type::CharacterType: + { + wchar_t wc = *((wchar_t*) PropertyValue.c_str()); + // wchar_t wc = (wchar_t)((wchar_t*)eq)[0]; + // TODO - this is not a very accesible way of storing a wchar + if (wc == list[li]->getCharacter(p)) ok = 1; + } + break; + + case Type::IntegerType: + { + long ic = atol(PropertyValue.c_str()); + if (ic == list[li]->getInteger(p)) ok = 1; + } + break; + + case Type::DateType: + { + long dc = atol(PropertyValue.c_str()); + if (dc == (long)(list[li]->getDate(p).getTime())) ok = 1; + } + break; + + case Type::DoubleType: + { + // TODO - double needs a bigger size than float + long double ldc = (long double)atof(PropertyValue.c_str()); + if (ldc == list[li]->getDouble(p)) ok = 1; + } + break; + + case Type::FloatType: + { + float fc = atof(PropertyValue.c_str()); + if (fc == list[li]->getFloat(p)) ok = 1; + } + break; + + case Type::LongType: + { +#if defined(WIN32) || defined (_WINDOWS) + int64_t lic = (int64_t)_atoi64(PropertyValue.c_str()); +#else + int64_t lic = (int64_t)strtoll(PropertyValue.c_str(), NULL, 0); +#endif + + if (lic == list[li]->getLong(p)) ok = 1; + } + break; + + case Type::ShortType: + { + short sic = atoi(PropertyValue.c_str()); + if (sic == list[li]->getShort(p)) ok = 1; + } + break; + + case Type::BytesType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + { + + if (!strcmp(PropertyValue.c_str(), list[li]->getCString(p))) ok = 1; + // try with quotes too + size_t firstquote = PropertyValue.find('"'); + size_t firstsingle = PropertyValue.find('\''); + + char searchchar = 0; + + if (firstsingle == string::npos) + { + if (firstquote != string::npos) + { + searchchar = '"'; + } + } + else + { + if (firstquote != string::npos && firstquote < firstsingle) + { + searchchar = '"'; + } + else + { + searchchar = '\''; + firstquote = firstsingle; + } + } + + if (searchchar != 0) + { + size_t ender = PropertyValue.find(searchchar, firstquote + 1); + if (ender != string::npos) + { + if (!strcmp(PropertyValue.substr(firstquote + 1, ender - (firstquote+1)).c_str(), list[li]->getCString(p))) + ok = 1; + } + } + } + break; + + case Type::DataObjectType: + break; + + default: + break; + } + + if (ok == 1) + { + DataObject* dob = list[li]; + *index = li; + return (DataObjectImpl*)dob; + } + + } + return 0; + } + + + ////////////////////////////////////////////////////////////////////// + // Find a data object and a property name within it. + ////////////////////////////////////////////////////////////////////// + SDOString DataObjectImpl::findPropertyContainer(const SDOString& path, DataObjectImpl** din) + { + // initially check for "#/" which indicates that we need to find the root object first + + if (path.length() <= 2) + { + if (path[0] == '#') + { + DataObjectImpl* root = this; + while (root->getContainerImpl() != 0) + { + root = root->getContainerImpl(); + } + *din = root; + return SDOString(); + } + } + + if (path[0] == '#' && path[1] == '/') + { + DataObjectImpl* root = this; + while (root->getContainerImpl() != 0) + { + root = root->getContainerImpl(); + } + return root->findPropertyContainer(SDOString(path, 2, string::npos), din); + } + + DataObjectImpl* d; + size_t slashPos = path.find('/'); // i is the subscript of the found character + SDOString remaining; + SDOString token; + + if (slashPos != string::npos) // If we found a slash character + { + if (slashPos > 0) // If there is something before the slash + { + token.assign(path, 0, slashPos); + } + if ((path.length() - slashPos) > 1) // If there is something after the slash + { + remaining.assign(path, slashPos + 1, string::npos); + } + } + else + { + remaining = path; + } + + if (token.empty()) + { + if (remaining == "..") + { + /* Its the container itself */ + *din = getContainerImpl(); + return SDOString(); + } + + /* Its this data object - property could be empty or + valid or invalid - user must check */ + *din = this; + return remaining; + } + + if (token == "..") { + /* Its derived from the container */ + d = getContainerImpl(); + /* carry on trying to find a property */ + if (d != 0) { + return d->findPropertyContainer(remaining, din); + } + /* Give up - no container */ + *din = 0; + return SDOString(); + } + + /* Try to find a property ....*/ + long l; + d = findDataObject(token, &l); + if (d != 0) { + return d->findPropertyContainer(remaining, din); + } + + /* Give up its not in the tree */ + *din = 0; + return SDOString(); + } + + + + + // Returns a read-only List of the Properties currently used in thIs DataObject. + // ThIs list will contain all of the properties in getType().getProperties() + // and any properties where isSet(property) is true. + // For example, properties resulting from the use of + // open or mixed XML content are present if allowed by the Type. + // The list does not contain duplicates. + // The order of the properties in the list begins with getType().getProperties() + // and the order of the remaining properties is determined by the implementation. + // The same list will be returned unless the DataObject is updated so that + // the contents of the list change + // @return the list of Properties currently used in thIs DataObject. + + PropertyList /* Property */ DataObjectImpl::getInstanceProperties() + { + std::vector<PropertyImpl*> theVec; + const std::list<PropertyImpl*> propList = getType().getPropertyListReference(); + + for (std::list<PropertyImpl*>::const_iterator i = propList.begin(); + i != propList.end(); + i++) + { + theVec.push_back((*i)); + } + std::list<PropertyImpl>::iterator j; + for (j = openProperties.begin() ; + j != openProperties.end() ; ++j) + { + theVec.push_back(&(*j)); + } + return PropertyList(theVec); + } + + void DataObjectImpl::setInstancePropertyType(unsigned int index, + const Type* t) + { + if (index >= openBase && index - openBase < openProperties.size()) + { + std::list<PropertyImpl>::iterator j; + unsigned int count = openBase; + for (j = openProperties.begin() ; + j != openProperties.end() ; ++j) + { + if (count == index) + { + openProperties.insert(j, + PropertyImpl(getType(), + (*j).getName(), + (TypeImpl&)*t, + (*j).isMany(), + (*j).isReadOnly(), + (*j).isContainment())); + + DataFactory* df = factory; + ((DataFactoryImpl*)df)->addOpenProperty( + PropertyImpl(getType(), + (*j).getName(), + (TypeImpl&)*t, + (*j).isMany(), + (*j).isReadOnly(), + (*j).isContainment())); + + openProperties.erase(j); + + return; + } + count++; + } + } + return; + } + + // Returns the Sequence for thIs DataObject. + // When Type.isSequencedType() == true, + // the Sequence of a DataObject corresponds to the + // XML elements representing the values of its properties. + // Updates through DataObject and the Lists or Sequences returned + // from DataObject operate on the same data. + // When Type.isSequencedType() == false, null is returned. + // @return the <code>Sequence</code> or null. + + SequenceImpl* DataObjectImpl::getSequenceImpl() + { + + return sequence; + } + + SequencePtr DataObjectImpl::getSequence() + { + return (SequencePtr)sequence; + } + + SequencePtr DataObjectImpl::getSequence(const char* path) + { + return getSequence(SDOString(path)); + } + + SequencePtr DataObjectImpl::getSequence(const SDOString& path) + { + DataObject* d = (DataObject*)getDataObject(path); + if (d) return d->getSequence(); + return 0; + } + + SequencePtr DataObjectImpl::getSequence(unsigned int propertyIndex) + { + DataObject* d = (DataObject*)getDataObject(propertyIndex); + if (d) return d->getSequence(); + return 0; + } + + SequencePtr DataObjectImpl::getSequence(const Property& property) + { + DataObject* d = (DataObject*)getDataObject(property); + if (d) return d->getSequence(); + return 0; + } + + + + ChangeSummaryPtr DataObjectImpl::getChangeSummary(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + return(getChangeSummary(SDOString())); + } + else + { + return(getChangeSummary(SDOString(path))); + } + } + + ChangeSummaryPtr DataObjectImpl::getChangeSummary(const SDOString& path) + { + DataObjectImpl* d = getDataObjectImpl(path); + return d->getChangeSummary(); + } + + ChangeSummaryPtr DataObjectImpl::getChangeSummary(unsigned int propIndex) + { + DataObjectImpl* d = getDataObjectImpl(propIndex); + return d->getChangeSummary(); + } + + ChangeSummaryPtr DataObjectImpl::getChangeSummary(const Property& prop) + { + DataObjectImpl* d = getDataObjectImpl(prop); + return d->getChangeSummary(); + + } + + ChangeSummaryPtr DataObjectImpl::getChangeSummary() + { + if (getType().isChangeSummaryType()) + { + return (ChangeSummaryPtr)localCS; + } + // The changesummaryobject MUST be a change summary type + // but as an additional check against looping, I will use + // a redundent getSummary() method. + // TODO - remove this. + if (changesummaryobject != 0) return + (ChangeSummaryPtr)(changesummaryobject->getSummary()); + return 0; + } + + + ChangeSummaryImpl* DataObjectImpl::getChangeSummaryImpl() + { + if (getType().isChangeSummaryType()) + { + return localCS; + } + // The changesummaryobject MUST be a change summary type + // but as an additional check against looping, I will use + // a redundent getSummary() method. + // TODO - remove this. + if (changesummaryobject != 0) return changesummaryobject->getSummary(); + return 0; + } + + ChangeSummaryImpl* DataObjectImpl::getSummary() + { + return localCS; + } + + // sets a property of either this object or an object reachable from it, + // as identified by the specified path, + // to the specified value. + // @param path the path to a valid object and property. + // @param value the new value for the property. + + void DataObjectImpl::setDataObject(const char* path, DataObjectPtr value) + { + setDataObject(SDOString(path), value, true); + } + + void DataObjectImpl::setDataObject(const char* path, DataObjectPtr value, bool updateSequence) + { + setDataObject(SDOString(path), value, updateSequence); + } + + void DataObjectImpl::setDataObject(const SDOString& path, + DataObjectPtr value) + { + setDataObject(path, value, false); + } + + void DataObjectImpl::setDataObject(const SDOString& path, + DataObjectPtr value, + bool updateSequence) + { + DataObjectImpl* d; + + SDOString prop = findPropertyContainer(path, &d); + if (d != 0) + { + if (!prop.empty()) { + const PropertyImpl* p = d->getPropertyImpl(prop); + if ((p == 0) && (d->getType().isOpenType())) + { + if (value != 0) + { + p = d->defineDataObject(prop, value->getType()); + } + } + if (p != 0) + { + ASSERT_SETTABLE(p, DataObject); + if (p->isMany()) + { + DataObjectList& dol = d->getList((Property&)*p); + long idx; + DataObjectImpl* dx = d->findDataObject(prop,&idx); + // fix this. This is the only place the 2nd parm to findDataObject + // is used. Need a better way to do this + unsigned int index = (unsigned int) idx; + if (index >= 0) + { + if(index < dol.size()) + { + dol.setDataObject(index, value); + } + else + { + dol.append(value); + } + return; + } + string msg("Set of data object on many valued item"); + msg += path; + SDO_THROW_EXCEPTION("setDataObject", + SDOUnsupportedOperationException, + msg.c_str()); + } + else + { + d->setDataObject((Property&) *p, value, updateSequence); + return; + } + } + } + } + + string msg("Path not valid:"); + msg += path; + SDO_THROW_EXCEPTION("setDataObject", SDOPathNotFoundException, + msg.c_str()); + } + + void DataObjectImpl::validateIndex(unsigned int index) + { + const std::list<PropertyImpl*> pl = getType().getPropertyListReference(); + + if (index >= pl.size()) { + + // open type support + if (getType().isOpenType()) + { + if (index < openBase + openProperties.size()) + { + return; + } + } + + string msg("Index of property out of range:"); + msg += index; + SDO_THROW_EXCEPTION("Index Validation", SDOIndexOutOfRangeException, + msg.c_str()); + } + } + + + void DataObjectImpl::checkFactory(DataObjectPtr dob, + unsigned int propertyIndex) + { + + DataObjectImpl* d = (DataObjectImpl*)(DataObject*)dob; + + if (d->getDataFactory() == getDataFactory()) return; + + if (d->getContainer() != 0) + { + string msg("Insertion of object from another factory is only allowed if the parent is null: "); + const Type& t = d->getType(); + msg += t.getURI(); + msg += "#"; + msg += t.getName(); + msg += " into property "; + msg += getProperty(propertyIndex).getName(); + msg += " of "; + msg += getType().getURI(); + msg += "#"; + msg += getType().getName(); + SDO_THROW_EXCEPTION("checkFactory", SDOInvalidConversionException, + msg.c_str()); + } + + } + + + void DataObjectImpl::checkType( const Property& prop, + const Type& objectType) + { + const Type& propType = prop.getType(); + if (propType.equals(objectType)) return; + + DataFactory* df = (DataFactory*)factory; + + const TypeImpl* ti = ((DataFactoryImpl*)df)->findTypeImpl + (objectType.getURI(),objectType.getName()); + if (ti != 0) + { + do + { + ti = (const TypeImpl*)ti->getBaseType(); + if (ti == 0) break; + if (propType.equals(*ti)) return; + } while (ti != 0); + + // allow types of any substitutes + const PropertyImpl* pi = + getPropertyImpl(getPropertyIndex(prop)); + if (pi != 0) + { + unsigned int subcount = pi->getSubstitutionCount(); + for (unsigned int i=0;i<subcount;i++) + { + const Type* tsub = pi->getSubstitutionType(i); + if (tsub != 0 && tsub->equals(objectType)) return; + } + } + } + + // no match.. + string msg("Insertion of object of incompatible type "); + msg += objectType.getURI(); + msg += "#"; + msg += objectType.getName(); + msg += " into property of type "; + msg += propType.getURI(); + msg += "#"; + msg += propType.getName(); + SDO_THROW_EXCEPTION("TypeCheck", SDOInvalidConversionException, + msg.c_str()); + } + + void DataObjectImpl::setDataObject(unsigned int propertyIndex, DataObjectPtr value) + { + setDataObject(getProperty(propertyIndex), value, true); + } + + void DataObjectImpl::setDataObject(unsigned int propertyIndex, DataObjectPtr value, bool updateSequence) + { + setDataObject(getProperty(propertyIndex), value, updateSequence); + } + + void DataObjectImpl::setDataObject(const Property& prop, DataObjectPtr value) + { + setDataObject(prop, value, false); + } + +void DataObjectImpl::setDataObject(const Property& prop, + DataObjectPtr value, + bool updateSequence) +{ + unsigned int propertyIndex = getPropertyIndexInternal(prop); + + if (value != 0) + { + checkFactory(value, propertyIndex); + checkType(prop, value->getType()); + } + + validateIndex(propertyIndex); + + if (prop.isReference() && (value != 0)) + { + // just need to make sure that the object is already part of our tree. + DataObjectImpl* r1 = this; + while (r1->getContainerImpl() != 0) + { + r1 = r1->getContainerImpl(); + } + DataObjectImpl* r2 = (DataObjectImpl*) (DataObject*) value; + while (r2->getContainerImpl() != 0) + { + r2 = r2->getContainerImpl(); + } + if (r1 != r2) + { + string msg("Set of a reference to an object outside the graph"); + SDO_THROW_EXCEPTION("setDataObject", + SDOUnsupportedOperationException, + msg.c_str()); + } + } + + if ((prop.isMany())) + { + string msg("Set operation on a many valued property:"); + msg += prop.getName(); + SDO_THROW_EXCEPTION("setDataObject", + SDOUnsupportedOperationException, + msg.c_str()); + } + + ASSERT_WRITABLE(prop, setDataObject); + + if (value == 0) + { + // The new data object value is actually a null pointer. + PropertyValueMap::iterator j; + // Scan the property value map looking for this property. + for (j = PropertyValues.begin(); j != PropertyValues.end(); ++j) + { + if ((*j).first == propertyIndex) + { + if (prop.isReference()) + { + ((*j).second)->unsetReference(this, prop); + } + else + { + // log both deletion and change - change is not + // automatically recorded by deletion. + ((*j).second)->logDeletion(); + } + logChange(prop); + (*j).second = RefCountingPointer<DataObjectImpl>(0); + // We have just changed the value of this property, therefore + // if this is a sequenced data object, then we must update the + // sequence so that the new setting appears at the end (and + // the existing entry is removed). + if ((getType().isSequencedType()) && updateSequence) + { + SequenceImpl* mySequence = getSequenceImpl(); + mySequence->removeAll(prop); + mySequence->push(prop, 0); + } + + return; + } + } + // The property does not currently have a value. + logChange(prop); + PropertyValues.push_back(rdo(propertyIndex, (DataObjectImpl*) 0)); + // If this is a sequenced data object then update the + // sequence. We already know that a) the property was not previously + // set so it can't be in the sequence currently and b) it is not a + // multi-valued property. + if ((getType().isSequencedType()) && updateSequence) + { + getSequenceImpl()->push(prop, 0); + } + return; + } + + DataObject* dob = value; + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == propertyIndex) + { + if (prop.isReference()) + { + ((*i).second)->unsetReference(this, prop); + } + else + { + // log both deletion and change - change is not + // automatically recorded by deletion. + ((*i).second)->logDeletion(); + } + logChange(prop); + + (*i).second = RefCountingPointer<DataObjectImpl>((DataObjectImpl*) dob); + + if (prop.isReference()) + { + ((DataObjectImpl*) dob)->setReference(this, prop); + } + else + { + logCreation((*i).second, this, prop); + } + return; + } + } + if (prop.isReference()) + { + ((DataObjectImpl*)dob)->setReference(this, prop); + } + else + { + ((DataObjectImpl*)dob)->setContainer(this); + ((DataObjectImpl*)dob)->setApplicableChangeSummary(); + // log creation before putting into property values. + // also log change - not done by logCreation + logCreation((DataObjectImpl*)dob, this, prop); + } + + logChange(prop); + + PropertyValues.push_back(rdo(propertyIndex, (DataObjectImpl*) dob)); + // If this is a sequenced data object then update the + // sequence. We already know that a) the property is not + // in the sequence currently and b) it is not a + // multi-valued property. + if ((getType().isSequencedType()) && updateSequence) + { + getSequenceImpl()->push(prop, 0); + } + + return; +} + + bool DataObjectImpl::isValid(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + return(isValid(SDOString())); + } + else + { + return(isValid(SDOString(path))); + } + + } + + bool DataObjectImpl::isValid(const SDOString& path) + { + DataObjectImpl* d; + SDOString prop = findPropertyContainer(path, &d); + if (d != 0) { + if (!prop.empty()) { + const Property& p = d->getProperty(prop); + return d->isValid(p); + } + } + string msg("Invalid path:"); + msg += path; + SDO_THROW_EXCEPTION("isSet" ,SDOPathNotFoundException, + msg.c_str()); + } + + // Returns whether a property of either this object or an object reachable + // from it, as identified by the specified path, + // is considered to be set. + // @param path the path to a valid Object* and property. + + bool DataObjectImpl::isSet(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + return(isSet(SDOString())); + } + else + { + return(isSet(SDOString(path))); + } + } + + bool DataObjectImpl::isSet(const SDOString& path) + { + DataObjectImpl* d; + SDOString prop = findPropertyContainer(path, &d); + if (d != 0) { + if (!prop.empty()) { + const Property& p = d->getProperty(prop); + return d->isSet(p); + } + } + string msg("Invalid path:"); + msg += path; + SDO_THROW_EXCEPTION("isSet" ,SDOPathNotFoundException, + msg.c_str()); + } + + bool DataObjectImpl::isValid(unsigned int propertyIndex) + { + return isValid(getProperty(propertyIndex)); + } + + bool DataObjectImpl::isValid(const Property& p) + { + if (p.isDefaulted()) return true; + if (isSet(p))return true; + return false; + } + + bool DataObjectImpl::isSet(unsigned int propertyIndex) + { + return isSet(getProperty(propertyIndex), propertyIndex); + } + + bool DataObjectImpl::isSet(const Property& property) + { + return isSet(property, getPropertyIndex(property)); + } + + bool DataObjectImpl::isSet(const Property& prop, unsigned int propertyIndex) + { + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == propertyIndex) { + if (prop.isMany()) + { + DataObjectImpl* dol = (*i).second; + if (dol != 0 && dol->getList().size() == 0) + { + return false; + } + } + return true; + } + } + return false; + } + + + // unSets a property of either this Object or an Object reachable from it, + // as identified by the specified path. + // @param path the path to a valid Object and property. + // @see #unSet(Property) + + void DataObjectImpl::unset(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + unset(SDOString()); + } + else + { + unset(SDOString(path)); + } + } + + void DataObjectImpl::unset(const SDOString& path) + { + DataObjectImpl* d; + SDOString prop = findPropertyContainer(path, &d); + if (d != 0) + { + if (!prop.empty()) + { + const Property& p = d->getProperty(prop); + ASSERT_WRITABLE(p, unset); + if (p.isMany()) + { + SDOString subscript; + size_t beginbrace = prop.find('['); + if (beginbrace != string::npos) + { + size_t endbrace = prop.find(']', ++beginbrace); + if (endbrace != string::npos) { + subscript = + prop.substr(beginbrace, (endbrace - beginbrace)); + } + unsigned int i = atoi(subscript.c_str()); + if (i > 0) { + i--; + DataObjectList& li = d->getList(p); + li.remove(i); + } + return; + } + size_t firstdot = prop.find('.'); + if (firstdot != string::npos) { + subscript = prop.substr(++firstdot); + unsigned int i = atoi(subscript.c_str()); + DataObjectList& li = d->getList(p); + li.remove(i); + return; + } + } + d->unset(p); + return; + } + } + + string msg("Invalid path:"); + msg += path; + SDO_THROW_EXCEPTION("unset", + SDOPathNotFoundException, + msg.c_str()); + } + + void DataObjectImpl::unset(unsigned int propertyIndex) + { + unset(getProperty(propertyIndex)); + } + + void DataObjectImpl::unset(const Property& p) + { + ASSERT_WRITABLE(p, unset) + + PropertyValueMap::iterator i; + unsigned int index = getPropertyIndex(p); + + if (getType().isSequencedType()) + { + Sequence* sq = getSequence(); + sq->removeAll(p); + } + + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == index) { + DataObjectImplPtr dol = (*i).second; + if (p.getType().isDataType()) + { + dol->clearReferences(); + logChange(index); + if (p.isMany()) { + DataObjectList& dl = dol->getList(); + while (dl.size() > 0) + { + RefCountingPointer<DataObject> dli = dl.remove(0); + } + } + else + { + PropertyValues.erase(i); + } + } + else { + // if its a reference, we dont want to delete anything + if (!p.isReference()) + { + if (dol) { + dol->clearReferences(); + if (p.isMany()) { + DataObjectList& dl = dol->getList(); + while (dl.size() > 0) + { + if (p.getType().isDataObjectType()) + { + DataObject* dob = dl[0]; + ((DataObjectImpl*)dob)->logDeletion(); + } + // the remove will record a change + // remove will also clear the container. + RefCountingPointer<DataObject> dli = dl.remove(0); + } + } + else + { + PropertyValues.erase(i); + dol->logDeletion(); + logChange(index); + } + } + else + { + logChange(index); + PropertyValues.erase(i); + } + } + else { + logChange(index); + PropertyValues.erase(i); + } + } + if (getType().isOpenType() && index >= openBase) + { + if (p.isMany()) + { + PropertyValues.erase(i); + } + undefineProperty(index); + } + return; + } + } + return; + } + + + + // Returns the value of a DataObject property identified by + // the specified path. + // @param path the path to a valid object and property. + // @return the DataObject value of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::getDataObject(const char* path) + { + return getDataObject(SDOString(path)); + } + + RefCountingPointer<DataObject> DataObjectImpl::getDataObject(const SDOString& path) + { + DataObjectImpl* ptr = getDataObjectImpl(path); + return RefCountingPointer<DataObject> ((DataObject*)ptr); + } + + DataObjectImpl* DataObjectImpl::getDataObjectImpl(const SDOString& path) + { + + DataObjectImpl* d = 0; + SDOString prop = findPropertyContainer(path, &d); + if (d != 0) + { + if (!prop.empty()) + { + if (prop.find_first_of("[.") != string::npos) + { + /* Its a multi-valued property */ + long l; + DataObjectImpl* theob = d->findDataObject(prop, &l); + if (theob == 0) + { + string msg("Get DataObject - index out of range:"); + msg += path; + SDO_THROW_EXCEPTION("getDataObject", + SDOIndexOutOfRangeException, + msg.c_str()); + } + return theob; + } + else + { + if (prop.length() == 0) + { + return d; + } + const Property& p = d->getProperty(prop); + return d->getDataObjectImpl(p); + } + } + else + { + return d; + } + } + + string msg("Invalid path:"); + msg += path; + SDO_THROW_EXCEPTION("getDataObject", + SDOPathNotFoundException, + msg.c_str()); + } + + RefCountingPointer<DataObject> DataObjectImpl::getDataObject(unsigned int propertyIndex) + { + if ((getProperty(propertyIndex).isMany())) + { + string msg("get operation on a many valued property:"); + msg += getProperty(propertyIndex).getName(); + SDO_THROW_EXCEPTION("getDataObject", + SDOUnsupportedOperationException, + msg.c_str()); + } + DataObjectImpl* ptr = getDataObjectImpl(propertyIndex); + + return RefCountingPointer<DataObject>((DataObject*)ptr); + } + + DataObjectImpl* DataObjectImpl::getDataObjectImpl(unsigned int propertyIndex) + { + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == propertyIndex) + { + DataObject* dob = (*i).second; + if ((dob == 0) || ((DataObjectImpl*) dob)->isNull()) + { + return 0; + } + return (DataObjectImpl*) dob; + } + } + return 0; + } + + + RefCountingPointer<DataObject> DataObjectImpl::getDataObject(const Property& property) + { + DataObjectImpl* ptr = getDataObjectImpl(property); + return RefCountingPointer<DataObject>((DataObject*) ptr); + } + + DataObjectImpl* DataObjectImpl::getDataObjectImpl(const Property& property) + { + return getDataObjectImpl(getPropertyIndex(property)); + } + + + + // Returns a new DataObject contained by this Object using the specified property, + // which must be a containment property. + // The type of the created Object is the declared type of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::createDataObject(const SDOString& propertyName) + { + // Throws runtime exception for type or property not found + + const Property& p = getProperty(propertyName); + return createDataObject(p); + } + + // Returns a new DataObject contained by this Object using the specified property, + // which must be a containment property. + // The type of the created Object is the declared type of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::createDataObject(const char* propertyName) + { + // Can propertyName really be a null pointer? + if (propertyName == 0) + { + return(createDataObject(SDOString())); + } + else + { + return(createDataObject(SDOString(propertyName))); + } + } + + // Returns a new DataObject contained by this Object using the specified property, + // which must be a containment property. + // The type of the created Object is the declared type of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::createDataObject(unsigned int propertyIndex) + { + const Property& p = getProperty(propertyIndex); + return createDataObject(p); + } + + // Returns a new DataObject contained by this Object using the specified property, + // which must be a containment property. + // The type of the created Object is the declared type of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::createDataObject(const Property& property) + { + const Type& tp = property.getType(); + return createDataObject(property,tp.getURI(), tp.getName()); + } + + + // Returns a new DataObject contained by this Object using the specified property, + // which must be a containment property. + // The type of the created Object is the declared type of the specified property. + + RefCountingPointer<DataObject> DataObjectImpl::createDataObject(const Property& property, const char* namespaceURI, + const char* typeName) + { + if (!property.isContainment()) + { + string msg("Create data object on non-containment property:"); + msg += property.getName(); + SDO_THROW_EXCEPTION("createDataObject", SDOUnsupportedOperationException, + msg.c_str()); + } + + DataFactory* df = getDataFactory(); + if (property.isMany()) { + /* add to the list */ + RefCountingPointer<DataObject> ptr = df->create(namespaceURI, typeName); + DataObject* dob = ptr; + ((DataObjectImpl*)dob)->setContainer(this); + ((DataObjectImpl*)dob)->setApplicableChangeSummary(); + + // log creation before adding to list - the change must record the old state + // of the list + logCreation(((DataObjectImpl*)dob), this, property); + //logChange(property); + + DataObjectImpl* theDO = getDataObjectImpl(property); + if ( theDO == 0) { /* No value set yet */ + unsigned int ind = getPropertyIndex(property); + RefCountingPointer<DataObject> listptr = + df->create(Type::SDOTypeNamespaceURI,"DataObject"); + + DataObject* doptr = listptr; + + PropertyValues.push_back(rdo(ind, (DataObjectImpl*) doptr)); + + ((DataObjectImpl*)doptr)->setContainer(this); + ((DataObjectImpl*)doptr)->setApplicableChangeSummary(); + + DataObjectListImpl* list = new DataObjectListImpl(df, + this, ind, namespaceURI,typeName); + + ((DataObjectImpl*)doptr)->setList(list); + // the append will log a change to the property. + list->append(ptr); + + // now done by list append + //if (getType().isSequencedType()) + //{ + // SequenceImpl* sq = getSequenceImpl(); + // sq->push(property,0); + //} + } + else + { + DataObjectList& list = theDO->getList(); + // the append will log a change to the property, and update the + // sequence + list.append(ptr); + //if (getType().isSequencedType()) + //{ + // SequenceImpl* sq = getSequenceImpl(); + // sq->push(property,list.size()-1); + //} + + } + return ptr; + + } + else { + unset(property); + DataObjectImpl* ditem = + new DataObjectImpl(df, df->getType(namespaceURI, typeName)); + ditem->setContainer(this); + ditem->setApplicableChangeSummary(); + + // log both creation and change - creations no longer log + // changes automatically. + + logCreation(ditem, this, property); + logChange(property); + + PropertyValues.push_back(rdo(getPropertyIndex(property), ditem)); + + if (getType().isSequencedType()) + { + SequenceImpl* sq = getSequenceImpl(); + sq->push(property,0); + } + return RefCountingPointer<DataObject>((DataObject*)ditem); + } + return 0; + } + + void DataObjectImpl::setList( DataObjectList* theList) + { + listValue = (DataObjectListImpl*)theList; + } + + + bool DataObjectImpl::remove(DataObjectImpl* indol) + { + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + const Property& prop = getProperty((*i).first); + if (prop.isMany()) + { + DataObjectList& dol = ((*i).second)->getList(); + for (unsigned int j=0;j< dol.size(); j++) + { + if (dol[j] == indol) + { + indol->logDeletion(); + logChange(prop); + indol->setContainer(0); + dol.remove(j); + return true; + } + } + } + DataObjectImpl* tmp = (*i).second; + if (tmp == indol) { + indol->logDeletion(); + logChange(prop); + indol->setContainer(0); + PropertyValues.erase(i); + return true; + } + } + return false; + } + + // remove this Object from its container and dont unSet all its properties. + + void DataObjectImpl::detach() + { + // remove this data object from its tree + clearReferences(); + if (container == 0) return; + container->remove(this); + return ; + } + + void DataObjectImpl::clear() + { + // clear this objects state + PropertyValueMap::iterator i = PropertyValues.begin(); + + while (i != PropertyValues.end()) + { + unset((*i).first); + i = PropertyValues.begin(); + } + return ; + } + + // Returns the containing Object + // of 0 if there is no container. + + RefCountingPointer<DataObject> DataObjectImpl::getContainer() + { + DataObject* dob = (DataObject*)container; + return RefCountingPointer<DataObject> (dob); + } + + DataObjectImpl* DataObjectImpl::getContainerImpl() + { + return container; + } + + void DataObjectImpl::setContainer(DataObjectImpl* d) + { + container = d; + } + + const Property* DataObjectImpl::findInProperties(DataObject* ob) + { + PropertyValueMap::iterator i; + for (i = PropertyValues.begin() ;i != PropertyValues.end() ; ++i) + { + if (getProperty((*i).first).isReference()) continue; + if (getProperty((*i).first).isMany()) + { + DataObjectList& dl = ((*i).second)->getList(); + for (unsigned int j = 0 ; j < dl.size(); j++) + { + if (dl[j] == ob) + { + return &(getProperty((*i).first)); + } + } + } + else + { + if ((*i).second == ob) + { + return &(getProperty((*i).first)); + } + } + } + return 0; // this can happen if the object has been detached + + //string msg("Object cannot find its containing property"); + //SDO_THROW_EXCEPTION("FindInProperties" ,SDOPropertyNotFoundException, + // msg.c_str()); + } + + // Return the Property of the data Object containing this data Object + // or 0 if there is no container. + + const Property& DataObjectImpl::getContainmentProperty() + { + if (container != 0) { + const Property* p = container->findInProperties(this); + if (p != 0)return *p; + } + SDO_THROW_EXCEPTION("getContainmentProperty" ,SDOPropertyNotFoundException, + "Object cannot find its containment property"); + } + + + // Returns the data Object's type. + // The type defines the properties available for reflective access. + + const Type& DataObjectImpl::getType() + { + return (const Type&)(*ObjectType); + } + + const Type::Types DataObjectImpl::getTypeEnum() + { + return ObjectType->getTypeEnum(); + } + + const TypeImpl& DataObjectImpl::getTypeImpl() + { + return (const TypeImpl&)*ObjectType; + } + + + // open type support + + const Property& DataObjectImpl::getProperty(const char* prop) + { + return getProperty(SDOString(prop)); + } + + const Property& DataObjectImpl::getProperty(const SDOString& prop) + { + PropertyImpl* pi = getPropertyImpl(prop); + if (pi == 0) + { + string msg("Cannot find property:"); + msg += prop; + SDO_THROW_EXCEPTION("getProperty", SDOPropertyNotFoundException, + msg.c_str()); + + } + return (Property&)*pi; + } + + PropertyImpl* DataObjectImpl::getPropertyImpl(const SDOString& prop) + { + PropertyImpl* pi = getTypeImpl().getPropertyImpl(prop); + if (pi != 0) return pi; + + if (getType().isOpenType()) + { + std::list<PropertyImpl>::iterator j; + for (j=openProperties.begin(); + j != openProperties.end(); ++j) + { + if (!strcmp((*j).getName(), prop.c_str())) + { + return (PropertyImpl*)&(*j); + } + } + } + return 0; + } + + DataFactory* DataObjectImpl::getDataFactory() + { + return factory; + } + + void DataObjectImpl::setDataFactory(DataFactory* df) + { + ObjectType = (TypeImpl*)&(df->getType(ObjectType->getURI(), + ObjectType->getName())); + factory = df; + } + + /////////////////////////////////////////////////////////////////////////// + // These finally are the setters/getters for primitives given + // that the data object is a primitive type. + /////////////////////////////////////////////////////////////////////////// + + + bool DataObjectImpl::getBoolean() + { + return getTypeImpl().convertToBoolean(sdoValue); + } + + char DataObjectImpl::getByte() + { + return getTypeImpl().convertToByte(sdoValue); + } + + wchar_t DataObjectImpl::getCharacter() + { + return getTypeImpl().convertToCharacter(sdoValue); + } + + long DataObjectImpl::getInteger() + { + return getTypeImpl().convertToInteger(sdoValue); + } + + long double DataObjectImpl::getDouble() + { + return getTypeImpl().convertToDouble(sdoValue); + } + + float DataObjectImpl::getFloat() + { + return getTypeImpl().convertToFloat(sdoValue); + } + + int64_t DataObjectImpl::getLong() + { + return getTypeImpl().convertToLong(sdoValue); + } + + short DataObjectImpl::getShort() + { + return getTypeImpl().convertToShort(sdoValue); + } + + unsigned int DataObjectImpl::getString(wchar_t* outptr, unsigned int max) + { + return getTypeImpl().convertToString(sdoValue, outptr, max); + } + + unsigned int DataObjectImpl::getBytes( char* outptr, unsigned int max) + { + return getTypeImpl().convertToBytes(sdoValue, outptr, max); + } + + const char* DataObjectImpl::getCString() + { + return getTypeImpl().convertToCString(sdoValue); + } + + const SDODate DataObjectImpl::getDate() + { + return getTypeImpl().convertToDate(sdoValue); + } + + DataObjectImpl* DataObjectImpl::getDataObject() + { + // If the sdoValue is unset, then there is no primitive value. + // If doValue is non-null then that is the data object value. + switch (getTypeImpl().getTypeEnum()) + { + case Type::OtherTypes: + case Type::DataObjectType: + return doValue; + + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::BytesType: + case Type::UriType: + default: + { + string msg("Cannot get Data Object from object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::getDataObject", + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return 0; + } + + void DataObjectImpl::setBoolean(bool invalue) + { + switch(getTypeEnum()) + { + + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::LongType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::DoubleType: + case Type::FloatType: + case Type::DateType: + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Boolean on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("setBoolean" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + + void DataObjectImpl::setByte(char invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Byte on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setByte" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + + void DataObjectImpl::setCharacter(wchar_t invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Character on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setCharacter" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setString(const wchar_t* invalue, unsigned int len) + { + switch (getTypeEnum()) + { + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::UriType: + case Type::StringType: + case Type::BytesType: + case Type::BooleanType: + case Type::CharacterType: + case Type::ByteType: + case Type::ShortType: + case Type::IntegerType: + case Type::LongType: + sdoValue = SDOValue(invalue, len); + break; + + case Type::DoubleType: + case Type::FloatType: + case Type::DateType: + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set String on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setString" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setBytes(const char* invalue, unsigned int len) + { + switch (getTypeEnum()) + { + case Type::BytesType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::UriType: + case Type::StringType: + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::LongType: + sdoValue = SDOValue(invalue, len); + break; + + case Type::DoubleType: + case Type::FloatType: + case Type::DateType: + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Bytes on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setBytes" , + SDOInvalidConversionException, + msg.c_str()); + return; + } + } + return; + } + + void DataObjectImpl::setInteger(long invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set LongLong on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setInteger" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + + void DataObjectImpl::setDouble(long double invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + sdoValue = SDOValue(invalue); + break; + + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Long Double on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("setDouble" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setFloat(float invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + sdoValue = SDOValue(invalue); + break; + + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Float on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("setFloat" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + break; + } + return; + } + + + void DataObjectImpl::setLong(int64_t invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set Long on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setLong" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + + void DataObjectImpl::setShort(short invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set short on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setShort" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setCString(const char* invalue) + { + setCString(SDOString(invalue)); + } + + void DataObjectImpl::setCString(const SDOString& invalue) + { + switch (getTypeEnum()) + { + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set CString on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setCString" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setDate(const SDODate invalue) + { + switch (getTypeEnum()) + { + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::UriType: + case Type::BytesType: + sdoValue = SDOValue(invalue); + break; + + case Type::OtherTypes: + case Type::BooleanType: + case Type::DataObjectType: + case Type::ChangeSummaryType: + default: + { + string msg("Cannot set LongLong on object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setDate" , + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setDataObject(DataObject* inValue) + { + // If the sdoValue is unset, then there is no primitive value. + // If doValue is non-null then that is the data object value. + switch (getTypeImpl().getTypeEnum()) + { + case Type::OtherTypes: + case Type::DataObjectType: + doValue = (DataObjectImpl*) inValue; + break; + + case Type::BooleanType: + case Type::ByteType: + case Type::CharacterType: + case Type::IntegerType: + case Type::ShortType: + case Type::DoubleType: + case Type::FloatType: + case Type::LongType: + case Type::DateType: + case Type::BigDecimalType: + case Type::BigIntegerType: + case Type::StringType: + case Type::BytesType: + case Type::UriType: + default: + { + string msg("Cannot set Data Object for object of type:"); + msg += getTypeImpl().getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setDataObject", + SDOInvalidConversionException, + msg.c_str()); + break; + } + } + return; + } + + void DataObjectImpl::setNull() + { + isnull = true; + } + + bool DataObjectImpl::isNull() + { + return isnull; + } + + void DataObjectImpl::unsetNull() + { + isnull = false; + } + + + DataObjectImpl::DataObjectImpl(const TypeImpl& t) : + ObjectType((TypeImpl*) &t), + container(0), + doValue(0), + isnull(false), + userdata((void*) 0xFFFFFFFF), + changesummaryobject(0) + { + // open type support + openBase = t.getPropertiesSize() ; + + if (t.isChangeSummaryType()) + { + localCS = new ChangeSummaryImpl(); + } + else + { + localCS = 0; + } + + if (getType().isSequencedType()) + { + sequence = new SequenceImpl(this); + } + else + { + sequence = 0; + } + } + + + DataObjectImpl::DataObjectImpl(DataFactory* df, const Type& t) : + ObjectType((TypeImpl*) &t), + factory(df), + container(0), + isnull(false), + userdata((void*) 0xFFFFFFFF), + changesummaryobject(0) + { + // open type support + openBase = ObjectType->getPropertiesSize() ; + + + if (ObjectType->isChangeSummaryType()) + { + localCS = new ChangeSummaryImpl(); + } + else + { + localCS = 0; + } + + if (getType().isSequencedType()) + { + sequence = new SequenceImpl(this); + } + else + { + sequence = 0; + } + } + + + DataObjectImpl::~DataObjectImpl() + { + // We do not want to log changes to our own deletion + // if this DO owns the ChangeSummary. Do not delete + // it here as contained DOs still have a reference to it. + + if (getTypeImpl().isChangeSummaryType()) + { + ChangeSummaryPtr c = getChangeSummary(); + if (c) { + if (c->isLogging()) + { + c->endLogging(); + } + } + } + + + clearReferences(); + PropertyValueMap::iterator i = PropertyValues.begin(); + while (i != PropertyValues.end()) + { + unsigned int pindx = (*i).first; + unset(pindx); + i = PropertyValues.begin(); + if (i != PropertyValues.end() && (*i).first == pindx) + { + // unset has not removed the item from the list - do it + // here instead + PropertyValues.erase(i); + i = PropertyValues.begin(); + } + } + + // Theory: A DO cant get here if its still attached to anything, + //so we dont need to detach.... + //detach(); + + if (sdoValue.isSet()) + { + sdoValue = SDOValue::unsetSDOValue; + } + + if (getType().isSequencedType()) + { + if (sequence != 0) delete sequence; + } + + + if (getTypeImpl().isChangeSummaryType() ) + { + if (getChangeSummary() != 0) + { + delete localCS; + localCS = 0; + } + } + } + + void DataObjectImpl::setApplicableChangeSummary() + { + changesummaryobject = 0; + if (getType().isChangeSummaryType()) + { + changesummaryobject = 0; + return; + } + else { + DataObjectImpl* dob = getContainerImpl(); + while (dob != 0) { + if (dob->getType().isChangeSummaryType()) + { + changesummaryobject = dob; + return; + } + dob = dob->getContainerImpl(); + } + } + + } + + void DataObjectImpl::logCreation(DataObjectImpl* dol, DataObjectImpl* cont, + const Property& theprop) + { + if (getChangeSummaryImpl() != 0 && getChangeSummaryImpl()->isLogging()) + { + getChangeSummaryImpl()->logCreation(dol,cont,theprop); + } + } + + void DataObjectImpl::logDeletion() + { + // Only log if ChangeSummary is inherited from container + + if (getChangeSummaryImpl() != 0 && getChangeSummaryImpl()->isLogging() && !getType().isChangeSummaryType()) + { + DataObjectImpl* cont = getContainerImpl(); + if (cont != 0) // log if there is a container. If there is not, then + // this can only be the object with the CS, so logging + // would not make sense. + { + const Property* p = cont->findInProperties(this); + if ( p != 0) // if the object is not in the properties, then its been + // detached, and has already been logged as deleted + { + getChangeSummaryImpl()->logDeletion(this,cont,*p, + objectToXPath(), true); + } + } + } + } + + void DataObjectImpl::logChange(const Property& prop) + { + if (getChangeSummaryImpl() != 0 && getChangeSummaryImpl()->isLogging()) + { + getChangeSummaryImpl()->logChange(this,prop); + } + } + + void DataObjectImpl::logChange(unsigned int propIndex) + { + if (getChangeSummaryImpl() != 0 && getChangeSummaryImpl()->isLogging()) + { + getChangeSummaryImpl()->logChange(this,getProperty(propIndex)); + } + } + // reference support + + void DataObjectImpl::setReference(DataObject* dol, const Property& prop) + { + LOGINFO_1(INFO,"ChangeSummary:Setting a reference to %s",prop.getName()); + + refs.push_back(new Reference(dol,prop)); + } + void DataObjectImpl::unsetReference(DataObject* dol, const Property& prop) + { + LOGINFO_1(INFO,"ChangeSummary:Unsetting a reference to %s",prop.getName()); + + for (unsigned int i=0;i< refs.size();i++) + { + if (refs[i]->getDataObject() == dol) + { + if (!strcmp(refs[i]->getProperty().getName(), + prop.getName())) + { + delete refs[i]; + refs.erase(refs.begin() + i); + } + } + } + } + + + void DataObjectImpl::clearReferences() + { + for (unsigned int i=0;i<refs.size();i++) + { + // Note - no loop as the referer must be of type reference + refs[i]->getDataObject()->unset(refs[i]->getProperty()); + delete refs[i]; + } + refs.clear(); + } + + const char* DataObjectImpl::objectToXPath() + { + asXPathBuffer = ""; + + DataObjectImpl* dob = getContainerImpl(); + DataObject*thisob = this; + while (dob != 0){ + const Property& p = thisob->getContainmentProperty(); + if (asXPathBuffer != "") + { + asXPathBuffer = "/" + asXPathBuffer; + } + + if (p.isMany()) { + DataObjectList& dol = dob->getList(p); + for (unsigned int i=0;i<dol.size();i++) + { + if (dol[i] == thisob) + { + char index[64]; + sprintf(index,"%d",i); + asXPathBuffer = index + asXPathBuffer; + asXPathBuffer = "." + asXPathBuffer; + break; + } + } + } + asXPathBuffer = p.getName() + asXPathBuffer; + + thisob = dob; + dob = dob->getContainerImpl(); + } + + asXPathBuffer = "#/" + asXPathBuffer; + + return asXPathBuffer.c_str(); +/* + char* temp1; + char* temp2; + + if (asXPathBuffer == 0) + { + asXPathBuffer = new char[2]; + sprintf(asXPathBuffer,"#"); + } + + DataObjectImpl* dob = getContainerImpl(); + DataObject*thisob = this; + while (dob != 0){ + const Property& p = thisob->getContainmentProperty(); + const char* name = p.getName(); + temp1 = new char[strlen(name) + 34]; + temp1[0] = 0; + + + if (p.isMany()) { + DataObjectList& dol = dob->getList(p); + for (int i=0;i<dol.size();i++) + { + if (dol[i] == thisob) + { + sprintf(temp1,"#/%s.%d",name,i); + break; + } + } + } + else { + sprintf(temp1,"#/%s",name); + } + if (asXPathBuffer != 0) { + temp2 = new char[strlen(asXPathBuffer) + strlen(temp1) + 1]; + sprintf(temp2,"%s%s", temp1, asXPathBuffer+1 ); + delete asXPathBuffer; + } + else { + temp2 = new char[strlen(temp1) + 1]; + sprintf(temp2,"%s", temp1); + } + delete temp1; + asXPathBuffer = temp2; + thisob = dob; + dob = dob->getContainerImpl(); + } + return asXPathBuffer; */ + } + + // user data support... + void* DataObjectImpl::getUserData(const char* path) + { + // Can path really be a null pointer? + if (path == 0) + { + return(getUserData(SDOString())); + } + else + { + return(getUserData(SDOString(path))); + } + } + + void* DataObjectImpl::getUserData(const SDOString& path) + { + DataObjectImpl *d; + void* v = 0; + SDOString spath; + SDOString prop; + try { + DataObjectImpl::stripPath(path, spath); + prop = findPropertyContainer(spath, &d); + if (d != 0) + { + if (!prop.empty()) + { + const Property& p = d->getProperty(prop); + if (p.getType().isDataType()) return 0; + if (p.isMany()) + { + DataObjectImpl* d2 = d->getDataObjectImpl(prop); + if (d2) v = d2->getUserData(); + return v; + } + v = d->getUserData(p); + return v; + } + return d->getUserData(); + } + return 0; + } + catch (SDORuntimeException e) + { + return 0; + } + } + + void* DataObjectImpl::getUserData(unsigned int propertyIndex) + { + if ((getProperty(propertyIndex).isMany())) + { + return 0; + } + if ((getProperty(propertyIndex).getType().isDataType())) + { + return 0; + } + DataObjectImpl* ptr = getDataObjectImpl(propertyIndex); + if (ptr) return ptr->getUserData(); + return 0; + } + + void* DataObjectImpl::getUserData(const Property& property) + { + if (property.isMany()) + { + return 0; + } + if (property.getType().isDataType()) + { + return 0; + } + DataObjectImpl* ptr = getDataObjectImpl(property); + if (ptr) return ptr->getUserData(); + return 0; + } + + void* DataObjectImpl::getUserData() + { + return userdata; + } + + void DataObjectImpl::setUserData(const char* path, void* value) + { + // Can path really be a null pointer? + if (path == 0) + { + setUserData(SDOString(), value); + } + else + { + setUserData(SDOString(path), value); + } + } + + void DataObjectImpl::setUserData(const SDOString& path, void* value) + { + SDOString spath; + SDOString prop; + DataObjectImpl *d; + try { + DataObjectImpl::stripPath(path, spath); + prop = findPropertyContainer(spath, &d); + if (d != 0) + { + if (!prop.empty()) + { + const Property& p = d->getProperty(prop); + if (p.getType().isDataType()) + return; + if (p.isMany()) + { + DataObjectImpl* d2 = d->getDataObjectImpl(prop); + if (d2) d2->setUserData(value); + return; + } + d->setUserData(p, value); + return; + } + d->setUserData(value); + return; + } + } + catch (SDORuntimeException e) + { + return; + } + + } + + void DataObjectImpl::setUserData(unsigned int propertyIndex, void* value) + { + if ((getProperty(propertyIndex).isMany())) + { + return; + } + if ((getProperty(propertyIndex).getType().isDataType())) + { + return; + } + DataObjectImpl* ptr = getDataObjectImpl(propertyIndex); + if (ptr) ptr->setUserData(value); + return; + } + + void DataObjectImpl::setUserData(const Property& property, void* value) + { + if (property.isMany()) + { + return; + } + if (property.getType().isDataType()) + { + return; + } + DataObjectImpl* ptr = getDataObjectImpl(property); + if (ptr) ptr->setUserData(value); + return; + } + + void DataObjectImpl::setUserData(void* value) + { + userdata = value; + } + + std::ostream& DataObjectImpl::printSelf(std::ostream &os) + { + SDOUtils::printDataObject(os, this); + return os; + } + + // +++ + // Extra methods to support SDOValue as an internal mechanism that + // simplifies dealing with the many interchangeable primitive data types. + + // set methods. + + void DataObjectImpl::setSDOValue(const SDOString& path, + const SDOValue& sval, + const SDOString& dataType) + { + DataObjectImpl *d = 0; + + SDOString spath; + SDOString prop; + try + { + DataObjectImpl::stripPath(path, spath); + prop = findPropertyContainer(spath, &d); + + if (d != 0) + { + if (prop.length() == 0) + { + d->setSDOValue(sval); + } + else + { + const PropertyImpl* p = d->getPropertyImpl(prop); + if ((p == 0) && (d->getType().isOpenType())) + { + // p = d->defineBytes(prop); + p = d->defineSDOValue(prop, sval); + } + + if (p == 0) + { + string msg("DataObjectImpl::setSDOValue - path not found: "); + SDO_THROW_EXCEPTION("setter", + SDOPathNotFoundException, + msg.c_str()); + } + + if (p->isReadOnly()) + { + SDOString stringBuffer = p->getName(); + stringBuffer += " is read-only."; + SDO_THROW_EXCEPTION("DataObjectImpl::setSDOValue", + SDOUnsupportedOperationException, + stringBuffer.c_str()); + } + + if ((p->isMany()) || (p->getTypeImpl()->isFromList())) + { + long l; + DataObjectList& dol = d->getList((Property&) *p); + DataObjectImpl* doi = d->findDataObject(prop, &l); + if (doi != 0) + { + doi->setSDOValue(sval); + } + else + { + dol.append(sval); + } + } + else + { + d->setSDOValue((Property&)*p, sval, dataType); + } + } + } + } + catch (SDORuntimeException e) + { + SDO_RETHROW_EXCEPTION("setSDOValue", e); + } + } + + void DataObjectImpl::setSDOValue(unsigned int propertyIndex, + const SDOValue& sval, + const SDOString& dataType) + { + setSDOValue(propertyIndex, sval, dataType, false); + } + + void DataObjectImpl::setSDOValue(unsigned int propertyIndex, + const SDOValue& sval, + const SDOString& dataType, + bool updateSequence) + { + validateIndex(propertyIndex); + + PropertyImpl *const p = getPropertyImpl(propertyIndex); + + if ((p->isMany()) || (p->getTypeImpl()->isFromList())) + { + string msg("Set value not available on many valued property: "); + msg += p->getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::setSDOValue", + SDOUnsupportedOperationException, + msg.c_str()); + } + + if (p->isReadOnly()) + { + SDOString stringBuffer = p->getName(); + stringBuffer += "is read-only."; + SDO_THROW_EXCEPTION("DataObjectImpl::setSDOValue", + SDOUnsupportedOperationException, + stringBuffer.c_str()); + } + + // PropertyValues is a std::list of rdo objects. + PropertyValueMap::iterator i; + for (i = PropertyValues.begin(); i != PropertyValues.end(); ++i) + { + if ((*i).first == propertyIndex) + { + logChange(propertyIndex); + (*i).second->unsetNull(); + (*i).second->setSDOValue(sval); + + // If this is a sequenced data object then update the sequence. We + // already know that a) the property is already set and b) it + // is not a multi-valued property. + if ((getType().isSequencedType()) && updateSequence) + { + SequenceImpl* mySequence = getSequenceImpl(); + mySequence->removeAll(getProperty(propertyIndex)); + mySequence->push(getProperty(propertyIndex), 0); + } + return; + } + } + + // No existing property has the given index. + DataFactory* df = getDataFactory(); + // It is tempting to use the raw data type from the SDOValue object to + // set the type of the created DataObjectImpl but we can't because the + // SDOValue specifies a C++ type while we need an SDO type. + DataObjectImpl* b = + new DataObjectImpl(df, df->getType(Type::SDOTypeNamespaceURI, dataType.c_str())); + b->setContainer(this); + b->setApplicableChangeSummary(); + logChange(propertyIndex); + PropertyValues.push_back(rdo(propertyIndex, b)); + b->setSDOValue(sval); + + // If this is a sequenced data object then update the sequence. We + // already know that a) the property is not already set and b) it + // is not a multi-valued property. + if ((getType().isSequencedType()) && updateSequence) + { + SequenceImpl* mySequence = getSequenceImpl(); + mySequence->removeAll(getProperty(propertyIndex)); + mySequence->push(getProperty(propertyIndex), 0); + } + + return; + } + + void DataObjectImpl::setSDOValue(const Property& property, + const SDOValue& sval, + const SDOString& dataType) + { + setSDOValue(getPropertyIndexInternal(property), sval, dataType); + } + + void DataObjectImpl::setSDOValue(const Property& property, + const SDOValue& sval, + const SDOString& dataType, + bool updateSequence) + { + setSDOValue(getPropertyIndexInternal(property), sval, dataType, updateSequence); + } + + void DataObjectImpl::setSDOValue(const SDOValue& invalue) + { + sdoValue = invalue; + return; + } + + // get methods + + const SDOValue& DataObjectImpl::getSDOValue(const SDOString& path, + PropertyImpl** propertyForDefault) + { + *propertyForDefault = 0; + + DataObjectImpl* d = 0; + SDOString spath; + SDOString prop; + try + { + DataObjectImpl::stripPath(path, spath); + // It is possible for findPropertyContainer to return a 0 which caues an accvio. + prop = findPropertyContainer(spath, &d); + if (d != 0) + { + if (prop.length() == 0) + { + return d->getSDOValue(propertyForDefault); + } + else + { + PropertyImpl* p = d->getPropertyImpl(prop); + if (p != 0) + { + if ((p->isMany()) || p->getTypeImpl()->isFromList()) + { + long l; + DataObjectImpl* doi = d->findDataObject(prop, &l); + if (doi != 0) + { + return doi->getSDOValue(propertyForDefault); + } + string msg("DataObjectImpl::getSDOValue - index out of range"); + msg += path; + SDO_THROW_EXCEPTION("getter", + SDOIndexOutOfRangeException, + msg.c_str()); + } + else + { + if (!d->isSet(*p)) + { + *propertyForDefault = p; + return SDOValue::unsetSDOValue; + } + return d->getSDOValue(*p, propertyForDefault); + } + } + } + } + string msg("Object not found"); + SDO_THROW_EXCEPTION("DataObjectImpl::getSDOValue", + SDOPathNotFoundException, + msg.c_str()); + } + catch (SDORuntimeException e) { + SDO_RETHROW_EXCEPTION("getSDOValue", e); + } + } + + const SDOValue& DataObjectImpl::getSDOValue(const unsigned int propertyIndex, + PropertyImpl** propertyForDefault) + { + *propertyForDefault = 0; + + validateIndex(propertyIndex); + + // Since validateIndex didn't throw an exception, the following call + // will not return a null pointer. + PropertyImpl* targetProperty = getPropertyImpl(propertyIndex); + if ((targetProperty->isMany()) || + targetProperty->getTypeImpl()->isFromList()) + { + string msg("Get value not available on many valued property:"); + msg += targetProperty->getName(); + SDO_THROW_EXCEPTION("DataObjectImpl::getSDOValue", + SDOUnsupportedOperationException, + msg.c_str()); + } + + DataObjectImpl* d = getDataObjectImpl(propertyIndex); + if (d != 0) + { + if (!d->isNull()) + { + return d->getSDOValue(propertyForDefault); + } + else + { + return SDOValue::nullSDOValue; + } + } + + // To get here, the property does not have a value, but there are still 2 + // cases to consider: + // 1. The property has never had a value. In this case, we return + // "unset" for the value of the property. + // 2. The property did have a value at one time but since then has + // been explicitly set to null, causing the value to be discarded. In + // that case return an explicit null. + + if (isSet(propertyIndex)) + { + return SDOValue::nullSDOValue; + } + + *propertyForDefault = targetProperty; + return SDOValue::unsetSDOValue; + + } + + const SDOValue& DataObjectImpl::getSDOValue(const Property& property, + PropertyImpl** propertyForDefault) + { + return getSDOValue(getPropertyIndex(property), propertyForDefault); + } + + const SDOValue& DataObjectImpl::getSDOValue(PropertyImpl** propertyForDefault) + { + if (sdoValue.isSet()) + { + *propertyForDefault = 0; + } + else + { + *propertyForDefault = (PropertyImpl*) &(getContainmentProperty()); + } + return sdoValue; + } + + // End of SDOValue methods + // --- + + // +++ + // setBoolean using SDOValue methods + + void DataObjectImpl::setBoolean(unsigned int propertyIndex, + bool value) + { + setSDOValue(propertyIndex, SDOValue(value), "Boolean"); + } + + void DataObjectImpl::setBoolean(const Property& property, bool value) + { + setBoolean(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setBoolean(const SDOString& path, + bool value) + { + setSDOValue(path, SDOValue(value), "Boolean"); + } + + // End of setBoolean using SDOValue methods + // --- + + // +++ + // getBoolean using SDOValue methods + + bool DataObjectImpl::getBoolean(const Property& property) + { + return getBoolean(getPropertyIndex(property)); + } + + bool DataObjectImpl::getBoolean(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getBooleanDefault(); + } + else + { + if (result.isNull()) + { + return false; + } + else + { + return result.getBoolean(); + } + } + } + + bool DataObjectImpl::getBoolean(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getBooleanDefault(); + } + else + { + if (result.isNull()) + { + return false; + } + else + { + return result.getBoolean(); + } + } + } + + // End of getBoolean using SDOValue methods + // --- + + // +++ + // setFloat using SDOValue methods + + void DataObjectImpl::setFloat(unsigned int propertyIndex, + float value) + { + setSDOValue(propertyIndex, SDOValue(value), "Float"); + } + + void DataObjectImpl::setFloat(const Property& property, float value) + { + setFloat(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setFloat(const SDOString& path, + float value) + { + setSDOValue(path, SDOValue(value), "Float"); + } + + // End of setFloat using SDOValue methods + // --- + + // +++ + // getFloat using SDOValue methods + + float DataObjectImpl::getFloat(const Property& property) + { + return getFloat(getPropertyIndex(property)); + } + + float DataObjectImpl::getFloat(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getFloatDefault(); + } + else + { + if (result.isNull()) + { + return 0.0F; // Default is 0 cast to return type + } + else + { + return result.getFloat(); + } + } + } + + float DataObjectImpl::getFloat(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getFloatDefault(); + } + else + { + if (result.isNull()) + { + return 0.0F; // Default is 0 cast to return type + } + else + { + return result.getFloat(); + } + } + } + + // End of getFloat using SDOValue methods + // --- + + // +++ + // setDouble using SDOValue methods + + void DataObjectImpl::setDouble(unsigned int propertyIndex, + long double value) + { + setSDOValue(propertyIndex, SDOValue(value), "Double"); + } + + void DataObjectImpl::setDouble(const Property& property, long double value) + { + setDouble(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setDouble(const SDOString& path, + long double value) + { + setSDOValue(path, SDOValue(value), "Double"); + } + + // End of setDouble using SDOValue methods + // --- + + // +++ + // getDouble using SDOValue methods + + long double DataObjectImpl::getDouble(const Property& property) + { + return getDouble(getPropertyIndex(property)); + } + + long double DataObjectImpl::getDouble(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getDoubleDefault(); + } + else + { + if (result.isNull()) + { + return 0.0; // Default is 0 cast to return type + } + else + { + return result.getDouble(); + } + } + } + + long double DataObjectImpl::getDouble(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getDoubleDefault(); + } + else + { + if (result.isNull()) + { + return 0.0; // Default is 0 cast to return type + } + else + { + return result.getDouble(); + } + } + } + + // End of getDouble using SDOValue methods + // --- + + // +++ + // setShort using SDOValue methods + + void DataObjectImpl::setShort(unsigned int propertyIndex, + short value) + { + setSDOValue(propertyIndex, SDOValue(value), "Short"); + } + + void DataObjectImpl::setShort(const Property& property, short value) + { + setShort(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setShort(const SDOString& path, + short value) + { + setSDOValue(path, SDOValue(value), "Short"); + } + + // End of setShort using SDOValue methods + // --- + + // +++ + // getShort using SDOValue methods + + short DataObjectImpl::getShort(const Property& property) + { + return getShort(getPropertyIndex(property)); + } + + short DataObjectImpl::getShort(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getShortDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getShort(); + } + } + } + + short DataObjectImpl::getShort(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getShortDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getShort(); + } + } + } + + // End of getShort using SDOValue methods + // --- + + // +++ + // setByte using SDOValue methods + + void DataObjectImpl::setByte(unsigned int propertyIndex, + char value) + { + setSDOValue(propertyIndex, SDOValue(value), "Byte"); + } + + void DataObjectImpl::setByte(const Property& property, char value) + { + setByte(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setByte(const SDOString& path, + char value) + { + setSDOValue(path, SDOValue(value), "Byte"); + } + + // End of setByte using SDOValue methods + // --- + + // +++ + // getByte using SDOValue methods + + char DataObjectImpl::getByte(const Property& property) + { + return getByte(getPropertyIndex(property)); + } + + char DataObjectImpl::getByte(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getByteDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getByte(); + } + } + } + + char DataObjectImpl::getByte(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getByteDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getByte(); + } + } + } + + // End of getByte using SDOValue methods + // --- + + // +++ + // setDate using SDOValue methods + + void DataObjectImpl::setDate(unsigned int propertyIndex, + const SDODate value) + { + setSDOValue(propertyIndex, SDOValue(value), "Date"); + } + + void DataObjectImpl::setDate(const Property& property, const SDODate value) + { + setDate(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setDate(const SDOString& path, + const SDODate value) + { + setSDOValue(path, SDOValue(value), "Date"); + } + + // End of setDouble using SDOValue methods + // --- + + // +++ + // getDate using SDOValue methods + + const SDODate DataObjectImpl::getDate(const Property& property) + { + return getDate(getPropertyIndex(property)); + } + + const SDODate DataObjectImpl::getDate(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getDateDefault(); + } + else + { + if (result.isNull()) + { + return SDODate(0); // Default is 0 cast to return type + } + else + { + return result.getDate(); + } + } + } + + const SDODate DataObjectImpl::getDate(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getDateDefault(); + } + else + { + if (result.isNull()) + { + return SDODate(0); // Default is 0 cast to return type + } + else + { + return result.getDate(); + } + } + } + + // End of getDouble using SDOValue methods + // --- + + // +++ + // setInteger using SDOValue methods + + void DataObjectImpl::setInteger(unsigned int propertyIndex, + long value) + { + setSDOValue(propertyIndex, SDOValue(value), "Integer"); + } + + void DataObjectImpl::setInteger(const Property& property, long value) + { + setInteger(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setInteger(const SDOString& path, + long value) + { + setSDOValue(path, SDOValue(value), "Integer"); + } + + // End of setInteger using SDOValue methods + // --- + + // +++ + // getInteger using SDOValue methods + + long DataObjectImpl::getInteger(const Property& property) + { + return getInteger(getPropertyIndex(property)); + } + + long DataObjectImpl::getInteger(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getIntegerDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getInteger(); + } + } + } + + long DataObjectImpl::getInteger(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getIntegerDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getInteger(); + } + } + } + + // End of getInteger using SDOValue methods + // --- + + // +++ + // setCString using SDOValue methods + + void DataObjectImpl::setCString(unsigned int propertyIndex, + const SDOString& value) + { + setSDOValue(propertyIndex, SDOValue(value), "String"); + } + + void DataObjectImpl::setCString(const Property& property, const SDOString& value) + { + setCString(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setCString(const SDOString& path, + const SDOString& value) + { + setSDOValue(path, SDOValue(value), "String"); + } + + // End of setCString using SDOValue methods + // --- + + // +++ + // getCString using SDOValue methods + + const char* DataObjectImpl::getCString(const Property& property) + { + return getCString(getPropertyIndex(property)); + } + + const char* DataObjectImpl::getCString(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getCStringDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getCString(); + } + } + } + + const char* DataObjectImpl::getCString(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getCStringDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getCString(); + } + } + } + + // End of getCString using SDOValue methods + // --- + + // +++ + // setCharacter using SDOValue methods + + void DataObjectImpl::setCharacter(unsigned int propertyIndex, + wchar_t value) + { + setSDOValue(propertyIndex, SDOValue(value), "Character"); + } + + void DataObjectImpl::setCharacter(const Property& property, wchar_t value) + { + setCharacter(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setCharacter(const SDOString& path, + wchar_t value) + { + setSDOValue(path, SDOValue(value), "Character"); + } + + // End of setByte using SDOValue methods + // --- + + // +++ + // getByte using SDOValue methods + + wchar_t DataObjectImpl::getCharacter(const Property& property) + { + return getCharacter(getPropertyIndex(property)); + } + + wchar_t DataObjectImpl::getCharacter(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getCharacterDefault(); + } + else + { + if (result.isNull()) + { + return (wchar_t) 0; // Default is 0 cast to return type + } + else + { + return result.getCharacter(); + } + } + } + + wchar_t DataObjectImpl::getCharacter(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getCharacterDefault(); + } + else + { + if (result.isNull()) + { + return (wchar_t) 0; // Default is 0 cast to return type + } + else + { + return result.getCharacter(); + } + } + } + + // End of getCharacter using SDOValue methods + // --- + + // +++ + // setLong using SDOValue methods + + void DataObjectImpl::setLong(unsigned int propertyIndex, + int64_t value) + { + setSDOValue(propertyIndex, SDOValue(value), "Long"); + } + + void DataObjectImpl::setLong(const Property& property, int64_t value) + { + setLong(getPropertyIndexInternal(property), value); + } + + void DataObjectImpl::setLong(const SDOString& path, + int64_t value) + { + setSDOValue(path, SDOValue(value), "Long"); + } + + // End of setLong using SDOValue methods + // --- + + // +++ + // getLong using SDOValue methods + + int64_t DataObjectImpl::getLong(const Property& property) + { + return getLong(getPropertyIndex(property)); + } + + int64_t DataObjectImpl::getLong(unsigned int propertyIndex) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getLongDefault(); + } + else + { + if (result.isNull()) + { + return 0L; // Default is 0 cast to return type + } + else + { + return result.getLong(); + } + } + } + + int64_t DataObjectImpl::getLong(const SDOString& path) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getLongDefault(); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getLong(); + } + } + } + + // End of getLong using SDOValue methods + // --- + + // The input value is a non-null terminated sequence of bytes. + void DataObjectImpl::setBytes(unsigned int propertyIndex, const char* value, unsigned int len) + { + setSDOValue(propertyIndex, SDOValue(value, len), "Bytes"); + } + + void DataObjectImpl::setString(unsigned int propertyIndex, const wchar_t* value, unsigned int len) + { + setSDOValue(propertyIndex, SDOValue(value, len), "String"); + } + + unsigned int DataObjectImpl::getBytes(unsigned int propertyIndex, char* valptr , unsigned int max) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getBytesDefault(valptr, max); + } + else + { + if (result.isNull()) + { + return 0; + } + else + { + return result.getBytes(valptr, max); + } + } + } + + unsigned int DataObjectImpl::getString(unsigned int propertyIndex, wchar_t* valptr , unsigned int max) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(propertyIndex, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getStringDefault(valptr, max); + } + else + { + if (result.isNull()) + { + return 0; + } + else + { + return result.getString(valptr, max); + } + } + } + + unsigned int DataObjectImpl::getString(const SDOString& path, wchar_t* valptr , unsigned int max) + { + + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getStringDefault(valptr, max); + } + else + { + if (result.isNull()) + { + return 0; + } + else + { + return result.getString(valptr, max); + } + } + } + + unsigned int DataObjectImpl::getBytes(const SDOString& path, char* valptr , unsigned int max) + { + PropertyImpl* propertyForDefault = 0; + const SDOValue& result = getSDOValue(path, &propertyForDefault); + + if (!result.isSet()) + { + return propertyForDefault->getBytesDefault(valptr, max); + } + else + { + if (result.isNull()) + { + return 0; // Default is 0 cast to return type + } + else + { + return result.getBytes(valptr, max); + } + } + } + + void DataObjectImpl::setString(const char* path, const wchar_t* value, unsigned int len) + { + setString(SDOString(path), value, len); + } + + void DataObjectImpl::setBytes(const char* path, const char* value, unsigned int len) + { + setBytes(SDOString(path), value, len); + } + + void DataObjectImpl::setString(const SDOString& path, const wchar_t* value, unsigned int len) + { + setSDOValue(path, SDOValue(value, len), "String"); + } + + + void DataObjectImpl::setBytes(const SDOString& path, const char* value, unsigned int len) + { + setSDOValue(path, SDOValue(value, len), "Bytes"); + } + + unsigned int DataObjectImpl::getString(const Property& property, wchar_t* val, unsigned int max) + { + return getString(getPropertyIndex(property), val, max); + } + + unsigned int DataObjectImpl::getBytes(const Property& property, char* val, unsigned int max) + { + return getBytes(getPropertyIndex(property), val, max); + } + + void DataObjectImpl::setString(const Property& property, const wchar_t* value, unsigned int len) + { + setString(getPropertyIndexInternal(property),value, len); + } + + void DataObjectImpl::setBytes(const Property& property, const char* value, unsigned int len) + { + setBytes(getPropertyIndexInternal(property),value, len); + } + +}; +}; |