1 /******************************************************************************
2
3 This source file is part of the MoleQueue project.
4
5 Copyright 2012 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #include "jobeventlist.h"
18 #include "messagehandler.h"
19
20 #include <QtXmlPatterns/QAbstractXmlReceiver>
21 #include <QtXmlPatterns/QXmlNamePool>
22 #include <QtXmlPatterns/QXmlQuery>
23 #include <QtCore/QList>
24 #include <QtCore/QRegExp>
25
26 namespace {
27
28 /**
29 * @brief XML receiver to parser JobEvent tags.
30 */
31 class JobEventListXmlReceiver : public QAbstractXmlReceiver
32 {
33
34 public:
35 JobEventListXmlReceiver(QXmlNamePool pool);
36
atomicValue(const QVariant & value)37 void atomicValue ( const QVariant & value ) { Q_UNUSED(value); }
attribute(const QXmlName & name,const QStringRef & value)38 void attribute ( const QXmlName & name, const QStringRef & value ) {
39 Q_UNUSED(name);
40 Q_UNUSED(value);
41 }
42 void characters ( const QStringRef & value );
comment(const QString & value)43 void comment ( const QString & value ) { Q_UNUSED(value); }
endDocument()44 void endDocument () {}
45 void endElement ();
endOfSequence()46 void endOfSequence () {};
namespaceBinding(const QXmlName & name)47 void namespaceBinding ( const QXmlName & name ) { Q_UNUSED(name); };
processingInstruction(const QXmlName & target,const QString & value)48 void processingInstruction ( const QXmlName & target,
49 const QString & value) {
50 Q_UNUSED(target);
51 Q_UNUSED(value);
52 };
startDocument()53 void startDocument () {};
54 void startElement ( const QXmlName & name );
startOfSequence()55 void startOfSequence () {};
56
jobEvents() const57 QList<MoleQueue::Uit::JobEvent> jobEvents() const {
58 return m_events;
59 };
60
61 private:
62 QXmlNamePool m_pool;
63 MoleQueue::Uit::JobEvent m_currentEvent;
64 QString m_currentName;
65 QString m_currentValue;
66 QList<MoleQueue::Uit::JobEvent> m_events;
67 int tagDepth;
68
69 };
70
JobEventListXmlReceiver(QXmlNamePool pool)71 JobEventListXmlReceiver::JobEventListXmlReceiver(QXmlNamePool pool)
72 : m_pool(pool), tagDepth(0)
73 {
74
75 }
76
77
characters(const QStringRef & value)78 void JobEventListXmlReceiver::characters ( const QStringRef & value )
79 {
80 if (!m_currentName.isEmpty()) {
81 m_currentValue.append(value);
82 }
83 }
84
endElement()85 void JobEventListXmlReceiver::endElement ()
86 {
87 if (tagDepth-- == 1) {
88 // Save the current event.
89 m_events.append(m_currentEvent);
90 m_currentEvent = MoleQueue::Uit::JobEvent();
91 }
92 else if (m_currentName == "acctHost") {
93 m_currentEvent.setAcctHost(m_currentValue);
94 }
95 else if (m_currentName == "eventType") {
96 m_currentEvent.setEventType(m_currentValue);
97 }
98 else if (m_currentName == "eventTime") {
99 m_currentEvent.setEventTime(m_currentValue.toInt());
100 }
101 else if (m_currentName == "jobID") {
102 QRegExp regex ("^(\\d+)\\..*$");
103 regex.indexIn(m_currentValue.trimmed());
104 m_currentEvent.setJobId(regex.cap(1).toLongLong());
105 }
106 else if (m_currentName == "jobQueue") {
107 m_currentEvent.setJobQueue(m_currentValue);
108 }
109 else if (m_currentName == "jobStatus") {
110 m_currentEvent.setJobStatus(m_currentValue);
111 }
112 else if (m_currentName == "jobStatusText") {
113 m_currentEvent.setJobStatusText(m_currentValue);
114 }
115
116 m_currentName.clear();
117 m_currentValue.clear();
118 }
119
startElement(const QXmlName & name)120 void JobEventListXmlReceiver::startElement ( const QXmlName & name )
121 {
122 tagDepth++;
123 m_currentName = name.localName(m_pool);
124 m_currentValue.clear();
125 }
126
127 } /* namespace anonymous */
128
129 namespace MoleQueue {
130 namespace Uit {
131
JobEventList()132 JobEventList::JobEventList()
133 : m_valid(false)
134 {
135
136 }
137
JobEventList(const JobEventList & other)138 JobEventList::JobEventList(const JobEventList &other)
139 : m_valid(false), m_jobEvents(other.jobEvents())
140 {
141
142 }
143
fromXml(const QString & xml)144 JobEventList JobEventList::fromXml(const QString &xml)
145 {
146 QList<qint64> empty;
147 return fromXml(xml, "", empty);
148 }
149
fromXml(const QString & xml,const QString & userName,QList<qint64> jobIds)150 JobEventList JobEventList::fromXml(const QString &xml, const QString &userName,
151 QList<qint64> jobIds)
152 {
153 JobEventList list;
154 list.setContent(xml, userName, jobIds);
155
156 return list;
157 }
158
setContent(const QString & content,const QString & userName,QList<qint64> jobIds)159 void JobEventList::setContent(const QString &content, const QString &userName,
160 QList<qint64> jobIds)
161 {
162 m_xml = content;
163 m_valid = true;
164
165 MessageHandler handler;
166 QXmlQuery query;
167 query.setMessageHandler(&handler);
168 JobEventListXmlReceiver receiver(query.namePool());
169 query.setFocus(m_xml);
170
171 if (jobIds.isEmpty()) {
172 query.setQuery("/list/JobEvent");
173 }
174 else {
175 QString xpath = "/list/JobEvent/jobID[";
176 QListIterator<qint64> iter(jobIds);
177
178 while (iter.hasNext()) {
179 qint64 jobId = iter.next();
180 xpath += QString("starts-with(text(), '%1')").arg(jobId);
181 if (iter.hasNext())
182 xpath += " or ";
183 }
184
185 xpath += "]/parent::node()";
186
187 query.setQuery(xpath);
188 }
189
190 m_valid = query.evaluateTo(&receiver);
191
192 m_jobEvents = receiver.jobEvents();
193 }
194
195 } /* namespace Uit */
196 } /* namespace MoleQueue */
197