CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DDXMLElement.cc
Go to the documentation of this file.
1 /***************************************************************************
2  DDXMLElement.cc - description
3  -------------------
4  begin : Fri Mar 15 2002
5  email : case@ucdhep.ucdavis.edu
6  ***************************************************************************/
7 
11 
13 
14 #include <algorithm>
15 #include <iostream>
16 #include <sstream>
17 
19  : myRegistry_( myreg ),
20  attributes_(),
21  text_(),
22  autoClear_( false )
23 {}
24 
25 DDXMLElement::DDXMLElement( DDLElementRegistry* myreg, const bool& clearme )
26  : myRegistry_( myreg ),
27  attributes_(),
28  text_(),
29  autoClear_( clearme )
30 {}
31 
33 {}
34 
35 // For pre-processing, after attributes are loaded. Default, do nothing!
36 void
37 DDXMLElement::preProcessElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
38 {
39  DCOUT_V('P', "DDXMLElement::preProcessElementBase default, do nothing) started-completed.");
40 }
41 
42 // This loads the attributes into the attributes_ std::vector.
43 void
44 DDXMLElement::loadAttributes( const std::string& elemName,
45  const std::vector<std::string> & names,
46  const std::vector<std::string> & values,
47  const std::string& nmspace, DDCompactView& cpv )
48 {
49  attributes_.resize(attributes_.size()+1);
50  DDXMLAttribute & tAttributes = attributes_.back();
51 
52  // adds attributes
53  for (size_t i = 0; i < names.size(); ++i)
54  {
55  // tAttributes[ names[i] ] = values[i];
56  tAttributes.insert(std::make_pair(names[i], values[i]));
57  }
58 
59  preProcessElement( elemName, nmspace, cpv );
60  DCOUT_V('P', "DDXMLElement::loadAttributes completed. " << *this);
61 }
62 
63 // clear data.
64 void
66 {
67  text_.clear();
68  attributes_.clear();
69  attributeAccumulator_.clear();
70 }
71 
72 // Access to current attributes by name.
73 const std::string &
74 DDXMLElement::getAttribute( const std::string& name ) const
75 {
76  static const std::string ldef;
77  if (attributes_.size())
78  return get(name, attributes_.size() - 1);
79  return ldef;
80 }
81 
82 const DDXMLAttribute&
83 DDXMLElement::getAttributeSet( size_t aIndex ) const
84 {
85  // if (aIndex < attributes_.size())
86  return attributes_[aIndex];
87 }
88 
89 
90 const DDName
91 DDXMLElement::getDDName( const std::string& defaultNS, const std::string& attname, size_t aIndex )
92 {
93  if (aIndex < attributes_.size()
94  && attributes_[aIndex].find(attname) != attributes_[aIndex].end()) {
95  std::string ns = defaultNS;
96  // For the user to fully control namespaces they must provide for
97  // all name attributes something of the form, for example:
98  // <Solid name="ns:name" ...
99  // If defaultNS is "!" (magic I don't like) then find and set
100  // the namespace properly.
101  if ( defaultNS == "!" ) {
102  ns = "";
103  }
104  const std::string & name = attributes_[aIndex].find(attname)->second;
105  std::string rn = name;
106  size_t foundColon= name.find(':');
107  if (foundColon != std::string::npos) {
108  ns = name.substr(0,foundColon);
109  rn = name.substr(foundColon+1);
110 
111  }
112  // std::cout << "Name: " << rn << " Namespace: " << ns << std::endl;
113  return DDName(rn, ns);
114  }
115  // std::cout << "no " << attname << " default namespace: " << defaultNS << " at index " << aIndex << std::endl;
116  std::string msg = "DDXMLElement:getDDName failed. It was asked to make ";
117  msg += "a DDName using attribute: " + attname;
118  msg += " in position: " + itostr(int(aIndex)) + ". There are ";
119  msg += itostr(int(attributes_.size())) + " entries in the element.";
120  throwError(msg);
121  return DDName("justToCompile", "justToCompile"); // used to make sure it compiles
122 }
123 
124 // std::string DDXMLElement::getNameSpace(const std::string& defaultNS, const std::string& attname
125 // , size_t aIndex)
126 // {
127 // std::cout << "DEPRECATED: PLEASE DO NOT USE getNameSpace ANYMORE!" << std::endl;
128 // std::string ns;
129 // const std::string & name = get(attname, aIndex);
130 // size_t foundColon= name.find(':');
131 // if (foundColon != std::string::npos)
132 // ns = name.substr(0,foundColon);
133 // else
134 // {
135 // ns = defaultNS;
136 // }
137 // return ns;
138 // }
139 
140 // const std::string DDXMLElement::getName(const std::string& attname
141 // , size_t aIndex)
142 // {
143 // std::cout << "DEPRECATED: PLEASE DO NOT USE getName ANYMORE!!" << std::endl;
144 // std::string rn;
145 // const std::string & name = get(attname, aIndex);
146 // size_t foundColon= name.find(':');
147 // if (foundColon != std::string::npos)
148 // rn = name.substr(foundColon+1);
149 // {
150 // rn = name;
151 // }
152 // return rn;
153 // }
154 
155 
156 
157 // Returns a specific value from the aIndex set of attributes.
158 const std::string &
159 DDXMLElement::get( const std::string& name, const size_t aIndex ) const
160 {
161  static const std::string sts;
162  if (aIndex < attributes_.size())
163  {
164  DDXMLAttribute::const_iterator it = attributes_[aIndex].find(name);
165  if (attributes_[aIndex].end() == it)
166  {
167  DCOUT_V('P', "WARNING: DDXMLElement::get did not find the requested attribute: " << name << std::endl << *this);
168  return sts;
169  }
170  else
171  return (it->second);
172  }
173  std::string msg = "DDXMLElement:get failed. It was asked for attribute " + name;
174  msg += " in position " + itostr(int(aIndex)) + " when there are only ";
175  msg += itostr(int(attributes_.size())) + " in the element storage.\n";
176  throwError(msg);
177  // meaningless...
178  return sts;
179 }
180 
181 // Returns a specific set of values as a std::vector of std::strings,
182 // given the attribute name.
183 std::vector<std::string>
185 {
186  // The idea here is that the attributeAccumulator_ is a cache of
187  // on-the-fly generation from the std::vector<DDXMLAttribute> and the
188  // reason is simply to speed things up if it is requested more than once.
189  std::vector<std::string> tv;
190  AttrAccumType::const_iterator ita = attributeAccumulator_.find(name);
191  if (ita != attributeAccumulator_.end())
192  {
194  if (tv.size() < attributes_.size())
195  {
196  appendAttributes(tv, name);
197  }
198  DCOUT_V('P', "DDXMLElement::getAttribute found attribute named " << name << " in a map of size " << size());
199  }
200  else
201  {
202  if (attributes_.size())
203  {
204  appendAttributes(tv, name);
205  }
206  else
207  {
208  DCOUT_V('P', "DDXMLAttributeAccumulator::getAttribute was asked to provide a std::vector of values for an attribute named " << name << " but there was no such attribute.");
209  // throw DDException(msg);
210  }
211  }
212  return tv;
213 }
214 
215 // Default do-nothing processElementBases.
216 void
217 DDXMLElement::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
218 {
219  DCOUT_V('P', "DDXMLElement::processElementBase (default, do nothing) started-completed");
220  loadText(std::string());
221  if ( autoClear_ ) clear();
222 
223 }
224 
225 void
226 DDXMLElement::loadText( const std::string& inText )
227 {
228  text_.push_back(inText);
229  // std::cout << "just put a std::string using loadText. size is now: " << text_.size() << std::endl;
230 }
231 
232 void
233 DDXMLElement::appendText( const std::string& inText )
234 {
235  static const std::string cr("\n");
236  if (text_.size() > 0) {
237  text_[text_.size() - 1] += cr;
238  text_[text_.size() - 1] += inText ;
239  } else
240  {
241  std::string msg = "DDXMLElement::appendText could not append to non-existent text.";
242  throwError(msg);
243  }
244 }
245 
246 const std::string
247 DDXMLElement::getText( size_t tindex ) const
248 {
249  if (tindex > text_.size()) {
250  std::string msg = "DDXMLElement::getText tindex is greater than text_.size()).";
251  throwError(msg);
252  }
253  return text_[tindex];
254 }
255 
256 bool
258 {
259  if (text_.size() != 0)
260  return true;
261  return false;
262 }
263 
264 std::ostream & operator<<( std::ostream & os, const DDXMLElement & element )
265 {
266  element.stream(os);
267  return os;
268 }
269 
270 void
271 DDXMLElement::stream( std::ostream & os ) const
272 {
273  os << "Output of current element attributes:" << std::endl;
274  for (std::vector<DDXMLAttribute>::const_iterator itv = attributes_.begin();
275  itv != attributes_.end(); ++itv)
276  {
277  for (DDXMLAttribute::const_iterator it = itv->begin();
278  it != itv->end(); ++it)
279  os << it->first << " = " << it->second << "\t";
280  os << std::endl;
281  }
282 }
283 
284 void
285 DDXMLElement::appendAttributes( std::vector<std::string> & tv,
286  const std::string& name )
287 {
288  for (size_t i = tv.size(); i < attributes_.size(); ++i)
289  {
290  DDXMLAttribute::const_iterator itnv = attributes_[i].find(name);
291  if (itnv != attributes_[i].end())
292  tv.push_back(itnv->second);
293  else
294  tv.push_back("");
295  }
296 }
297 
298 // Number of elements accumulated.
299 size_t
300 DDXMLElement::size( void ) const
301 {
302  return attributes_.size();
303 }
304 
305 std::vector<DDXMLAttribute>::const_iterator
307 {
308  myIter_ = attributes_.begin();
309  return attributes_.begin();
310 }
311 
312 std::vector<DDXMLAttribute>::const_iterator
314 {
315  myIter_ = attributes_.end();
316  return attributes_.end();
317 }
318 
319 std::vector<DDXMLAttribute>::const_iterator&
321 {
322  myIter_ = myIter_ + inc;
323  return myIter_;
324 }
325 
326 const std::string&
327 DDXMLElement::parent( void ) const
328 {
329  return parentElement_;
330 }
331 
332 void
333 DDXMLElement::setParent( const std::string& pename )
334 {
335  parentElement_ = pename;
336 }
337 
338 void
339 DDXMLElement::setSelf( const std::string& sename )
340 {
341  myElement_ = sename;
342 }
343 
344 // yet another :-)
345 std::string
347 {
348  std::ostringstream ostr;
349  ostr << in;
350  return ostr.str();
351 }
352 
353 bool
355 {
356  return (attributes_.size() == 0 ? true : false);
357 }
358 
359 void
360 DDXMLElement::throwError( const std::string& keyMessage ) const
361 {
362  std::string msg = keyMessage + "\n";
363  // if (myElement_) {
364  msg += " Element " + myElement_ +"\n";
365  // }
366  // msg += " File " + DDLParser::instance()->getCurrFileName() + ".\n";
367  throw DDException(msg);
368 }
virtual bool isEmpty(void) const
Have any elements of this type been encountered but not processed?
int i
Definition: DBlmapReader.cc:9
std::string parentElement_
Definition: DDXMLElement.h:199
std::vector< DDXMLAttribute >::const_iterator & operator++(int inc)
Allow the elements of this type to be iterated over using ++ operator.
static std::string itostr(int i)
WARNING: abused by other classes in this system: yet another conversion from int to std::string...
void appendText(const std::string &inText)
append to the current (i.e. most recently added)
An exception for DDD errors.
Definition: DDException.h:23
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 &quot;row&quot; of attributes, i.e. one attribute set.
Definition: DDXMLElement.cc:83
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:18
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...
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
type of data representation of DDCompactView
Definition: DDCompactView.h:81
std::map< std::string, std::string > DDXMLAttribute
Definition: DDXMLElement.h:56
virtual void preProcessElement(const std::string &name, const std::string &nmspace, DDCompactView &cpv)
Called by loadAttributes AFTER attributes are loaded.
Definition: DDXMLElement.cc:37
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:44
virtual size_t size(void) const
Number of elements accumulated.
std::vector< DDXMLAttribute >::const_iterator myIter_
Definition: DDXMLElement.h:197
std::vector< DDXMLAttribute > attributes_
Definition: DDXMLElement.h:193
std::string myElement_
Definition: DDXMLElement.h:198
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:195
#define DCOUT_V(M_v_Y, M_v_S)
Definition: DDdebug.h:54
virtual ~DDXMLElement(void)
Destructor.
Definition: DDXMLElement.cc:32
This is a base class for processing XML elements in the DDD.
Definition: DDXMLElement.h:59
virtual const std::string & getAttribute(const std::string &name) const
Access to attributes by name.
Definition: DDXMLElement.cc:74
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:65
DDXMLElement(DDLElementRegistry *myreg)
Constructor.
Definition: DDXMLElement.cc:18
virtual const DDName getDDName(const std::string &defaultNS, const std::string &attname=std::string("name"), size_t aIndex=0)
Definition: DDXMLElement.cc:91
static const HistoName names[]
const std::string getText(size_t tindex=0) const
retrieve the text blob.
std::vector< std::string > text_
Definition: DDXMLElement.h:194