| /************************************************************** |
| * |
| * 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 "ExternalViewLogger.hxx" |
| #include <iostream> |
| #include <boost/assert.hpp> |
| #include <stdio.h> |
| |
| #ifdef WNT |
| #define SNPRINTF(buffer, size, format, args) _snprintf(buffer, size, format, args) |
| #else |
| #define SNPRINTF(buffer, size, format, args) snprintf(buffer, size, format, args) |
| #endif |
| |
| using namespace std; |
| |
| namespace util |
| { |
| |
| NodeDescription::NodeDescription(const string& parent, const string& refersTo, const string& value, bool inUse) : |
| mParentNodeId(parent), |
| mRefersToNodeId(refersTo), |
| mNodeValue(value), |
| mInUse(inUse) |
| {} |
| |
| ExternalViewLoggerImpl::ExternalViewLoggerImpl(const string& fileName) : |
| mFileName(fileName), |
| mFile(fileName.c_str()) |
| { |
| if (!mFile) |
| throw "Cannot open file"; |
| } |
| |
| string ExternalViewLoggerImpl::getNewStyleName() |
| { |
| static int i = 0; |
| char buff[20]; |
| SNPRINTF(buff, sizeof(buff), "Style_%d", i++); |
| return string(buff); |
| } |
| |
| void ExternalViewLoggerImpl::beginTree() |
| { |
| mParentNodeStack.push(""); |
| } |
| |
| void ExternalViewLoggerImpl::dumpNodeContainer(const std::string& fileName) |
| { |
| std::ofstream file(fileName.c_str()); |
| NodeContainer_t::iterator iter = mNodeContainer.begin(); |
| NodeContainer_t::iterator iter_end = mNodeContainer.end(); |
| for (; iter != iter_end; ++iter) |
| { |
| file << iter->first << string(" ") << iter->second->mParentNodeId << string(" ") << iter->second->mRefersToNodeId << string(" ") << iter->second->mNodeValue << endl; |
| } |
| } |
| |
| void ExternalViewLoggerImpl::endTree() |
| { |
| //dumpNodeContainer(mFileName + string(".dmp")); |
| |
| mFile << "digraph {" << endl; |
| mFile << "Root [shape=box, color=grey];" << endl; |
| |
| while (!mParentNodeStack.empty()) |
| mParentNodeStack.pop(); |
| |
| mParentNodeStack.push("Root"); |
| |
| NodeContainer_t::iterator iter = mNodeContainer.begin(); |
| NodeContainer_t::iterator iter_end = mNodeContainer.end(); |
| for (; iter != iter_end; ++iter) |
| { |
| if (isUnreferencedLeaf(iter->first)) |
| { |
| string newStyleName = getNewStyleName(); |
| mFile << newStyleName << " [shape=box];" << endl; |
| mFile << mParentNodeStack.top() << " -> " << newStyleName << endl; |
| mParentNodeStack.push(newStyleName); |
| dumpTree(iter->first); |
| mParentNodeStack.pop(); |
| } |
| } |
| |
| mFile << "}" << endl; |
| } |
| |
| void ExternalViewLoggerImpl::beginNode(const std::string& nodeId, const std::string& value, const std::string& refersToNodeId, bool inUse) |
| { |
| mNodeContainer.insert( |
| NodeContainer_t::value_type(nodeId, |
| NodeDescription::Pointer_t(new NodeDescription(mParentNodeStack.top(), refersToNodeId, value, inUse)))); |
| mParentNodeStack.push(nodeId); |
| } |
| |
| void ExternalViewLoggerImpl::endNode(const std::string& nodeId) |
| { |
| mParentNodeStack.pop(); |
| } |
| |
| bool ExternalViewLoggerImpl::isLeaf(const std::string& nodeId) |
| { |
| bool isLeaf = true; |
| |
| NodeContainer_t::const_iterator iter = mNodeContainer.begin(); |
| NodeContainer_t::const_iterator iter_end = mNodeContainer.end(); |
| for (; iter != iter_end; ++iter) |
| { |
| if (iter->second->mParentNodeId == nodeId) |
| { |
| isLeaf = false; |
| break; |
| } |
| } |
| return isLeaf; |
| } |
| |
| bool ExternalViewLoggerImpl::isUnreferencedLeaf(const string& nodeId) |
| { |
| return isLeaf(nodeId) && !isReferenced(nodeId); |
| } |
| |
| bool ExternalViewLoggerImpl::isReferenced(const string& nodeId) |
| { |
| bool isReferenced = false; |
| |
| NodeContainer_t::const_iterator iter = mNodeContainer.begin(); |
| NodeContainer_t::const_iterator iter_end = mNodeContainer.end(); |
| for (; iter != iter_end; ++iter) |
| { |
| if (iter->second->mRefersToNodeId == nodeId) |
| { |
| isReferenced = true; |
| break; |
| } |
| } |
| return isReferenced; |
| } |
| |
| bool ExternalViewLoggerImpl::isReferingToOtherNode(const string& nodeId) |
| { |
| NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId); |
| BOOST_ASSERT(iter != mNodeContainer.end()); |
| return !iter->second->mRefersToNodeId.empty(); |
| } |
| |
| bool ExternalViewLoggerImpl::hasParent(const string& nodeId) |
| { |
| NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId); |
| BOOST_ASSERT(iter != mNodeContainer.end()); |
| return iter->second->mParentNodeId != "Root" && iter->second->mParentNodeId != ""; |
| } |
| |
| string ExternalViewLoggerImpl::getValue(const string& nodeId) |
| { |
| return mNodeContainer.find(nodeId)->second->mNodeValue; |
| } |
| |
| void ExternalViewLoggerImpl::dumpTree(const string& nodeId) |
| { |
| if (nodeId != "Root") |
| { |
| mFile << nodeId << " [label=\"(" << getValue(nodeId) << ")\",shape=box];" << endl; |
| mFile << mParentNodeStack.top() << " -> " << nodeId << ";" << endl; |
| if (isReferingToOtherNode(nodeId)) |
| { |
| mParentNodeStack.push(nodeId); |
| dumpTree(mNodeContainer.find(nodeId)->second->mRefersToNodeId); |
| mParentNodeStack.pop(); |
| } |
| } |
| |
| if (hasParent(nodeId)) |
| dumpTree(mNodeContainer.find(nodeId)->second->mParentNodeId); |
| } |
| |
| } // namespace util |
| |