blob: 71156937f5e6856cd0ff07a5a8c56745f34ac664 [file] [log] [blame]
/*
* 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 <activemq/commands/ActiveMQMapMessage.h>
#include <activemq/wireformat/openwire/marshal/PrimitiveTypesMarshaller.h>
#include <activemq/util/CMSExceptionSupport.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/io/ByteArrayInputStream.h>
#include <decaf/io/ByteArrayOutputStream.h>
#include <decaf/io/BufferedInputStream.h>
#include <decaf/io/DataInputStream.h>
#include <decaf/io/DataOutputStream.h>
#include <decaf/util/zip/DeflaterOutputStream.h>
#include <decaf/util/zip/InflaterInputStream.h>
using namespace std;
using namespace decaf;
using namespace decaf::io;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::util;
using namespace decaf::util::zip;
using namespace activemq;
using namespace activemq::util;
using namespace activemq::exceptions;
using namespace activemq::commands;
using namespace activemq::wireformat;
using namespace activemq::wireformat::openwire;
using namespace activemq::wireformat::openwire::marshal;
////////////////////////////////////////////////////////////////////////////////
const unsigned char ActiveMQMapMessage::ID_ACTIVEMQMAPMESSAGE = 25;
////////////////////////////////////////////////////////////////////////////////
ActiveMQMapMessage::ActiveMQMapMessage() : ActiveMQMessageTemplate<cms::MapMessage>(), map() {
}
////////////////////////////////////////////////////////////////////////////////
ActiveMQMapMessage::~ActiveMQMapMessage() throw() {
}
////////////////////////////////////////////////////////////////////////////////
unsigned char ActiveMQMapMessage::getDataStructureType() const {
return ActiveMQMapMessage::ID_ACTIVEMQMAPMESSAGE;
}
////////////////////////////////////////////////////////////////////////////////
ActiveMQMapMessage* ActiveMQMapMessage::cloneDataStructure() const {
ActiveMQMapMessage* message = new ActiveMQMapMessage();
message->copyDataStructure( this );
return message;
}
////////////////////////////////////////////////////////////////////////////////
cms::MapMessage* ActiveMQMapMessage::clone() const {
ActiveMQMapMessage* clone = this->cloneDataStructure();
clone->setReadOnlyBody(false);
clone->setReadOnlyProperties(false);
return dynamic_cast<cms::MapMessage*>(clone);
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::copyDataStructure(const DataStructure* src) {
ActiveMQMessageTemplate<cms::MapMessage>::copyDataStructure(src);
const ActiveMQMapMessage* srcMap = dynamic_cast<const ActiveMQMapMessage*>(src);
if (srcMap != NULL && srcMap->map.get() != NULL) {
this->map.reset(new util::PrimitiveMap(*srcMap->map));
}
}
////////////////////////////////////////////////////////////////////////////////
std::string ActiveMQMapMessage::toString() const {
return ActiveMQMessageTemplate<cms::MapMessage>::toString();
}
////////////////////////////////////////////////////////////////////////////////
bool ActiveMQMapMessage::equals(const DataStructure* value) const {
return ActiveMQMessageTemplate<cms::MapMessage>::equals(value);
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::clearBody() throw (cms::CMSException) {
ActiveMQMessageTemplate<cms::MapMessage>::clearBody();
this->getMap().clear();
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::beforeMarshal(WireFormat* wireFormat) {
try {
// Let the base class do its thing.
ActiveMQMessageTemplate<cms::MapMessage>::beforeMarshal(wireFormat);
if (map.get() != NULL && !map->isEmpty()) {
ByteArrayOutputStream* bytesOut = new ByteArrayOutputStream();
OutputStream* os = bytesOut;
if (this->connection != NULL && this->connection->isUseCompression()) {
this->compressed = true;
Deflater* deflator = new Deflater(this->connection->getCompressionLevel());
os = new DeflaterOutputStream(os, deflator, true, true);
}
DataOutputStream dataOut(os, true);
PrimitiveTypesMarshaller::marshalMap(map.get(), dataOut);
dataOut.close();
std::pair<unsigned char*, int> array = bytesOut->toByteArray();
this->setContent(std::vector<unsigned char>(array.first, array.first + array.second));
delete[] array.first;
} else {
clearBody();
}
}
AMQ_CATCH_RETHROW(decaf::io::IOException)
AMQ_CATCH_EXCEPTION_CONVERT(Exception, decaf::io::IOException)
AMQ_CATCHALL_THROW(decaf::io::IOException)
}
////////////////////////////////////////////////////////////////////////////////
PrimitiveMap& ActiveMQMapMessage::getMap() {
try {
this->checkMapIsUnmarshalled();
return *map;
}
AMQ_CATCH_RETHROW(NullPointerException)
AMQ_CATCH_EXCEPTION_CONVERT(Exception, NullPointerException)
AMQ_CATCHALL_THROW(NullPointerException)
}
////////////////////////////////////////////////////////////////////////////////
const PrimitiveMap& ActiveMQMapMessage::getMap() const {
try {
this->checkMapIsUnmarshalled();
return *map;
}
AMQ_CATCH_RETHROW(NullPointerException)
AMQ_CATCH_EXCEPTION_CONVERT(Exception, NullPointerException)
AMQ_CATCHALL_THROW(NullPointerException)
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::checkMapIsUnmarshalled() const {
try {
if (map.get() == NULL && !getContent().empty()) {
InputStream* is = new ByteArrayInputStream(getContent());
if (isCompressed()) {
is = new InflaterInputStream(is, true);
is = new BufferedInputStream(is, true);
}
DataInputStream dataIn(is, true);
map.reset(PrimitiveTypesMarshaller::unmarshalMap(dataIn));
if (map.get() == NULL) {
throw NullPointerException(
__FILE__, __LINE__,
"ActiveMQMapMessage::getMap() - All attempts to create a map have failed.");
}
} else if (map.get() == NULL) {
map.reset(new PrimitiveMap());
}
}
AMQ_CATCH_RETHROW(NullPointerException)
AMQ_CATCH_EXCEPTION_CONVERT(Exception, NullPointerException)
AMQ_CATCHALL_THROW(NullPointerException)
}
////////////////////////////////////////////////////////////////////////////////
bool ActiveMQMapMessage::isEmpty() const {
try {
return getMap().isEmpty();
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> ActiveMQMapMessage::getMapNames() const {
try {
return getMap().keySet().toArray();
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
bool ActiveMQMapMessage::itemExists(const std::string& name) const {
try {
return getMap().containsKey(name);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
cms::Message::ValueType ActiveMQMapMessage::getValueType(const std::string& key) const {
try {
util::PrimitiveValueNode::PrimitiveType type = this->getMap().getValueType(key);
switch (type) {
case util::PrimitiveValueNode::NULL_TYPE:
return cms::Message::NULL_TYPE;
case util::PrimitiveValueNode::BOOLEAN_TYPE:
return cms::Message::BOOLEAN_TYPE;
case util::PrimitiveValueNode::BYTE_TYPE:
return cms::Message::BYTE_TYPE;
case util::PrimitiveValueNode::CHAR_TYPE:
return cms::Message::CHAR_TYPE;
case util::PrimitiveValueNode::SHORT_TYPE:
return cms::Message::SHORT_TYPE;
case util::PrimitiveValueNode::INTEGER_TYPE:
return cms::Message::INTEGER_TYPE;
case util::PrimitiveValueNode::LONG_TYPE:
return cms::Message::LONG_TYPE;
case util::PrimitiveValueNode::DOUBLE_TYPE:
return cms::Message::DOUBLE_TYPE;
case util::PrimitiveValueNode::FLOAT_TYPE:
return cms::Message::FLOAT_TYPE;
case util::PrimitiveValueNode::STRING_TYPE:
case util::PrimitiveValueNode::BIG_STRING_TYPE:
return cms::Message::STRING_TYPE;
case util::PrimitiveValueNode::BYTE_ARRAY_TYPE:
return cms::Message::BYTE_ARRAY_TYPE;
default:
break;
}
return cms::Message::UNKNOWN_TYPE;
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
bool ActiveMQMapMessage::getBoolean(const std::string& name) const {
try {
return getMap().getBool(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setBoolean(const std::string& name, bool value) {
failIfReadOnlyBody();
try {
getMap().setBool(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
unsigned char ActiveMQMapMessage::getByte(const std::string& name) const {
try {
return getMap().getByte(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setByte(const std::string& name, unsigned char value) {
failIfReadOnlyBody();
try {
getMap().setByte(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
std::vector<unsigned char> ActiveMQMapMessage::getBytes(const std::string& name) const {
try {
return getMap().getByteArray(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setBytes(const std::string& name, const std::vector<unsigned char>& value) {
failIfReadOnlyBody();
try {
getMap().setByteArray(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
char ActiveMQMapMessage::getChar(const std::string& name) const {
try {
return getMap().getChar(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setChar(const std::string& name, char value) {
failIfReadOnlyBody();
try {
getMap().setChar(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
double ActiveMQMapMessage::getDouble(const std::string& name) const {
try {
return getMap().getDouble(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setDouble(const std::string& name, double value) {
failIfReadOnlyBody();
try {
getMap().setDouble(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
float ActiveMQMapMessage::getFloat(const std::string& name) const {
try {
return getMap().getFloat(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setFloat(const std::string& name, float value) {
failIfReadOnlyBody();
try {
getMap().setFloat(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
int ActiveMQMapMessage::getInt(const std::string& name) const {
try {
return getMap().getInt(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setInt(const std::string& name, int value) {
failIfReadOnlyBody();
try {
getMap().setInt(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
long long ActiveMQMapMessage::getLong(const std::string& name) const {
try {
return getMap().getLong(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setLong(const std::string& name, long long value) {
failIfReadOnlyBody();
try {
getMap().setLong(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
short ActiveMQMapMessage::getShort(const std::string& name) const {
try {
return getMap().getShort(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setShort(const std::string& name, short value) {
failIfReadOnlyBody();
try {
getMap().setShort(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
std::string ActiveMQMapMessage::getString(const std::string& name) const {
try {
return getMap().getString(name);
} catch (UnsupportedOperationException& ex) {
throw CMSExceptionSupport::createMessageFormatException(ex);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQMapMessage::setString(const std::string& name, const std::string& value) {
failIfReadOnlyBody();
try {
getMap().setString(name, value);
}
AMQ_CATCH_ALL_THROW_CMSEXCEPTION()
}