diff --git a/pom.xml b/pom.xml index ea57686..a9decb7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,19 +5,24 @@ pl.com.it-crowd youtrack-rest-api - 1.0.2-SNAPSHOT + 1.1.0-SNAPSHOT junit junit 4.8.2 + test + + + org.apache.httpcomponents + httpclient + 4.2-beta1 - - net.sourceforge.htmlunit - htmlunit - 2.8 + commons-io + commons-io + 2.3 diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/IssuesUnmarshaller.java b/src/main/java/pl/com/it_crowd/youtrack/api/ErrorUnmarshaller.java index 7621f92..ac7f53e 100644 --- a/src/main/java/pl/com/it_crowd/youtrack/api/IssuesUnmarshaller.java +++ b/src/main/java/pl/com/it_crowd/youtrack/api/ErrorUnmarshaller.java @@ -1,38 +1,42 @@ package pl.com.it_crowd.youtrack.api; import org.apache.commons.io.IOUtils; -import pl.com.it_crowd.youtrack.api.rest.Issues; +import pl.com.it_crowd.youtrack.api.rest.ObjectFactory; import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; -import java.net.URL; -public class IssuesUnmarshaller { +//TODO methods from this class should be probably merged with YoutrackUnmarshaller +public final class ErrorUnmarshaller { +// -------------------------- STATIC METHODS -------------------------- - public static Issues unmarshal(String url) throws JAXBException, IOException + public static String unmarshal(String string) throws JAXBException, IOException { - return unmarshal(new URL(url).openStream()); + return unmarshal(new StringReader(string)); } - public static Issues unmarshal(InputStream stream) throws JAXBException, IOException - { - return unmarshal(new InputStreamReader(stream)); - } - - public static Issues unmarshal(Reader reader) throws JAXBException, IOException + public static String unmarshal(Reader reader) throws JAXBException, IOException { String content = IOUtils.toString(reader); try { - JAXBContext jaxbContext = JAXBContext.newInstance(Issues.class.getPackage().getName()); - return (Issues) jaxbContext.createUnmarshaller().unmarshal(new StringReader(content)); + JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class); + @SuppressWarnings("unchecked") + final JAXBElement element = (JAXBElement) jaxbContext.createUnmarshaller().unmarshal(new StringReader(content)); + return element.getValue(); } catch (JAXBException e) { +// TODO we need logging here System.err.println("Cannot unmarshal input stream.\n" + content + e); throw e; } } + +// --------------------------- CONSTRUCTORS --------------------------- + + private ErrorUnmarshaller() + { + } } diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/Issue.java b/src/main/java/pl/com/it_crowd/youtrack/api/IssueWrapper.java index 8f89e34..b94f96b 100644 --- a/src/main/java/pl/com/it_crowd/youtrack/api/Issue.java +++ b/src/main/java/pl/com/it_crowd/youtrack/api/IssueWrapper.java @@ -2,7 +2,9 @@ package pl.com.it_crowd.youtrack.api; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import pl.com.it_crowd.youtrack.api.rest.Issues; +import pl.com.it_crowd.youtrack.api.rest.Comment; +import pl.com.it_crowd.youtrack.api.rest.Field; +import pl.com.it_crowd.youtrack.api.rest.Issue; import java.io.Serializable; import java.util.ArrayList; @@ -10,30 +12,30 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class Issue implements Serializable { +public class IssueWrapper implements Serializable { // ------------------------------ FIELDS ------------------------------ - private static final Log log = LogFactory.getLog(Issue.class); + private static final Log log = LogFactory.getLog(IssueWrapper.class); - private List comments; + private List comments; - private Map fieldMap; + private Map fieldMap; - private Issues.Issue issue; + private Issue issue; // --------------------------- CONSTRUCTORS --------------------------- - public Issue(Issues.Issue issue) + public IssueWrapper(Issue issue) { this.issue = issue; - fieldMap = new HashMap(); - comments = new ArrayList(); + fieldMap = new HashMap(); + comments = new ArrayList(); for (Object o : issue.getFieldOrComment()) { - if (o instanceof Issues.Issue.Field) { - Issues.Issue.Field field = (Issues.Issue.Field) o; + if (o instanceof Field) { + Field field = (Field) o; fieldMap.put(field.getName(), field); - } else if (o instanceof Issues.Issue.Comment) { - comments.add((Issues.Issue.Comment) o); + } else if (o instanceof Comment) { + comments.add((Comment) o); } else { log.warn("Object " + o + " is not Field nor Coment"); } @@ -42,18 +44,18 @@ public class Issue implements Serializable { // -------------------------- OTHER METHODS -------------------------- - public Issues.Issue.Field getField(String field) + public Field getField(String field) { return fieldMap.get(field); } public String getFieldValue(String fieldName) { - Issues.Issue.Field field = fieldMap.get(fieldName); + Field field = getField(fieldName); if (field == null) { return null; } - List values = field.getValues(); + List values = field.getValues(); return values.isEmpty() ? null : values.get(0).getContent(); } diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackAPI.java b/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackAPI.java index b727810..023e82a 100644 --- a/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackAPI.java +++ b/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackAPI.java @@ -1,49 +1,116 @@ package pl.com.it_crowd.youtrack.api; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.HttpMethod; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebRequest; -import com.gargoylesoftware.htmlunit.WebResponse; -import com.gargoylesoftware.htmlunit.html.DomNode; -import com.gargoylesoftware.htmlunit.util.NameValuePair; -import com.gargoylesoftware.htmlunit.xml.XmlPage; -import org.apache.http.auth.AuthenticationException; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.conn.SchemeRegistryFactory; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import pl.com.it_crowd.youtrack.api.exceptions.NoResultFoundException; +import pl.com.it_crowd.youtrack.api.exceptions.YoutrackAPIException; +import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException; +import pl.com.it_crowd.youtrack.api.rest.Issue; import pl.com.it_crowd.youtrack.api.rest.Issues; +import pl.com.it_crowd.youtrack.api.rest.ObjectFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.GeneralSecurityException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class YoutrackAPI { // ------------------------------ FIELDS ------------------------------ + private HttpClient httpClient; + private String serviceLocation; - private WebClient webClient; +// -------------------------- STATIC METHODS -------------------------- + + private static HttpClient getDefaultHttpClient() + { + SSLContext sslContext; + try { + sslContext = SSLContext.getInstance("SSL"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + // set up a TrustManager that trusts everything + try { + sslContext.init(null, new TrustManager[]{new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException + { + } + + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException + { + } + + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[0]; + } + }}, new SecureRandom()); + } catch (KeyManagementException e) { + throw new RuntimeException(e); + } + + SSLSocketFactory sf = new SSLSocketFactory(sslContext); + Scheme httpsScheme = new Scheme("https", 443, sf); + SchemeRegistry schemeRegistry = SchemeRegistryFactory.createDefault(); + schemeRegistry.register(schemeRegistry.unregister("https")); + schemeRegistry.register(httpsScheme); + + ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); + return new DefaultHttpClient(cm); + } // --------------------------- CONSTRUCTORS --------------------------- public YoutrackAPI(String serviceLocation) { + this(serviceLocation, getDefaultHttpClient()); + } + + public YoutrackAPI(String serviceLocation, HttpClient httpClient) + { this.serviceLocation = serviceLocation; - this.webClient = new WebClient(BrowserVersion.FIREFOX_3_6); - this.webClient.setJavaScriptEnabled(false); - this.webClient.setCssEnabled(false); - try { - this.webClient.setUseInsecureSSL(true); - } catch (GeneralSecurityException e) { - throw new RuntimeException("Cannot turn on 'Use insecure SSL'", e); - } + this.httpClient = httpClient; } - public YoutrackAPI(String serviceLocation, String username, String password) throws IOException, AuthenticationException + public YoutrackAPI(String serviceLocation, String username, String password) throws IOException, JAXBException { this(serviceLocation); login(username, password); @@ -58,68 +125,184 @@ public class YoutrackAPI { // -------------------------- OTHER METHODS -------------------------- - public void login(String username, String password) throws IOException, AuthenticationException + /** + * Creates new issue on Youtrack. + * + * @param project project to create issue in + * @param summary summary of the issue + * @param description longer description of the issue + * + * @return issue id of created issue + * + * @throws IOException in case of communication problems + */ + public String createIssue(String project, String summary, String description) throws IOException + { + final URI uri; + try { + uri = new URIBuilder(serviceLocation + "/rest/issue").addParameter("project", project) + .addParameter("summary", summary) + .addParameter("description", description) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + final HttpResponse response = httpClient.execute(new HttpPut(uri)); + final StatusLine statusLine = response.getStatusLine(); + final HttpEntity entity = response.getEntity(); + final String responseText = entity == null ? null : EntityUtils.toString(entity); + throwExceptionsIfNeeded(statusLine, responseText); + + final Header header = response.getFirstHeader(HttpHeaders.LOCATION); + if (header == null) { + throw new YoutrackAPIException("Missing location header despite positive status code: " + statusLine.getStatusCode()); + } + final String issueURL = header.getValue(); + final Matcher matcher = Pattern.compile(".*(" + project + "-\\d+)").matcher(issueURL); + if (!matcher.find() || matcher.groupCount() < 1) { + throw new YoutrackAPIException("Cannot extract issue id from issue URL: " + issueURL); + } + return matcher.group(1); + } + + public IssueWrapper getIssue(String issueId) throws IOException, JAXBException { - ArrayList requestParameters = new ArrayList(); - requestParameters.add(new NameValuePair("login", username)); - requestParameters.add(new NameValuePair("password", password)); - WebRequest request = new WebRequest(new URL(serviceLocation + "/rest/user/login"), HttpMethod.POST); - request.setRequestParameters(requestParameters); + final URI uri; + try { + uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueId).build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + final String responseString; try { - webClient.getPage(request); - } catch (FailingHttpStatusCodeException e) { - if (e.getStatusCode() == 403) { - DomNode error = ((XmlPage) webClient.getCurrentWindow().getEnclosedPage()).getFirstChild(); - if (error != null) { - throw new AuthenticationException(error.getTextContent()); + responseString = execute(new HttpGet(uri)); + } catch (HttpResponseException e) { + if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { + try { + final String error = ErrorUnmarshaller.unmarshal(e.getMessage()); + throw new NoResultFoundException(error); + } catch (JAXBException e1) { + // TODO we should log on debug level the JAXBException + throw e; } + } else { + throw e; } - throw e; + } + final Object result = YoutrackUnmarshaller.unmarshall(responseString); + if (result instanceof pl.com.it_crowd.youtrack.api.rest.Issue) { + return new IssueWrapper((Issue) result); + } else if (result instanceof JAXBElement) { + final JAXBElement jaxbElement = (JAXBElement) result; + if (ObjectFactory._Error_QNAME.equals(jaxbElement.getName())) { + throw new RuntimeException("Unexpected type: " + jaxbElement.getValue()); + } else if (ObjectFactory._Issue_QNAME.equals(jaxbElement.getName())) { + return new IssueWrapper((Issue) jaxbElement.getValue()); + } else { + throw new RuntimeException(jaxbElement.getValue() + ""); + } + } else { + throw new RuntimeException("Unexpected type " + result); } } - public List searchIssuesByProject(String project, Object filter) throws JAXBException, IOException + public void login(String username, String password) throws IOException, JAXBException { - String url = serviceLocation + "/rest/issue/byproject/" + project + "?filter=" + filter; - WebResponse webResponse = webClient.getPage(url).getWebResponse(); + final HttpPost request = new HttpPost(serviceLocation + "/rest/user/login"); + request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password)))); + try { + execute(request); + } catch (HttpResponseException e) { + if (e.getStatusCode() == HttpStatus.SC_FORBIDDEN) { + try { + final String error = ErrorUnmarshaller.unmarshal(e.getMessage()); + throw new YoutrackErrorException(error, e.getStatusCode()); + } catch (JAXBException e1) { + // TODO we should log on debug level the JAXBException + throw e; + } + } else { + throw e; + } + } + } - List issues = IssuesUnmarshaller.unmarshal(webResponse.getContentAsStream()).getIssue(); - List result = new ArrayList(); - for (Issues.Issue issue : issues) { - result.add(new Issue(issue)); + public List searchIssuesByProject(String project, Object filter) throws JAXBException, IOException + { + final URI uri; + try { + uri = new URIBuilder(serviceLocation + "/rest/issue/byproject/" + project).addParameter("filter", filter == null ? null : filter.toString()) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + final Object result = YoutrackUnmarshaller.unmarshall(execute(new HttpGet(uri))); + if (!(result instanceof Issues)) { + throw new YoutrackAPIException("Unmarshalling problem. Expected Issues, received: " + result.getClass() + " " + result); + } + List issues = ((Issues) result).getIssues(); + List wrappedIssues = new ArrayList(); + for (Issue issue : issues) { + wrappedIssues.add(new IssueWrapper(issue)); } - return result; + return wrappedIssues; } public void setTotalBilledHours(String issueSignature, Long billedHours) { - String url = serviceLocation + "/rest/issue/" + issueSignature + "/execute"; - ArrayList requestParameters = new ArrayList(); - requestParameters.add(new NameValuePair("command", "Billed hours " + billedHours)); + //QA-SUGGESTION this method should not be in this project, remove it from this class + final URI uri; try { - WebRequest request = new WebRequest(new URL(url), HttpMethod.POST); - request.setRequestParameters(requestParameters); - webClient.getPage(request); - } catch (MalformedURLException e) { - e.printStackTrace(); + uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueSignature + "/execute").build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + try { + final HttpPost request = new HttpPost(uri); + request.getParams().setParameter("command", "Billed hours " + billedHours); + execute(request); } catch (IOException e) { - e.printStackTrace(); + throw new RuntimeException(e); } } public void setTotalIssueDuration(String issueSignature, Long issueTotalDuration) { - String url = serviceLocation + "/rest/issue/" + issueSignature + "/execute"; - ArrayList requestParameters = new ArrayList(); - requestParameters.add(new NameValuePair("command", "Real completion time " + issueTotalDuration)); + //QA-SUGGESTION this method should not be in this project, remove it from this class + final URI uri; + try { + uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueSignature + "/execute").build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } try { - WebRequest request = new WebRequest(new URL(url), HttpMethod.POST); - request.setRequestParameters(requestParameters); - webClient.getPage(request); - } catch (MalformedURLException e) { - e.printStackTrace(); + final HttpPost request = new HttpPost(uri); + request.getParams().setParameter("command", "Real completion time " + issueTotalDuration); + execute(request); } catch (IOException e) { - e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private String execute(HttpUriRequest request) throws IOException + { + final HttpResponse response = httpClient.execute(request); + final StatusLine statusLine = response.getStatusLine(); + final HttpEntity entity = response.getEntity(); + String responseText = entity == null ? null : EntityUtils.toString(entity); + if (statusLine.getStatusCode() >= 300) { + throw new HttpResponseException(statusLine.getStatusCode(), responseText); + } + if (entity == null) { + throw new ClientProtocolException("Response contains no content"); + } + return responseText; + } + + private void throwExceptionsIfNeeded(StatusLine statusLine, String responseText) throws IOException + { + if (statusLine.getStatusCode() >= 300) { + throw new HttpResponseException(statusLine.getStatusCode(), responseText); } } } \ No newline at end of file diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackUnmarshaller.java b/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackUnmarshaller.java new file mode 100644 index 0000000..a7ada03 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/YoutrackUnmarshaller.java @@ -0,0 +1,28 @@ +package pl.com.it_crowd.youtrack.api; + +import pl.com.it_crowd.youtrack.api.rest.ObjectFactory; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import java.io.Reader; +import java.io.StringReader; + +public final class YoutrackUnmarshaller { +// -------------------------- STATIC METHODS -------------------------- + + public static Object unmarshall(String string) throws JAXBException + { + return unmarshall(new StringReader(string)); + } + + public static Object unmarshall(Reader reader) throws JAXBException + { + return JAXBContext.newInstance(ObjectFactory.class).createUnmarshaller().unmarshal(reader); + } + +// --------------------------- CONSTRUCTORS --------------------------- + + private YoutrackUnmarshaller() + { + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/NoResultFoundException.java b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/NoResultFoundException.java new file mode 100644 index 0000000..effe9e7 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/NoResultFoundException.java @@ -0,0 +1,14 @@ +package pl.com.it_crowd.youtrack.api.exceptions; + +public class NoResultFoundException extends RuntimeException { +// --------------------------- CONSTRUCTORS --------------------------- + + public NoResultFoundException() + { + } + + public NoResultFoundException(String message) + { + super(message); + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackAPIException.java b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackAPIException.java new file mode 100644 index 0000000..be96924 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackAPIException.java @@ -0,0 +1,14 @@ +package pl.com.it_crowd.youtrack.api.exceptions; + +public class YoutrackAPIException extends RuntimeException { +// --------------------------- CONSTRUCTORS --------------------------- + + public YoutrackAPIException() + { + } + + public YoutrackAPIException(String message) + { + super(message); + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackErrorException.java b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackErrorException.java new file mode 100644 index 0000000..ee93cdc --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/exceptions/YoutrackErrorException.java @@ -0,0 +1,22 @@ +package pl.com.it_crowd.youtrack.api.exceptions; + +public class YoutrackErrorException extends RuntimeException { +// ------------------------------ FIELDS ------------------------------ + + private int statusCode; + +// --------------------------- CONSTRUCTORS --------------------------- + + public YoutrackErrorException(String message, int statusCode) + { + super(message); + this.statusCode = statusCode; + } + +// --------------------- GETTER / SETTER METHODS --------------------- + + public int getStatusCode() + { + return statusCode; + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/rest/Comment.java b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Comment.java new file mode 100644 index 0000000..887b1f9 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Comment.java @@ -0,0 +1,399 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.02 at 11:11:34 PM CEST +// + +package pl.com.it_crowd.youtrack.api.rest; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlElementRefs; +import javax.xml.bind.annotation.XmlMixed; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + *

Java class for commentType complex type. + *

+ *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <complexType name="commentType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="replies" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="value" maxOccurs="unbounded" minOccurs="0">
+ *           <complexType>
+ *             <simpleContent>
+ *               <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ *                 <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               </extension>
+ *             </simpleContent>
+ *           </complexType>
+ *         </element>
+ *       </sequence>
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="issueId" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="deleted" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="text" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="shownForIssueAuthor" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="created" type="{http://www.w3.org/2001/XMLSchema}long" />
+ *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "commentType", propOrder = {"content"}) +public class Comment { +// ------------------------------ FIELDS ------------------------------ + + @XmlAttribute + protected String author; + + @XmlElementRefs({@XmlElementRef(name = "value", type = JAXBElement.class), @XmlElementRef(name = "replies", type = JAXBElement.class)}) + @XmlMixed + protected List content; + + @XmlAttribute + protected Long created; + + @XmlAttribute + protected String deleted; + + @XmlAttribute + protected String id; + + @XmlAttribute + protected String issueId; + + @XmlAttribute + protected String name; + + @XmlAttribute + protected String shownForIssueAuthor; + + @XmlAttribute + protected String text; + +// --------------------- GETTER / SETTER METHODS --------------------- + + /** + * Gets the value of the author property. + * + * @return possible object is + * {@link String } + */ + public String getAuthor() + { + return author; + } + + /** + * Sets the value of the author property. + * + * @param value allowed object is + * {@link String } + */ + public void setAuthor(String value) + { + this.author = value; + } + + /** + * Gets the value of the content property. + *

+ *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the content property. + *

+ *

+ * For example, to add a new item, do as follows: + *

+     *    getContent().add(newItem);
+     * 
+ *

+ *

+ *

+ * Objects of the following type(s) are allowed in the list + * {@link JAXBElement }{@code <}{@link String }{@code >} + * {@link JAXBElement }{@code <}{@link Comment.Value }{@code >} + * {@link String } + */ + public List getContent() + { + if (content == null) { + content = new ArrayList(); + } + return this.content; + } + + /** + * Gets the value of the created property. + * + * @return possible object is + * {@link Long } + */ + public Long getCreated() + { + return created; + } + + /** + * Sets the value of the created property. + * + * @param value allowed object is + * {@link Long } + */ + public void setCreated(Long value) + { + this.created = value; + } + + /** + * Gets the value of the deleted property. + * + * @return possible object is + * {@link String } + */ + public String getDeleted() + { + return deleted; + } + + /** + * Sets the value of the deleted property. + * + * @param value allowed object is + * {@link String } + */ + public void setDeleted(String value) + { + this.deleted = value; + } + + /** + * Gets the value of the id property. + * + * @return possible object is + * {@link String } + */ + public String getId() + { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value allowed object is + * {@link String } + */ + public void setId(String value) + { + this.id = value; + } + + /** + * Gets the value of the issueId property. + * + * @return possible object is + * {@link String } + */ + public String getIssueId() + { + return issueId; + } + + /** + * Sets the value of the issueId property. + * + * @param value allowed object is + * {@link String } + */ + public void setIssueId(String value) + { + this.issueId = value; + } + + /** + * Gets the value of the name property. + * + * @return possible object is + * {@link String } + */ + public String getName() + { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value allowed object is + * {@link String } + */ + public void setName(String value) + { + this.name = value; + } + + /** + * Gets the value of the shownForIssueAuthor property. + * + * @return possible object is + * {@link String } + */ + public String getShownForIssueAuthor() + { + return shownForIssueAuthor; + } + + /** + * Sets the value of the shownForIssueAuthor property. + * + * @param value allowed object is + * {@link String } + */ + public void setShownForIssueAuthor(String value) + { + this.shownForIssueAuthor = value; + } + + /** + * Gets the value of the text property. + * + * @return possible object is + * {@link String } + */ + public String getText() + { + return text; + } + + /** + * Sets the value of the text property. + * + * @param value allowed object is + * {@link String } + */ + public void setText(String value) + { + this.text = value; + } + +// -------------------------- INNER CLASSES -------------------------- + + /** + *

Java class for anonymous complex type. + *

+ *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+     * <complexType>
+     *   <simpleContent>
+     *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
+     *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     </extension>
+     *   </simpleContent>
+     * </complexType>
+     * 
+ */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = {"value"}) + public static class Value { +// ------------------------------ FIELDS ------------------------------ + + @XmlAttribute + protected String role; + + @XmlAttribute + protected String type; + + @XmlValue + protected String value; + +// --------------------- GETTER / SETTER METHODS --------------------- + + /** + * Gets the value of the role property. + * + * @return possible object is + * {@link String } + */ + public String getRole() + { + return role; + } + + /** + * Sets the value of the role property. + * + * @param value allowed object is + * {@link String } + */ + public void setRole(String value) + { + this.role = value; + } + + /** + * Gets the value of the type property. + * + * @return possible object is + * {@link String } + */ + public String getType() + { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value allowed object is + * {@link String } + */ + public void setType(String value) + { + this.type = value; + } + + /** + * Gets the value of the value property. + * + * @return possible object is + * {@link String } + */ + public String getValue() + { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value allowed object is + * {@link String } + */ + public void setValue(String value) + { + this.value = value; + } + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/rest/Field.java b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Field.java new file mode 100644 index 0000000..d890361 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Field.java @@ -0,0 +1,209 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.02 at 11:11:34 PM CEST +// + +package pl.com.it_crowd.youtrack.api.rest; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import java.util.ArrayList; +import java.util.List; + +/** + *

Java class for fieldType complex type. + *

+ *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <complexType name="fieldType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence maxOccurs="unbounded" minOccurs="0">
+ *         <element name="value">
+ *           <complexType>
+ *             <complexContent>
+ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               </restriction>
+ *             </complexContent>
+ *           </complexType>
+ *         </element>
+ *       </sequence>
+ *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "fieldType", propOrder = {"values"}) +public class Field { +// ------------------------------ FIELDS ------------------------------ + + @XmlAttribute + protected String name; + + @XmlElement(name = "value") + protected List values; + +// --------------------- GETTER / SETTER METHODS --------------------- + + /** + * Gets the value of the name property. + * + * @return possible object is + * {@link String } + */ + public String getName() + { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value allowed object is + * {@link String } + */ + public void setName(String value) + { + this.name = value; + } + + /** + * Gets the value of the values property. + *

+ *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the values property. + *

+ *

+ * For example, to add a new item, do as follows: + *

+     *    getValues().add(newItem);
+     * 
+ *

+ *

+ *

+ * Objects of the following type(s) are allowed in the list + * {@link Field.Value } + */ + public List getValues() + { + if (values == null) { + values = new ArrayList(); + } + return this.values; + } + +// -------------------------- INNER CLASSES -------------------------- + + /** + *

Java class for anonymous complex type. + *

+ *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = {"content"}) + public static class Value { +// ------------------------------ FIELDS ------------------------------ + + @XmlValue + protected String content; + + @XmlAttribute + protected String role; + + @XmlAttribute + protected String type; + +// --------------------- GETTER / SETTER METHODS --------------------- + + /** + * Gets the value of the content property. + * + * @return possible object is + * {@link String } + */ + public String getContent() + { + return content; + } + + /** + * Sets the value of the content property. + * + * @param value allowed object is + * {@link String } + */ + public void setContent(String value) + { + this.content = value; + } + + /** + * Gets the value of the role property. + * + * @return possible object is + * {@link String } + */ + public String getRole() + { + return role; + } + + /** + * Sets the value of the role property. + * + * @param value allowed object is + * {@link String } + */ + public void setRole(String value) + { + this.role = value; + } + + /** + * Gets the value of the type property. + * + * @return possible object is + * {@link String } + */ + public String getType() + { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value allowed object is + * {@link String } + */ + public void setType(String value) + { + this.type = value; + } + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issue.java b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issue.java new file mode 100644 index 0000000..597fc85 --- /dev/null +++ b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issue.java @@ -0,0 +1,101 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.02 at 11:11:34 PM CEST +// + +package pl.com.it_crowd.youtrack.api.rest; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlType; +import java.util.ArrayList; +import java.util.List; + +/** + *

Java class for issueType complex type. + *

+ *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <complexType name="issueType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice maxOccurs="unbounded" minOccurs="0">
+ *         <element name="field" type="{}fieldType"/>
+ *         <element name="comment" type="{}commentType"/>
+ *       </choice>
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "issueType", propOrder = {"fieldOrComment"}) +public class Issue { +// ------------------------------ FIELDS ------------------------------ + + @XmlElements({@XmlElement(name = "comment", type = Comment.class), @XmlElement(name = "field", type = Field.class)}) + protected List fieldOrComment; + + @XmlAttribute + protected String id; + +// --------------------- GETTER / SETTER METHODS --------------------- + + /** + * Gets the value of the fieldOrComment property. + *

+ *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the fieldOrComment property. + *

+ *

+ * For example, to add a new item, do as follows: + *

+     *    getFieldOrComment().add(newItem);
+     * 
+ *

+ *

+ *

+ * Objects of the following type(s) are allowed in the list + * {@link Comment } + * {@link Field } + */ + public List getFieldOrComment() + { + if (fieldOrComment == null) { + fieldOrComment = new ArrayList(); + } + return this.fieldOrComment; + } + + /** + * Gets the value of the id property. + * + * @return possible object is + * {@link String } + */ + public String getId() + { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value allowed object is + * {@link String } + */ + public void setId(String value) + { + this.id = value; + } +} diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issues.java b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issues.java index 9e02507..0e98feb 100644 --- a/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issues.java +++ b/src/main/java/pl/com/it_crowd/youtrack/api/rest/Issues.java @@ -2,19 +2,16 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.16 at 10:06:20 AM CET +// Generated on: 2012.07.02 at 11:11:34 PM CEST // package pl.com.it_crowd.youtrack.api.rest; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; import java.util.ArrayList; import java.util.List; @@ -27,68 +24,8 @@ import java.util.List; * <complexType> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="issue" maxOccurs="unbounded" minOccurs="0"> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <choice maxOccurs="unbounded" minOccurs="0"> - * <element name="field"> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="value" maxOccurs="unbounded" minOccurs="0"> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" /> - * </restriction> - * </complexContent> - * </complexType> - * </element> - * </sequence> - * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> - * </restriction> - * </complexContent> - * </complexType> - * </element> - * <element name="comment"> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="replies" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> - * <element name="value" minOccurs="0"> - * <complexType> - * <simpleContent> - * <extension base="<http://www.w3.org/2001/XMLSchema>string"> - * <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" /> - * </extension> - * </simpleContent> - * </complexType> - * </element> - * </sequence> - * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="issueId" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="deleted" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="text" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="shownForIssueAuthor" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="created" type="{http://www.w3.org/2001/XMLSchema}string" /> - * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> - * </restriction> - * </complexContent> - * </complexType> - * </element> - * </choice> - * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" /> - * </restriction> - * </complexContent> - * </complexType> - * </element> + * <sequence maxOccurs="unbounded" minOccurs="0"> + * <element name="issue" type="{}issueType"/> * </sequence> * </restriction> * </complexContent> @@ -96,734 +33,41 @@ import java.util.List; * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = {"issue"}) +@XmlType(name = "", propOrder = {"issues"}) @XmlRootElement(name = "issues") public class Issues { +// ------------------------------ FIELDS ------------------------------ - protected List issue; + @XmlElement(name = "issue") + protected List issues; + +// --------------------- GETTER / SETTER METHODS --------------------- /** - * Gets the value of the issue property. + * Gets the value of the issues property. *

*

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. - * This is why there is not a set method for the issue property. + * This is why there is not a set method for the issues property. *

*

* For example, to add a new item, do as follows: *

-     *    getIssue().add(newItem);
+     *    getIssues().add(newItem);
      * 
*

*

*

* Objects of the following type(s) are allowed in the list - * {@link Issues.Issue } + * {@link Issue } */ - public List getIssue() + public List getIssues() { - if (issue == null) { - issue = new ArrayList(); - } - return this.issue; - } - - /** - *

Java class for anonymous complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

-     * <complexType>
-     *   <complexContent>
-     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       <choice maxOccurs="unbounded" minOccurs="0">
-     *         <element name="field">
-     *           <complexType>
-     *             <complexContent>
-     *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 <sequence>
-     *                   <element name="value" maxOccurs="unbounded" minOccurs="0">
-     *                     <complexType>
-     *                       <complexContent>
-     *                         <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                           <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                           <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                         </restriction>
-     *                       </complexContent>
-     *                     </complexType>
-     *                   </element>
-     *                 </sequence>
-     *                 <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *               </restriction>
-     *             </complexContent>
-     *           </complexType>
-     *         </element>
-     *         <element name="comment">
-     *           <complexType>
-     *             <complexContent>
-     *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 <sequence>
-     *                   <element name="replies" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *                   <element name="value" minOccurs="0">
-     *                     <complexType>
-     *                       <simpleContent>
-     *                         <extension base="<http://www.w3.org/2001/XMLSchema>string">
-     *                           <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                           <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                         </extension>
-     *                       </simpleContent>
-     *                     </complexType>
-     *                   </element>
-     *                 </sequence>
-     *                 <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="issueId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="deleted" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="text" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="shownForIssueAuthor" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="created" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *               </restriction>
-     *             </complexContent>
-     *           </complexType>
-     *         </element>
-     *       </choice>
-     *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     </restriction>
-     *   </complexContent>
-     * </complexType>
-     * 
- */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = {"fieldOrComment"}) - public static class Issue { - - @XmlElements({@XmlElement(name = "field", type = Issues.Issue.Field.class), @XmlElement(name = "comment", type = Issues.Issue.Comment.class)}) - protected List fieldOrComment; - - @XmlAttribute - protected String id; - - /** - * Gets the value of the fieldOrComment property. - *

- *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the fieldOrComment property. - *

- *

- * For example, to add a new item, do as follows: - *

-         *    getFieldOrComment().add(newItem);
-         * 
- *

- *

- *

- * Objects of the following type(s) are allowed in the list - * {@link Issues.Issue.Field } - * {@link Issues.Issue.Comment } - */ - public List getFieldOrComment() - { - if (fieldOrComment == null) { - fieldOrComment = new ArrayList(); - } - return this.fieldOrComment; - } - - /** - * Gets the value of the id property. - * - * @return possible object is - * {@link String } - */ - public String getId() - { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value allowed object is - * {@link String } - */ - public void setId(String value) - { - this.id = value; - } - - /** - *

Java class for anonymous complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

-         * <complexType>
-         *   <complexContent>
-         *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       <sequence>
-         *         <element name="replies" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-         *         <element name="value" minOccurs="0">
-         *           <complexType>
-         *             <simpleContent>
-         *               <extension base="<http://www.w3.org/2001/XMLSchema>string">
-         *                 <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                 <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *               </extension>
-         *             </simpleContent>
-         *           </complexType>
-         *         </element>
-         *       </sequence>
-         *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="issueId" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="deleted" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="text" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="shownForIssueAuthor" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="created" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *     </restriction>
-         *   </complexContent>
-         * </complexType>
-         * 
- */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = {"replies", "value"}) - public static class Comment { - - protected String replies; - - protected Issues.Issue.Comment.Value value; - - @XmlAttribute - protected String id; - - @XmlAttribute - protected String author; - - @XmlAttribute - protected String issueId; - - @XmlAttribute - protected String deleted; - - @XmlAttribute - protected String text; - - @XmlAttribute - protected String shownForIssueAuthor; - - @XmlAttribute - protected String created; - - @XmlAttribute - protected String name; - - /** - * Gets the value of the replies property. - * - * @return possible object is - * {@link String } - */ - public String getReplies() - { - return replies; - } - - /** - * Sets the value of the replies property. - * - * @param value allowed object is - * {@link String } - */ - public void setReplies(String value) - { - this.replies = value; - } - - /** - * Gets the value of the value property. - * - * @return possible object is - * {@link Issues.Issue.Comment.Value } - */ - public Issues.Issue.Comment.Value getValue() - { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value allowed object is - * {@link Issues.Issue.Comment.Value } - */ - public void setValue(Issues.Issue.Comment.Value value) - { - this.value = value; - } - - /** - * Gets the value of the id property. - * - * @return possible object is - * {@link String } - */ - public String getId() - { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value allowed object is - * {@link String } - */ - public void setId(String value) - { - this.id = value; - } - - /** - * Gets the value of the author property. - * - * @return possible object is - * {@link String } - */ - public String getAuthor() - { - return author; - } - - /** - * Sets the value of the author property. - * - * @param value allowed object is - * {@link String } - */ - public void setAuthor(String value) - { - this.author = value; - } - - /** - * Gets the value of the issueId property. - * - * @return possible object is - * {@link String } - */ - public String getIssueId() - { - return issueId; - } - - /** - * Sets the value of the issueId property. - * - * @param value allowed object is - * {@link String } - */ - public void setIssueId(String value) - { - this.issueId = value; - } - - /** - * Gets the value of the deleted property. - * - * @return possible object is - * {@link String } - */ - public String getDeleted() - { - return deleted; - } - - /** - * Sets the value of the deleted property. - * - * @param value allowed object is - * {@link String } - */ - public void setDeleted(String value) - { - this.deleted = value; - } - - /** - * Gets the value of the text property. - * - * @return possible object is - * {@link String } - */ - public String getText() - { - return text; - } - - /** - * Sets the value of the text property. - * - * @param value allowed object is - * {@link String } - */ - public void setText(String value) - { - this.text = value; - } - - /** - * Gets the value of the shownForIssueAuthor property. - * - * @return possible object is - * {@link String } - */ - public String getShownForIssueAuthor() - { - return shownForIssueAuthor; - } - - /** - * Sets the value of the shownForIssueAuthor property. - * - * @param value allowed object is - * {@link String } - */ - public void setShownForIssueAuthor(String value) - { - this.shownForIssueAuthor = value; - } - - /** - * Gets the value of the created property. - * - * @return possible object is - * {@link String } - */ - public String getCreated() - { - return created; - } - - /** - * Sets the value of the created property. - * - * @param value allowed object is - * {@link String } - */ - public void setCreated(String value) - { - this.created = value; - } - - /** - * Gets the value of the name property. - * - * @return possible object is - * {@link String } - */ - public String getName() - { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value allowed object is - * {@link String } - */ - public void setName(String value) - { - this.name = value; - } - - /** - *

Java class for anonymous complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

-             * <complexType>
-             *   <simpleContent>
-             *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
-             *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *       <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *     </extension>
-             *   </simpleContent>
-             * </complexType>
-             * 
- */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = {"value"}) - public static class Value { - - @XmlValue - protected String value; - - @XmlAttribute - protected String type; - - @XmlAttribute - protected String role; - - /** - * Gets the value of the value property. - * - * @return possible object is - * {@link String } - */ - public String getValue() - { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value allowed object is - * {@link String } - */ - public void setValue(String value) - { - this.value = value; - } - - /** - * Gets the value of the type property. - * - * @return possible object is - * {@link String } - */ - public String getType() - { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value allowed object is - * {@link String } - */ - public void setType(String value) - { - this.type = value; - } - - /** - * Gets the value of the role property. - * - * @return possible object is - * {@link String } - */ - public String getRole() - { - return role; - } - - /** - * Sets the value of the role property. - * - * @param value allowed object is - * {@link String } - */ - public void setRole(String value) - { - this.role = value; - } - } - } - - /** - *

Java class for anonymous complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

-         * <complexType>
-         *   <complexContent>
-         *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       <sequence>
-         *         <element name="value" maxOccurs="unbounded" minOccurs="0">
-         *           <complexType>
-         *             <complexContent>
-         *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *                 <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                 <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *               </restriction>
-         *             </complexContent>
-         *           </complexType>
-         *         </element>
-         *       </sequence>
-         *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *     </restriction>
-         *   </complexContent>
-         * </complexType>
-         * 
- */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = {"values"}) - public static class Field { - - @XmlElement(name = "value") - protected List values; - - @XmlAttribute - protected String name; - - /** - * Gets the value of the values property. - *

- *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the values property. - *

- *

- * For example, to add a new item, do as follows: - *

-             *    getValues().add(newItem);
-             * 
- *

- *

- *

- * Objects of the following type(s) are allowed in the list - * {@link Issues.Issue.Field.Value } - */ - public List getValues() - { - if (values == null) { - values = new ArrayList(); - } - return this.values; - } - - /** - * Gets the value of the name property. - * - * @return possible object is - * {@link String } - */ - public String getName() - { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value allowed object is - * {@link String } - */ - public void setName(String value) - { - this.name = value; - } - - /** - *

Java class for anonymous complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

-             * <complexType>
-             *   <complexContent>
-             *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-             *       <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *       <attribute name="role" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *     </restriction>
-             *   </complexContent>
-             * </complexType>
-             * 
- */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = {"content"}) - public static class Value { - - @XmlValue - protected String content; - - @XmlAttribute - protected String type; - - @XmlAttribute - protected String role; - - /** - * Gets the value of the content property. - * - * @return possible object is - * {@link String } - */ - public String getContent() - { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value allowed object is - * {@link String } - */ - public void setContent(String value) - { - this.content = value; - } - - /** - * Gets the value of the type property. - * - * @return possible object is - * {@link String } - */ - public String getType() - { - return type; - } - - /** - * Sets the value of the type property. - * - * @param value allowed object is - * {@link String } - */ - public void setType(String value) - { - this.type = value; - } - - /** - * Gets the value of the role property. - * - * @return possible object is - * {@link String } - */ - public String getRole() - { - return role; - } - - /** - * Sets the value of the role property. - * - * @param value allowed object is - * {@link String } - */ - public void setRole(String value) - { - this.role = value; - } - } + if (issues == null) { + issues = new ArrayList(); } + return this.issues; } } diff --git a/src/main/java/pl/com/it_crowd/youtrack/api/rest/ObjectFactory.java b/src/main/java/pl/com/it_crowd/youtrack/api/rest/ObjectFactory.java index 2bb77c5..7a3f515 100644 --- a/src/main/java/pl/com/it_crowd/youtrack/api/rest/ObjectFactory.java +++ b/src/main/java/pl/com/it_crowd/youtrack/api/rest/ObjectFactory.java @@ -2,12 +2,15 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.16 at 10:06:20 AM CET +// Generated on: 2012.07.02 at 11:11:34 PM CEST // package pl.com.it_crowd.youtrack.api.rest; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; /** * This object contains factory methods for each @@ -24,6 +27,17 @@ import javax.xml.bind.annotation.XmlRegistry; */ @XmlRegistry public class ObjectFactory { +// ------------------------------ FIELDS ------------------------------ + + public final static QName _Error_QNAME = new QName("", "error"); + + public final static QName _Issue_QNAME = new QName("", "issue"); + + private final static QName _CommentReplies_QNAME = new QName("", "replies"); + + private final static QName _CommentValue_QNAME = new QName("", "value"); + +// --------------------------- CONSTRUCTORS --------------------------- /** * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: pl.com.it_crowd.youtrack.api.rest @@ -32,51 +46,89 @@ public class ObjectFactory { { } +// -------------------------- OTHER METHODS -------------------------- + /** - * Create an instance of {@link Issues.Issue } + * Create an instance of {@link Comment } */ - public Issues.Issue createIssuesIssue() + public Comment createComment() { - return new Issues.Issue(); + return new Comment(); } /** - * Create an instance of {@link Issues.Issue.Comment } + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} */ - public Issues.Issue.Comment createIssuesIssueComment() + @XmlElementDecl(namespace = "", name = "replies", scope = Comment.class) + public JAXBElement createCommentReplies(String value) { - return new Issues.Issue.Comment(); + return new JAXBElement(_CommentReplies_QNAME, String.class, Comment.class, value); } /** - * Create an instance of {@link Issues } + * Create an instance of {@link Comment.Value } */ - public Issues createIssues() + public Comment.Value createCommentValue() { - return new Issues(); + return new Comment.Value(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Comment.Value }{@code >}} + */ + @XmlElementDecl(namespace = "", name = "value", scope = Comment.class) + public JAXBElement createCommentValue(Comment.Value value) + { + return new JAXBElement(_CommentValue_QNAME, Comment.Value.class, Comment.class, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + */ + @XmlElementDecl(namespace = "", name = "error") + public JAXBElement createError(String value) + { + return new JAXBElement(_Error_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link Field } + */ + public Field createField() + { + return new Field(); } /** - * Create an instance of {@link Issues.Issue.Comment.Value } + * Create an instance of {@link Field.Value } */ - public Issues.Issue.Comment.Value createIssuesIssueCommentValue() + public Field.Value createFieldValue() { - return new Issues.Issue.Comment.Value(); + return new Field.Value(); } /** - * Create an instance of {@link Issues.Issue.Field.Value } + * Create an instance of {@link Issue } */ - public Issues.Issue.Field.Value createIssuesIssueFieldValue() + public Issue createIssue() { - return new Issues.Issue.Field.Value(); + return new Issue(); } /** - * Create an instance of {@link Issues.Issue.Field } + * Create an instance of {@link JAXBElement }{@code <}{@link Issue }{@code >}} */ - public Issues.Issue.Field createIssuesIssueField() + @XmlElementDecl(namespace = "", name = "issue") + public JAXBElement createIssue(Issue value) { - return new Issues.Issue.Field(); + return new JAXBElement(_Issue_QNAME, Issue.class, null, value); + } + + /** + * Create an instance of {@link Issues } + */ + public Issues createIssues() + { + return new Issues(); } } diff --git a/src/main/xjb/bindings.xjb b/src/main/xjb/bindings.xjb index 95d5880..85db285 100644 --- a/src/main/xjb/bindings.xjb +++ b/src/main/xjb/bindings.xjb @@ -1,18 +1,33 @@ - + xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"> + + + + + + + + - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/xsd/error.xml b/src/main/xsd/error.xml new file mode 100644 index 0000000..aabbfcc --- /dev/null +++ b/src/main/xsd/error.xml @@ -0,0 +1,2 @@ + +Incorrect login or password. \ No newline at end of file diff --git a/src/main/xsd/error.xsd b/src/main/xsd/error.xsd new file mode 100644 index 0000000..285fb42 --- /dev/null +++ b/src/main/xsd/error.xsd @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/main/xsd/issue.xml b/src/main/xsd/issue.xml new file mode 100644 index 0000000..9615330 --- /dev/null +++ b/src/main/xsd/issue.xml @@ -0,0 +1,51 @@ + + + + TST + + + 1 + + + Example bug + + + This is some example bug + + + 1341232706054 + + + 1341232706054 + + + root + + + root + + + root + + + root + + + 0 + + + 0 + + + Normal + + + Bug + + + Submitted + + + No subsystem + + \ No newline at end of file diff --git a/src/main/xsd/issue.xsd b/src/main/xsd/issue.xsd new file mode 100644 index 0000000..20109aa --- /dev/null +++ b/src/main/xsd/issue.xsd @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/xsd/issuesByProject.xml b/src/main/xsd/issuesByProject.xml index 321a578..8e68bef 100644 --- a/src/main/xsd/issuesByProject.xml +++ b/src/main/xsd/issuesByProject.xml @@ -1,5 +1,6 @@ - + + diff --git a/src/main/xsd/issuesByProject.xsd b/src/main/xsd/issuesByProject.xsd index 261031c..b0f5901 100644 --- a/src/main/xsd/issuesByProject.xsd +++ b/src/main/xsd/issuesByProject.xsd @@ -1,53 +1,10 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/src/main/xsd/types.xsd b/src/main/xsd/types.xsd new file mode 100644 index 0000000..b101132 --- /dev/null +++ b/src/main/xsd/types.xsd @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/pl/com/it_crowd/youtrack/api/rest/YoutrackAPITest.java b/src/test/java/pl/com/it_crowd/youtrack/api/rest/YoutrackAPITest.java index 81fd2fa..905a2a8 100644 --- a/src/test/java/pl/com/it_crowd/youtrack/api/rest/YoutrackAPITest.java +++ b/src/test/java/pl/com/it_crowd/youtrack/api/rest/YoutrackAPITest.java @@ -1,47 +1,87 @@ package pl.com.it_crowd.youtrack.api.rest; import junit.framework.Assert; +import org.apache.http.HttpStatus; import org.apache.http.auth.AuthenticationException; import org.junit.Test; -import pl.com.it_crowd.youtrack.api.Issue; +import pl.com.it_crowd.youtrack.api.IssueWrapper; import pl.com.it_crowd.youtrack.api.YoutrackAPI; +import pl.com.it_crowd.youtrack.api.exceptions.NoResultFoundException; +import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException; import javax.xml.bind.JAXBException; import java.io.IOException; import java.util.List; /** - * This test requires setting JVM params youtrackUsername and youtrackPassword. + * This test requires Youtrack instance with "Test(TST)" project to be running and expects following JVM params: + * youtrackLocation, youtrackUsername and youtrackPassword. */ public class YoutrackAPITest { // -------------------------- OTHER METHODS -------------------------- - @Test(expected = AuthenticationException.class) - public void loginFailureTest() throws IOException, AuthenticationException + @Test + public void createIssueTest() throws IOException, AuthenticationException, JAXBException + { + YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); + final String issueId = api.createIssue("TST", "Test summary", "Test description"); + Assert.assertNotNull(issueId); + Assert.assertTrue(issueId.startsWith("TST")); + } + + @Test + public void getIssueTest() throws IOException, AuthenticationException, JAXBException + { + YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); + final IssueWrapper issue = api.getIssue("TST-1"); + Assert.assertNotNull(issue); + + try { + api.getIssue("TST-2"); + Assert.fail("YoutrackErrorException expected"); + } catch (NoResultFoundException e) { + Assert.assertEquals("Issue not found.", e.getMessage()); + } + try { + api.getIssue("TSTX-1"); + Assert.fail("YoutrackErrorException expected"); + } catch (NoResultFoundException e) { + Assert.assertEquals("Issue not found.", e.getMessage()); + } + } + + @Test(expected = YoutrackErrorException.class) + public void loginFailureTest() throws IOException, JAXBException { final String username = "someFakeLogin"; final String password = "someFakePassword"; - new YoutrackAPI("http://youtrack.it-crowd.com.pl", username, password); + try { + new YoutrackAPI(getServiceLocation(), username, password); + } catch (YoutrackErrorException e) { + Assert.assertEquals("Incorrect login or password.", e.getMessage()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, e.getStatusCode()); + throw e; + } } @Test - public void loginTest() throws IOException, AuthenticationException + public void loginTest() throws IOException, AuthenticationException, JAXBException { final String username = getUsername(); final String password = getPassword(); - new YoutrackAPI("http://youtrack.it-crowd.com.pl", username, password); - YoutrackAPI api = new YoutrackAPI("http://youtrack.it-crowd.com.pl"); + new YoutrackAPI(getServiceLocation(), username, password); + YoutrackAPI api = new YoutrackAPI(getServiceLocation()); api.login(username, password); } @Test public void searchIssuesByProjectTest() throws IOException, AuthenticationException, JAXBException { - YoutrackAPI api = new YoutrackAPI("http://youtrack.it-crowd.com.pl", getUsername(), getPassword()); - List issues = api.searchIssuesByProject("SM", null); + YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); + List issues = api.searchIssuesByProject("TST", null); Assert.assertTrue(!issues.isEmpty()); - for (Issue issue : issues) { - String summary = issue.getFieldValue(Issue.Fields.summary); + for (IssueWrapper issue : issues) { + String summary = issue.getFieldValue(IssueWrapper.Fields.summary); Assert.assertNotNull(summary); Assert.assertTrue(!"".equals(summary.trim())); } @@ -52,6 +92,11 @@ public class YoutrackAPITest { return System.getProperty("youtrackPassword"); } + private String getServiceLocation() + { + return System.getProperty("youtrackLocation"); + } + private String getUsername() { return System.getProperty("youtrackUsername");