CMS 3D CMS Logo

DDXMLElement.cc
Go to the documentation of this file.
2 
3 #include <ext/alloc_traits.h>
4 #include <iostream>
5 #include <memory>
6 #include <utility>
7 #include <string>
8 
11 
12 class DDCompactView;
13 class DDLElementRegistry;
14 
16  : myRegistry_( myreg ),
17  attributes_(),
18  text_(),
19  autoClear_( false )
20 {}
21 
22 DDXMLElement::DDXMLElement( DDLElementRegistry* myreg, const bool& clearme )
23  : myRegistry_( myreg ),
24  attributes_(),
25  text_(),
26  autoClear_( clearme )
27 {}
28 
29 // For pre-processing, after attributes are loaded. Default, do nothing!
30 void
32 {}
33 
34 // This loads the attributes into the attributes_ std::vector.
35 void
37  const std::vector<std::string> & names,
38  const std::vector<std::string> & values,
39  const std::string& nmspace, DDCompactView& cpv )
40 {
41  attributes_.resize(attributes_.size()+1);
42  DDXMLAttribute & tAttributes = attributes_.back();
43 
44  // adds attributes
45  for (size_t i = 0; i < names.size(); ++i)
46  {
47  tAttributes.insert(std::make_pair(names[i], values[i]));
48  }
49 
50  preProcessElement( elemName, nmspace, cpv );
51 }
52 
53 // clear data.
54 void
56 {
57  text_.clear();
58  attributes_.clear();
59  attributeAccumulator_.clear();
60 }
61 
62 // Access to current attributes by name.
63 const std::string &
65 {
66  static const std::string ldef;
67  if (attributes_.size())
68  return get(name, attributes_.size() - 1);
69  return ldef;
70 }
71 
72 const DDXMLAttribute&
73 DDXMLElement::getAttributeSet( size_t aIndex ) const
74 {
75  return attributes_[aIndex];
76 }
77 
78 
79 const DDName
80 DDXMLElement::getDDName( const std::string& defaultNS, const std::string& attname, size_t aIndex )
81 {
82  if (aIndex < attributes_.size()
83  && attributes_[aIndex].find(attname) != attributes_[aIndex].end()) {
84  std::string ns = defaultNS;
85  // For the user to fully control namespaces they must provide for
86  // all name attributes something of the form, for example:
87  // <Solid name="ns:name" ...
88  // If defaultNS is "!" (magic I don't like) then find and set
89  // the namespace properly.
90  if ( defaultNS == "!" ) {
91  ns = "";
92  }
93  const std::string & name = attributes_[aIndex].find(attname)->second;
94  std::string rn = name;
95  size_t foundColon= name.find(':');
96  if (foundColon != std::string::npos) {
97  ns = name.substr(0,foundColon);
98  rn = name.substr(foundColon+1);
99 
100  }
101  return DDName(rn, ns);
102  }
103  std::string msg = "DDXMLElement:getDDName failed. It was asked to make ";
104  msg += "a DDName using attribute: " + attname;
105  msg += " in position: " + std::to_string(aIndex) + ". There are ";
106  msg += std::to_string(attributes_.size()) + " entries in the element.";
107  throwError(msg);
108  return DDName("justToCompile", "justToCompile"); // used to make sure it compiles
109 }
110 
111 // Returns a specific value from the aIndex set of attributes.
112 const std::string &
113 DDXMLElement::get( const std::string& name, const size_t aIndex ) const
114 {
115  static const std::string sts;
116  if (aIndex < attributes_.size())
117  {
118  DDXMLAttribute::const_iterator it = attributes_[aIndex].find(name);
119  if (attributes_[aIndex].end() == it)
120  {
121  return sts;
122  }
123  else
124  return (it->second);
125  }
126  std::string msg = "DDXMLElement:get failed. It was asked for attribute " + name;
127  msg += " in position " + std::to_string(aIndex) + " when there are only ";
128  msg += std::to_string(attributes_.size()) + " in the element storage.\n";
129  throwError(msg);
130  // meaningless...
131  return sts;
132 }
133 
134 // Returns a specific set of values as a std::vector of std::strings,
135 // given the attribute name.
136 std::vector<std::string>
138 {
139  // The idea here is that the attributeAccumulator_ is a cache of
140  // on-the-fly generation from the std::vector<DDXMLAttribute> and the
141  // reason is simply to speed things up if it is requested more than once.
142  std::vector<std::string> tv;
143  AttrAccumType::const_iterator ita = attributeAccumulator_.find(name);
144  if (ita != attributeAccumulator_.end())
145  {
147  if (tv.size() < attributes_.size())
148  {
149  appendAttributes(tv, name);
150  }
151  }
152  else
153  {
154  if (attributes_.size())
155  {
156  appendAttributes(tv, name);
157  }
158  else
159  {
160  // throw cms::Exception("DDException") << msg;
161  }
162  }
163  return tv;
164 }
165 
166 // Default do-nothing processElementBases.
167 void
169 {
171  if ( autoClear_ ) clear();
172 }
173 
174 void
176 {
177  text_.push_back(inText);
178 }
179 
180 void
182 {
183  static const std::string cr("\n");
184  if (text_.size() > 0) {
185  text_[text_.size() - 1] += cr;
186  text_[text_.size() - 1] += inText ;
187  } else
188  {
189  std::string msg = "DDXMLElement::appendText could not append to non-existent text.";
190  throwError(msg);
191  }
192 }
193 
194 const std::string
195 DDXMLElement::getText( size_t tindex ) const
196 {
197  if (tindex > text_.size()) {
198  std::string msg = "DDXMLElement::getText tindex is greater than text_.size()).";
199  throwError(msg);
200  }
201  return text_[tindex];
202 }
203 
204 bool
206 {
207  if (text_.size() != 0)
208  return true;
209  return false;
210 }
211 
212 std::ostream & operator<<( std::ostream & os, const DDXMLElement & element )
213 {
214  element.stream(os);
215  return os;
216 }
217 
218 void
219 DDXMLElement::stream( std::ostream & os ) const
220 {
221  os << "Output of current element attributes:" << std::endl;
222  for (std::vector<DDXMLAttribute>::const_iterator itv = attributes_.begin();
223  itv != attributes_.end(); ++itv)
224  {
225  for (DDXMLAttribute::const_iterator it = itv->begin();
226  it != itv->end(); ++it)
227  os << it->first << " = " << it->second << "\t";
228  os << std::endl;
229  }
230 }
231 
232 void
233 DDXMLElement::appendAttributes( std::vector<std::string> & tv,
234  const std::string& name )
235 {
236  for (size_t i = tv.size(); i < attributes_.size(); ++i)
237  {
238  DDXMLAttribute::const_iterator itnv = attributes_[i].find(name);
239  if (itnv != attributes_[i].end())
240  tv.push_back(itnv->second);
241  else
242  tv.push_back("");
243  }
244 }
245 
246 // Number of elements accumulated.
247 size_t
248 DDXMLElement::size( void ) const
249 {
250  return attributes_.size();
251 }
252 
253 std::vector<DDXMLAttribute>::const_iterator
255 {
256  myIter_ = attributes_.begin();
257  return attributes_.begin();
258 }
259 
260 std::vector<DDXMLAttribute>::const_iterator
262 {
263  myIter_ = attributes_.end();
264  return attributes_.end();
265 }
266 
267 std::vector<DDXMLAttribute>::const_iterator&
269 {
270  myIter_ = myIter_ + inc;
271  return myIter_;
272 }
273 
274 const std::string&
275 DDXMLElement::parent( void ) const
276 {
277  return parentElement_;
278 }
279 
280 void
282 {
283  parentElement_ = pename;
284 }
285 
286 void
288 {
289  myElement_ = sename;
290 }
291 
292 bool
294 {
295  return (attributes_.size() == 0 ? true : false);
296 }
297 
298 void
299 DDXMLElement::throwError( const std::string& keyMessage ) const
300 {
301  std::string msg = keyMessage + "\n";
302  msg += " Element " + myElement_ +"\n";
303 
304  throw cms::Exception("DDException") << msg;
305 }
virtual bool isEmpty(void) const
Have any elements of this type been encountered but not processed?
std::string parentElement_
Definition: DDXMLElement.h:184
std::vector< DDXMLAttribute >::const_iterator & operator++(int inc)
Allow the elements of this type to be iterated over using ++ operator.
DDLElementRegistry * myRegistry_
Definition: DDXMLElement.h:172
static const HistoName names[]
void appendText(const std::string &inText)
append to the current (i.e. most recently added)
void setParent(const std::string &pename)
Set parent element name to central list of names.
virtual const DDXMLAttribute & getAttributeSet(size_t aIndex=0) const
Get a "row" of attributes, i.e. one attribute set.
Definition: DDXMLElement.cc:73
virtual const std::string & get(const std::string &name, size_t aIndex=0) const
Returns a specific value from the aIndex set of attributes.
void throwError(const std::string &keyMessage) const
format std::string for throw an error.
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:16
virtual void processElement(const std::string &name, const std::string &nmspace, DDCompactView &cpv)
Processing the element.
const std::string & parent(void) const
access to parent element name
void appendAttributes(std::vector< std::string > &tv, const std::string &name)
behind the scenes appending to pAttributes...
type of data representation of DDCompactView
Definition: DDCompactView.h:90
std::map< std::string, std::string > DDXMLAttribute
Definition: DDXMLElement.h:45
virtual void preProcessElement(const std::string &name, const std::string &nmspace, DDCompactView &cpv)
Called by loadAttributes AFTER attributes are loaded.
Definition: DDXMLElement.cc:31
void loadText(const std::string &inText)
Used to load both text and XML comments into this object.
void setSelf(const std::string &sename)
Set self element name to central list of names.
virtual std::vector< DDXMLAttribute >::const_iterator end(void)
void loadAttributes(const std::string &elemName, const std::vector< std::string > &names, const std::vector< std::string > &values, const std::string &nmspace, DDCompactView &cpv)
Load the element attributes.
Definition: DDXMLElement.cc:36
virtual size_t size(void) const
Number of elements accumulated.
std::vector< DDXMLAttribute >::const_iterator myIter_
Definition: DDXMLElement.h:182
std::vector< DDXMLAttribute > attributes_
Definition: DDXMLElement.h:178
friend std::ostream & operator<<(std::ostream &os, const DDXMLElement &element)
std::string myElement_
Definition: DDXMLElement.h:183
virtual bool gotText(void) const
gotText()? kind of like gotMilk? Yes = text has already been encountered.
virtual std::vector< std::string > getVectorAttribute(const std::string &name)
Returns a set of values as a std::vector of strings, given the attribute name.
AttrAccumType attributeAccumulator_
Definition: DDXMLElement.h:180
This is a base class for processing XML elements in the DDD.
Definition: DDXMLElement.h:48
virtual const std::string & getAttribute(const std::string &name) const
Access to attributes by name.
Definition: DDXMLElement.cc:64
virtual std::vector< DDXMLAttribute >::const_iterator begin(void)
virtual void stream(std::ostream &os) const
Allow for the elements to have their own streaming method, but also provide a default.
The main class for processing parsed elements.
virtual void clear(void)
clear this element&#39;s contents.
Definition: DDXMLElement.cc:55
DDXMLElement(DDLElementRegistry *myreg)
Constructor.
Definition: DDXMLElement.cc:15
virtual const DDName getDDName(const std::string &defaultNS, const std::string &attname=std::string("name"), size_t aIndex=0)
Definition: DDXMLElement.cc:80
const std::string getText(size_t tindex=0) const
retrieve the text blob.
std::vector< std::string > text_
Definition: DDXMLElement.h:179