xref: /AOO41X/main/writerfilter/qa/cppunittests/odiapi/ExternalViewLogger.cxx (revision b4a4f18ca4dc88f864a44914739541fc69bd3f91)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "ExternalViewLogger.hxx"
25 #include <iostream>
26 #include <boost/assert.hpp>
27 #include <stdio.h>
28 
29 #ifdef WNT
30     #define SNPRINTF(buffer, size, format, args) _snprintf(buffer, size, format, args)
31 #else
32     #define SNPRINTF(buffer, size, format, args) snprintf(buffer, size, format, args)
33 #endif
34 
35 using namespace std;
36 
37 namespace util
38 {
39 
NodeDescription(const string & parent,const string & refersTo,const string & value,bool inUse)40   NodeDescription::NodeDescription(const string& parent, const string& refersTo, const string& value, bool inUse) :
41     mParentNodeId(parent),
42     mRefersToNodeId(refersTo),
43     mNodeValue(value),
44     mInUse(inUse)
45   {}
46 
ExternalViewLoggerImpl(const string & fileName)47   ExternalViewLoggerImpl::ExternalViewLoggerImpl(const string& fileName) :
48     mFileName(fileName),
49     mFile(fileName.c_str())
50   {
51     if (!mFile)
52       throw "Cannot open file";
53   }
54 
getNewStyleName()55   string ExternalViewLoggerImpl::getNewStyleName()
56   {
57     static int i = 0;
58     char buff[20];
59     SNPRINTF(buff, sizeof(buff), "Style_%d", i++);
60     return string(buff);
61   }
62 
beginTree()63   void ExternalViewLoggerImpl::beginTree()
64   {
65     mParentNodeStack.push("");
66   }
67 
dumpNodeContainer(const std::string & fileName)68   void ExternalViewLoggerImpl::dumpNodeContainer(const std::string& fileName)
69   {
70     std::ofstream file(fileName.c_str());
71     NodeContainer_t::iterator iter = mNodeContainer.begin();
72     NodeContainer_t::iterator iter_end = mNodeContainer.end();
73     for (; iter != iter_end; ++iter)
74     {
75         file << iter->first << string(" ") << iter->second->mParentNodeId << string(" ") << iter->second->mRefersToNodeId << string(" ") << iter->second->mNodeValue << endl;
76     }
77   }
78 
endTree()79   void ExternalViewLoggerImpl::endTree()
80   {
81     //dumpNodeContainer(mFileName + string(".dmp"));
82 
83     mFile << "digraph {" << endl;
84     mFile << "Root [shape=box, color=grey];" << endl;
85 
86     while (!mParentNodeStack.empty())
87       mParentNodeStack.pop();
88 
89     mParentNodeStack.push("Root");
90 
91     NodeContainer_t::iterator iter = mNodeContainer.begin();
92     NodeContainer_t::iterator iter_end = mNodeContainer.end();
93     for (; iter != iter_end; ++iter)
94     {
95       if (isUnreferencedLeaf(iter->first))
96       {
97         string newStyleName = getNewStyleName();
98         mFile << newStyleName << " [shape=box];" << endl;
99         mFile << mParentNodeStack.top() << " -> " << newStyleName << endl;
100         mParentNodeStack.push(newStyleName);
101         dumpTree(iter->first);
102         mParentNodeStack.pop();
103       }
104     }
105 
106     mFile << "}" << endl;
107   }
108 
beginNode(const std::string & nodeId,const std::string & value,const std::string & refersToNodeId,bool inUse)109   void ExternalViewLoggerImpl::beginNode(const std::string& nodeId, const std::string& value, const std::string& refersToNodeId, bool inUse)
110   {
111     mNodeContainer.insert(
112         NodeContainer_t::value_type(nodeId,
113         NodeDescription::Pointer_t(new NodeDescription(mParentNodeStack.top(), refersToNodeId, value, inUse))));
114     mParentNodeStack.push(nodeId);
115   }
116 
endNode(const std::string & nodeId)117   void ExternalViewLoggerImpl::endNode(const std::string& nodeId)
118   {
119     mParentNodeStack.pop();
120   }
121 
isLeaf(const std::string & nodeId)122   bool ExternalViewLoggerImpl::isLeaf(const std::string& nodeId)
123   {
124     bool isLeaf = true;
125 
126     NodeContainer_t::const_iterator iter = mNodeContainer.begin();
127     NodeContainer_t::const_iterator iter_end = mNodeContainer.end();
128     for (; iter != iter_end; ++iter)
129     {
130       if (iter->second->mParentNodeId == nodeId)
131       {
132         isLeaf = false;
133         break;
134       }
135     }
136     return isLeaf;
137   }
138 
isUnreferencedLeaf(const string & nodeId)139   bool ExternalViewLoggerImpl::isUnreferencedLeaf(const string& nodeId)
140   {
141     return isLeaf(nodeId) && !isReferenced(nodeId);
142   }
143 
isReferenced(const string & nodeId)144   bool ExternalViewLoggerImpl::isReferenced(const string& nodeId)
145   {
146     bool isReferenced = false;
147 
148     NodeContainer_t::const_iterator iter = mNodeContainer.begin();
149     NodeContainer_t::const_iterator iter_end = mNodeContainer.end();
150     for (; iter != iter_end; ++iter)
151     {
152       if (iter->second->mRefersToNodeId == nodeId)
153       {
154         isReferenced = true;
155         break;
156       }
157     }
158     return isReferenced;
159   }
160 
isReferingToOtherNode(const string & nodeId)161   bool ExternalViewLoggerImpl::isReferingToOtherNode(const string& nodeId)
162   {
163     NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId);
164     BOOST_ASSERT(iter != mNodeContainer.end());
165     return !iter->second->mRefersToNodeId.empty();
166   }
167 
hasParent(const string & nodeId)168   bool ExternalViewLoggerImpl::hasParent(const string& nodeId)
169   {
170     NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId);
171     BOOST_ASSERT(iter != mNodeContainer.end());
172     return iter->second->mParentNodeId != "Root" && iter->second->mParentNodeId != "";
173   }
174 
getValue(const string & nodeId)175   string ExternalViewLoggerImpl::getValue(const string& nodeId)
176   {
177     return mNodeContainer.find(nodeId)->second->mNodeValue;
178   }
179 
dumpTree(const string & nodeId)180   void ExternalViewLoggerImpl::dumpTree(const string& nodeId)
181   {
182     if (nodeId != "Root")
183     {
184       mFile << nodeId << " [label=\"(" << getValue(nodeId) << ")\",shape=box];" << endl;
185       mFile << mParentNodeStack.top() << " -> " << nodeId << ";" << endl;
186       if (isReferingToOtherNode(nodeId))
187       {
188         mParentNodeStack.push(nodeId);
189         dumpTree(mNodeContainer.find(nodeId)->second->mRefersToNodeId);
190         mParentNodeStack.pop();
191       }
192     }
193 
194     if (hasParent(nodeId))
195       dumpTree(mNodeContainer.find(nodeId)->second->mParentNodeId);
196   }
197 
198 } // namespace util
199 
200