PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/org.svenk.redmine.core/src/org/svenk/redmine/core/client/RedmineRestfulStaxReader.java

https://github.com/farukcank/redmin-mylyncon
Java | 781 lines | 619 code | 133 blank | 29 comment | 65 complexity | ff1dfa2e50e876f0f7ca0e2b9cb155c0 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2004, 2007 Mylyn project committers and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Mylyn project committers
  10. *******************************************************************************/
  11. /*******************************************************************************
  12. * Copyright (c) 2008 Sven Krzyzak
  13. * All rights reserved. This program and the accompanying materials
  14. * are made available under the terms of the Eclipse Public License v1.0
  15. * which accompanies this distribution, and is available at
  16. * http://www.eclipse.org/legal/epl-v10.html
  17. *
  18. * Contributors:
  19. * Sven Krzyzak - adapted Trac implementation for Redmine
  20. *******************************************************************************/
  21. package org.svenk.redmine.core.client;
  22. import java.io.InputStream;
  23. import java.util.ArrayList;
  24. import java.util.Date;
  25. import java.util.List;
  26. import javax.xml.parsers.ParserConfigurationException;
  27. import javax.xml.parsers.SAXParserFactory;
  28. import javax.xml.stream.XMLInputFactory;
  29. import javax.xml.stream.XMLStreamConstants;
  30. import javax.xml.stream.XMLStreamException;
  31. import javax.xml.stream.XMLStreamReader;
  32. import org.svenk.redmine.core.accesscontrol.internal.RedmineAcl;
  33. import org.svenk.redmine.core.client.container.Version;
  34. import org.svenk.redmine.core.client.container.Version.Plugin;
  35. import org.svenk.redmine.core.client.container.Version.Redmine;
  36. import org.svenk.redmine.core.exception.RedmineErrorException;
  37. import org.svenk.redmine.core.exception.RedmineException;
  38. import org.svenk.redmine.core.exception.RedmineInputParserException;
  39. import org.svenk.redmine.core.model.RedmineActivity;
  40. import org.svenk.redmine.core.model.RedmineAttachment;
  41. import org.svenk.redmine.core.model.RedmineCustomField;
  42. import org.svenk.redmine.core.model.RedmineCustomValue;
  43. import org.svenk.redmine.core.model.RedmineIssueCategory;
  44. import org.svenk.redmine.core.model.RedmineMember;
  45. import org.svenk.redmine.core.model.RedminePriority;
  46. import org.svenk.redmine.core.model.RedmineProject;
  47. import org.svenk.redmine.core.model.RedmineStoredQuery;
  48. import org.svenk.redmine.core.model.RedmineTicket;
  49. import org.svenk.redmine.core.model.RedmineTicketJournal;
  50. import org.svenk.redmine.core.model.RedmineTicketRelation;
  51. import org.svenk.redmine.core.model.RedmineTicketStatus;
  52. import org.svenk.redmine.core.model.RedmineTimeEntry;
  53. import org.svenk.redmine.core.model.RedmineTracker;
  54. import org.svenk.redmine.core.model.RedmineVersion;
  55. import org.svenk.redmine.core.model.RedmineTicket.Key;
  56. import org.svenk.redmine.core.util.RedmineUtil;
  57. import org.xml.sax.SAXException;
  58. import org.xml.sax.XMLReader;
  59. public class RedmineRestfulStaxReader {
  60. public final static String NS_API_25 = "http://redmin-mylyncon.sf.net/schemas/WS-API-2.5";
  61. private final static String NS_PREFIX = null;
  62. private SAXParserFactory parserFactory;
  63. private XMLInputFactory inputFactory;
  64. public RedmineRestfulStaxReader() {
  65. // inputFactory = org.codehaus.stax2.XMLInputFactory2.newInstance("com.ctc.wstx.osgi.InputFactoryProviderImpl", this.getClass().getClassLoader());
  66. inputFactory = new com.ctc.wstx.osgi.InputFactoryProviderImpl().createInputFactory();
  67. }
  68. public RedmineTicket readTicket(InputStream in) throws RedmineException {
  69. RedmineTicket ticket = null;
  70. try {
  71. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  72. reader.nextTag();
  73. ticket = readCurrentTagAsTicket(reader);
  74. } catch (XMLStreamException e) {
  75. throw new RedmineErrorException("An error ocurred during the parsing of ticket", e);
  76. }
  77. return ticket;
  78. }
  79. public List<RedmineTicket> readTickets(InputStream in) throws RedmineException {
  80. List<RedmineTicket> tickets = new ArrayList<RedmineTicket>();
  81. try {
  82. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  83. reader.nextTag();
  84. RedmineTicket ticket = null;
  85. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("issue")) {
  86. ticket = readCurrentTagAsTicket(reader);
  87. if (ticket!=null) {
  88. tickets.add(ticket);
  89. }
  90. }
  91. } catch (XMLStreamException e) {
  92. throw new RedmineErrorException("An error ocurred during the parsing of tickets", e);
  93. }
  94. return tickets;
  95. }
  96. public List<Integer> readUpdatedTickets(InputStream in) throws RedmineException {
  97. List<Integer> list = new ArrayList<Integer>();
  98. try {
  99. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  100. reader.nextTag();//updatedIssues
  101. String[] values = reader.getElementText().split(" ");
  102. for (String val : values) {
  103. val = val.trim();
  104. if (val.length()>0) {
  105. list.add(Integer.valueOf(val));
  106. }
  107. }
  108. } catch (XMLStreamException e) {
  109. throw new RedmineErrorException("An error ocurred during the parsing of updated tickets", e);
  110. }
  111. return list;
  112. }
  113. public List<RedmineTicketStatus> readTicketStatuses(InputStream in) throws RedmineException {
  114. List<RedmineTicketStatus> list = new ArrayList<RedmineTicketStatus>();
  115. try {
  116. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  117. reader.nextTag();//issueStatuses
  118. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  119. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  120. reader.nextTag();//name
  121. String name = reader.getElementText().trim();
  122. RedmineTicketStatus status = new RedmineTicketStatus(name, id);
  123. reader.nextTag();//position, unused
  124. Integer.parseInt(reader.getElementText());
  125. reader.nextTag();//closed
  126. status.setClosed(Boolean.parseBoolean(reader.getElementText()));
  127. reader.nextTag();//default
  128. status.setDefaultStatus(Boolean.parseBoolean(reader.getElementText()));
  129. list.add(status);
  130. reader.nextTag();//issueStatus End-Tag
  131. }
  132. } catch (XMLStreamException e) {
  133. throw new RedmineErrorException("An error ocurred during the parsing of status", e);
  134. }
  135. return list;
  136. }
  137. public List<RedminePriority> readPriorities(InputStream in) throws RedmineException {
  138. List<RedminePriority> list = new ArrayList<RedminePriority>();
  139. try {
  140. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  141. reader.nextTag();//priorities
  142. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  143. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  144. reader.nextTag();//name
  145. String name = reader.getElementText().trim();
  146. reader.nextTag();//position
  147. int position = Integer.parseInt(reader.getElementText());
  148. RedminePriority priority = new RedminePriority(name, id, position);
  149. reader.nextTag();//default
  150. priority.setDefaultPriority(Boolean.parseBoolean(reader.getElementText()));
  151. list.add(priority);
  152. reader.nextTag();//priority End-Tag
  153. }
  154. } catch (XMLStreamException e) {
  155. throw new RedmineErrorException("An error ocurred during the parsing of priorities", e);
  156. }
  157. return list;
  158. }
  159. public List<RedmineActivity> readActivities(InputStream in) throws RedmineException {
  160. List<RedmineActivity> list = new ArrayList<RedmineActivity>();
  161. try {
  162. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  163. reader.nextTag();//priorities
  164. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  165. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  166. reader.nextTag();//name
  167. String name = reader.getElementText().trim();
  168. reader.nextTag();//position
  169. int position = Integer.parseInt(reader.getElementText());
  170. RedmineActivity activity = new RedmineActivity(name, id, position);
  171. reader.nextTag();//default
  172. activity.setDefaultPriority(Boolean.parseBoolean(reader.getElementText()));
  173. list.add(activity);
  174. reader.nextTag();//priority End-Tag
  175. }
  176. } catch (XMLStreamException e) {
  177. throw new RedmineErrorException("An error ocurred during the parsing of activities", e);
  178. }
  179. return list;
  180. }
  181. public List<RedmineCustomField> readCustomFields(InputStream in) throws RedmineException {
  182. List<RedmineCustomField> list = new ArrayList<RedmineCustomField>();
  183. try {
  184. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  185. reader.nextTag();//customFields
  186. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("customField")) {
  187. RedmineCustomField customField = readCurrentTagAsCustomField(reader);
  188. if(customField!=null) {
  189. list.add(customField);
  190. }
  191. }
  192. } catch (XMLStreamException e) {
  193. throw new RedmineErrorException("An error ocurred during the parsing of customfields", e);
  194. }
  195. return list;
  196. }
  197. public List<RedmineProjectData> readProjects(InputStream in) throws RedmineException {
  198. List<RedmineProjectData> projects = new ArrayList<RedmineProjectData>();
  199. try {
  200. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  201. reader.nextTag();
  202. RedmineProjectData projectData = null;
  203. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("project")) {
  204. projectData = readCurrentTagAsProject(reader);
  205. if (projectData!=null) {
  206. projects.add(projectData);
  207. }
  208. }
  209. } catch (XMLStreamException e) {
  210. throw new RedmineErrorException("An error ocurred during the parsing of projects", e);
  211. }
  212. return projects;
  213. }
  214. public Version readVersion(InputStream in) throws RedmineException {
  215. Version version = null;
  216. try {
  217. XMLStreamReader reader = inputFactory.createXMLStreamReader(in);
  218. reader.nextTag(); //version
  219. version = new Version();
  220. reader.nextTag(); //plugin
  221. version.plugin = Plugin.fromString(reader.getElementText().trim());
  222. reader.nextTag(); //redmine
  223. version.redmine = Redmine.fromString(reader.getElementText().trim());
  224. } catch (XMLStreamException e) {
  225. throw new RedmineErrorException("An error ocurred during the parsing of versions", e);
  226. }
  227. return version;
  228. }
  229. protected XMLReader newReader() throws SAXException, ParserConfigurationException {
  230. if (parserFactory==null) {
  231. parserFactory = SAXParserFactory.newInstance();
  232. parserFactory.setNamespaceAware(false);
  233. }
  234. return parserFactory.newSAXParser().getXMLReader();
  235. }
  236. protected RedmineProjectData readCurrentTagAsProject(XMLStreamReader reader) throws RedmineInputParserException, XMLStreamException {
  237. RedmineProjectData data = null;
  238. try {
  239. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  240. reader.nextTag();
  241. RedmineProject project = new RedmineProject(reader.getElementText(), id);
  242. //skip identifier
  243. reader.nextTag();
  244. reader.getElementText();
  245. reader.nextTag();
  246. project.setIssueEditAllowed(Boolean.parseBoolean(reader.getElementText()));
  247. data = new RedmineProjectData(project);
  248. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  249. if (reader.getLocalName().equals("trackers")) {
  250. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  251. RedmineTracker tracker = readCurrentTagAsTracker(reader);
  252. if (tracker!=null) {
  253. data.trackers.add(tracker);
  254. }
  255. }
  256. } else if (reader.getLocalName().equals("versions")) {
  257. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  258. RedmineVersion version = readCurrentTagAsVersion(reader);
  259. if (version!=null) {
  260. data.versions.add(version);
  261. }
  262. }
  263. } else if (reader.getLocalName().equals("members")) {
  264. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  265. RedmineMember member = readCurrentTagAsMember(reader);
  266. if (member!=null) {
  267. data.members.add(member);
  268. }
  269. }
  270. } else if (reader.getLocalName().equals("issueCategories")) {
  271. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  272. RedmineIssueCategory category = readCurrentTagAsCategory(reader);
  273. if (category!=null) {
  274. data.categorys.add(category);
  275. }
  276. }
  277. } else if (reader.getLocalName().equals("issueCustomFields")) {
  278. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  279. RedmineCustomField field = readCurrentTagAsCustomField(reader);
  280. if (field!=null) {
  281. data.customTicketFields.add(field);
  282. }
  283. }
  284. } else if (reader.getLocalName().equals("queries")) {
  285. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  286. RedmineStoredQuery query = readCurrentTagAsQuery(reader);
  287. if (query!=null) {
  288. data.storedQueries.add(query);
  289. }
  290. }
  291. } else {
  292. //catch/skip unknown Tags
  293. skipToEndTag(reader.getLocalName(), reader);
  294. }
  295. }
  296. } finally {
  297. if (!(reader.getEventType()==XMLStreamConstants.END_ELEMENT && reader.getLocalName().equals("project"))) {
  298. skipToEndTag("project", reader);
  299. }
  300. }
  301. return data;
  302. }
  303. protected RedmineTicket readCurrentTagAsTicket(XMLStreamReader reader) throws XMLStreamException {
  304. RedmineTicket ticket = null;
  305. try {
  306. ticket = new RedmineTicket(Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id")));
  307. String useDoneration = reader.getAttributeValue(NS_PREFIX, "useDoneratioField");
  308. ticket.setUseDoneratioField(useDoneration==null || Boolean.valueOf(useDoneration));
  309. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  310. Key key = Key.fromTagName(reader.getLocalName());
  311. if (key==null) {
  312. if (reader.getLocalName().equals("availableStatus")) {
  313. List<Integer> idList = ticket.getAvailableStatusList();
  314. for (String id : reader.getElementText().split("\\s+")) {
  315. id = id.trim();
  316. if (id.length()>0) {
  317. idList.add(Integer.valueOf(id));
  318. }
  319. }
  320. } else if (reader.getLocalName().equals("customValues")) {
  321. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  322. try {
  323. Integer cfId = Integer.valueOf(reader.getAttributeValue(NS_PREFIX, "customFieldId"));
  324. String value = reader.getElementText();
  325. ticket.putCustomFieldValue(cfId, value);
  326. } catch (NumberFormatException e) {
  327. reader.getElementText(); //Skip Content
  328. }
  329. }
  330. } else if (reader.getLocalName().equals("journals")) {
  331. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  332. RedmineTicketJournal journal = readCurrentTagAsJournal(reader);
  333. if (journal!=null) {
  334. ticket.addJournal(journal);
  335. }
  336. }
  337. } else if (reader.getLocalName().equals("attachments")) {
  338. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  339. RedmineAttachment attachment = readCurrentTagAsAttachment(reader);
  340. if (attachment!=null) {
  341. ticket.addAttachment(attachment);
  342. }
  343. }
  344. } else if (reader.getLocalName().equals("issueRelations")) {
  345. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  346. RedmineTicketRelation relation = readCurrentTagAsRelation(reader);
  347. if (relation!=null) {
  348. ticket.addRelation(relation);
  349. }
  350. }
  351. } else if (reader.getLocalName().equals("timeEntries")) {
  352. boolean viewAllowed = Boolean.parseBoolean(reader.getAttributeValue(NS_PREFIX, "viewAllowed"));
  353. ticket.putRight(RedmineAcl.TIMEENTRY_VIEW, viewAllowed);
  354. ticket.putRight(RedmineAcl.TIMEENTRY_NEW, Boolean.parseBoolean(reader.getAttributeValue(NS_PREFIX, "newAllowed")));
  355. if (viewAllowed) {
  356. reader.nextTag();//sum
  357. ticket.putBuiltinValue(Key.TIME_ENTRY_TOTAL, reader.getElementText());
  358. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  359. RedmineTimeEntry timeEntry = readCurrentTagAsTimeEntry(reader);
  360. if (timeEntry!=null) {
  361. ticket.addTimeEntry(timeEntry);
  362. }
  363. }
  364. }
  365. } else {
  366. //catch/skip unknown Tags
  367. skipToEndTag(reader.getLocalName(), reader);
  368. }
  369. } else {
  370. switch (key) {
  371. case CREATED_ON : {
  372. long unixtime = Long.parseLong(reader.getAttributeValue(NS_PREFIX, "unixtime"));
  373. ticket.setCreated(new Date(unixtime*1000L));
  374. reader.getElementText(); //Skip Content
  375. break;
  376. }
  377. case UPDATED_ON : {
  378. long unixtime = Long.parseLong(reader.getAttributeValue(NS_PREFIX, "unixtime"));
  379. ticket.setLastChanged(new Date(unixtime*1000L));
  380. reader.getElementText(); //Skip Content
  381. break;
  382. }
  383. default : ticket.putBuiltinValue(key, reader.getElementText());
  384. }
  385. }
  386. }
  387. } catch (NumberFormatException e) {
  388. ticket = null;
  389. } finally {
  390. if (!(reader.getEventType()==XMLStreamConstants.END_ELEMENT && reader.getLocalName().equals("issue"))) {
  391. skipToEndTag("issue", reader);
  392. }
  393. }
  394. return ticket;
  395. }
  396. protected RedmineTicketJournal readCurrentTagAsJournal(XMLStreamReader reader) throws XMLStreamException {
  397. RedmineTicketJournal journal = new RedmineTicketJournal();
  398. try {
  399. journal.setId(Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id")));
  400. reader.nextTag();
  401. journal.setAuthorName(reader.getElementText());
  402. reader.nextTag();
  403. long unixtime = Long.parseLong(reader.getAttributeValue(NS_PREFIX, "unixtime"));
  404. journal.setCreated(new Date(unixtime*1000L));
  405. reader.getElementText(); //Skip Content
  406. reader.nextTag();
  407. journal.setNotes(reader.getElementText());
  408. reader.nextTag();
  409. journal.setEditable(Boolean.parseBoolean(reader.getElementText()));
  410. } catch (NumberFormatException e) {
  411. journal = null;
  412. } finally {
  413. skipToEndTag("journal", reader);
  414. }
  415. return journal;
  416. }
  417. protected RedmineAttachment readCurrentTagAsAttachment(XMLStreamReader reader) throws XMLStreamException {
  418. RedmineAttachment attachment = null;
  419. try {
  420. attachment = new RedmineAttachment(Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id")));
  421. reader.nextTag();
  422. attachment.setAuthorName(reader.getElementText());
  423. reader.nextTag();
  424. long unixtime = Long.parseLong(reader.getAttributeValue(NS_PREFIX, "unixtime"));
  425. attachment.setCreated(new Date(unixtime*1000L));
  426. reader.getElementText(); //Skip Content
  427. reader.nextTag();
  428. attachment.setFilename(reader.getElementText());
  429. reader.nextTag();
  430. attachment.setFilesize(Integer.parseInt(reader.getElementText()));
  431. reader.nextTag();
  432. attachment.setDigest(reader.getElementText());
  433. reader.nextTag();
  434. attachment.setContentType(reader.getElementText());
  435. reader.nextTag();
  436. attachment.setDescription(reader.getElementText());
  437. } finally {
  438. skipToEndTag("attachment", reader);
  439. }
  440. return attachment;
  441. }
  442. protected RedmineTicketRelation readCurrentTagAsRelation(XMLStreamReader reader) throws XMLStreamException {
  443. RedmineTicketRelation relation = null;
  444. try {
  445. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  446. reader.nextTag();
  447. int fromId = Integer.parseInt(reader.getElementText());
  448. reader.nextTag();
  449. int toId = Integer.parseInt(reader.getElementText());
  450. reader.nextTag();
  451. String type = reader.getElementText();
  452. relation = new RedmineTicketRelation(id, fromId, toId, type);
  453. } finally {
  454. skipToEndTag("issueRelation", reader);
  455. }
  456. return relation;
  457. }
  458. protected RedmineTimeEntry readCurrentTagAsTimeEntry(XMLStreamReader reader) throws XMLStreamException {
  459. RedmineTimeEntry timeEntry = null;
  460. try {
  461. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  462. reader.nextTag();
  463. float hours = Float.parseFloat(reader.getElementText());
  464. reader.nextTag();
  465. int activityId = Integer.parseInt(reader.getElementText());
  466. reader.nextTag();
  467. int userId = Integer.parseInt(reader.getElementText());
  468. timeEntry = new RedmineTimeEntry();
  469. timeEntry.setId(id);
  470. timeEntry.setHours(hours);
  471. timeEntry.setActivityId(activityId);
  472. timeEntry.setUserId(userId);
  473. reader.nextTag();
  474. timeEntry.setSpentOn(RedmineUtil.parseDate(reader.getElementText()));
  475. reader.nextTag();
  476. timeEntry.setComments(reader.getElementText());
  477. reader.nextTag();//customValues
  478. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  479. RedmineCustomValue customValue = readCurrentTagAsCustomValue(reader);
  480. if (customValue!=null) {
  481. timeEntry.addCustomValue(customValue);
  482. }
  483. }
  484. } finally {
  485. skipToEndTag("timeEntry", reader);
  486. }
  487. return timeEntry;
  488. }
  489. protected RedmineCustomValue readCurrentTagAsCustomValue(XMLStreamReader reader) throws XMLStreamException {
  490. RedmineCustomValue customValue = null;
  491. try {
  492. int customFieldId = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "customFieldId"));
  493. String value = reader.getElementText();
  494. customValue = new RedmineCustomValue();
  495. customValue.setCustomFieldId(customFieldId);
  496. customValue.setValue(value);
  497. } finally {
  498. // skipToEndTag("customValue", reader);
  499. }
  500. return customValue;
  501. }
  502. protected RedmineTracker readCurrentTagAsTracker(XMLStreamReader reader) throws XMLStreamException {
  503. RedmineTracker tracker = null;
  504. try {
  505. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  506. reader.nextTag();
  507. tracker = new RedmineTracker(reader.getElementText(), id);
  508. //skip position
  509. } finally {
  510. skipToEndTag("tracker", reader);
  511. }
  512. return tracker;
  513. }
  514. protected RedmineVersion readCurrentTagAsVersion(XMLStreamReader reader) throws XMLStreamException {
  515. RedmineVersion version = null;
  516. try {
  517. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  518. reader.nextTag();
  519. version = new RedmineVersion(reader.getElementText(), id);
  520. reader.nextTag();
  521. if(reader.getLocalName().equals("open")) {
  522. version.setOpen(Boolean.valueOf(reader.getElementText()));
  523. }
  524. } finally {
  525. skipToEndTag("version", reader);
  526. }
  527. return version;
  528. }
  529. protected RedmineMember readCurrentTagAsMember(XMLStreamReader reader) throws XMLStreamException {
  530. RedmineMember member = null;
  531. try {
  532. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  533. reader.nextTag();
  534. String name = reader.getElementText();
  535. reader.nextTag();
  536. member = new RedmineMember(name, id, Boolean.parseBoolean(reader.getElementText()));
  537. //skip emailAddress
  538. //skip emailNotification
  539. } finally {
  540. skipToEndTag("member", reader);
  541. }
  542. return member;
  543. }
  544. protected RedmineIssueCategory readCurrentTagAsCategory(XMLStreamReader reader) throws XMLStreamException {
  545. RedmineIssueCategory category = null;
  546. try {
  547. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  548. reader.nextTag();
  549. category = new RedmineIssueCategory(reader.getElementText(), id);
  550. } finally {
  551. skipToEndTag("issueCategory", reader);
  552. }
  553. return category;
  554. }
  555. protected RedmineStoredQuery readCurrentTagAsQuery(XMLStreamReader reader) throws XMLStreamException {
  556. RedmineStoredQuery query = null;
  557. try {
  558. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  559. reader.nextTag();
  560. query = new RedmineStoredQuery(reader.getElementText(), id);
  561. } finally {
  562. skipToEndTag("query", reader);
  563. }
  564. return query;
  565. }
  566. protected void skipToEndTag(String tagname, XMLStreamReader reader) throws XMLStreamException {
  567. while(!(reader.isEndElement() && reader.getLocalName().equals(tagname))) {
  568. if(reader.isStartElement() && reader.hasText()) {
  569. reader.getElementText();
  570. }
  571. reader.next();
  572. }
  573. }
  574. private enum CustomFieldTag {name, type, fieldFormat, minLength, maxLength, regexp, possibleValues, defaultValue, required, filter, forAll, trackers;
  575. private static CustomFieldTag fromTagName(String tagName) {
  576. for (CustomFieldTag tag : CustomFieldTag.values()) {
  577. if (tag.name().equals(tagName)) {
  578. return tag;
  579. }
  580. }
  581. return null;
  582. }
  583. };
  584. private RedmineCustomField readCurrentTagAsCustomField(XMLStreamReader reader) throws XMLStreamException, RedmineInputParserException{
  585. String tagName = reader.getLocalName();
  586. RedmineCustomField field = null;
  587. try {
  588. int id = Integer.parseInt(reader.getAttributeValue(NS_PREFIX, "id"));
  589. String name = null;
  590. RedmineCustomField.CustomType customType = null;
  591. while(!(reader.nextTag()==XMLStreamConstants.END_ELEMENT && reader.getLocalName().equals(tagName))) {
  592. CustomFieldTag tag = CustomFieldTag.fromTagName(reader.getLocalName());
  593. if (tag==null) {
  594. throw new RedmineInputParserException(Messages.RedmineRestfulStaxReader_PARSING_OF_CUSTOMFIELD_FAILED_UNKNOWN_TAG + reader.getLocalName());
  595. }
  596. switch(tag) {
  597. case name : name = reader.getElementText().trim(); break;
  598. case type :
  599. customType = RedmineCustomField.CustomType.fromString(reader.getElementText().trim());
  600. if (customType==null) {
  601. //unsed CustomType
  602. skipToEndTag(tagName, reader);
  603. return null;
  604. }
  605. break;
  606. case fieldFormat :
  607. field = customType==null
  608. ? new RedmineCustomField(id, reader.getElementText().trim())
  609. : new RedmineCustomField(id, reader.getElementText().trim(), customType);
  610. field.setName(name);
  611. break;
  612. case minLength : field.setMin(Integer.parseInt(reader.getElementText().trim())); break;
  613. case maxLength : field.setMax(Integer.parseInt(reader.getElementText().trim())); break;
  614. case regexp : field.setValidationRegex(reader.getElementText().trim()); break;
  615. case defaultValue : field.setDefaultValue(reader.getElementText().trim()); break;
  616. case required : field.setRequired(Boolean.parseBoolean(reader.getElementText().trim())); break;
  617. case forAll : field.setForAll(Boolean.parseBoolean(reader.getElementText().trim())); break;
  618. case filter : field.setSupportFilter(Boolean.parseBoolean(reader.getElementText().trim()));break;
  619. case possibleValues :
  620. List<String> possibleValues = new ArrayList<String>();
  621. while(reader.nextTag()==XMLStreamConstants.START_ELEMENT) {
  622. possibleValues.add(reader.getElementText());
  623. }
  624. field.setListValues(possibleValues.toArray(new String[possibleValues.size()]));
  625. break;
  626. case trackers :
  627. String[] trackerIdVals = reader.getElementText().trim().split("\\s+");
  628. int[] trackerIds = new int[trackerIdVals.length];
  629. for (int i=trackerIdVals.length-1; i>=0; i--) {
  630. trackerIds[i] = Integer.parseInt(trackerIdVals[i]);
  631. }
  632. field.setTrackerId(trackerIds);
  633. break;
  634. default :
  635. }
  636. }
  637. } catch (NumberFormatException e) {
  638. field = null;
  639. throw new RedmineInputParserException(Messages.RedmineRestfulStaxReader_PARSING_OF_CUSTOMFIELD_FAILED, e);
  640. } catch (XMLStreamException e) {
  641. field = null;
  642. throw new RedmineInputParserException(Messages.RedmineRestfulStaxReader_PARSING_OF_CUSTOMFIELD_FAILED, e);
  643. } finally {
  644. skipToEndTag(tagName, reader);
  645. }
  646. return field;
  647. }
  648. }