Line data Source code
1 :
2 : /*
3 : * ALMA - Atacama Large Millimeter Array
4 : * (c) European Southern Observatory, 2002
5 : * (c) Associated Universities Inc., 2002
6 : * Copyright by ESO (in the framework of the ALMA collaboration),
7 : * Copyright by AUI (in the framework of the ALMA collaboration),
8 : * All rights reserved.
9 : *
10 : * This library is free software; you can redistribute it and/or
11 : * modify it under the terms of the GNU Lesser General Public
12 : * License as published by the Free software Foundation; either
13 : * version 2.1 of the License, or (at your option) any later version.
14 : *
15 : * This library is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY, without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : * Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; if not, write to the Free Software
22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 : * MA 02111-1307 USA
24 : *
25 : * Warning!
26 : * --------------------------------------------------------------------
27 : * | This is generated code! Do not modify this file. |
28 : * | If you do, all changes will be lost when the file is re-generated. |
29 : * --------------------------------------------------------------------
30 : *
31 : * File FocusModelTable.cpp
32 : */
33 : #include <alma/ASDM/ConversionException.h>
34 : #include <alma/ASDM/DuplicateKey.h>
35 : #include <alma/ASDM/OutOfBoundsException.h>
36 :
37 : using asdm::ConversionException;
38 : using asdm::DuplicateKey;
39 : using asdm::OutOfBoundsException;
40 :
41 : #include <alma/ASDM/ASDM.h>
42 : #include <alma/ASDM/FocusModelTable.h>
43 : #include <alma/ASDM/FocusModelRow.h>
44 : #include <alma/ASDM/Parser.h>
45 :
46 : using asdm::ASDM;
47 : using asdm::FocusModelTable;
48 : using asdm::FocusModelRow;
49 : using asdm::Parser;
50 :
51 : #include <iostream>
52 : #include <fstream>
53 : #include <iterator>
54 : #include <sstream>
55 : #include <set>
56 : #include <algorithm>
57 : using namespace std;
58 :
59 : #include <alma/ASDM/Misc.h>
60 : using namespace asdm;
61 :
62 : #include <libxml/parser.h>
63 : #include <libxml/tree.h>
64 :
65 : #ifndef WITHOUT_BOOST
66 : #include "boost/filesystem/operations.hpp"
67 : #include <boost/algorithm/string.hpp>
68 : #else
69 : #include <sys/stat.h>
70 : #endif
71 :
72 : namespace asdm {
73 : // The name of the entity we will store in this table.
74 : static string entityNameOfFocusModel = "FocusModel";
75 :
76 : // An array of string containing the names of the columns of this table.
77 : // The array is filled in the order : key, required value, optional value.
78 : //
79 : static string attributesNamesOfFocusModel_a[] = {
80 :
81 : "antennaId"
82 : ,
83 : "focusModelId"
84 :
85 :
86 : , "polarizationType"
87 :
88 : , "receiverBand"
89 :
90 : , "numCoeff"
91 :
92 : , "coeffName"
93 :
94 : , "coeffFormula"
95 :
96 : , "coeffVal"
97 :
98 : , "assocNature"
99 :
100 : , "assocFocusModelId"
101 :
102 :
103 : };
104 :
105 : // A vector of string whose content is a copy of the strings in the array above.
106 : //
107 : static vector<string> attributesNamesOfFocusModel_v (attributesNamesOfFocusModel_a, attributesNamesOfFocusModel_a + sizeof(attributesNamesOfFocusModel_a) / sizeof(attributesNamesOfFocusModel_a[0]));
108 :
109 : // An array of string containing the names of the columns of this table.
110 : // The array is filled in the order where the names would be read by default in the XML header of a file containing
111 : // the table exported in binary mode.
112 : //
113 : static string attributesNamesInBinOfFocusModel_a[] = {
114 :
115 : "antennaId" , "focusModelId" , "polarizationType" , "receiverBand" , "numCoeff" , "coeffName" , "coeffFormula" , "coeffVal" , "assocNature" , "assocFocusModelId"
116 : ,
117 :
118 :
119 : };
120 :
121 : // A vector of string whose content is a copy of the strings in the array above.
122 : //
123 : static vector<string> attributesNamesInBinOfFocusModel_v(attributesNamesInBinOfFocusModel_a, attributesNamesInBinOfFocusModel_a + sizeof(attributesNamesInBinOfFocusModel_a) / sizeof(attributesNamesInBinOfFocusModel_a[0]));
124 :
125 :
126 : // The array of attributes (or column) names that make up key key.
127 : //
128 : string keyOfFocusModel_a[] = {
129 :
130 : "antennaId"
131 : ,
132 : "focusModelId"
133 :
134 : };
135 :
136 : // A vector of strings which are copies of those stored in the array above.
137 : vector<string> keyOfFocusModel_v(keyOfFocusModel_a, keyOfFocusModel_a + sizeof(keyOfFocusModel_a) / sizeof(keyOfFocusModel_a[0]));
138 :
139 : /**
140 : * Return the list of field names that make up key key
141 : * as a const reference to a vector of strings.
142 : */
143 0 : const vector<string>& FocusModelTable::getKeyName() {
144 0 : return keyOfFocusModel_v;
145 : }
146 :
147 :
148 4 : FocusModelTable::FocusModelTable(ASDM &c) : container(c) {
149 :
150 : // Define a default entity.
151 4 : entity.setEntityId(EntityId("uid://X0/X0/X0"));
152 4 : entity.setEntityIdEncrypted("na");
153 4 : entity.setEntityTypeName("FocusModelTable");
154 4 : entity.setEntityVersion("1");
155 4 : entity.setInstanceVersion("1");
156 :
157 : // Archive XML
158 4 : archiveAsBin = false;
159 :
160 : // File XML
161 4 : fileAsBin = false;
162 :
163 : // By default the table is considered as present in memory
164 4 : presentInMemory = true;
165 :
166 : // By default there is no load in progress
167 4 : loadInProgress = false;
168 4 : }
169 :
170 : /**
171 : * A destructor for FocusModelTable.
172 : */
173 8 : FocusModelTable::~FocusModelTable() {
174 4 : for (unsigned int i = 0; i < privateRows.size(); i++)
175 0 : delete(privateRows.at(i));
176 8 : }
177 :
178 : /**
179 : * Container to which this table belongs.
180 : */
181 0 : ASDM &FocusModelTable::getContainer() const {
182 0 : return container;
183 : }
184 :
185 : /**
186 : * Return the number of rows in the table.
187 : */
188 0 : unsigned int FocusModelTable::size() const {
189 0 : if (presentInMemory)
190 0 : return privateRows.size();
191 : else
192 0 : return declaredSize;
193 : }
194 :
195 : /**
196 : * Return the name of this table.
197 : */
198 96 : string FocusModelTable::getName() const {
199 96 : return entityNameOfFocusModel;
200 : }
201 :
202 : /**
203 : * Return the name of this table.
204 : */
205 0 : string FocusModelTable::name() {
206 0 : return entityNameOfFocusModel;
207 : }
208 :
209 : /**
210 : * Return the the names of the attributes (or columns) of this table.
211 : */
212 0 : const vector<string>& FocusModelTable::getAttributesNames() { return attributesNamesOfFocusModel_v; }
213 :
214 : /**
215 : * Return the the names of the attributes (or columns) of this table as they appear by default
216 : * in an binary export of this table.
217 : */
218 0 : const vector<string>& FocusModelTable::defaultAttributesNamesInBin() { return attributesNamesInBinOfFocusModel_v; }
219 :
220 : /**
221 : * Return this table's Entity.
222 : */
223 0 : Entity FocusModelTable::getEntity() const {
224 0 : return entity;
225 : }
226 :
227 : /**
228 : * Set this table's Entity.
229 : */
230 0 : void FocusModelTable::setEntity(Entity e) {
231 0 : this->entity = e;
232 0 : }
233 :
234 : //
235 : // ====> Row creation.
236 : //
237 :
238 : /**
239 : * Create a new row.
240 : */
241 0 : FocusModelRow *FocusModelTable::newRow() {
242 0 : return new FocusModelRow (*this);
243 : }
244 :
245 :
246 : /**
247 : * Create a new row initialized to the specified values.
248 : * @return a pointer on the created and initialized row.
249 :
250 : * @param antennaId
251 :
252 : * @param polarizationType
253 :
254 : * @param receiverBand
255 :
256 : * @param numCoeff
257 :
258 : * @param coeffName
259 :
260 : * @param coeffFormula
261 :
262 : * @param coeffVal
263 :
264 : * @param assocNature
265 :
266 : * @param assocFocusModelId
267 :
268 : */
269 0 : FocusModelRow* FocusModelTable::newRow(Tag antennaId, PolarizationTypeMod::PolarizationType polarizationType, ReceiverBandMod::ReceiverBand receiverBand, int numCoeff, std::vector<std::string > coeffName, std::vector<std::string > coeffFormula, std::vector<float > coeffVal, std::string assocNature, int assocFocusModelId){
270 0 : FocusModelRow *row = new FocusModelRow(*this);
271 :
272 0 : row->setAntennaId(antennaId);
273 :
274 0 : row->setPolarizationType(polarizationType);
275 :
276 0 : row->setReceiverBand(receiverBand);
277 :
278 0 : row->setNumCoeff(numCoeff);
279 :
280 0 : row->setCoeffName(coeffName);
281 :
282 0 : row->setCoeffFormula(coeffFormula);
283 :
284 0 : row->setCoeffVal(coeffVal);
285 :
286 0 : row->setAssocNature(assocNature);
287 :
288 0 : row->setAssocFocusModelId(assocFocusModelId);
289 :
290 0 : return row;
291 : }
292 :
293 :
294 :
295 0 : FocusModelRow* FocusModelTable::newRow(FocusModelRow* row) {
296 0 : return new FocusModelRow(*this, row);
297 : }
298 :
299 : //
300 : // Append a row to its table.
301 : //
302 :
303 :
304 :
305 :
306 : /**
307 : * Look up the table for a row whose noautoincrementable attributes are matching their
308 : * homologues in *x. If a row is found this row else autoincrement *x.focusModelId,
309 : * add x to its table and returns x.
310 : *
311 : * @returns a pointer on a FocusModelRow.
312 : * @param x. A pointer on the row to be added.
313 : */
314 :
315 :
316 0 : FocusModelRow* FocusModelTable::add(FocusModelRow* x) {
317 0 : FocusModelRow* aRow = lookup(
318 :
319 0 : x->getAntennaId()
320 : ,
321 : x->getPolarizationType()
322 : ,
323 : x->getReceiverBand()
324 : ,
325 : x->getNumCoeff()
326 : ,
327 0 : x->getCoeffName()
328 : ,
329 0 : x->getCoeffFormula()
330 : ,
331 0 : x->getCoeffVal()
332 : ,
333 0 : x->getAssocNature()
334 : ,
335 : x->getAssocFocusModelId()
336 :
337 : );
338 0 : if (aRow) return aRow;
339 :
340 : // Autoincrementation algorithm. We use the hashtable.
341 0 : ostringstream noAutoIncIdsEntry;
342 : noAutoIncIdsEntry
343 :
344 :
345 0 : << x->antennaId.toString() << "_"
346 :
347 :
348 : ;
349 :
350 0 : map<string, int>::iterator iter;
351 0 : if ((iter=noAutoIncIds.find(noAutoIncIdsEntry.str())) == noAutoIncIds.end()) {
352 : // There is not yet a combination of the non autoinc attributes values in the hashtable
353 :
354 :
355 : // Initialize focusModelId to 0.
356 0 : x->focusModelId = 0;
357 : //x->setFocusModelId(0);
358 :
359 : // Record it in the map.
360 0 : noAutoIncIds.insert(make_pair(noAutoIncIdsEntry.str(), 0));
361 : }
362 : else {
363 : // There is already a combination of the non autoinc attributes values in the hashtable
364 : // Increment its value.
365 0 : int n = iter->second + 1;
366 :
367 : // Initialize focusModelId to n.
368 : //x->setFocusModelId(n);
369 0 : x->focusModelId = n;
370 :
371 : // Record it in the map.
372 0 : noAutoIncIds.erase(iter);
373 0 : noAutoIncIds.insert(make_pair(noAutoIncIdsEntry.str(), n));
374 : }
375 :
376 0 : row.push_back(x);
377 0 : privateRows.push_back(x);
378 0 : x->isAdded(true);
379 0 : return x;
380 0 : }
381 :
382 :
383 :
384 0 : void FocusModelTable::addWithoutCheckingUnique(FocusModelRow * x) {
385 0 : if (getRowByKey(
386 0 : x->getAntennaId()
387 : ,
388 : x->getFocusModelId()
389 0 : ) != (FocusModelRow *) 0)
390 0 : throw DuplicateKey("Dupicate key exception in ", "FocusModelTable");
391 0 : row.push_back(x);
392 0 : privateRows.push_back(x);
393 0 : x->isAdded(true);
394 0 : }
395 :
396 :
397 :
398 :
399 : //
400 : // A private method to append a row to its table, used by input conversion
401 : // methods, with row uniqueness.
402 : //
403 :
404 :
405 : /**
406 : * If this table has an autoincrementable attribute then check if *x verifies the rule of uniqueness and throw exception if not.
407 : * Check if *x verifies the key uniqueness rule and throw an exception if not.
408 : * Append x to its table.
409 : * @param x a pointer on the row to be appended.
410 : * @returns a pointer on x.
411 : * @throws DuplicateKey
412 :
413 : * @throws UniquenessViolationException
414 :
415 : */
416 0 : FocusModelRow* FocusModelTable::checkAndAdd(FocusModelRow* x, bool skipCheckUniqueness) {
417 0 : if (!skipCheckUniqueness) {
418 :
419 :
420 0 : if (lookup(
421 :
422 0 : x->getAntennaId()
423 : ,
424 : x->getPolarizationType()
425 : ,
426 : x->getReceiverBand()
427 : ,
428 : x->getNumCoeff()
429 : ,
430 0 : x->getCoeffName()
431 : ,
432 0 : x->getCoeffFormula()
433 : ,
434 0 : x->getCoeffVal()
435 : ,
436 0 : x->getAssocNature()
437 : ,
438 : x->getAssocFocusModelId()
439 :
440 0 : )) throw UniquenessViolationException();
441 :
442 :
443 : }
444 :
445 0 : if (getRowByKey(
446 :
447 0 : x->getAntennaId()
448 : ,
449 : x->getFocusModelId()
450 :
451 0 : )) throw DuplicateKey("Duplicate key exception in ", "FocusModelTable");
452 :
453 0 : row.push_back(x);
454 0 : privateRows.push_back(x);
455 0 : x->isAdded(true);
456 0 : return x;
457 : }
458 :
459 :
460 :
461 : //
462 : // A private method to brutally append a row to its table, without checking for row uniqueness.
463 : //
464 :
465 0 : void FocusModelTable::append(FocusModelRow *x) {
466 0 : privateRows.push_back(x);
467 0 : x->isAdded(true);
468 0 : }
469 :
470 :
471 :
472 :
473 :
474 0 : vector<FocusModelRow *> FocusModelTable::get() {
475 0 : checkPresenceInMemory();
476 0 : return privateRows;
477 : }
478 :
479 0 : const vector<FocusModelRow *>& FocusModelTable::get() const {
480 0 : const_cast<FocusModelTable&>(*this).checkPresenceInMemory();
481 0 : return privateRows;
482 : }
483 :
484 :
485 :
486 :
487 :
488 :
489 :
490 :
491 : /*
492 : ** Returns a FocusModelRow* given a key.
493 : ** @return a pointer to the row having the key whose values are passed as parameters, or 0 if
494 : ** no row exists for that key.
495 : **
496 : */
497 0 : FocusModelRow* FocusModelTable::getRowByKey(Tag antennaId, int focusModelId) {
498 0 : checkPresenceInMemory();
499 0 : FocusModelRow* aRow = 0;
500 0 : for (unsigned int i = 0; i < privateRows.size(); i++) {
501 0 : aRow = row.at(i);
502 :
503 :
504 0 : if (aRow->antennaId != antennaId) continue;
505 :
506 :
507 :
508 0 : if (aRow->focusModelId != focusModelId) continue;
509 :
510 :
511 0 : return aRow;
512 : }
513 0 : return 0;
514 : }
515 :
516 :
517 :
518 : /**
519 : * Look up the table for a row whose all attributes except the autoincrementable one
520 : * are equal to the corresponding parameters of the method.
521 : * @return a pointer on this row if any, 0 otherwise.
522 : *
523 :
524 : * @param antennaId.
525 :
526 : * @param polarizationType.
527 :
528 : * @param receiverBand.
529 :
530 : * @param numCoeff.
531 :
532 : * @param coeffName.
533 :
534 : * @param coeffFormula.
535 :
536 : * @param coeffVal.
537 :
538 : * @param assocNature.
539 :
540 : * @param assocFocusModelId.
541 :
542 : */
543 0 : FocusModelRow* FocusModelTable::lookup(Tag antennaId, PolarizationTypeMod::PolarizationType polarizationType, ReceiverBandMod::ReceiverBand receiverBand, int numCoeff, std::vector<std::string > coeffName, std::vector<std::string > coeffFormula, std::vector<float > coeffVal, std::string assocNature, int assocFocusModelId) {
544 : FocusModelRow* aRow;
545 0 : for (unsigned int i = 0; i < privateRows.size(); i++) {
546 0 : aRow = privateRows.at(i);
547 0 : if (aRow->compareNoAutoInc(antennaId, polarizationType, receiverBand, numCoeff, coeffName, coeffFormula, coeffVal, assocNature, assocFocusModelId)) return aRow;
548 : }
549 0 : return 0;
550 : }
551 :
552 :
553 :
554 :
555 : /*
556 : * Returns a vector of pointers on rows whose key element focusModelId
557 : * is equal to the parameter focusModelId.
558 : * @return a vector of vector <FocusModelRow *>. A returned vector of size 0 means that no row has been found.
559 : * @param focusModelId int contains the value of
560 : * the autoincrementable attribute that is looked up in the table.
561 : */
562 0 : vector <FocusModelRow *> FocusModelTable::getRowByFocusModelId(int focusModelId) {
563 0 : checkPresenceInMemory();
564 0 : vector<FocusModelRow *> list;
565 0 : for (unsigned int i = 0; i < row.size(); ++i) {
566 0 : FocusModelRow &x = *row[i];
567 :
568 0 : if (x.focusModelId == focusModelId)
569 :
570 0 : list.push_back(row[i]);
571 : }
572 : //if (list.size() == 0) throw NoSuchRow("","FocusModel");
573 0 : return list;
574 0 : }
575 :
576 :
577 :
578 :
579 : #ifndef WITHOUT_ACS
580 : using asdmIDL::FocusModelTableIDL;
581 : #endif
582 :
583 : #ifndef WITHOUT_ACS
584 : // Conversion Methods
585 :
586 : FocusModelTableIDL *FocusModelTable::toIDL() {
587 : FocusModelTableIDL *x = new FocusModelTableIDL ();
588 : unsigned int nrow = size();
589 : x->row.length(nrow);
590 : vector<FocusModelRow*> v = get();
591 : for (unsigned int i = 0; i < nrow; ++i) {
592 : //x->row[i] = *(v[i]->toIDL());
593 : v[i]->toIDL(x->row[i]);
594 : }
595 : return x;
596 : }
597 :
598 : void FocusModelTable::toIDL(asdmIDL::FocusModelTableIDL& x) const {
599 : unsigned int nrow = size();
600 : x.row.length(nrow);
601 : vector<FocusModelRow*> v = get();
602 : for (unsigned int i = 0; i < nrow; ++i) {
603 : v[i]->toIDL(x.row[i]);
604 : }
605 : }
606 : #endif
607 :
608 : #ifndef WITHOUT_ACS
609 : void FocusModelTable::fromIDL(FocusModelTableIDL x) {
610 : unsigned int nrow = x.row.length();
611 : for (unsigned int i = 0; i < nrow; ++i) {
612 : FocusModelRow *tmp = newRow();
613 : tmp->setFromIDL(x.row[i]);
614 : // checkAndAdd(tmp);
615 : add(tmp);
616 : }
617 : }
618 : #endif
619 :
620 :
621 0 : string FocusModelTable::toXML() {
622 0 : string buf;
623 :
624 0 : buf.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> ");
625 0 : buf.append("<FocusModelTable xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:focsm=\"http://Alma/XASDM/FocusModelTable\" xsi:schemaLocation=\"http://Alma/XASDM/FocusModelTable http://almaobservatory.org/XML/XASDM/4/FocusModelTable.xsd\" schemaVersion=\"4\" schemaRevision=\"-1\">\n");
626 :
627 0 : buf.append(entity.toXML());
628 0 : string s = container.getEntity().toXML();
629 : // Change the "Entity" tag to "ContainerEntity".
630 0 : buf.append("<Container" + s.substr(1,s.length() - 1)+" ");
631 0 : vector<FocusModelRow*> v = get();
632 0 : for (unsigned int i = 0; i < v.size(); ++i) {
633 : try {
634 0 : buf.append(v[i]->toXML());
635 0 : } catch (const NoSuchRow &e) {
636 0 : }
637 0 : buf.append(" ");
638 : }
639 0 : buf.append("</FocusModelTable> ");
640 0 : return buf;
641 0 : }
642 :
643 :
644 0 : string FocusModelTable::getVersion() const {
645 0 : return version;
646 : }
647 :
648 :
649 0 : void FocusModelTable::fromXML(string& tableInXML) {
650 : //
651 : // Look for a version information in the schemaVersion of the XML
652 : //
653 : xmlDoc *doc;
654 : #if LIBXML_VERSION >= 20703
655 0 : doc = xmlReadMemory(tableInXML.data(), tableInXML.size(), "XMLTableHeader.xml", NULL, XML_PARSE_NOBLANKS|XML_PARSE_HUGE);
656 : #else
657 : doc = xmlReadMemory(tableInXML.data(), tableInXML.size(), "XMLTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
658 : #endif
659 0 : if ( doc == NULL )
660 0 : throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "FocusModel");
661 :
662 0 : xmlNode* root_element = xmlDocGetRootElement(doc);
663 0 : if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
664 0 : throw ConversionException("Failed to retrieve the root element in the DOM structure.", "FocusModel");
665 :
666 0 : xmlChar * propValue = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
667 0 : if ( propValue != 0 ) {
668 0 : version = string( (const char*) propValue);
669 0 : xmlFree(propValue);
670 : }
671 :
672 0 : Parser xml(tableInXML);
673 0 : if (!xml.isStr("<FocusModelTable"))
674 0 : error();
675 : // cout << "Parsing a FocusModelTable" << endl;
676 0 : string s = xml.getElement("<Entity","/>");
677 0 : if (s.length() == 0)
678 0 : error();
679 0 : Entity e;
680 0 : e.setFromXML(s);
681 0 : if (e.getEntityTypeName() != "FocusModelTable")
682 0 : error();
683 0 : setEntity(e);
684 : // Skip the container's entity; but, it has to be there.
685 0 : s = xml.getElement("<ContainerEntity","/>");
686 0 : if (s.length() == 0)
687 0 : error();
688 :
689 : // Get each row in the table.
690 0 : s = xml.getElementContent("<row>","</row>");
691 : FocusModelRow *row;
692 0 : if (getContainer().checkRowUniqueness()) {
693 : try {
694 0 : while (s.length() != 0) {
695 0 : row = newRow();
696 0 : row->setFromXML(s);
697 0 : checkAndAdd(row);
698 0 : s = xml.getElementContent("<row>","</row>");
699 : }
700 :
701 : }
702 0 : catch (const DuplicateKey &e1) {
703 0 : throw ConversionException(e1.getMessage(),"FocusModelTable");
704 0 : }
705 0 : catch (const UniquenessViolationException &e1) {
706 0 : throw ConversionException(e1.getMessage(),"FocusModelTable");
707 0 : }
708 0 : catch (...) {
709 : // cout << "Unexpected error in FocusModelTable::checkAndAdd called from FocusModelTable::fromXML " << endl;
710 0 : }
711 : }
712 : else {
713 : try {
714 0 : while (s.length() != 0) {
715 0 : row = newRow();
716 0 : row->setFromXML(s);
717 0 : addWithoutCheckingUnique(row);
718 0 : s = xml.getElementContent("<row>","</row>");
719 : }
720 : }
721 0 : catch (const DuplicateKey &e1) {
722 0 : throw ConversionException(e1.getMessage(),"FocusModelTable");
723 0 : }
724 0 : catch (...) {
725 : // cout << "Unexpected error in FocusModelTable::addWithoutCheckingUnique called from FocusModelTable::fromXML " << endl;
726 0 : }
727 : }
728 :
729 :
730 0 : if (!xml.isStr("</FocusModelTable>"))
731 0 : error();
732 :
733 : //Does not change the convention defined in the model.
734 : //archiveAsBin = false;
735 : //fileAsBin = false;
736 :
737 : // clean up the xmlDoc pointer
738 0 : if ( doc != NULL ) xmlFreeDoc(doc);
739 :
740 0 : }
741 :
742 :
743 0 : void FocusModelTable::error() {
744 0 : throw ConversionException("Invalid xml document","FocusModel");
745 : }
746 :
747 :
748 0 : string FocusModelTable::MIMEXMLPart(const asdm::ByteOrder* byteOrder) {
749 0 : string UID = getEntity().getEntityId().toString();
750 0 : string withoutUID = UID.substr(6);
751 0 : string containerUID = getContainer().getEntity().getEntityId().toString();
752 0 : ostringstream oss;
753 0 : oss << "<?xml version='1.0' encoding='ISO-8859-1'?>";
754 0 : oss << "\n";
755 0 : oss << "<FocusModelTable xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:focsm=\"http://Alma/XASDM/FocusModelTable\" xsi:schemaLocation=\"http://Alma/XASDM/FocusModelTable http://almaobservatory.org/XML/XASDM/4/FocusModelTable.xsd\" schemaVersion=\"4\" schemaRevision=\"-1\">\n";
756 0 : oss<< "<Entity entityId='"<<UID<<"' entityIdEncrypted='na' entityTypeName='FocusModelTable' schemaVersion='1' documentVersion='1'/>\n";
757 0 : oss<< "<ContainerEntity entityId='"<<containerUID<<"' entityIdEncrypted='na' entityTypeName='ASDM' schemaVersion='1' documentVersion='1'/>\n";
758 0 : oss << "<BulkStoreRef file_id='"<<withoutUID<<"' byteOrder='"<<byteOrder->toString()<<"' />\n";
759 0 : oss << "<Attributes>\n";
760 :
761 0 : oss << "<antennaId/>\n";
762 0 : oss << "<focusModelId/>\n";
763 0 : oss << "<polarizationType/>\n";
764 0 : oss << "<receiverBand/>\n";
765 0 : oss << "<numCoeff/>\n";
766 0 : oss << "<coeffName/>\n";
767 0 : oss << "<coeffFormula/>\n";
768 0 : oss << "<coeffVal/>\n";
769 0 : oss << "<assocNature/>\n";
770 0 : oss << "<assocFocusModelId/>\n";
771 :
772 0 : oss << "</Attributes>\n";
773 0 : oss << "</FocusModelTable>\n";
774 :
775 0 : return oss.str();
776 0 : }
777 :
778 0 : string FocusModelTable::toMIME(const asdm::ByteOrder* byteOrder) {
779 0 : EndianOSStream eoss(byteOrder);
780 :
781 0 : string UID = getEntity().getEntityId().toString();
782 :
783 : // The MIME Header
784 0 : eoss <<"MIME-Version: 1.0";
785 0 : eoss << "\n";
786 0 : eoss << "Content-Type: Multipart/Related; boundary='MIME_boundary'; type='text/xml'; start= '<header.xml>'";
787 0 : eoss <<"\n";
788 0 : eoss <<"Content-Description: Correlator";
789 0 : eoss <<"\n";
790 0 : eoss <<"alma-uid:" << UID;
791 0 : eoss <<"\n";
792 0 : eoss <<"\n";
793 :
794 : // The MIME XML part header.
795 0 : eoss <<"--MIME_boundary";
796 0 : eoss <<"\n";
797 0 : eoss <<"Content-Type: text/xml; charset='ISO-8859-1'";
798 0 : eoss <<"\n";
799 0 : eoss <<"Content-Transfer-Encoding: 8bit";
800 0 : eoss <<"\n";
801 0 : eoss <<"Content-ID: <header.xml>";
802 0 : eoss <<"\n";
803 0 : eoss <<"\n";
804 :
805 : // The MIME XML part content.
806 0 : eoss << MIMEXMLPart(byteOrder);
807 :
808 : // The MIME binary part header
809 0 : eoss <<"--MIME_boundary";
810 0 : eoss <<"\n";
811 0 : eoss <<"Content-Type: binary/octet-stream";
812 0 : eoss <<"\n";
813 0 : eoss <<"Content-ID: <content.bin>";
814 0 : eoss <<"\n";
815 0 : eoss <<"\n";
816 :
817 : // The MIME binary content
818 0 : entity.toBin(eoss);
819 0 : container.getEntity().toBin(eoss);
820 0 : eoss.writeInt((int) privateRows.size());
821 0 : for (unsigned int i = 0; i < privateRows.size(); i++) {
822 0 : privateRows.at(i)->toBin(eoss);
823 : }
824 :
825 : // The closing MIME boundary
826 0 : eoss << "\n--MIME_boundary--";
827 0 : eoss << "\n";
828 :
829 0 : return eoss.str();
830 0 : }
831 :
832 :
833 0 : void FocusModelTable::setFromMIME(const string & mimeMsg) {
834 0 : string xmlPartMIMEHeader = "Content-ID: <header.xml>\n\n";
835 :
836 0 : string binPartMIMEHeader = "--MIME_boundary\nContent-Type: binary/octet-stream\nContent-ID: <content.bin>\n\n";
837 :
838 : // Detect the XML header.
839 0 : string::size_type loc0 = mimeMsg.find(xmlPartMIMEHeader, 0);
840 0 : if ( loc0 == string::npos) {
841 : // let's try with CRLFs
842 0 : xmlPartMIMEHeader = "Content-ID: <header.xml>\r\n\r\n";
843 0 : loc0 = mimeMsg.find(xmlPartMIMEHeader, 0);
844 0 : if ( loc0 == string::npos )
845 0 : throw ConversionException("Failed to detect the beginning of the XML header", "FocusModel");
846 : }
847 :
848 0 : loc0 += xmlPartMIMEHeader.size();
849 :
850 : // Look for the string announcing the binary part.
851 0 : string::size_type loc1 = mimeMsg.find( binPartMIMEHeader, loc0 );
852 :
853 0 : if ( loc1 == string::npos ) {
854 0 : throw ConversionException("Failed to detect the beginning of the binary part", "FocusModel");
855 : }
856 :
857 : //
858 : // Extract the xmlHeader and analyze it to find out what is the byte order and the sequence
859 : // of attribute names.
860 : //
861 0 : string xmlHeader = mimeMsg.substr(loc0, loc1-loc0);
862 : xmlDoc *doc;
863 0 : doc = xmlReadMemory(xmlHeader.data(), xmlHeader.size(), "BinaryTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
864 0 : if ( doc == NULL )
865 0 : throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "FocusModel");
866 :
867 : // This vector will be filled by the names of all the attributes of the table
868 : // in the order in which they are expected to be found in the binary representation.
869 : //
870 0 : vector<string> attributesSeq;
871 :
872 0 : xmlNode* root_element = xmlDocGetRootElement(doc);
873 0 : if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
874 0 : throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "FocusModel");
875 :
876 0 : const ByteOrder* byteOrder=0;
877 0 : if ( string("ASDMBinaryTable").compare((const char*) root_element->name) == 0) {
878 : // Then it's an "old fashioned" MIME file for tables.
879 : // Just try to deserialize it with Big_Endian for the bytes ordering.
880 0 : byteOrder = asdm::ByteOrder::Big_Endian;
881 :
882 : //
883 : // Let's consider a default order for the sequence of attributes.
884 : //
885 :
886 :
887 0 : attributesSeq.push_back("antennaId") ;
888 :
889 0 : attributesSeq.push_back("focusModelId") ;
890 :
891 0 : attributesSeq.push_back("polarizationType") ;
892 :
893 0 : attributesSeq.push_back("receiverBand") ;
894 :
895 0 : attributesSeq.push_back("numCoeff") ;
896 :
897 0 : attributesSeq.push_back("coeffName") ;
898 :
899 0 : attributesSeq.push_back("coeffFormula") ;
900 :
901 0 : attributesSeq.push_back("coeffVal") ;
902 :
903 0 : attributesSeq.push_back("assocNature") ;
904 :
905 0 : attributesSeq.push_back("assocFocusModelId") ;
906 :
907 :
908 :
909 :
910 :
911 : // And decide that it has version == "2"
912 0 : version = "2";
913 : }
914 0 : else if (string("FocusModelTable").compare((const char*) root_element->name) == 0) {
915 : // It's a new (and correct) MIME file for tables.
916 : //
917 : // 1st ) Look for a BulkStoreRef element with an attribute byteOrder.
918 : //
919 0 : xmlNode* bulkStoreRef = 0;
920 0 : xmlNode* child = root_element->children;
921 :
922 0 : if (xmlHasProp(root_element, (const xmlChar*) "schemaVersion")) {
923 0 : xmlChar * value = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
924 0 : version = string ((const char *) value);
925 0 : xmlFree(value);
926 : }
927 :
928 : // Skip the two first children (Entity and ContainerEntity).
929 0 : bulkStoreRef = (child == 0) ? 0 : ( (child->next) == 0 ? 0 : child->next->next );
930 :
931 0 : if ( bulkStoreRef == 0 || (bulkStoreRef->type != XML_ELEMENT_NODE) || (string("BulkStoreRef").compare((const char*) bulkStoreRef->name) != 0))
932 0 : throw ConversionException ("Could not find the element '/FocusModelTable/BulkStoreRef'. Invalid XML header '"+ xmlHeader + "'.", "FocusModel");
933 :
934 : // We found BulkStoreRef, now look for its attribute byteOrder.
935 0 : _xmlAttr* byteOrderAttr = 0;
936 0 : for (struct _xmlAttr* attr = bulkStoreRef->properties; attr; attr = attr->next)
937 0 : if (string("byteOrder").compare((const char*) attr->name) == 0) {
938 0 : byteOrderAttr = attr;
939 0 : break;
940 : }
941 :
942 0 : if (byteOrderAttr == 0)
943 0 : throw ConversionException("Could not find the element '/FocusModelTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader +"'.", "FocusModel");
944 :
945 0 : string byteOrderValue = string((const char*) byteOrderAttr->children->content);
946 0 : if (!(byteOrder = asdm::ByteOrder::fromString(byteOrderValue)))
947 0 : throw ConversionException("No valid value retrieved for the element '/FocusModelTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader + "'.", "FocusModel");
948 :
949 : //
950 : // 2nd) Look for the Attributes element and grab the names of the elements it contains.
951 : //
952 0 : xmlNode* attributes = bulkStoreRef->next;
953 0 : if ( attributes == 0 || (attributes->type != XML_ELEMENT_NODE) || (string("Attributes").compare((const char*) attributes->name) != 0))
954 0 : throw ConversionException ("Could not find the element '/FocusModelTable/Attributes'. Invalid XML header '"+ xmlHeader + "'.", "FocusModel");
955 :
956 0 : xmlNode* childOfAttributes = attributes->children;
957 :
958 0 : while ( childOfAttributes != 0 && (childOfAttributes->type == XML_ELEMENT_NODE) ) {
959 0 : attributesSeq.push_back(string((const char*) childOfAttributes->name));
960 0 : childOfAttributes = childOfAttributes->next;
961 : }
962 0 : }
963 : // Create an EndianISStream from the substring containing the binary part.
964 0 : EndianISStream eiss(mimeMsg.substr(loc1+binPartMIMEHeader.size()), byteOrder);
965 :
966 0 : entity = Entity::fromBin((EndianIStream&) eiss);
967 :
968 : // We do nothing with that but we have to read it.
969 0 : Entity containerEntity = Entity::fromBin((EndianIStream&) eiss);
970 :
971 : // Let's read numRows but ignore it and rely on the value specified in the ASDM.xml file.
972 0 : int numRows = ((EndianIStream&) eiss).readInt();
973 0 : if ((numRows != -1) // Then these are *not* data produced at the EVLA.
974 0 : && ((unsigned int) numRows != this->declaredSize )) { // Then the declared size (in ASDM.xml) is not equal to the one
975 : // written into the binary representation of the table.
976 0 : cout << "The a number of rows ('"
977 : << numRows
978 0 : << "') declared in the binary representation of the table is different from the one declared in ASDM.xml ('"
979 0 : << this->declaredSize
980 0 : << "'). I'll proceed with the value declared in ASDM.xml"
981 0 : << endl;
982 : }
983 :
984 0 : if (getContainer().checkRowUniqueness()) {
985 : try {
986 0 : for (uint32_t i = 0; i < this->declaredSize; i++) {
987 0 : FocusModelRow* aRow = FocusModelRow::fromBin((EndianIStream&) eiss, *this, attributesSeq);
988 0 : checkAndAdd(aRow);
989 : }
990 : }
991 0 : catch (const DuplicateKey &e) {
992 0 : throw ConversionException("Error while writing binary data , the message was "
993 0 : + e.getMessage(), "FocusModel");
994 0 : }
995 0 : catch (const TagFormatException &e) {
996 0 : throw ConversionException("Error while reading binary data , the message was "
997 0 : + e.getMessage(), "FocusModel");
998 0 : }
999 : }
1000 : else {
1001 0 : for (uint32_t i = 0; i < this->declaredSize; i++) {
1002 0 : FocusModelRow* aRow = FocusModelRow::fromBin((EndianIStream&) eiss, *this, attributesSeq);
1003 0 : append(aRow);
1004 : }
1005 : }
1006 : //Does not change the convention defined in the model.
1007 : //archiveAsBin = true;
1008 : //fileAsBin = true;
1009 0 : if ( doc != NULL ) xmlFreeDoc(doc);
1010 :
1011 0 : }
1012 :
1013 0 : void FocusModelTable::setUnknownAttributeBinaryReader(const string& attributeName, BinaryAttributeReaderFunctor* barFctr) {
1014 : //
1015 : // Is this attribute really unknown ?
1016 : //
1017 0 : for (vector<string>::const_iterator iter = attributesNamesOfFocusModel_v.begin(); iter != attributesNamesOfFocusModel_v.end(); iter++) {
1018 0 : if ((*iter).compare(attributeName) == 0)
1019 0 : throw ConversionException("the attribute '"+attributeName+"' is known you can't override the way it's read in the MIME binary file containing the table.", "FocusModel");
1020 : }
1021 :
1022 : // Ok then register the functor to activate when an unknown attribute is met during the reading of a binary table?
1023 0 : unknownAttributes2Functors[attributeName] = barFctr;
1024 0 : }
1025 :
1026 0 : BinaryAttributeReaderFunctor* FocusModelTable::getUnknownAttributeBinaryReader(const string& attributeName) const {
1027 0 : map<string, BinaryAttributeReaderFunctor*>::const_iterator iter = unknownAttributes2Functors.find(attributeName);
1028 0 : return (iter == unknownAttributes2Functors.end()) ? 0 : iter->second;
1029 : }
1030 :
1031 :
1032 0 : void FocusModelTable::toFile(string directory) {
1033 0 : if (!directoryExists(directory.c_str()) &&
1034 0 : !createPath(directory.c_str())) {
1035 0 : throw ConversionException("Could not create directory " , directory);
1036 : }
1037 :
1038 0 : string fileName = directory + "/FocusModel.xml";
1039 0 : ofstream tableout(fileName.c_str(),ios::out|ios::trunc);
1040 0 : if (tableout.rdstate() == ostream::failbit)
1041 0 : throw ConversionException("Could not open file " + fileName + " to write ", "FocusModel");
1042 0 : if (fileAsBin)
1043 0 : tableout << MIMEXMLPart();
1044 : else
1045 0 : tableout << toXML() << endl;
1046 0 : tableout.close();
1047 0 : if (tableout.rdstate() == ostream::failbit)
1048 0 : throw ConversionException("Could not close file " + fileName, "FocusModel");
1049 :
1050 0 : if (fileAsBin) {
1051 : // write the bin serialized
1052 0 : string fileName = directory + "/FocusModel.bin";
1053 0 : ofstream tableout(fileName.c_str(),ios::out|ios::trunc);
1054 0 : if (tableout.rdstate() == ostream::failbit)
1055 0 : throw ConversionException("Could not open file " + fileName + " to write ", "FocusModel");
1056 0 : tableout << toMIME() << endl;
1057 0 : tableout.close();
1058 0 : if (tableout.rdstate() == ostream::failbit)
1059 0 : throw ConversionException("Could not close file " + fileName, "FocusModel");
1060 0 : }
1061 0 : }
1062 :
1063 :
1064 0 : void FocusModelTable::setFromFile(const string& directory) {
1065 : #ifndef WITHOUT_BOOST
1066 : if (boost::filesystem::exists(boost::filesystem::path(uniqSlashes(directory + "/FocusModel.xml"))))
1067 : setFromXMLFile(directory);
1068 : else if (boost::filesystem::exists(boost::filesystem::path(uniqSlashes(directory + "/FocusModel.bin"))))
1069 : setFromMIMEFile(directory);
1070 : #else
1071 : // alternative in Misc.h
1072 0 : if (file_exists(uniqSlashes(directory + "/FocusModel.xml")))
1073 0 : setFromXMLFile(directory);
1074 0 : else if (file_exists(uniqSlashes(directory + "/FocusModel.bin")))
1075 0 : setFromMIMEFile(directory);
1076 : #endif
1077 : else
1078 0 : throw ConversionException("No file found for the FocusModel table", "FocusModel");
1079 0 : }
1080 :
1081 :
1082 0 : void FocusModelTable::setFromMIMEFile(const string& directory) {
1083 0 : string tablePath ;
1084 :
1085 0 : tablePath = directory + "/FocusModel.bin";
1086 0 : ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
1087 0 : if (!tablefile.is_open()) {
1088 0 : throw ConversionException("Could not open file " + tablePath, "FocusModel");
1089 : }
1090 : // Read in a stringstream.
1091 0 : stringstream ss; ss << tablefile.rdbuf();
1092 :
1093 0 : if (tablefile.rdstate() == istream::failbit || tablefile.rdstate() == istream::badbit) {
1094 0 : throw ConversionException("Error reading file " + tablePath,"FocusModel");
1095 : }
1096 :
1097 : // And close.
1098 0 : tablefile.close();
1099 0 : if (tablefile.rdstate() == istream::failbit)
1100 0 : throw ConversionException("Could not close file " + tablePath,"FocusModel");
1101 :
1102 0 : setFromMIME(ss.str());
1103 0 : }
1104 : /*
1105 : void FocusModelTable::openMIMEFile (const string& directory) {
1106 :
1107 : // Open the file.
1108 : string tablePath ;
1109 : tablePath = directory + "/FocusModel.bin";
1110 : ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
1111 : if (!tablefile.is_open())
1112 : throw ConversionException("Could not open file " + tablePath, "FocusModel");
1113 :
1114 : // Locate the xmlPartMIMEHeader.
1115 : string xmlPartMIMEHeader = "CONTENT-ID: <HEADER.XML>\n\n";
1116 : CharComparator comparator;
1117 : istreambuf_iterator<char> BEGIN(tablefile.rdbuf());
1118 : istreambuf_iterator<char> END;
1119 : istreambuf_iterator<char> it = search(BEGIN, END, xmlPartMIMEHeader.begin(), xmlPartMIMEHeader.end(), comparator);
1120 : if (it == END)
1121 : throw ConversionException("failed to detect the beginning of the XML header", "FocusModel");
1122 :
1123 : // Locate the binaryPartMIMEHeader while accumulating the characters of the xml header.
1124 : string binPartMIMEHeader = "--MIME_BOUNDARY\nCONTENT-TYPE: BINARY/OCTET-STREAM\nCONTENT-ID: <CONTENT.BIN>\n\n";
1125 : string xmlHeader;
1126 : CharCompAccumulator compaccumulator(&xmlHeader, 100000);
1127 : ++it;
1128 : it = search(it, END, binPartMIMEHeader.begin(), binPartMIMEHeader.end(), compaccumulator);
1129 : if (it == END)
1130 : throw ConversionException("failed to detect the beginning of the binary part", "FocusModel");
1131 :
1132 : cout << xmlHeader << endl;
1133 : //
1134 : // We have the xmlHeader , let's parse it.
1135 : //
1136 : xmlDoc *doc;
1137 : doc = xmlReadMemory(xmlHeader.data(), xmlHeader.size(), "BinaryTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
1138 : if ( doc == NULL )
1139 : throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "FocusModel");
1140 :
1141 : // This vector will be filled by the names of all the attributes of the table
1142 : // in the order in which they are expected to be found in the binary representation.
1143 : //
1144 : vector<string> attributesSeq(attributesNamesInBinOfFocusModel_v);
1145 :
1146 : xmlNode* root_element = xmlDocGetRootElement(doc);
1147 : if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
1148 : throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "FocusModel");
1149 :
1150 : const ByteOrder* byteOrder=0;
1151 : if ( string("ASDMBinaryTable").compare((const char*) root_element->name) == 0) {
1152 : // Then it's an "old fashioned" MIME file for tables.
1153 : // Just try to deserialize it with Big_Endian for the bytes ordering.
1154 : byteOrder = asdm::ByteOrder::Big_Endian;
1155 :
1156 : // And decide that it has version == "2"
1157 : version = "2";
1158 : }
1159 : else if (string("FocusModelTable").compare((const char*) root_element->name) == 0) {
1160 : // It's a new (and correct) MIME file for tables.
1161 : //
1162 : // 1st ) Look for a BulkStoreRef element with an attribute byteOrder.
1163 : //
1164 : xmlNode* bulkStoreRef = 0;
1165 : xmlNode* child = root_element->children;
1166 :
1167 : if (xmlHasProp(root_element, (const xmlChar*) "schemaVersion")) {
1168 : xmlChar * value = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
1169 : version = string ((const char *) value);
1170 : xmlFree(value);
1171 : }
1172 :
1173 : // Skip the two first children (Entity and ContainerEntity).
1174 : bulkStoreRef = (child == 0) ? 0 : ( (child->next) == 0 ? 0 : child->next->next );
1175 :
1176 : if ( bulkStoreRef == 0 || (bulkStoreRef->type != XML_ELEMENT_NODE) || (string("BulkStoreRef").compare((const char*) bulkStoreRef->name) != 0))
1177 : throw ConversionException ("Could not find the element '/FocusModelTable/BulkStoreRef'. Invalid XML header '"+ xmlHeader + "'.", "FocusModel");
1178 :
1179 : // We found BulkStoreRef, now look for its attribute byteOrder.
1180 : _xmlAttr* byteOrderAttr = 0;
1181 : for (struct _xmlAttr* attr = bulkStoreRef->properties; attr; attr = attr->next)
1182 : if (string("byteOrder").compare((const char*) attr->name) == 0) {
1183 : byteOrderAttr = attr;
1184 : break;
1185 : }
1186 :
1187 : if (byteOrderAttr == 0)
1188 : throw ConversionException("Could not find the element '/FocusModelTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader +"'.", "FocusModel");
1189 :
1190 : string byteOrderValue = string((const char*) byteOrderAttr->children->content);
1191 : if (!(byteOrder = asdm::ByteOrder::fromString(byteOrderValue)))
1192 : throw ConversionException("No valid value retrieved for the element '/FocusModelTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader + "'.", "FocusModel");
1193 :
1194 : //
1195 : // 2nd) Look for the Attributes element and grab the names of the elements it contains.
1196 : //
1197 : xmlNode* attributes = bulkStoreRef->next;
1198 : if ( attributes == 0 || (attributes->type != XML_ELEMENT_NODE) || (string("Attributes").compare((const char*) attributes->name) != 0))
1199 : throw ConversionException ("Could not find the element '/FocusModelTable/Attributes'. Invalid XML header '"+ xmlHeader + "'.", "FocusModel");
1200 :
1201 : xmlNode* childOfAttributes = attributes->children;
1202 :
1203 : while ( childOfAttributes != 0 && (childOfAttributes->type == XML_ELEMENT_NODE) ) {
1204 : attributesSeq.push_back(string((const char*) childOfAttributes->name));
1205 : childOfAttributes = childOfAttributes->next;
1206 : }
1207 : }
1208 : // Create an EndianISStream from the substring containing the binary part.
1209 : EndianIFStream eifs(&tablefile, byteOrder);
1210 :
1211 : entity = Entity::fromBin((EndianIStream &) eifs);
1212 :
1213 : // We do nothing with that but we have to read it.
1214 : Entity containerEntity = Entity::fromBin((EndianIStream &) eifs);
1215 :
1216 : // Let's read numRows but ignore it and rely on the value specified in the ASDM.xml file.
1217 : int numRows = eifs.readInt();
1218 : if ((numRows != -1) // Then these are *not* data produced at the EVLA.
1219 : && ((unsigned int) numRows != this->declaredSize )) { // Then the declared size (in ASDM.xml) is not equal to the one
1220 : // written into the binary representation of the table.
1221 : cout << "The a number of rows ('"
1222 : << numRows
1223 : << "') declared in the binary representation of the table is different from the one declared in ASDM.xml ('"
1224 : << this->declaredSize
1225 : << "'). I'll proceed with the value declared in ASDM.xml"
1226 : << endl;
1227 : }
1228 : // clean up xmlDoc pointer
1229 : if ( doc != NULL ) xmlFreeDoc(doc);
1230 : }
1231 : */
1232 :
1233 :
1234 0 : void FocusModelTable::setFromXMLFile(const string& directory) {
1235 0 : string tablePath ;
1236 :
1237 0 : tablePath = directory + "/FocusModel.xml";
1238 :
1239 : /*
1240 : ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
1241 : if (!tablefile.is_open()) {
1242 : throw ConversionException("Could not open file " + tablePath, "FocusModel");
1243 : }
1244 : // Read in a stringstream.
1245 : stringstream ss;
1246 : ss << tablefile.rdbuf();
1247 :
1248 : if (tablefile.rdstate() == istream::failbit || tablefile.rdstate() == istream::badbit) {
1249 : throw ConversionException("Error reading file '" + tablePath + "'", "FocusModel");
1250 : }
1251 :
1252 : // And close
1253 : tablefile.close();
1254 : if (tablefile.rdstate() == istream::failbit)
1255 : throw ConversionException("Could not close file '" + tablePath + "'", "FocusModel");
1256 :
1257 : // Let's make a string out of the stringstream content and empty the stringstream.
1258 : string xmlDocument = ss.str(); ss.str("");
1259 :
1260 : // Let's make a very primitive check to decide
1261 : // whether the XML content represents the table
1262 : // or refers to it via a <BulkStoreRef element.
1263 : */
1264 :
1265 0 : string xmlDocument;
1266 : try {
1267 0 : xmlDocument = getContainer().getXSLTransformer()(tablePath);
1268 0 : if (getenv("ASDM_DEBUG")) cout << "About to read " << tablePath << endl;
1269 : }
1270 0 : catch (const XSLTransformerException &e) {
1271 0 : throw ConversionException("Caugth an exception whose message is '" + e.getMessage() + "'.", "FocusModel");
1272 0 : }
1273 :
1274 0 : if (xmlDocument.find("<BulkStoreRef") != string::npos)
1275 0 : setFromMIMEFile(directory);
1276 : else
1277 0 : fromXML(xmlDocument);
1278 0 : }
1279 :
1280 :
1281 :
1282 :
1283 :
1284 :
1285 :
1286 :
1287 :
1288 :
1289 0 : void FocusModelTable::autoIncrement(string key, FocusModelRow* x) {
1290 0 : map<string, int>::iterator iter;
1291 0 : if ((iter=noAutoIncIds.find(key)) == noAutoIncIds.end()) {
1292 : // There is not yet a combination of the non autoinc attributes values in the hashtable
1293 :
1294 : // Initialize focusModelId to 0.
1295 0 : x->setFocusModelId(0);
1296 :
1297 : // Record it in the map.
1298 0 : noAutoIncIds.insert(make_pair(key, 0));
1299 : }
1300 : else {
1301 : // There is already a combination of the non autoinc attributes values in the hashtable
1302 : // Increment its value.
1303 0 : int n = iter->second + 1;
1304 :
1305 : // Initialize focusModelId to n.
1306 0 : x->setFocusModelId(n);
1307 :
1308 : // Record it in the map.
1309 0 : noAutoIncIds.insert(make_pair(key, n));
1310 : }
1311 0 : }
1312 :
1313 : } // End namespace asdm
1314 :
|