1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "ChunkImporter.h"
23 #include "FieldImpls.h"
24 #include "TableImpls.h"
25 #include "StringUtilities.h"
27 #include "DetailManager.h"
30 std::string
ChunkImporter::MyDetail::toString()
34 result
.append(String::Get()->unlines(m_description
, "\n", 0));
35 for(MyDetailVector::iterator it
= m_details
.begin(); it
!= m_details
.end(); it
++)
37 result
.append((*it
)->toString());
43 void ChunkImporter::MyDetail::apply(mud::DetailPtr detail
)
47 MyDetailVector details
= getDetails();
48 for(MyDetailVector::iterator it
= details
.begin(); it
!= details
.end(); it
++)
50 MyDetailPtr onedetail
= *it
;
52 KeysPtr newdetailkeys
= mud::Managers::Get()->Detail
->Add();
53 mud::DetailPtr newdetail
= mud::Managers::Get()->Detail
->GetByKey(newdetailkeys
->first()->getIntegerValue());
54 newdetail
->setDescription(String::Get()->unlines(onedetail
->getDescription() , " ", 0));
58 * Connect the detail to the chunk
60 RelationPtr
relation(new Relation(db::TableImpls::Get()->DETAILDETAIL
));
61 relation
->addKey(db::TableImpls::Get()->DETAILDETAIL
->FKDETAILSPRIMARY
, newdetail
->getID());
62 relation
->addKey(db::TableImpls::Get()->DETAILDETAIL
->FKDETAILSSECONDARY
, detail
->getID());
65 onedetail
->apply(newdetail
);
69 ChunkImporter::ChunkImporter(
70 const std::string
& input
) :
76 ChunkImporter::~ChunkImporter()
83 The format is as follows:
87 This may span several lines
89 ** Detail of Detail of Chunk
90 Continuation of detail
92 ** Another Detail of Detail of Chunk
93 *** Detail of above detail
94 ** Yet Another Detail of Detail of Chunk
96 * Some more detail of the chunk
99 [formal format description]
106 | description '\n' details
108 description: description '\n' TEXT
112 | details '\n' detail
115 | '*' TEXT '\n' lines
118 lines: lines tabs TEXT '\n'
124 subdetail: '*' detail
126 [/formal format description]
128 bovenaan [current = topDetail, details.top() = NULL]
129 * klein [ current = newDetail, details.top() = topDetail] // details.push(current), current = new Detail()
130 ** heel erg [ current = notherNewDetail, details.top() = newDetail] // details.push(current), current = new Detail()
131 * blauw [ current = newDetail, details.top() = topDetail] // details.top()->addDetail(current), current = details.pop(), detail.top()->addDetail(current), current = new Detail()
132 en groen [ current = newDetail, details.top() = topDetail] // current.append(line)
133 * dinges [ current = YoNewDetail, details.top() = topDetail] // details.top()->addDetail(current), current = new Detail()
136 void ChunkImporter::Parse()
142 std::stack
<MyDetailPtr
> details
;
143 MyDetailPtr
current(new ChunkImporter::MyDetail());
145 Strings lines
= String::Get()->lines(m_input
, "\n");
147 for(Strings::iterator it
= lines
.begin(); it
!= lines
.end(); it
++)
149 std::string line
= *it
;
156 * If we're still in the description of the chunk, just append.
161 * This is the first detail, so stop appending
169 current
->append(line
);
175 * Find out how deep the rabbit hole goes
177 for(i
= 0; i
< line
.size(); i
++)
187 * Apparently not that deep, just append this line to the current detail
192 * Find out how deep the tabbification is
195 for(i
= 0; i
< line
.size(); i
++)
205 * The format dictates that there is at least one tab before each continuation
209 Global::Get()->bugf("Malformed import line.\n");
215 * Erase the tabs and append it to the current detail
217 line
.erase(0, tabDepth
);
218 current
->append(line
);
222 line
.erase(0, depth
);
224 if(depth
< lastDepth
)
226 details
.top()->addDetail(current
);
227 current
= details
.top();
231 if(depth
> lastDepth
)
233 details
.push(current
);
234 current
.reset(new MyDetail());
238 * This needs to be done not only when depth==lastDepth, but also when we just went down a detail level
240 if(lastDepth
>= depth
&& details
.size())
242 details
.top()->addDetail(current
);
243 current
.reset(new MyDetail());
246 current
->append(line
);
250 while(details
.size() > 0)
252 details
.top()->addDetail(current
);
253 current
= details
.top();
258 m_resultstring
= current
->toString();
261 void ChunkImporter::Apply(mud::ChunkPtr chunk
)
266 * Set description to that of the top node
268 chunk
->setDescription(String::Get()->unlines(m_result
->getDescription() , " ", 0));
271 * Add all the details as details of the chunk
273 MyDetailVector details
= m_result
->getDetails();
274 for(MyDetailVector::iterator it
= details
.begin(); it
!= details
.end(); it
++)
276 MyDetailPtr onedetail
= *it
;
278 KeysPtr detailkeys
= mud::Managers::Get()->Detail
->Add();
279 mud::DetailPtr detail
= mud::Managers::Get()->Detail
->GetByKey(detailkeys
->first()->getIntegerValue());
280 detail
->setDescription(String::Get()->unlines(onedetail
->getDescription() , " ", 0));
284 * Connect the new detail to the chunk
286 RelationPtr
relation(new Relation(db::TableImpls::Get()->DETAILS
));
287 relation
->addKey(db::TableImpls::Get()->DETAILS
->DETAILID
, chunk
->getID());
288 relation
->addKey(db::TableImpls::Get()->CHUNKS
->CHUNKID
, detail
->getID());
291 onedetail
->apply(detail
);
295 const std::string
& ChunkImporter::getResult()
297 return m_resultstring
;