10#include <QDomDocument>
31bool Schema::Private::load(
const QString& _fileName)
35 QDomDocument document;
36 QFile
file(_fileName);
37#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
40 if (!document.setContent(&file, &error, &line, &column)) {
41 dbgMetaData << error <<
" at " << line <<
", " << column <<
" in " << _fileName;
43 QDomDocument::ParseResult result = document.setContent(&file);
45 dbgMetaData << result.errorMessage <<
" at " << result.errorLine <<
", " << result.errorColumn <<
" in " << _fileName;
50 QDomElement docElem = document.documentElement();
51 if (docElem.tagName() !=
"schema") {
56 if (!docElem.hasAttribute(
"prefix")) {
61 if (!docElem.hasAttribute(
"uri")) {
66 prefix = docElem.attribute(
"prefix");
67 uri = docElem.attribute(
"uri");
70 QDomElement structuresElt = docElem.firstChildElement(
"structures");
71 if (structuresElt.isNull()) {
75 QDomElement propertiesElt = docElem.firstChildElement(
"properties");
76 if (propertiesElt.isNull()) {
80 parseStructures(structuresElt);
81 parseProperties(propertiesElt);
86void Schema::Private::parseStructures(QDomElement& elt)
88 Q_ASSERT(elt.tagName() ==
"structures");
91 QDomElement e = elt.firstChildElement();
92 for (; !e.isNull(); e = e.nextSiblingElement()) {
93 if (e.tagName() ==
"structure") {
96 errMetaData <<
"Invalid tag: " << e.tagName() <<
" in structures section";
101void Schema::Private::parseStructure(QDomElement& elt)
103 Q_ASSERT(elt.tagName() ==
"structure");
105 if (!elt.hasAttribute(
"name")) {
110 QString structureName = elt.attribute(
"name");
111 if (structures.contains(structureName)) {
112 errMetaData << structureName <<
" is defined twice";
115 dbgMetaData <<
"Parsing structure " << structureName;
117 if (!elt.hasAttribute(
"prefix")) {
118 errMetaData <<
"prefix is required for structure " << structureName;
122 if (!elt.hasAttribute(
"uri")) {
123 errMetaData <<
"uri is required for structure " << structureName;
127 QString structurePrefix = elt.attribute(
"prefix");
128 QString structureUri = elt.attribute(
"uri");
131 Schema* schema =
new Schema(structureUri, structurePrefix);
133 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
137 if (!parseEltType(e, info, name,
false,
false)) {
141 if (schema->
d->types.contains(name)) {
146 schema->
d->types[
name ] = info;
149 structures[ structureName ] = TypeInfo::Private::createStructure(schema, structureName);
152void Schema::Private::parseProperties(QDomElement& elt)
154 Q_ASSERT(elt.tagName() ==
"properties");
158 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
162 if (!parseEltType(e, info, name,
false,
false)) {
166 if (types.contains(name)) {
171 types[
name ] = info;
175bool Schema::Private::parseEltType(QDomElement &elt,
176 EntryInfo &entryInfo,
178 bool ignoreStructure,
181 dbgMetaData << elt.tagName() << elt.attributes().count() <<
name << ignoreStructure << ignoreName;
183 QString tagName = elt.tagName();
184 if (!ignoreName && !elt.hasAttribute(
"name")) {
185 errMetaData <<
"Missing name attribute for tag " << tagName;
188 name = elt.attribute(
"name");
191 if (tagName ==
"integer") {
192 entryInfo.propertyType = TypeInfo::Private::Integer;
193 }
else if (tagName ==
"boolean") {
194 entryInfo.propertyType = TypeInfo::Private::Boolean;
195 }
else if (tagName ==
"date") {
196 entryInfo.propertyType = TypeInfo::Private::Date;
197 }
else if (tagName ==
"text") {
198 entryInfo.propertyType = TypeInfo::Private::Text;
199 }
else if (tagName ==
"seq") {
200 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
202 ei = parseEmbType(elt, ignoreStructure);
210 entryInfo.propertyType = TypeInfo::Private::orderedArray(ei);
211 }
else if (tagName ==
"bag") {
212 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
214 ei = parseEmbType(elt, ignoreStructure);
222 entryInfo.propertyType = TypeInfo::Private::unorderedArray(ei);
223 }
else if (tagName ==
"alt") {
224 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
226 ei = parseEmbType(elt, ignoreStructure);
234 entryInfo.propertyType = TypeInfo::Private::alternativeArray(ei);
235 }
else if (tagName ==
"lang") {
236 entryInfo.propertyType = TypeInfo::Private::LangArray;
237 }
else if (tagName ==
"rational") {
238 entryInfo.propertyType = TypeInfo::Private::Rational;
239 }
else if (tagName ==
"gpscoordinate") {
240 entryInfo.propertyType = TypeInfo::Private::GPSCoordinate;
241 }
else if (tagName ==
"openedchoice" || tagName ==
"closedchoice") {
242 entryInfo.propertyType = parseChoice(elt);
243 }
else if (!ignoreStructure && structures.contains(tagName)) {
244 entryInfo.propertyType = structures.value(tagName);
253const TypeInfo* Schema::Private::parseAttType(QDomElement& elt,
bool ignoreStructure)
255 if (!elt.hasAttribute(
"type")) {
259 QString type = elt.attribute(
"type");
260 if (type ==
"integer") {
261 return TypeInfo::Private::Integer;
262 }
else if (type ==
"boolean") {
263 return TypeInfo::Private::Boolean;
264 }
else if (type ==
"date") {
265 return TypeInfo::Private::Date;
266 }
else if (type ==
"text") {
267 return TypeInfo::Private::Text;
268 }
else if (type ==
"rational") {
269 return TypeInfo::Private::Rational;
270 }
else if (!ignoreStructure && structures.contains(type)) {
271 return structures[type];
274 errMetaData <<
"Unsupported type: " << type <<
" in an attribute";
278const TypeInfo* Schema::Private::parseEmbType(QDomElement& elt,
bool ignoreStructure)
280 dbgMetaData <<
"Parse embedded type for " << elt.tagName();
283 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
284 QString type = e.tagName();
285 if (type ==
"integer") {
286 return TypeInfo::Private::Integer;
287 }
else if (type ==
"boolean") {
288 return TypeInfo::Private::Boolean;
289 }
else if (type ==
"date") {
290 return TypeInfo::Private::Date;
291 }
else if (type ==
"text") {
292 return TypeInfo::Private::Text;
293 }
else if (type ==
"openedchoice" || type ==
"closedchoice") {
294 return parseChoice(e);
295 }
else if (!ignoreStructure && structures.contains(type)) {
296 return structures[type];
303const TypeInfo* Schema::Private::parseChoice(QDomElement& elt)
305 const TypeInfo* choiceType = parseAttType(elt,
true);
307 if (elt.tagName() ==
"openedchoice") {
308 propertyType = TypeInfo::OpenedChoice;
310 Q_ASSERT(elt.tagName() ==
"closedchoice");
311 propertyType = TypeInfo::ClosedChoice;
316 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
320 if (!parseEltType(e, info, name,
true,
true)) {
325 choiceType = info.propertyType;
328 if (choiceType != info.propertyType) {
329 errMetaData <<
"All members of a choice need to be of the same type";
333 QString text = e.text();
336 if (choiceType->propertyType() == TypeInfo::IntegerType) {
338 }
else if (choiceType->propertyType() == TypeInfo::DateType) {
341 var = var.toDateTime();
346 return TypeInfo::Private::createChoice(propertyType, choiceType, choices);
363 dbgMetaData <<
"Deleting schema " <<
d->uri <<
" " <<
d->prefix;
370 if (
d->types.contains(_propertyName)) {
371 return d->types.value(_propertyName).propertyType;
378 return d->structures.value(_structureName);
394 dbgMetaData <<
"generateQualifiedName for " << name;
395 Q_ASSERT(!name.isEmpty() && !name.isNull());
396 return prefix() +
':' + name;
401 debug.nospace() <<
"Uri = " << c.
uri() <<
" Prefix = " << c.
prefix();
402 return debug.space();
QDebug KRITACOMMAND_EXPORT operator<<(QDebug dbg, const KisCumulativeUndoData &data)
const char * name(StandardAction id)