/* * 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. */ #include "qmf/engine/ObjectImpl.h" #include "qmf/engine/ValueImpl.h" #include "qmf/engine/BrokerProxyImpl.h" #include using namespace std; using namespace qmf::engine; using namespace qpid::sys; using qpid::framing::Buffer; ObjectImpl::ObjectImpl(const SchemaObjectClass* type) : objectClass(type), broker(0), createTime(uint64_t(Duration(EPOCH, now()))), destroyTime(0), lastUpdatedTime(createTime) { int propCount = objectClass->getPropertyCount(); int statCount = objectClass->getStatisticCount(); int idx; for (idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); properties[prop->getName()] = ValuePtr(new Value(prop->getType())); } for (idx = 0; idx < statCount; idx++) { const SchemaStatistic* stat = objectClass->getStatistic(idx); statistics[stat->getName()] = ValuePtr(new Value(stat->getType())); } } ObjectImpl::ObjectImpl(const SchemaObjectClass* type, BrokerProxyImpl* b, Buffer& buffer, bool prop, bool stat, bool managed) : objectClass(type), broker(b), createTime(0), destroyTime(0), lastUpdatedTime(0) { int idx; if (managed) { lastUpdatedTime = buffer.getLongLong(); createTime = buffer.getLongLong(); destroyTime = buffer.getLongLong(); objectId.reset(ObjectIdImpl::factory(buffer)); } if (prop) { int propCount = objectClass->getPropertyCount(); set excludes; parsePresenceMasks(buffer, excludes); for (idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); if (excludes.count(prop->getName()) != 0) { properties[prop->getName()] = ValuePtr(new Value(prop->getType())); } else { Value* pval = ValueImpl::factory(prop->getType(), buffer); properties[prop->getName()] = ValuePtr(pval); } } } if (stat) { int statCount = objectClass->getStatisticCount(); for (idx = 0; idx < statCount; idx++) { const SchemaStatistic* stat = objectClass->getStatistic(idx); Value* sval = ValueImpl::factory(stat->getType(), buffer); statistics[stat->getName()] = ValuePtr(sval); } } } Object* ObjectImpl::factory(const SchemaObjectClass* type, BrokerProxyImpl* b, Buffer& buffer, bool prop, bool stat, bool managed) { ObjectImpl* impl(new ObjectImpl(type, b, buffer, prop, stat, managed)); return new Object(impl); } ObjectImpl::~ObjectImpl() { } void ObjectImpl::destroy() { destroyTime = uint64_t(Duration(EPOCH, now())); // TODO - flag deletion } Value* ObjectImpl::getValue(const string& key) const { map::const_iterator iter; iter = properties.find(key); if (iter != properties.end()) return iter->second.get(); iter = statistics.find(key); if (iter != statistics.end()) return iter->second.get(); return 0; } void ObjectImpl::invokeMethod(const string& methodName, const Value* inArgs, void* context) const { if (broker != 0 && objectId.get() != 0) broker->sendMethodRequest(objectId.get(), objectClass, methodName, inArgs, context); } void ObjectImpl::merge(const Object& from) { for (map::const_iterator piter = from.impl->properties.begin(); piter != from.impl->properties.end(); piter++) properties[piter->first] = piter->second; for (map::const_iterator siter = from.impl->statistics.begin(); siter != from.impl->statistics.end(); siter++) statistics[siter->first] = siter->second; } void ObjectImpl::parsePresenceMasks(Buffer& buffer, set& excludeList) { int propCount = objectClass->getPropertyCount(); excludeList.clear(); uint8_t bit = 0; uint8_t mask = 0; for (int idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); if (prop->isOptional()) { if (bit == 0) { mask = buffer.getOctet(); bit = 1; } if ((mask & bit) == 0) excludeList.insert(string(prop->getName())); if (bit == 0x80) bit = 0; else bit = bit << 1; } } } void ObjectImpl::encodeSchemaKey(qpid::framing::Buffer& buffer) const { buffer.putShortString(objectClass->getClassKey()->getPackageName()); buffer.putShortString(objectClass->getClassKey()->getClassName()); buffer.putBin128(const_cast(objectClass->getClassKey()->getHash())); } void ObjectImpl::encodeManagedObjectData(qpid::framing::Buffer& buffer) const { buffer.putLongLong(lastUpdatedTime); buffer.putLongLong(createTime); buffer.putLongLong(destroyTime); objectId->impl->encode(buffer); } void ObjectImpl::encodeProperties(qpid::framing::Buffer& buffer) const { int propCount = objectClass->getPropertyCount(); uint8_t bit = 0; uint8_t mask = 0; ValuePtr value; for (int idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); if (prop->isOptional()) { value = properties[prop->getName()]; if (bit == 0) bit = 1; if (!value->isNull()) mask |= bit; if (bit == 0x80) { buffer.putOctet(mask); bit = 0; mask = 0; } else bit = bit << 1; } } if (bit != 0) { buffer.putOctet(mask); } for (int idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); value = properties[prop->getName()]; if (!prop->isOptional() || !value->isNull()) { value->impl->encode(buffer); } } } void ObjectImpl::encodeStatistics(qpid::framing::Buffer& buffer) const { int statCount = objectClass->getStatisticCount(); for (int idx = 0; idx < statCount; idx++) { const SchemaStatistic* stat = objectClass->getStatistic(idx); ValuePtr value = statistics[stat->getName()]; value->impl->encode(buffer); } } //================================================================== // Wrappers //================================================================== Object::Object(const SchemaObjectClass* type) : impl(new ObjectImpl(type)) {} Object::Object(ObjectImpl* i) : impl(i) {} Object::Object(const Object& from) : impl(new ObjectImpl(*(from.impl))) {} Object::~Object() { delete impl; } void Object::destroy() { impl->destroy(); } const ObjectId* Object::getObjectId() const { return impl->getObjectId(); } void Object::setObjectId(ObjectId* oid) { impl->setObjectId(oid); } const SchemaObjectClass* Object::getClass() const { return impl->getClass(); } Value* Object::getValue(const char* key) const { return impl->getValue(key); } void Object::invokeMethod(const char* m, const Value* a, void* c) const { impl->invokeMethod(m, a, c); } bool Object::isDeleted() const { return impl->isDeleted(); } void Object::merge(const Object& from) { impl->merge(from); }