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