10#include <QDomDocument>
31bool Schema::Private::load(
const QString& _fileName)
35 QDomDocument document;
38 QFile
file(_fileName);
39 if (!document.setContent(&file, &error, &line, &column)) {
40 dbgMetaData << error <<
" at " << line <<
", " << column <<
" in " << _fileName;
44 QDomElement docElem = document.documentElement();
45 if (docElem.tagName() !=
"schema") {
50 if (!docElem.hasAttribute(
"prefix")) {
55 if (!docElem.hasAttribute(
"uri")) {
60 prefix = docElem.attribute(
"prefix");
61 uri = docElem.attribute(
"uri");
64 QDomElement structuresElt = docElem.firstChildElement(
"structures");
65 if (structuresElt.isNull()) {
69 QDomElement propertiesElt = docElem.firstChildElement(
"properties");
70 if (propertiesElt.isNull()) {
74 parseStructures(structuresElt);
75 parseProperties(propertiesElt);
80void Schema::Private::parseStructures(QDomElement& elt)
82 Q_ASSERT(elt.tagName() ==
"structures");
85 QDomElement e = elt.firstChildElement();
86 for (; !e.isNull(); e = e.nextSiblingElement()) {
87 if (e.tagName() ==
"structure") {
90 errMetaData <<
"Invalid tag: " << e.tagName() <<
" in structures section";
95void Schema::Private::parseStructure(QDomElement& elt)
97 Q_ASSERT(elt.tagName() ==
"structure");
99 if (!elt.hasAttribute(
"name")) {
104 QString structureName = elt.attribute(
"name");
105 if (structures.contains(structureName)) {
106 errMetaData << structureName <<
" is defined twice";
109 dbgMetaData <<
"Parsing structure " << structureName;
111 if (!elt.hasAttribute(
"prefix")) {
112 errMetaData <<
"prefix is required for structure " << structureName;
116 if (!elt.hasAttribute(
"uri")) {
117 errMetaData <<
"uri is required for structure " << structureName;
121 QString structurePrefix = elt.attribute(
"prefix");
122 QString structureUri = elt.attribute(
"uri");
125 Schema* schema =
new Schema(structureUri, structurePrefix);
127 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
131 if (!parseEltType(e, info, name,
false,
false)) {
135 if (schema->
d->types.contains(name)) {
140 schema->
d->types[
name ] = info;
143 structures[ structureName ] = TypeInfo::Private::createStructure(schema, structureName);
146void Schema::Private::parseProperties(QDomElement& elt)
148 Q_ASSERT(elt.tagName() ==
"properties");
152 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
156 if (!parseEltType(e, info, name,
false,
false)) {
160 if (types.contains(name)) {
165 types[
name ] = info;
169bool Schema::Private::parseEltType(QDomElement &elt,
170 EntryInfo &entryInfo,
172 bool ignoreStructure,
175 dbgMetaData << elt.tagName() << elt.attributes().count() <<
name << ignoreStructure << ignoreName;
177 QString tagName = elt.tagName();
178 if (!ignoreName && !elt.hasAttribute(
"name")) {
179 errMetaData <<
"Missing name attribute for tag " << tagName;
182 name = elt.attribute(
"name");
185 if (tagName ==
"integer") {
186 entryInfo.propertyType = TypeInfo::Private::Integer;
187 }
else if (tagName ==
"boolean") {
188 entryInfo.propertyType = TypeInfo::Private::Boolean;
189 }
else if (tagName ==
"date") {
190 entryInfo.propertyType = TypeInfo::Private::Date;
191 }
else if (tagName ==
"text") {
192 entryInfo.propertyType = TypeInfo::Private::Text;
193 }
else if (tagName ==
"seq") {
194 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
196 ei = parseEmbType(elt, ignoreStructure);
204 entryInfo.propertyType = TypeInfo::Private::orderedArray(ei);
205 }
else if (tagName ==
"bag") {
206 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
208 ei = parseEmbType(elt, ignoreStructure);
216 entryInfo.propertyType = TypeInfo::Private::unorderedArray(ei);
217 }
else if (tagName ==
"alt") {
218 const TypeInfo* ei = parseAttType(elt, ignoreStructure);
220 ei = parseEmbType(elt, ignoreStructure);
228 entryInfo.propertyType = TypeInfo::Private::alternativeArray(ei);
229 }
else if (tagName ==
"lang") {
230 entryInfo.propertyType = TypeInfo::Private::LangArray;
231 }
else if (tagName ==
"rational") {
232 entryInfo.propertyType = TypeInfo::Private::Rational;
233 }
else if (tagName ==
"gpscoordinate") {
234 entryInfo.propertyType = TypeInfo::Private::GPSCoordinate;
235 }
else if (tagName ==
"openedchoice" || tagName ==
"closedchoice") {
236 entryInfo.propertyType = parseChoice(elt);
237 }
else if (!ignoreStructure && structures.contains(tagName)) {
238 entryInfo.propertyType = structures.value(tagName);
247const TypeInfo* Schema::Private::parseAttType(QDomElement& elt,
bool ignoreStructure)
249 if (!elt.hasAttribute(
"type")) {
253 QString type = elt.attribute(
"type");
254 if (type ==
"integer") {
255 return TypeInfo::Private::Integer;
256 }
else if (type ==
"boolean") {
257 return TypeInfo::Private::Boolean;
258 }
else if (type ==
"date") {
259 return TypeInfo::Private::Date;
260 }
else if (type ==
"text") {
261 return TypeInfo::Private::Text;
262 }
else if (type ==
"rational") {
263 return TypeInfo::Private::Rational;
264 }
else if (!ignoreStructure && structures.contains(type)) {
265 return structures[type];
268 errMetaData <<
"Unsupported type: " << type <<
" in an attribute";
272const TypeInfo* Schema::Private::parseEmbType(QDomElement& elt,
bool ignoreStructure)
274 dbgMetaData <<
"Parse embedded type for " << elt.tagName();
277 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
278 QString type = e.tagName();
279 if (type ==
"integer") {
280 return TypeInfo::Private::Integer;
281 }
else if (type ==
"boolean") {
282 return TypeInfo::Private::Boolean;
283 }
else if (type ==
"date") {
284 return TypeInfo::Private::Date;
285 }
else if (type ==
"text") {
286 return TypeInfo::Private::Text;
287 }
else if (type ==
"openedchoice" || type ==
"closedchoice") {
288 return parseChoice(e);
289 }
else if (!ignoreStructure && structures.contains(type)) {
290 return structures[type];
297const TypeInfo* Schema::Private::parseChoice(QDomElement& elt)
299 const TypeInfo* choiceType = parseAttType(elt,
true);
301 if (elt.tagName() ==
"openedchoice") {
302 propertyType = TypeInfo::OpenedChoice;
304 Q_ASSERT(elt.tagName() ==
"closedchoice");
305 propertyType = TypeInfo::ClosedChoice;
310 for (e = elt.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
314 if (!parseEltType(e, info, name,
true,
true)) {
319 choiceType = info.propertyType;
322 if (choiceType != info.propertyType) {
323 errMetaData <<
"All members of a choice need to be of the same type";
327 QString text = e.text();
330 if (choiceType->propertyType() == TypeInfo::IntegerType) {
332 }
else if (choiceType->propertyType() == TypeInfo::DateType) {
335 var = var.toDateTime();
340 return TypeInfo::Private::createChoice(propertyType, choiceType, choices);
357 dbgMetaData <<
"Deleting schema " <<
d->uri <<
" " <<
d->prefix;
364 if (
d->types.contains(_propertyName)) {
365 return d->types.value(_propertyName).propertyType;
372 return d->structures.value(_structureName);
388 dbgMetaData <<
"generateQualifiedName for " << name;
389 Q_ASSERT(!name.isEmpty() && !name.isNull());
390 return prefix() +
':' + name;
395 debug.nospace() <<
"Uri = " << c.
uri() <<
" Prefix = " << c.
prefix();
396 return debug.space();
QDebug KRITACOMMAND_EXPORT operator<<(QDebug dbg, const KisCumulativeUndoData &data)
const char * name(StandardAction id)