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