00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define FREPPLE_CORE
00029 #include "frepple/model.h"
00030
00031 namespace frepple
00032 {
00033
00034 template<class Calendar> DECLARE_EXPORT Tree utils::HasName<Calendar>::st;
00035 DECLARE_EXPORT const MetaCategory* Calendar::metadata;
00036 DECLARE_EXPORT const MetaCategory* Calendar::Bucket::metadata;
00037 DECLARE_EXPORT const MetaClass *CalendarVoid::metadata,
00038 *CalendarDouble::metadata,
00039 *CalendarInt::metadata,
00040 *CalendarBool::metadata,
00041 *CalendarString::metadata,
00042 *CalendarOperation::metadata;
00043
00044
00045 int Calendar::initialize()
00046 {
00047
00048 metadata = new MetaCategory("calendar", "calendars", reader, writer);
00049
00050
00051 return Calendar::Bucket::initialize() +
00052 FreppleCategory<Calendar>::initialize() +
00053 CalendarBucketIterator::initialize() +
00054 CalendarEventIterator::initialize();
00055 }
00056
00057
00058 int Calendar::Bucket::initialize()
00059 {
00060
00061 metadata = new MetaCategory("bucket", "buckets");
00062
00063
00064 PythonType& x = PythonExtension<Calendar::Bucket>::getType();
00065 x.setName("calendarBucket");
00066 x.setDoc("frePPLe calendar bucket");
00067 x.supportgetattro();
00068 x.supportsetattro();
00069 const_cast<MetaCategory*>(metadata)->pythonClass = x.type_object();
00070 return x.typeReady();
00071 }
00072
00073
00074 int CalendarVoid::initialize()
00075 {
00076
00077 metadata = new MetaClass("calendar", "calendar_void",
00078 Object::createString<CalendarVoid>);
00079
00080
00081 FreppleClass<CalendarVoid,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00082 FreppleClass<CalendarVoid,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00083 return FreppleClass<CalendarVoid,Calendar>::initialize();
00084 }
00085
00086
00087 int CalendarDouble::initialize()
00088 {
00089
00090 metadata = new MetaClass("calendar", "calendar_double",
00091 Object::createString<CalendarDouble>, true);
00092
00093
00094 FreppleClass<CalendarDouble,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00095 FreppleClass<CalendarDouble,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00096 return FreppleClass<CalendarDouble,Calendar>::initialize();
00097 }
00098
00099
00100 int CalendarInt::initialize()
00101 {
00102
00103 metadata = new MetaClass("calendar", "calendar_integer",
00104 Object::createString<CalendarInt>);
00105
00106
00107 FreppleClass<CalendarInt,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00108 FreppleClass<CalendarInt,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00109 return FreppleClass<CalendarInt,Calendar>::initialize();
00110 }
00111
00112
00113 int CalendarBool::initialize()
00114 {
00115
00116 metadata = new MetaClass("calendar", "calendar_boolean",
00117 Object::createString<CalendarBool>);
00118
00119
00120 FreppleClass<CalendarBool,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00121 FreppleClass<CalendarBool,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00122 return FreppleClass<CalendarBool,Calendar>::initialize();
00123 }
00124
00125
00126 int CalendarString::initialize()
00127 {
00128
00129 metadata = new MetaClass("calendar", "calendar_string",
00130 Object::createString<CalendarString>);
00131
00132
00133 FreppleClass<CalendarString,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00134 FreppleClass<CalendarString,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00135 return FreppleClass<CalendarString,Calendar>::initialize();
00136 }
00137
00138
00139 int CalendarOperation::initialize()
00140 {
00141
00142 metadata = new MetaClass("calendar", "calendar_operation",
00143 Object::createString<CalendarOperation>);
00144
00145
00146 FreppleClass<CalendarOperation,Calendar>::getType().addMethod("setValue", setPythonValue, METH_KEYWORDS, "update the value in a date range");
00147 FreppleClass<CalendarOperation,Calendar>::getType().addMethod("events", getEvents, METH_VARARGS, "return an event iterator");
00148 return FreppleClass<CalendarOperation,Calendar>::initialize();
00149 }
00150
00151
00152
00153 template <> DECLARE_EXPORT bool CalendarValue<string>::getBool() const
00154 {return defaultValue.empty();}
00155 template <> DECLARE_EXPORT bool CalendarValue<string>::BucketValue::getBool() const
00156 {return val.empty();}
00157
00158
00159 DECLARE_EXPORT Calendar::~Calendar()
00160 {
00161
00162 while (firstBucket)
00163 {
00164 Bucket* tmp = firstBucket;
00165 firstBucket = firstBucket->nextBucket;
00166 delete tmp;
00167 }
00168 }
00169
00170
00171 DECLARE_EXPORT CalendarDouble::~CalendarDouble()
00172 {
00173
00174 for (Buffer::iterator b = Buffer::begin(); b != Buffer::end(); ++b)
00175 {
00176 if (b->getMinimum()==this) b->setMinimum(NULL);
00177 if (b->getMaximum()==this) b->setMaximum(NULL);
00178 }
00179
00180
00181 for (Resource::iterator r = Resource::begin(); r != Resource::end(); ++r)
00182 if (r->getMaximum()==this) r->setMaximum(NULL);
00183 }
00184
00185
00186 DECLARE_EXPORT CalendarBool::~CalendarBool()
00187 {
00188
00189 for (Location::iterator l = Location::begin(); l != Location::end(); ++l)
00190 {
00191 if (l->getAvailable() == this)
00192 l->setAvailable(NULL);
00193 }
00194 }
00195
00196
00197 DECLARE_EXPORT Calendar::Bucket* Calendar::addBucket
00198 (Date start, Date end, string name)
00199 {
00200
00201 if (start > end)
00202 {
00203
00204 Date tmp = end;
00205 end = start;
00206 start = end;
00207 }
00208
00209
00210 Bucket *next = firstBucket, *prev = NULL;
00211 while (next && next->startdate < start)
00212 {
00213 prev = next;
00214 next = next->nextBucket;
00215 }
00216
00217
00218 Bucket *c = createNewBucket(start,end,name);
00219 c->nextBucket = next;
00220 c->prevBucket = prev;
00221
00222
00223 if (prev) prev->nextBucket = c;
00224 else firstBucket = c;
00225 if (next) next->prevBucket = c;
00226
00227
00228 return c;
00229 }
00230
00231
00232 DECLARE_EXPORT void Calendar::removeBucket(Calendar::Bucket* bkt)
00233 {
00234
00235 Bucket *b = firstBucket;
00236 while (b && b != bkt) b = b->nextBucket;
00237
00238
00239 if (!b)
00240 throw DataException("Trying to remove unavailable bucket from calendar '"
00241 + getName() + "'");
00242
00243
00244 if (bkt->prevBucket)
00245
00246 bkt->prevBucket->nextBucket = bkt->nextBucket;
00247 else
00248
00249 firstBucket = bkt->nextBucket;
00250 if (bkt->nextBucket)
00251
00252 bkt->nextBucket->prevBucket = bkt->prevBucket;
00253
00254
00255 delete bkt;
00256 }
00257
00258
00259 DECLARE_EXPORT Calendar::Bucket* Calendar::findBucket(Date d, bool fwd) const
00260 {
00261 Calendar::Bucket *curBucket = NULL;
00262 double curPriority = DBL_MAX;
00263 for (Bucket *b = firstBucket; b; b = b->nextBucket)
00264 {
00265 if (b->getStart() > d)
00266
00267
00268 break;
00269 else if (curPriority > b->getPriority() && b->checkValid(d)
00270 && ( (fwd && d >= b->getStart() && d < b->getEnd()) ||
00271 (!fwd && d > b->getStart() && d <= b->getEnd())
00272 ))
00273 {
00274
00275 curPriority = b->getPriority();
00276 curBucket = &*b;
00277 }
00278 }
00279 return curBucket;
00280 }
00281
00282
00283 DECLARE_EXPORT Calendar::Bucket* Calendar::findBucket(const string& d) const
00284 {
00285 for (Bucket *b = firstBucket; b; b = b->nextBucket)
00286 if (b->getName() == d) return b;
00287 return NULL;
00288 }
00289
00290
00291 DECLARE_EXPORT void Calendar::writeElement(XMLOutput *o, const Keyword& tag, mode m) const
00292 {
00293
00294 if (m == REFERENCE)
00295 {
00296 o->writeElement
00297 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00298 return;
00299 }
00300
00301
00302 if (m != NOHEADER) o->BeginObject
00303 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00304
00305
00306 o->BeginObject (Tags::tag_buckets);
00307 for (BucketIterator i = beginBuckets(); i != endBuckets(); ++i)
00308
00309
00310 o->writeElement(Tags::tag_bucket, *i, FULL);
00311 o->EndObject(Tags::tag_buckets);
00312
00313 o->EndObject(tag);
00314 }
00315
00316
00317 DECLARE_EXPORT Calendar::Bucket* Calendar::createBucket(const AttributeList& atts)
00318 {
00319
00320 Date startdate = atts.get(Tags::tag_start)->getDate();
00321 const DataElement* d = atts.get(Tags::tag_end);
00322 Date enddate = *d ? d->getDate() : Date::infiniteFuture;
00323 string name = atts.get(Tags::tag_name)->getString();
00324
00325
00326 Calendar::Bucket* result = NULL;
00327 for (BucketIterator x = beginBuckets(); x!=endBuckets(); ++x)
00328 {
00329 if ((!name.empty() && x->nm==name)
00330 || (name.empty() && x->startdate==startdate && x->enddate==enddate))
00331 {
00332
00333 result = &*x;
00334 break;
00335 }
00336 }
00337
00338
00339 switch (MetaClass::decodeAction(atts))
00340 {
00341 case ADD:
00342
00343 if (result)
00344 throw DataException("Bucket " + string(startdate) + " "
00345 + string(enddate) + " " + name
00346 + " already exists in calendar '" + getName() + "'");
00347 result = addBucket(startdate, enddate, name);
00348 return result;
00349 case CHANGE:
00350
00351 if (!result)
00352 throw DataException("Bucket " + string(startdate) + " " + string(enddate)
00353 + " " + name + " doesn't exist in calendar '" + getName() + "'");
00354 return result;
00355 case REMOVE:
00356
00357 if (!result)
00358 throw DataException("Bucket " + string(startdate) + " " + string(enddate)
00359 + " " + name + " doesn't exist in calendar '" + getName() + "'");
00360 else
00361 {
00362
00363 removeBucket(result);
00364 return NULL;
00365 }
00366 case ADD_CHANGE:
00367 if (!result)
00368
00369 result = addBucket(startdate, enddate, name);
00370 return result;
00371 }
00372
00373
00374 throw LogicException("Unreachable code reached");
00375 }
00376
00377
00378 DECLARE_EXPORT void Calendar::beginElement(XMLInput& pIn, const Attribute& pAttr)
00379 {
00380 if (pAttr.isA (Tags::tag_bucket)
00381 && pIn.getParentElement().first.isA(Tags::tag_buckets))
00382
00383 pIn.readto(createBucket(pIn.getAttributes()));
00384 }
00385
00386
00387 DECLARE_EXPORT void Calendar::Bucket::writeHeader(XMLOutput *o, const Keyword& tag) const
00388 {
00389
00390 if (startdate != Date::infinitePast)
00391 {
00392 if (enddate != Date::infiniteFuture)
00393 {
00394 if (!nm.empty())
00395 o->BeginObject(tag, Tags::tag_start, string(startdate), Tags::tag_end, string(enddate), Tags::tag_name, nm);
00396 else
00397 o->BeginObject(tag, Tags::tag_start, string(startdate), Tags::tag_end, string(enddate));
00398 }
00399 else
00400 {
00401 if (!nm.empty())
00402 o->BeginObject(tag, Tags::tag_start, string(startdate), Tags::tag_name, nm);
00403 else
00404 o->BeginObject(tag, Tags::tag_start, string(startdate));
00405 }
00406 }
00407 else
00408 {
00409 if (enddate != Date::infiniteFuture)
00410 {
00411 if (!nm.empty())
00412 o->BeginObject(tag, Tags::tag_end, string(enddate), Tags::tag_name, nm);
00413 else
00414 o->BeginObject(tag, Tags::tag_end, string(enddate));
00415 }
00416 else
00417 {
00418 if (!nm.empty())
00419 o->BeginObject(tag, Tags::tag_name, nm);
00420 else
00421 o->BeginObject(tag);
00422 }
00423 }
00424 }
00425
00426
00427 DECLARE_EXPORT void Calendar::Bucket::writeElement
00428 (XMLOutput *o, const Keyword& tag, mode m) const
00429 {
00430 assert(m == DEFAULT || m == FULL);
00431 writeHeader(o,tag);
00432 if (priority) o->writeElement(Tags::tag_priority, priority);
00433 o->EndObject(tag);
00434 }
00435
00436
00437 DECLARE_EXPORT void Calendar::Bucket::endElement (XMLInput& pIn, const Attribute& pAttr, const DataElement& pElement)
00438 {
00439 if (pAttr.isA(Tags::tag_priority))
00440 pElement >> priority;
00441 }
00442
00443
00444 DECLARE_EXPORT Calendar::EventIterator& Calendar::EventIterator::operator++()
00445 {
00446
00447 Date d = curDate;
00448 curDate = Date::infiniteFuture;
00449 curBucket = NULL;
00450 curPriority = DBL_MAX;
00451 for (const Calendar::Bucket *b = theCalendar->firstBucket; b; b = b->nextBucket)
00452 b->nextEvent(this, d);
00453 return *this;
00454 }
00455
00456
00457 DECLARE_EXPORT Calendar::EventIterator& Calendar::EventIterator::operator--()
00458 {
00459
00460 Date d = curDate;
00461 curDate = Date::infinitePast;
00462 curBucket = NULL;
00463 curPriority = DBL_MAX;
00464 for (const Calendar::Bucket *b = theCalendar->firstBucket; b; b = b->nextBucket)
00465 b->prevEvent(this, d);
00466 return *this;
00467 }
00468
00469
00470 DECLARE_EXPORT void Calendar::Bucket::nextEvent(EventIterator* iter, Date refDate) const
00471 {
00472 if (iter->curPriority < priority)
00473
00474 return;
00475
00476 if (refDate < startdate && startdate <= iter->curDate)
00477 {
00478
00479 iter->curDate = startdate;
00480 iter->curBucket = this;
00481 iter->curPriority = priority;
00482 return;
00483 }
00484
00485 if (refDate < enddate && enddate < iter->curDate)
00486 {
00487
00488 iter->curDate = enddate;
00489 iter->curBucket = iter->theCalendar->findBucket(enddate);
00490 iter->curPriority = priority;
00491 return;
00492 }
00493 }
00494
00495
00496 DECLARE_EXPORT void Calendar::Bucket::prevEvent(EventIterator* iter, Date refDate) const
00497 {
00498 if (iter->curPriority < priority)
00499
00500 return;
00501
00502 if (refDate > enddate && enddate >= iter->curDate)
00503 {
00504
00505 iter->curDate = enddate;
00506 iter->curBucket = this;
00507 iter->curPriority = priority;
00508 return;
00509 }
00510
00511 if (refDate > startdate && startdate > iter->curDate)
00512 {
00513
00514 iter->curDate = startdate;
00515 iter->curBucket = iter->theCalendar->findBucket(startdate,false);
00516 iter->curPriority = priority;
00517 return;
00518 }
00519
00520 }
00521
00522
00523 DECLARE_EXPORT PyObject* Calendar::getattro(const Attribute& attr)
00524 {
00525 if (attr.isA(Tags::tag_name))
00526 return PythonObject(getName());
00527 if (attr.isA(Tags::tag_buckets))
00528 return new CalendarBucketIterator(this);
00529 return NULL;
00530 }
00531
00532
00533 DECLARE_EXPORT int Calendar::setattro(const Attribute& attr, const PythonObject& field)
00534 {
00535 if (attr.isA(Tags::tag_name))
00536 setName(field.getString());
00537 else
00538 return -1;
00539 return 0;
00540 }
00541
00542
00543 DECLARE_EXPORT PyObject* CalendarVoid::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00544 {
00545 try
00546 {
00547
00548 CalendarVoid *cal = static_cast<CalendarVoid*>(self);
00549 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00550
00551
00552 PyObject *pystart, *pyend, *pyval = NULL;
00553 if (!PyArg_ParseTuple(args, "OO|O:setValue", &pystart, &pyend, &pyval))
00554 return NULL;
00555
00556
00557 PythonObject start(pystart), end(pyend);
00558 cal->addBucket(start.getDate(), end.getDate(), "");
00559 }
00560 catch(...)
00561 {
00562 PythonType::evalException();
00563 return NULL;
00564 }
00565 return Py_BuildValue("");
00566 }
00567
00568
00569 DECLARE_EXPORT PyObject* CalendarBool::getattro(const Attribute& attr)
00570 {
00571 if (attr.isA(Tags::tag_default))
00572 return PythonObject(getDefault());
00573 return Calendar::getattro(attr);
00574 }
00575
00576
00577 DECLARE_EXPORT int CalendarBool::setattro(const Attribute& attr, const PythonObject& field)
00578 {
00579 if (attr.isA(Tags::tag_default))
00580 setDefault(field.getBool());
00581 else
00582 return Calendar::setattro(attr, field);
00583 return 0;
00584 }
00585
00586
00587 DECLARE_EXPORT PyObject* CalendarBool::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00588 {
00589 try
00590 {
00591
00592 CalendarBool *cal = static_cast<CalendarBool*>(self);
00593 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00594
00595
00596 PyObject *pystart, *pyend, *pyval;
00597 if (!PyArg_ParseTuple(args, "OOO:setValue", &pystart, &pyend, &pyval))
00598 return NULL;
00599
00600
00601 PythonObject start(pystart), end(pyend), val(pyval);
00602 cal->setValue(start.getDate(), end.getDate(), val.getBool());
00603 }
00604 catch(...)
00605 {
00606 PythonType::evalException();
00607 return NULL;
00608 }
00609 return Py_BuildValue("");
00610 }
00611
00612
00613 DECLARE_EXPORT PyObject* CalendarDouble::getattro(const Attribute& attr)
00614 {
00615 if (attr.isA(Tags::tag_default))
00616 return PythonObject(getDefault());
00617 return Calendar::getattro(attr);
00618 }
00619
00620
00621 DECLARE_EXPORT int CalendarDouble::setattro(const Attribute& attr, const PythonObject& field)
00622 {
00623 if (attr.isA(Tags::tag_default))
00624 setDefault(field.getDouble());
00625 else
00626 return Calendar::setattro(attr, field);
00627 return 0;
00628 }
00629
00630
00631 DECLARE_EXPORT PyObject* CalendarDouble::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00632 {
00633 try
00634 {
00635
00636 CalendarDouble *cal = static_cast<CalendarDouble*>(self);
00637 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00638
00639
00640 PyObject *pystart, *pyend, *pyval;
00641 if (!PyArg_ParseTuple(args, "OOO:setValue", &pystart, &pyend, &pyval))
00642 return NULL;
00643
00644
00645 PythonObject start(pystart), end(pyend), val(pyval);
00646 cal->setValue(start.getDate(), end.getDate(), val.getDouble());
00647 }
00648 catch(...)
00649 {
00650 PythonType::evalException();
00651 return NULL;
00652 }
00653 return Py_BuildValue("");
00654 }
00655
00656
00657 DECLARE_EXPORT PyObject* CalendarString::getattro(const Attribute& attr)
00658 {
00659 if (attr.isA(Tags::tag_default))
00660 return PythonObject(getDefault());
00661 return Calendar::getattro(attr);
00662 }
00663
00664
00665 DECLARE_EXPORT int CalendarString::setattro(const Attribute& attr, const PythonObject& field)
00666 {
00667 if (attr.isA(Tags::tag_default))
00668 setDefault(field.getString());
00669 else
00670 return Calendar::setattro(attr, field);
00671 return 0;
00672 }
00673
00674
00675 DECLARE_EXPORT PyObject* CalendarString::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00676 {
00677 try
00678 {
00679
00680 CalendarString *cal = static_cast<CalendarString*>(self);
00681 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00682
00683
00684 PyObject *pystart, *pyend, *pyval;
00685 if (!PyArg_ParseTuple(args, "OOO:setValue", &pystart, &pyend, &pyval))
00686 return NULL;
00687
00688
00689 PythonObject start(pystart), end(pyend), val(pyval);
00690 cal->setValue(start.getDate(), end.getDate(), val.getString());
00691 }
00692 catch(...)
00693 {
00694 PythonType::evalException();
00695 return NULL;
00696 }
00697 return Py_BuildValue("");
00698 }
00699
00700
00701 DECLARE_EXPORT PyObject* CalendarInt::getattro(const Attribute& attr)
00702 {
00703 if (attr.isA(Tags::tag_default))
00704 return PythonObject(getDefault());
00705 return Calendar::getattro(attr);
00706 }
00707
00708
00709 DECLARE_EXPORT int CalendarInt::setattro(const Attribute& attr, const PythonObject& field)
00710 {
00711 if (attr.isA(Tags::tag_default))
00712 setDefault(field.getInt());
00713 else
00714 return Calendar::setattro(attr, field);
00715 return 0;
00716 }
00717
00718
00719 DECLARE_EXPORT PyObject* CalendarInt::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00720 {
00721 try
00722 {
00723
00724 CalendarInt *cal = static_cast<CalendarInt*>(self);
00725 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00726
00727
00728 PyObject *pystart, *pyend, *pyval;
00729 if (!PyArg_ParseTuple(args, "OOO:setValue", &pystart, &pyend, &pyval))
00730 return NULL;
00731
00732
00733 PythonObject start(pystart), end(pyend), val(pyval);
00734 cal->setValue(start.getDate(), end.getDate(), val.getInt());
00735 }
00736 catch(...)
00737 {
00738 PythonType::evalException();
00739 return NULL;
00740 }
00741 return Py_BuildValue("");
00742 }
00743
00744
00745 DECLARE_EXPORT PyObject* CalendarOperation::getattro(const Attribute& attr)
00746 {
00747 if (attr.isA(Tags::tag_default))
00748 return PythonObject(getDefault());
00749 return Calendar::getattro(attr);
00750 }
00751
00752
00753 DECLARE_EXPORT int CalendarOperation::setattro(const Attribute& attr, const PythonObject& field)
00754 {
00755 if (attr.isA(Tags::tag_default))
00756 {
00757 if (!field.check(Operation::metadata))
00758 {
00759 PyErr_SetString(PythonDataException, "calendar_operation stores values of type operation");
00760 return -1;
00761 }
00762 Operation* y = static_cast<Operation*>(static_cast<PyObject*>(field));
00763 setDefault(y);
00764 }
00765 else
00766 return Calendar::setattro(attr, field);
00767 return 0;
00768 }
00769
00770
00771 DECLARE_EXPORT PyObject* CalendarOperation::setPythonValue(PyObject* self, PyObject* args, PyObject* kwdict)
00772 {
00773 try
00774 {
00775
00776 CalendarOperation *cal = static_cast<CalendarOperation*>(self);
00777 if (!cal) throw LogicException("Can't set value of a NULL calendar");
00778
00779
00780 PyObject *pystart, *pyend, *pyval;
00781 if (!PyArg_ParseTuple(args, "OOO:setValue", &pystart, &pyend, &pyval))
00782 return NULL;
00783
00784
00785 PythonObject start(pystart), end(pyend), val(pyval);
00786 if (!val.check(Operation::metadata))
00787 {
00788 PyErr_SetString(PythonDataException, "calendar_operation stores values of type operation");
00789 return NULL;
00790 }
00791 Operation* y = static_cast<Operation*>(static_cast<PyObject*>(val));
00792 cal->setValue(start.getDate(), end.getDate(), y);
00793 }
00794 catch(...)
00795 {
00796 PythonType::evalException();
00797 return NULL;
00798 }
00799 return Py_BuildValue("");
00800 }
00801
00802
00803 int CalendarBucketIterator::initialize()
00804 {
00805
00806 PythonType& x = PythonExtension<CalendarBucketIterator>::getType();
00807 x.setName("calendarBucketIterator");
00808 x.setDoc("frePPLe iterator for calendar buckets");
00809 x.supportiter();
00810 return x.typeReady();
00811 }
00812
00813
00814 PyObject* CalendarBucketIterator::iternext()
00815 {
00816 if (i == cal->endBuckets()) return NULL;
00817 PyObject *result = &*(i++);
00818 Py_INCREF(result);
00819 return result;
00820 }
00821
00822
00823 DECLARE_EXPORT PyObject* Calendar::Bucket::getattro(const Attribute& attr)
00824 {
00825 if (attr.isA(Tags::tag_start))
00826 return PythonObject(getStart());
00827 if (attr.isA(Tags::tag_end))
00828 return PythonObject(getEnd());
00829 if (attr.isA(Tags::tag_value))
00830 {
00831 if (cal->getType() == *CalendarDouble::metadata)
00832 return PythonObject(dynamic_cast< CalendarValue<double>::BucketValue* >(this)->getValue());
00833 if (cal->getType() == *CalendarBool::metadata)
00834 return PythonObject(dynamic_cast< CalendarValue<bool>::BucketValue* >(this)->getValue());
00835 if (cal->getType() == *CalendarInt::metadata)
00836 return PythonObject(dynamic_cast< CalendarValue<int>::BucketValue* >(this)->getValue());
00837 if (cal->getType() == *CalendarString::metadata)
00838 return PythonObject(dynamic_cast< CalendarValue<string>::BucketValue* >(this)->getValue());
00839 if (cal->getType() == *CalendarOperation::metadata)
00840 return PythonObject(dynamic_cast< CalendarPointer<Operation>::BucketPointer* >(this)->getValue());
00841 if (cal->getType() == *CalendarVoid::metadata)
00842 return Py_BuildValue("");
00843 PyErr_SetString(PythonLogicException, "calendar type not recognized");
00844 return NULL;
00845 }
00846 if (attr.isA(Tags::tag_priority))
00847 return PythonObject(getPriority());
00848 if (attr.isA(Tags::tag_name))
00849 return PythonObject(getName());
00850 return NULL;
00851 }
00852
00853
00854 DECLARE_EXPORT int Calendar::Bucket::setattro(const Attribute& attr, const PythonObject& field)
00855 {
00856 if (attr.isA(Tags::tag_name))
00857 setName(field.getString());
00858 else if (attr.isA(Tags::tag_start))
00859 setStart(field.getDate());
00860 else if (attr.isA(Tags::tag_end))
00861 setEnd(field.getDate());
00862 else if (attr.isA(Tags::tag_priority))
00863 setPriority(field.getInt());
00864 else if (attr.isA(Tags::tag_value))
00865 {
00866 if (cal->getType() == *CalendarDouble::metadata)
00867 dynamic_cast< CalendarValue<double>::BucketValue* >(this)->setValue(field.getDouble());
00868 else if (cal->getType() == *CalendarBool::metadata)
00869 dynamic_cast< CalendarValue<bool>::BucketValue* >(this)->setValue(field.getBool());
00870 else if (cal->getType() == *CalendarInt::metadata)
00871 dynamic_cast< CalendarValue<int>::BucketValue* >(this)->setValue(field.getInt());
00872 else if (cal->getType() == *CalendarString::metadata)
00873 dynamic_cast< CalendarValue<string>::BucketValue* >(this)->setValue(field.getString());
00874 else if (cal->getType() == *CalendarOperation::metadata)
00875 {
00876 if (!field.check(Operation::metadata))
00877 {
00878 PyErr_SetString(PythonDataException, "calendar_operation stores values of type operation");
00879 return -1;
00880 }
00881 Operation* y = static_cast<Operation*>(static_cast<PyObject*>(field));
00882 dynamic_cast< CalendarPointer<Operation>::BucketPointer* >(this)->setValue(y);
00883 }
00884 else if (cal->getType() == *CalendarVoid::metadata)
00885 return -1;
00886 else
00887 {
00888 PyErr_SetString(PythonLogicException, "calendar type not recognized");
00889 return -1;
00890 }
00891 }
00892 else
00893 return -1;
00894 return 0;
00895 }
00896
00897
00898 DECLARE_EXPORT PyObject* Calendar::getEvents(
00899 PyObject* self, PyObject* args, PyObject* kwdict
00900 )
00901 {
00902 try
00903 {
00904
00905 Calendar *cal = NULL;
00906 PythonObject c(self);
00907 if (c.check(CalendarBool::metadata))
00908 cal = static_cast<CalendarBool*>(self);
00909 else if (c.check(CalendarDouble::metadata))
00910 cal = static_cast<CalendarDouble*>(self);
00911 else if (c.check(CalendarInt::metadata))
00912 cal = static_cast<CalendarInt*>(self);
00913 else if (c.check(CalendarOperation::metadata))
00914 cal = static_cast<CalendarOperation*>(self);
00915 else if (c.check(CalendarString::metadata))
00916 cal = static_cast<CalendarString*>(self);
00917 else if (c.check(CalendarVoid::metadata))
00918 cal = static_cast<CalendarVoid*>(self);
00919 else
00920 throw LogicException("Invalid calendar type");
00921
00922
00923 PyObject* pystart = NULL;
00924 PyObject* pydirection = NULL;
00925 if (!PyArg_ParseTuple(args, "|OO:setvalue", &pystart, &pydirection))
00926 return NULL;
00927 Date startdate = pystart ? PythonObject(pystart).getDate() : Date::infinitePast;
00928 bool forward = pydirection ? PythonObject(pydirection).getBool() : true;
00929
00930
00931 return new CalendarEventIterator(cal, startdate, forward);
00932 }
00933 catch(...)
00934 {
00935 PythonType::evalException();
00936 return NULL;
00937 }
00938 }
00939
00940
00941 int CalendarEventIterator::initialize()
00942 {
00943
00944 PythonType& x = PythonExtension<CalendarEventIterator>::getType();
00945 x.setName("calendarEventIterator");
00946 x.setDoc("frePPLe iterator for calendar events");
00947 x.supportiter();
00948 return x.typeReady();
00949 }
00950
00951
00952 PyObject* CalendarEventIterator::iternext()
00953 {
00954 if ((forward && eventiter.getDate() == Date::infiniteFuture)
00955 || (!forward && eventiter.getDate() == Date::infinitePast))
00956 return NULL;
00957 PythonObject x;
00958 if (dynamic_cast<CalendarBool*>(cal))
00959 {
00960 if (eventiter.getBucket())
00961 x = PythonObject(dynamic_cast<const CalendarBool::BucketValue*>(eventiter.getBucket())->getValue());
00962 else
00963 x = PythonObject(dynamic_cast<CalendarBool*>(cal)->getDefault());
00964 }
00965 else if (dynamic_cast<CalendarDouble*>(cal))
00966 {
00967 if (eventiter.getBucket())
00968 x = PythonObject(dynamic_cast<const CalendarDouble::BucketValue*>(eventiter.getBucket())->getValue());
00969 else
00970 x = PythonObject(dynamic_cast<CalendarDouble*>(cal)->getDefault());
00971 }
00972 else if (dynamic_cast<CalendarInt*>(cal))
00973 {
00974 if (eventiter.getBucket())
00975 x = PythonObject(dynamic_cast<const CalendarInt::BucketValue*>(eventiter.getBucket())->getValue());
00976 else
00977 x = PythonObject(dynamic_cast<CalendarInt*>(cal)->getDefault());
00978 }
00979 else if (dynamic_cast<CalendarOperation*>(cal))
00980 {
00981 if (eventiter.getBucket())
00982 x = PythonObject(dynamic_cast<const CalendarOperation::BucketPointer*>(eventiter.getBucket())->getValue());
00983 else
00984 x = PythonObject(dynamic_cast<CalendarOperation*>(cal)->getDefault());
00985 }
00986 else if (dynamic_cast<CalendarString*>(cal))
00987 {
00988 if (eventiter.getBucket())
00989 x = PythonObject(dynamic_cast<const CalendarString::BucketValue*>(eventiter.getBucket())->getValue());
00990 else
00991 x = PythonObject(dynamic_cast<CalendarString*>(cal)->getDefault());
00992 }
00993 PyObject* result = Py_BuildValue("(N,N)",
00994 static_cast<PyObject*>(PythonObject(eventiter.getDate())),
00995 static_cast<PyObject*>(x)
00996 );
00997 if (forward)
00998 ++eventiter;
00999 else
01000 --eventiter;
01001 return result;
01002 }
01003
01004 }