1 /*=============================================================================
2
3 Library: CTK
4
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19
20 =============================================================================*/
21
22
23 #include "ctkPluginGeneratorCodeModel.h"
24
25 #include <QDir>
26 #include <QHash>
27
28 #include <ctkException.h>
29
30
31 class ctkPluginGeneratorCodeModelPrivate
32 {
33 public:
34
35 QHash<QString, ctkPluginGeneratorAbstractTemplate*> rootTemplates;
36 QHash<QString, QString> contentMap;
37
38 QString symbolicNameWithPeriods;
39 QString symbolicNameWithUnderscores;
40 QString exportMacro;
41 QString exportMacroInclude;
42 QString license;
43 };
44
45 class ctkPluginGeneratorFolderTemplate : public ctkPluginGeneratorAbstractTemplate
46 {
47 public:
48
ctkPluginGeneratorFolderTemplate(const QString & name,ctkPluginGeneratorAbstractTemplate * parent=0)49 ctkPluginGeneratorFolderTemplate(const QString& name, ctkPluginGeneratorAbstractTemplate* parent = 0)
50 : ctkPluginGeneratorAbstractTemplate(name, parent)
51 {}
52
generateContent()53 QString generateContent()
54 {
55 return "";
56 }
57
create(const QString & location)58 void create(const QString& location)
59 {
60 QDir dir(location);
61 if (dir.mkdir(this->objectName()))
62 {
63 QString currLocation = location + QDir::separator() + this->objectName();
64 QListIterator<QObject*> it(this->children());
65 while (it.hasNext())
66 {
67 qobject_cast<ctkPluginGeneratorAbstractTemplate*>(it.next())->create(currLocation);
68 }
69 }
70 else
71 {
72 throw ctkRuntimeException("The directory " + location + this->objectName() + " could not be created");
73 }
74 }
75 };
76
ctkPluginGeneratorCodeModel()77 ctkPluginGeneratorCodeModel::ctkPluginGeneratorCodeModel()
78 : d_ptr(new ctkPluginGeneratorCodeModelPrivate)
79 {
80 }
81
~ctkPluginGeneratorCodeModel()82 ctkPluginGeneratorCodeModel::~ctkPluginGeneratorCodeModel()
83 {
84 }
85
addContent(const QString & marker,const QString & content)86 void ctkPluginGeneratorCodeModel::addContent(const QString& marker, const QString& content)
87 {
88 Q_D(ctkPluginGeneratorCodeModel);
89 d->contentMap[marker] = content;
90 }
91
getContent(const QString & marker) const92 QString ctkPluginGeneratorCodeModel::getContent(const QString& marker) const
93 {
94 Q_D(const ctkPluginGeneratorCodeModel);
95 if (d->contentMap.contains(marker))
96 {
97 return d->contentMap[marker];
98 }
99 return QString();
100 }
101
setExportMacro(const QString & exportMacro)102 void ctkPluginGeneratorCodeModel::setExportMacro(const QString& exportMacro)
103 {
104 Q_D(ctkPluginGeneratorCodeModel);
105 d->exportMacro = exportMacro;
106 }
107
getExportMacro() const108 QString ctkPluginGeneratorCodeModel::getExportMacro() const
109 {
110 Q_D(const ctkPluginGeneratorCodeModel);
111 return d->exportMacro;
112 }
113
setExportMacroInclude(const QString & exportMacroInclude)114 void ctkPluginGeneratorCodeModel::setExportMacroInclude(const QString& exportMacroInclude)
115 {
116 Q_D(ctkPluginGeneratorCodeModel);
117 d->exportMacroInclude = exportMacroInclude;
118 }
119
getExportMacroInclude() const120 QString ctkPluginGeneratorCodeModel::getExportMacroInclude() const
121 {
122 Q_D(const ctkPluginGeneratorCodeModel);
123 return d->exportMacroInclude;
124 }
125
setSymbolicName(const QString & symbolicName)126 void ctkPluginGeneratorCodeModel::setSymbolicName(const QString& symbolicName)
127 {
128 Q_D(ctkPluginGeneratorCodeModel);
129 d->symbolicNameWithPeriods = QString(symbolicName).replace("_", ".");
130 d->symbolicNameWithUnderscores = QString(symbolicName).replace(".", "_");
131 }
132
getSymbolicName(bool withPeriods) const133 QString ctkPluginGeneratorCodeModel::getSymbolicName(bool withPeriods) const
134 {
135 Q_D(const ctkPluginGeneratorCodeModel);
136 if (withPeriods)
137 {
138 return d->symbolicNameWithPeriods;
139 }
140 return d->symbolicNameWithUnderscores;
141 }
142
setLicense(const QString & license)143 void ctkPluginGeneratorCodeModel::setLicense(const QString& license)
144 {
145 Q_D(ctkPluginGeneratorCodeModel);
146 d->license = license;
147 }
148
getLicense() const149 QString ctkPluginGeneratorCodeModel::getLicense() const
150 {
151 Q_D(const ctkPluginGeneratorCodeModel);
152 return d->license;
153 }
154
addTemplate(ctkPluginGeneratorAbstractTemplate * templ,const QString & path)155 void ctkPluginGeneratorCodeModel::addTemplate(ctkPluginGeneratorAbstractTemplate *templ,
156 const QString& path)
157 {
158 Q_D(ctkPluginGeneratorCodeModel);
159
160 templ->setCodeModel(this);
161
162 if (path.isEmpty())
163 {
164 d->rootTemplates.insert(templ->objectName(), templ);
165 templ->setParent(this);
166 }
167 else
168 {
169 ctkPluginGeneratorAbstractTemplate* parentTemplate = 0;
170 QStringList paths = path.split("/", QString::SkipEmptyParts);
171 QStringListIterator it(paths);
172 if (it.hasNext())
173 {
174 QString rootEntry = it.next();
175 // search the root templates
176 if (d->rootTemplates.contains(rootEntry))
177 {
178 if (!dynamic_cast<ctkPluginGeneratorFolderTemplate*>(d->rootTemplates[rootEntry]))
179 {
180 throw ctkRuntimeException("The segment \"" + rootEntry + "\" in \"" + path + "\" is not a folder");
181 }
182 parentTemplate = d->rootTemplates[rootEntry];
183 }
184 else
185 {
186 parentTemplate = new ctkPluginGeneratorFolderTemplate(rootEntry);
187 d->rootTemplates.insert(rootEntry, parentTemplate);
188 }
189 while (it.hasNext())
190 {
191 QString currEntry = it.next();
192 QListIterator<QObject*> children(parentTemplate->children());
193 bool childFound = false;
194 while (children.hasNext())
195 {
196 QObject* child = children.next();
197 if (child->objectName() == currEntry)
198 {
199 childFound = true;
200 parentTemplate = qobject_cast<ctkPluginGeneratorAbstractTemplate*>(child);
201 if (parentTemplate == 0)
202 {
203 throw ctkRuntimeException("The segment \"" + currEntry + "\" in \"" + path + "\" is not a folder");
204 }
205 break;
206 }
207 }
208
209 if (!childFound)
210 {
211 parentTemplate = new ctkPluginGeneratorFolderTemplate(currEntry, parentTemplate);
212 }
213 }
214 }
215
216 templ->setParent(parentTemplate);
217 }
218 }
219
getTemplate(const QString & path) const220 ctkPluginGeneratorAbstractTemplate* ctkPluginGeneratorCodeModel::getTemplate(const QString& path) const
221 {
222 Q_D(const ctkPluginGeneratorCodeModel);
223
224 if (!path.contains("/"))
225 {
226 foreach(ctkPluginGeneratorAbstractTemplate* t, d->rootTemplates)
227 {
228 if (t->objectName() == path) return t;
229 ctkPluginGeneratorAbstractTemplate* child =
230 t->findChild<ctkPluginGeneratorAbstractTemplate*>(path);
231 if (child) return child;
232 }
233 return 0;
234 }
235
236 QStringList paths = path.split("/", QString::SkipEmptyParts);
237 if (paths.empty()) return 0;
238
239 QObject* currChild = d->rootTemplates[paths.front()];
240 paths.pop_front();
241
242 int depth = 0;
243 foreach (QString curr, paths)
244 {
245 foreach (QObject* child, currChild->children())
246 {
247 if (child->objectName() == curr)
248 {
249 currChild = child;
250 ++depth;
251 break;
252 }
253 }
254 }
255
256 if (paths.size() == depth)
257 {
258 return qobject_cast<ctkPluginGeneratorAbstractTemplate*>(currChild);
259 }
260
261 return 0;
262 }
263
create(const QString & location)264 void ctkPluginGeneratorCodeModel::create(const QString& location)
265 {
266 Q_D(ctkPluginGeneratorCodeModel);
267
268 QListIterator<ctkPluginGeneratorAbstractTemplate*> it(d->rootTemplates.values());
269 while (it.hasNext())
270 {
271 ctkPluginGeneratorAbstractTemplate* templ = it.next();
272 templ->create(location);
273 }
274 }
275
reset()276 void ctkPluginGeneratorCodeModel::reset()
277 {
278 Q_D(ctkPluginGeneratorCodeModel);
279 qDeleteAll(d->rootTemplates.values());
280 d->rootTemplates.clear();
281 }
282