BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlBaseCnv.cxx
Go to the documentation of this file.
1// $Header:
2// /bes/bes/BossCvs/Calibration/CalibSvc/CalibXmlCnvSvc/src/cnv/XmlBaseCnv.cxx,v 1.1.1.1
3// 2006/04/03 03:04:32 maqm Exp $
4
5#include "XmlBaseCnv.h"
6
7#include "GaudiKernel/CnvFactory.h"
8#include "GaudiKernel/DataObject.h"
9#include "GaudiKernel/IAddressCreator.h"
10#include "GaudiKernel/IConversionSvc.h"
11#include "GaudiKernel/IDataProviderSvc.h"
12#include "GaudiKernel/IOpaqueAddress.h"
13#include "GaudiKernel/MsgStream.h"
14
15#include "CalibData/CalibBase.h"
16#include "CalibData/CalibTime.h"
17#include "CalibSvc/ICalibMetaCnvSvc.h"
18#include "CalibSvc/ICalibXmlSvc.h"
19// #include "CalibData/Cal/Xpos.h"
20
21// Needed for ValSig
22#include "CalibData/RangeBase.h"
23#include "xmlBase/Dom.h"
24
25// A little ugly to include this here. It's needed for
26// CAL-specific utilities involving dac collections (maybe should be
27// moved to XmlCalbaseCnv ?)
28// #include "idents/CalXtalId.h"
29
30// Similarly this is needed for calibrations involving dac settings
31#include "CalibData/DacCol.h"
32
33#include "facilities/Util.h"
34
35#include <xercesc/dom/DOMDocument.hpp>
36// #include <xercesc/dom/DOM_NodeList.hpp>
37
38using namespace CalibData;
39XERCES_CPP_NAMESPACE_USE
40
42
43// static CnvFactory<XmlBaseCnv> s_factory;
44// const ICnvFactory& XmlBaseCnvFactory = s_factory;
45XmlBaseCnv::XmlBaseCnv( ISvcLocator* svc, const CLID& clid )
46 : Converter( XML_StorageType, clid, svc )
47 , m_xmlSvc( 0 )
48 , m_metaSvc( 0 )
49 , m_vstart( 0 )
50 , m_vend( 0 ) /*,
51m_nRow(10000), m_nCol(10000), m_nLayer(10000), m_nXtal(10000),
52m_nFace(10000), m_nRange(10000) */
53{}
54
56 StatusCode status = Converter::initialize();
57
58 IDataProviderSvc* dp;
59
60 // I guess the service names are assigned in jobOptions?
61
62 serviceLocator()->getService( "CalibDataSvc", IID_IDataProviderSvc, (IInterface*&)dp );
63 setDataProvider( dp );
64
65 // Locate the Xml Conversion Service
66 serviceLocator()->getService( "CalibXmlCnvSvc", IID_ICalibXmlSvc, (IInterface*&)m_xmlSvc );
67
68 // Locate meta conversion service
69 // Will anything need to be changed here to accommodate possibility
70 // of two concrete implementations of ICalibMetaCnvSvc? Would
71 // have different storage types. Could specify type desired
72 // as job option. Ditto for name of class?
73 serviceLocator()->getService( "CalibMySQLCnvSvc", IID_ICalibMetaCnvSvc,
74 (IInterface*&)m_metaSvc );
75 return status;
76}
77
78StatusCode XmlBaseCnv::finalize() { return Converter::finalize(); }
79
80// Create transient representation
81
82StatusCode XmlBaseCnv::createObj( IOpaqueAddress* addr, DataObject*& refpObject ) {
83
84 // creates a msg stream for debug purposes
85 MsgStream log( msgSvc(), "XmlBaseCnv" );
86
87 if ( 0 == addr ) { return StatusCode::FAILURE; }
88
89 // first do the things we always need:
90 // First string parameter of opaque address is file ident
91 // Parse file into DOM representation
92 const std::string* par = addr->par();
93
94 std::string par0 = par[0];
95
96 // Ignore trailing white space.
98
99 // Just in case there are environment variables in the file specification
100 // int nSub =
102
103 // XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc =
104 DOMDocument* doc = m_xmlSvc->parse( par0.c_str() );
105
106 if ( doc == 0 )
107 {
108 log << MSG::FATAL << "Unable to parse document " << par[0] << " aka " << par0 << endmsg;
109 return StatusCode::FAILURE;
110 }
111 else
112 {
113 log << MSG::INFO << "successfully parsed document " << par[0] << " aka " << par0 << endmsg;
114 }
115
116 // Could conceivably write some code here to handle generic
117 // parts of document. Or, alternatively, add services to
118 // CalibXmlCnvSvc for converters to invoke to do this.
119
120 // Then do some fancy footwork in internalCreateObj to get the
121 // appropriate specific converter invoked to interpret the DOM
122 // correctly and make a new object of the correct kind.
123
124 return internalCreateObj( doc->getDocumentElement(), refpObject, addr );
125}
126
127/** In a backhanded way, invoke the right specific converter
128 for the type of the object to be created
129 @param elt Document elt from XML document (input)
130 @param refpObject
131*/
132StatusCode XmlBaseCnv::internalCreateObj( const DOMElement* docElt, DataObject*& refpObject,
133 IOpaqueAddress* address ) {
134 // creates a msg stream for debug purposes
135 MsgStream log( msgSvc(), "XmlBaseCnv" );
136
137 // We're the default if we can't find anything better
138 XmlBaseCnv* converter = this;
139
140 CLID classId = address->clID();
141
142 IConverter* conv = this->conversionSvc()->converter( classId );
143
144 if ( 0 == conv )
145 {
146 log << MSG::WARNING << "No proper converter found for classID " << classId
147 << ", the default converter"
148 << " will be used. " << endmsg;
149 }
150 else
151 {
152 converter = dynamic_cast<XmlBaseCnv*>( conv );
153 if ( 0 == converter )
154 {
155 log << MSG::ERROR << "The converter found for classID " << classId
156 << " was not a descendent of XmlBaseCnv as it should be "
157 << "( was of type " << typeid( *converter ).name() << "). "
158 << "The default converter will be used" << endmsg;
159 converter = this;
160 }
161 }
162
163 unsigned int serNo = *( address->ipar() );
164 m_serNo = serNo;
165 /* maqm comment for remove getValidInterval()
166 StatusCode sc = m_metaSvc->getValidInterval(serNo,
167 &m_vstart,
168 &m_vend );
169
170
171 // creates an object for the node found
172
173
174 if (sc.isSuccess()) sc = converter->i_createObj (docElt, refpObject);
175 */
176 StatusCode sc = converter->i_createObj( docElt, refpObject );
177 if ( sc.isFailure() ) { return sc; }
178
179 // ends up the object construction
180 sc = converter->i_processObj( refpObject, address );
181 if ( sc.isSuccess() )
182 { log << MSG::DEBUG << "Successfully created calib. object " << endmsg; }
183 return sc;
184}
185
186// Default is to do nothing. Derived classes may override.
187StatusCode XmlBaseCnv::i_processObj( DataObject*, // pObject,
188 IOpaqueAddress* ) /* address */ {
189 return StatusCode::SUCCESS;
190}
191
192// Shouldn't ever really get here
193StatusCode XmlBaseCnv::i_createObj( const DOMElement*, DataObject*& ) {
194 return StatusCode::FAILURE;
195}
196
197/*
198// Not sure yet whether this needs a real implementation or not
199StatusCode XmlBaseCnv::updateObj(IOpaqueAddress* ,
200 DataObject*& ) {
201 return StatusCode::FAILURE;
202}
203
204// Since we're not expecting to support writing back to persistent
205// store, don't implement the converter *Rep functions.
206*/
207
208StatusCode XmlBaseCnv::readHeader( const DOMElement* ) { return StatusCode::SUCCESS; }
209
210const unsigned char XmlBaseCnv::storageType() { return XML_StorageType; }
211
212/*
213
214*/
215/// Another utility for derived classes to use
217 pObj->setValidity( *m_vstart, *m_vend );
218 pObj->setSerNo( m_serNo );
219}
220
221DOMElement* XmlBaseCnv::findFirstDacCol( const DOMElement* docElt ) {
222 return xmlBase::Dom::findFirstChildByName( docElt, "dac" );
223}
224
225DOMElement* XmlBaseCnv::findNextDacCol( const DOMElement* dacElt ) {
226 DOMElement* next = xmlBase::Dom::getSiblingElement( dacElt );
227 if ( xmlBase::Dom::checkTagName( next, "dac" ) ) return next;
228 else return 0;
229}
230
231CalibData::DacCol* XmlBaseCnv::processDacCol( DOMElement* dacColElt, unsigned* range ) {
232
233 using xmlBase::Dom;
234 // maqm comment using idents::CalXtalId;
235
236 std::string att = Dom::getAttribute( dacColElt, "range" );
237 /* maqm comment
238 if (att.compare(std::string("LEX8")) == 0) *range = CalXtalId::LEX8;
239 if (att.compare(std::string("LEX1")) == 0) *range = CalXtalId::LEX1;
240 if (att.compare(std::string("HEX8")) == 0) *range = CalXtalId::HEX8;
241 if (att.compare(std::string("HEX1")) == 0) *range = CalXtalId::HEX1;
242 */
243 // *range = Dom::getIntAttribute(dacColElt, "range");
244 std::vector<int> vals;
245
246 Dom::getIntsAttribute( dacColElt, "values", vals );
247
248 CalibData::DacCol* pDacCol = new CalibData::DacCol( &vals );
249 return pDacCol;
250}
251
252/* maqm comment
253 DOMElement* XmlBaseCnv::findXpos(const DOMElement* docElt) {
254 return xmlBase::Dom::findFirstChildByName(docElt, "xpos");
255}
256
257CalibData::Xpos* XmlBaseCnv::processXpos(DOMElement* xposElt) {
258 using xmlBase::Dom;
259
260 std::vector<float> vals;
261
262 Dom::getFloatsAttribute(xposElt, "values", vals);
263 CalibData::Xpos* pXpos = new CalibData::Xpos(&vals);
264
265 return pXpos;
266}
267*/
268/// Read in what will become a CalibData::ValSig
269CalibData::ValSig* XmlBaseCnv::processValSig( DOMElement* elt, std::string valName,
270 std::string sigName ) {
271 if ( elt == 0 ) return 0;
273 pValSig->m_val = xmlBase::Dom::getDoubleAttribute( elt, valName );
274 pValSig->m_sig = xmlBase::Dom::getDoubleAttribute( elt, sigName );
275 return pValSig;
276}
277
278std::vector<CalibData::ValSig>*
279XmlBaseCnv::processValSigs( DOMElement* elt, std::string valName, std::string sigName ) {
280
281 // creates a msg stream for debug purposes
282 MsgStream log( msgSvc(), "XmlBaseCnv" );
283
284 if ( elt == 0 ) return 0;
285 std::vector<float> vals;
286 std::vector<float> sigs;
287
288 xmlBase::Dom::getFloatsAttribute( elt, valName, vals );
289 xmlBase::Dom::getFloatsAttribute( elt, sigName, sigs );
290 if ( vals.size() != sigs.size() )
291 {
292 log << MSG::ERROR << "#values <> #sigmas " << endmsg;
293 return 0;
294 }
295 unsigned n = vals.size();
296 std::vector<CalibData::ValSig>* pValSigs = new std::vector<CalibData::ValSig>( n );
297 for ( unsigned i = 0; i < n; i++ )
298 {
299 ( *pValSigs )[i].m_val = vals[i];
300 ( *pValSigs )[i].m_sig = sigs[i];
301 }
302 return pValSigs;
303}
const Int_t n
IMessageSvc * msgSvc()
ICalibMetaCnvSvc * m_metaSvc
Definition XmlBaseCnv.h:136
CalibData::ValSig * processValSig(DOMElement *elt, std::string valName, std::string sigName)
Read in what will become a CalibData::ValSig.
ICalibXmlSvc * m_xmlSvc
Definition XmlBaseCnv.h:135
std::vector< CalibData::ValSig > * processValSigs(DOMElement *elt, std::string valName, std::string sigName)
Read in what will become a vector of CalibData::ValSig.
virtual StatusCode readHeader(const DOMElement *)
ITime * m_vend
Definition XmlBaseCnv.h:140
virtual ~XmlBaseCnv()
virtual StatusCode initialize()
void setBaseInfo(CalibData::CalibBase *pObj)
Another utility for derived classes to use.
static const unsigned char storageType()
CalibData::DacCol * processDacCol(DOMElement *dacColElt, unsigned *range)
virtual StatusCode i_processObj(DataObject *pObject, IOpaqueAddress *address)
In case there is additional work to do on the created object.
DOMElement * findNextDacCol(const DOMElement *rangeElt)
Still another one to navigate XML file and find next dac collection.
DOMElement * findFirstDacCol(const DOMElement *docElt)
Another one to find first dac collection element.
virtual StatusCode internalCreateObj(const DOMElement *element, DataObject *&refpObject, IOpaqueAddress *address)
ITime * m_vstart
Definition XmlBaseCnv.h:139
virtual StatusCode finalize()
virtual StatusCode createObj(IOpaqueAddress *addr, DataObject *&refpObject)
XmlBaseCnv(ISvcLocator *svc, const CLID &clid)
virtual StatusCode i_createObj(const DOMElement *element, DataObject *&refpObject)
static int expandEnvVar(std::string *toExpand, const std::string &openDel=std::string("$("), const std::string &closeDel=std::string(")"))
static unsigned trimTrailing(std::string *toTrim)
static DOMElement * getSiblingElement(const DOMNode *child)
Return next element sibling, if any.
Definition Dom.cxx:90
static unsigned getFloatsAttribute(const DOMNode *elt, std::string attName, std::vector< float > &values, bool clear=true)
Definition Dom.cxx:271
static double getDoubleAttribute(const DOMNode *elt, std::string attName)
Definition Dom.cxx:231
static DOMElement * findFirstChildByName(const DOMElement *parent, const char *const name)
Definition Dom.cxx:58
static bool checkTagName(const DOMElement *element, const std::string &tagName)
Definition Dom.cxx:136