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 Resource> DECLARE_EXPORT Tree utils::HasName<Resource>::st;
00035 DECLARE_EXPORT const MetaCategory* Resource::metadata;
00036 DECLARE_EXPORT const MetaClass* ResourceDefault::metadata;
00037 DECLARE_EXPORT const MetaClass* ResourceInfinite::metadata;
00038
00039
00040 int Resource::initialize()
00041 {
00042
00043 metadata = new MetaCategory("resource", "resources", reader, writer);
00044
00045
00046 return FreppleCategory<Resource>::initialize();
00047 }
00048
00049
00050 int ResourceDefault::initialize()
00051 {
00052
00053 ResourceDefault::metadata = new MetaClass(
00054 "resource",
00055 "resource_default",
00056 Object::createString<ResourceDefault>,
00057 true);
00058
00059
00060 return FreppleClass<ResourceDefault,Resource>::initialize();
00061 }
00062
00063
00064 int ResourceInfinite::initialize()
00065 {
00066
00067 ResourceInfinite::metadata = new MetaClass(
00068 "resource",
00069 "resource_infinite",
00070 Object::createString<ResourceInfinite>);
00071
00072
00073 return FreppleClass<ResourceInfinite,Resource>::initialize();
00074 }
00075
00076
00077 DECLARE_EXPORT void Resource::setMaximum(CalendarDouble* c)
00078 {
00079
00080 if (max_cal == c) return;
00081
00082
00083 setChanged();
00084
00085
00086 if (max_cal)
00087 {
00088 for (loadplanlist::iterator oo=loadplans.begin(); oo!=loadplans.end(); )
00089 if (oo->getType() == 4)
00090 {
00091 loadplans.erase(&(*oo));
00092 delete &(*(oo++));
00093 }
00094 else ++oo;
00095 }
00096
00097
00098 if (!c) return;
00099
00100
00101 max_cal = c;
00102 double curMax = 0.0;
00103 for (CalendarDouble::EventIterator x(max_cal); x.getDate()<Date::infiniteFuture; ++x)
00104 if (curMax != x.getValue())
00105 {
00106 curMax = x.getValue();
00107 loadplanlist::EventMaxQuantity *newBucket =
00108 new loadplanlist::EventMaxQuantity(x.getDate(), curMax);
00109 loadplans.insert(newBucket);
00110 }
00111 }
00112
00113
00114 DECLARE_EXPORT void Resource::writeElement(XMLOutput *o, const Keyword& tag, mode m) const
00115 {
00116
00117 if (m == REFERENCE)
00118 {
00119 o->writeElement(tag, Tags::tag_name, getName());
00120 return;
00121 }
00122
00123
00124 if (m != NOHEADER) o->BeginObject(tag, Tags::tag_name, getName());
00125
00126
00127 HasDescription::writeElement(o, tag);
00128 HasHierarchy<Resource>::writeElement(o, tag);
00129 o->writeElement(Tags::tag_maximum, max_cal);
00130 if (getMaxEarly() != TimePeriod(defaultMaxEarly))
00131 o->writeElement(Tags::tag_maxearly, getMaxEarly());
00132 if (getCost() != 0.0) o->writeElement(Tags::tag_cost, getCost());
00133 o->writeElement(Tags::tag_location, loc);
00134 if (!getSetup().empty()) o->writeElement(Tags::tag_setup, getSetup());
00135 if (getSetupMatrix())
00136 o->writeElement(Tags::tag_setupmatrix, getSetupMatrix());
00137 Plannable::writeElement(o, tag);
00138
00139
00140 loadplanlist::const_iterator i = loadplans.begin();
00141 if (o->getContentType() == XMLOutput::PLAN && i!=loadplans.end())
00142 {
00143 o->BeginObject(Tags::tag_loadplans);
00144 for (; i!=loadplans.end(); ++i)
00145 if (i->getType()==1)
00146 {
00147 const LoadPlan *lp = dynamic_cast<const LoadPlan*>(&*i);
00148 o->BeginObject(Tags::tag_loadplan);
00149 o->writeElement(Tags::tag_date, lp->getDate());
00150 o->writeElement(Tags::tag_quantity, lp->getQuantity());
00151 o->writeElement(Tags::tag_onhand, lp->getOnhand());
00152 o->writeElement(Tags::tag_minimum, lp->getMin());
00153 o->writeElement(Tags::tag_maximum, lp->getMax());
00154 o->writeElement(Tags::tag_operationplan, &*(lp->getOperationPlan()), FULL);
00155 o->EndObject(Tags::tag_loadplan);
00156 }
00157 o->EndObject(Tags::tag_loadplans);
00158 }
00159
00160
00161 o->EndObject(tag);
00162 }
00163
00164
00165 DECLARE_EXPORT void Resource::beginElement(XMLInput& pIn, const Attribute& pAttr)
00166 {
00167 if (pAttr.isA (Tags::tag_load)
00168 && pIn.getParentElement().first.isA(Tags::tag_loads))
00169 {
00170 Load* l = new Load();
00171 l->setResource(this);
00172 pIn.readto(&*l);
00173 }
00174 else if (pAttr.isA (Tags::tag_maximum))
00175 pIn.readto( Calendar::reader(Calendar::metadata,pIn.getAttributes()) );
00176 else if (pAttr.isA(Tags::tag_loadplans))
00177 pIn.IgnoreElement();
00178 else if (pAttr.isA(Tags::tag_location))
00179 pIn.readto( Location::reader(Location::metadata,pIn.getAttributes()) );
00180 else if (pAttr.isA(Tags::tag_setupmatrix))
00181 pIn.readto( SetupMatrix::reader(SetupMatrix::metadata,pIn.getAttributes()) );
00182 else
00183 HasHierarchy<Resource>::beginElement(pIn, pAttr);
00184 }
00185
00186
00187 DECLARE_EXPORT void Resource::endElement (XMLInput& pIn, const Attribute& pAttr, const DataElement& pElement)
00188 {
00189
00190
00191
00192 if (pAttr.isA (Tags::tag_maximum))
00193 {
00194 CalendarDouble * c = dynamic_cast<CalendarDouble*>(pIn.getPreviousObject());
00195 if (c)
00196 setMaximum(c);
00197 else
00198 {
00199 Calendar *c = dynamic_cast<Calendar*>(pIn.getPreviousObject());
00200 if (!c)
00201 throw LogicException("Incorrect object type during read operation");
00202 throw DataException("Calendar '" + c->getName() +
00203 "' has invalid type for use as resource max calendar");
00204 }
00205 }
00206 else if (pAttr.isA (Tags::tag_maxearly))
00207 setMaxEarly(pElement.getTimeperiod());
00208 else if (pAttr.isA (Tags::tag_cost))
00209 setCost(pElement.getDouble());
00210 else if (pAttr.isA(Tags::tag_location))
00211 {
00212 Location * d = dynamic_cast<Location*>(pIn.getPreviousObject());
00213 if (d) setLocation(d);
00214 else throw LogicException("Incorrect object type during read operation");
00215 }
00216 else if (pAttr.isA (Tags::tag_setup))
00217 setSetup(pElement.getString());
00218 else if (pAttr.isA(Tags::tag_setupmatrix))
00219 {
00220 SetupMatrix * d = dynamic_cast<SetupMatrix*>(pIn.getPreviousObject());
00221 if (d) setSetupMatrix(d);
00222 else throw LogicException("Incorrect object type during read operation");
00223 }
00224 else
00225 {
00226 Plannable::endElement(pIn, pAttr, pElement);
00227 HasDescription::endElement(pIn, pAttr, pElement);
00228 HasHierarchy<Resource>::endElement (pIn, pAttr, pElement);
00229 }
00230 }
00231
00232
00233 DECLARE_EXPORT void Resource::deleteOperationPlans(bool deleteLocked)
00234 {
00235
00236 for (loadlist::iterator i=loads.begin(); i!=loads.end(); ++i)
00237 OperationPlan::deleteOperationPlans(i->getOperation(),deleteLocked);
00238
00239
00240 setChanged();
00241 }
00242
00243
00244 DECLARE_EXPORT Resource::~Resource()
00245 {
00246
00247
00248
00249
00250 deleteOperationPlans(true);
00251
00252
00253
00254 }
00255
00256
00257 DECLARE_EXPORT void Resource::updateSetups(const LoadPlan* ldplan)
00258 {
00259
00260 if (!getSetupMatrix() || (ldplan && ldplan->getOperationPlan()->getOperation() != OperationSetup::setupoperation))
00261 return;
00262
00263
00264 OperationPlan *opplan = ldplan ? ldplan->getOperationPlan() : NULL;
00265 loadplanlist::const_iterator i = ldplan ?
00266 getLoadPlans().begin(ldplan) :
00267 getLoadPlans().begin();
00268 string prevsetup = ldplan ? ldplan->getSetup() : getSetup();
00269 Date latestCheckDate = ldplan ? ldplan->getDate() : Date::infiniteFuture;
00270 for (; i != getLoadPlans().end(); ++i)
00271 {
00272 const LoadPlan* l = dynamic_cast<const LoadPlan*>(&*i);
00273 if (l && !l->getLoad()->getSetup().empty()
00274 && l->getOperationPlan()->getOperation() == OperationSetup::setupoperation
00275 && l->getOperationPlan() != opplan
00276 && !l->isStart())
00277 {
00278
00279 OperationPlanState x = l->getOperationPlan()->getOperation()->setOperationPlanParameters(
00280 l->getOperationPlan(),
00281 l->getOperationPlan()->getQuantity(),
00282 Date::infinitePast,
00283 l->getOperationPlan()->getDates().getEnd(),
00284 true,
00285 false);
00286 if (x.start != l->getOperationPlan()->getDates().getStart())
00287
00288 l->getOperationPlan()->restore(x);
00289 else if (ldplan && x.start == l->getOperationPlan()->getDates().getStart())
00290
00291
00292 return;
00293 }
00294 }
00295 }
00296
00297
00298 DECLARE_EXPORT void ResourceInfinite::writeElement
00299 (XMLOutput *o, const Keyword &tag, mode m) const
00300 {
00301
00302 if (m == REFERENCE)
00303 {
00304 o->writeElement
00305 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00306 return;
00307 }
00308
00309
00310 if (m != NOHEADER) o->BeginObject
00311 (tag, Tags::tag_name, getName(), Tags::tag_type, getType().type);
00312
00313
00314 Resource::writeElement(o, tag, NOHEADER);
00315 }
00316
00317
00318 DECLARE_EXPORT PyObject* Resource::getattro(const Attribute& attr)
00319 {
00320 if (attr.isA(Tags::tag_name))
00321 return PythonObject(getName());
00322 if (attr.isA(Tags::tag_description))
00323 return PythonObject(getDescription());
00324 if (attr.isA(Tags::tag_category))
00325 return PythonObject(getCategory());
00326 if (attr.isA(Tags::tag_subcategory))
00327 return PythonObject(getSubCategory());
00328 if (attr.isA(Tags::tag_owner))
00329 return PythonObject(getOwner());
00330 if (attr.isA(Tags::tag_location))
00331 return PythonObject(getLocation());
00332 if (attr.isA(Tags::tag_maximum))
00333 return PythonObject(getMaximum());
00334 if (attr.isA(Tags::tag_maxearly))
00335 return PythonObject(getMaxEarly());
00336 if (attr.isA(Tags::tag_cost))
00337 return PythonObject(getCost());
00338 if (attr.isA(Tags::tag_hidden))
00339 return PythonObject(getHidden());
00340 if (attr.isA(Tags::tag_loadplans))
00341 return new LoadPlanIterator(this);
00342 if (attr.isA(Tags::tag_loads))
00343 return new LoadIterator(this);
00344 if (attr.isA(Tags::tag_setup))
00345 return PythonObject(getSetup());
00346 if (attr.isA(Tags::tag_setupmatrix))
00347 return PythonObject(getSetupMatrix());
00348 if (attr.isA(Tags::tag_level))
00349 return PythonObject(getLevel());
00350 if (attr.isA(Tags::tag_cluster))
00351 return PythonObject(getCluster());
00352 return NULL;
00353 }
00354
00355
00356 DECLARE_EXPORT int Resource::setattro(const Attribute& attr, const PythonObject& field)
00357 {
00358 if (attr.isA(Tags::tag_name))
00359 setName(field.getString());
00360 else if (attr.isA(Tags::tag_description))
00361 setDescription(field.getString());
00362 else if (attr.isA(Tags::tag_category))
00363 setCategory(field.getString());
00364 else if (attr.isA(Tags::tag_subcategory))
00365 setSubCategory(field.getString());
00366 else if (attr.isA(Tags::tag_owner))
00367 {
00368 if (!field.check(PythonExtension<Resource>::getType()))
00369 {
00370 PyErr_SetString(PythonDataException, "resource owner must be of type resource");
00371 return -1;
00372 }
00373 Resource* y = static_cast<Resource*>(static_cast<PyObject*>(field));
00374 setOwner(y);
00375 }
00376 else if (attr.isA(Tags::tag_location))
00377 {
00378 if (!field.check(Location::metadata))
00379 {
00380 PyErr_SetString(PythonDataException, "buffer location must be of type location");
00381 return -1;
00382 }
00383 Location* y = static_cast<Location*>(static_cast<PyObject*>(field));
00384 setLocation(y);
00385 }
00386 else if (attr.isA(Tags::tag_maximum))
00387 {
00388 if (!field.check(CalendarDouble::metadata))
00389 {
00390 PyErr_SetString(PythonDataException, "resource maximum must be of type calendar_double");
00391 return -1;
00392 }
00393 CalendarDouble* y = static_cast<CalendarDouble*>(static_cast<PyObject*>(field));
00394 setMaximum(y);
00395 }
00396 else if (attr.isA(Tags::tag_hidden))
00397 setHidden(field.getBool());
00398 else if (attr.isA(Tags::tag_cost))
00399 setCost(field.getDouble());
00400 else if (attr.isA(Tags::tag_maxearly))
00401 setMaxEarly(field.getTimeperiod());
00402 else if (attr.isA(Tags::tag_setup))
00403 setSetup(field.getString());
00404 else if (attr.isA(Tags::tag_setupmatrix))
00405 {
00406 if (!field.check(SetupMatrix::metadata))
00407 {
00408 PyErr_SetString(PythonDataException, "resource setup_matrix must be of type setup_matrix");
00409 return -1;
00410 }
00411 SetupMatrix* y = static_cast<SetupMatrix*>(static_cast<PyObject*>(field));
00412 setSetupMatrix(y);
00413 }
00414 else
00415 return -1;
00416 return 0;
00417 }
00418
00419 }