Verified Commit 25207b24 authored by Lukas Wiest's avatar Lukas Wiest 🚂
Browse files

feat(systems): add implementation for GitHub

parent 42f19bc5
package de.hftstuttgart.unifiedticketing.systems.github;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.hftstuttgart.unifiedticketing.core.Filter;
import de.hftstuttgart.unifiedticketing.core.Logging;
import de.hftstuttgart.unifiedticketing.core.TicketSystem;
import de.hftstuttgart.unifiedticketing.exceptions.*;
import okhttp3.*;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class GithubFilter extends Filter<GithubTicket, GithubFilter>
{
private final static Logger logger = Logging.getLogger(GithubFilter.class.getName());
protected final GithubTicketSystem parent;
protected GithubFilter(GithubTicketSystem parent)
{
this.parent = parent;
}
protected OkHttpClient getHttpClient() { return new OkHttpClient(); }
@Override
public List<GithubTicket> get()
{
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Request.Builder requestBuilder = new Request.Builder()
.url(parent.baseUrl)
.addHeader("accept", parent.acceptHeader)
.get();
if (parent.username != null && parent.apiKey != null)
{
requestBuilder.addHeader("Authorization", Credentials.basic(parent.username, parent.apiKey));
logger.log(Level.FINEST, "added token authentication header");
}
HttpUrl.Builder urlBuilder = requestBuilder.build().url().newBuilder();
for (Map.Entry<String, Object> mapEntry : setFilters.entrySet())
{
String f = mapEntry.getKey();
Object v = mapEntry.getValue();
try
{
if (f.equals(FilterNames.ASSIGNEEID.name()))
{
logger.log(Level.WARNING, "assignee-id check only possible after request |" +
" Filter: " + FilterNames.ASSIGNEEID.name());
} else if (f.equals(FilterNames.ASSIGNEENAME.name()))
{
Set<String> names = (Set<String>) v;
if (names.size() > 0)
{
urlBuilder.addQueryParameter("assignee", names.stream()
.findFirst()
.get());
if (names.size() > 1)
{
logger.log(Level.WARNING, "assignee-name filter natively only for one name supported");
}
}
} else if (f.equals(FilterNames.DESCRIPTION_CONTAIN.name()))
{
logger.log(Level.FINE, "Description contain check only possible after request |" +
" Filter: " + FilterNames.DESCRIPTION_CONTAIN.name());
} else if (f.equals(FilterNames.DESCRIPTION_MATCH.name()))
{
logger.log(Level.FINE, "Regex matching only possible after request |" +
" Filter: " + FilterNames.DESCRIPTION_MATCH.name());
} else if (f.equals(FilterNames.IDS.name()))
{
logger.log(Level.FINE, "Ticket id matching only possible after request |" +
" Filter: " + FilterNames.IDS.name());
} else if (f.equals(FilterNames.LABELS.name()))
{
urlBuilder.addQueryParameter("labels", ((Set<String>) v).stream()
.reduce((l1, l2) -> l1 + "," + l2)
.orElse(""));
} else if (f.equals(FilterNames.PAGE.name()))
{
urlBuilder.addQueryParameter("page", String.valueOf(v));
} else if (f.equals(FilterNames.PAGINATION.name()))
{
urlBuilder.addQueryParameter("per_page", String.valueOf(v));
} else if (f.equals(FilterNames.OPEN.name()))
{
urlBuilder.addQueryParameter("state", ((boolean) v) ? "open" : "closed");
} else if (f.equals(FilterNames.TITLE_CONTAINS.name()))
{
logger.log(Level.FINE, "title contain check only possible after request |" +
" Filter: " + FilterNames.TITLE_CONTAINS.name());
} else if (f.equals(FilterNames.TITLE_MATCH.name()))
{
logger.log(Level.FINE, "Regex matching only possible after request |" +
" Filter: " + FilterNames.TITLE_MATCH.name());
} else
{
logger.log(Level.WARNING, String.format("unrecognized filter key: %s", f));
}
}
catch (ClassCastException e)
{
logger.log(Level.SEVERE, "Filter with key "
+ f
+ " unexpectedly had type "
+ v.getClass().getName());
if (!this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR))
{
throw new AssertionException(e);
}
}
}
requestBuilder.url(urlBuilder.build());
OkHttpClient client = getHttpClient();
Response response;
try
{
Request request = requestBuilder.build();
logger.log(Level.FINEST, String.format(
"created request:\n%s",
(this.parent.apiKey != null)
? request.toString().replace(this.parent.apiKey, "SECRET")
: request.toString()
));
response = client.newCall(request).execute();
}
catch (IOException e)
{
logger.log(Level.SEVERE, String.format("get request FAILED with: %s", e.getMessage()));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpReqeustException(e);
}
if (response.code() >= 400)
{
logger.log(Level.SEVERE, String.format(
"request failed with response code %d",
response.code()
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException(
String.format("ticket query failed, error response code: %d", response.code()),
response.code());
}
logger.log(Level.FINEST, "response received\n");
ResponseBody responseBody;
responseBody = response.body();
if (responseBody == null)
{
logger.log(Level.SEVERE, "query didn't deliver a body in response");
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException("ticket query failed, no response body", response.code());
}
List<GithubTicketResponse> tr;
try
{
tr = mapper.readValue(responseBody.bytes(), new TypeReference<List<GithubTicketResponse>>(){});
logger.log(Level.FINER, "parsed response body to ticketResponse list instance");
logger.log(Level.FINEST, String.format("found %d items pre post-filter", tr.size()));
} catch (IOException e)
{
logger.log(Level.SEVERE, String.format("parsing query response FAILED with: %s", e.getMessage()));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new DeserializationException(e);
}
logger.log(Level.FINER, "starting query post filter");
Stream<GithubTicketResponse> ticketStream = tr.stream();
for (Map.Entry<String, Object> entry : setFilters.entrySet())
{
String f = entry.getKey();
Object v = entry.getValue();
try
{
if (f.equals(FilterNames.ASSIGNEEID.name()))
{
ticketStream = ticketStream.filter(t -> t.assignees.stream()
.map(a -> String.valueOf(a.id))
.collect(Collectors.toSet())
.equals((Set<String>) v));
}
else if (f.equals(FilterNames.ASSIGNEENAME.name()) && ((Set) v).size() > 1)
{
ticketStream = ticketStream.filter(t -> t.assignees.stream()
.map(a -> a.login)
.collect(Collectors.toSet())
.equals((Set<String>) v));
}
else if (f.equals(FilterNames.DESCRIPTION_CONTAIN))
{
ticketStream = ticketStream.filter(t -> t.body
.toLowerCase()
.contains(((String) v).toLowerCase()));
}
else if (f.equals(FilterNames.DESCRIPTION_MATCH.name()))
{
ticketStream = ticketStream.filter(t -> t.body.matches((String) v));
}
else if (f.equals(FilterNames.TITLE_CONTAINS.name()))
{
ticketStream = ticketStream.filter(t -> t.title
.toLowerCase()
.contains(((String) v).toLowerCase()));
}
else if (f.equals(FilterNames.TITLE_MATCH.name()))
{
ticketStream = ticketStream.filter(t -> t.title.matches((String) v));
}
} catch (ClassCastException e)
{
logger.log(Level.SEVERE, "Filter with key "
+ f
+ " unexpectedly had type "
+ v.getClass().getName());
}
}
logger.log(Level.FINER, "post-filter finished");
List<GithubTicket> ret = ticketStream.map(t -> GithubTicket.fromTicketResponse(parent, t))
.collect(Collectors.toList());
logger.log(Level.FINEST, String.format("remaining items: %d", ret.size()));
return ret;
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import de.hftstuttgart.unifiedticketing.core.Logging;
import de.hftstuttgart.unifiedticketing.core.Ticket;
import de.hftstuttgart.unifiedticketing.core.TicketSystem;
import de.hftstuttgart.unifiedticketing.exceptions.DeserializationException;
import de.hftstuttgart.unifiedticketing.exceptions.HttpReqeustException;
import de.hftstuttgart.unifiedticketing.exceptions.HttpResponseException;
import de.hftstuttgart.unifiedticketing.exceptions.SerializationException;
import okhttp3.*;
import java.io.IOException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class GithubTicket extends Ticket<GithubTicketSystem, GithubTicket>
{
private final static Logger logger = Logging.getLogger(GithubTicket.class.getName());
protected static GithubTicket fromTicketResponse(GithubTicketSystem parent, GithubTicketResponse response)
{
GithubTicket ret = new GithubTicket(parent);
ret.description = response.body;
ret.id = String.valueOf(response.number);
ret.open = response.state.equalsIgnoreCase("open");
ret.title = response.title;
if (response.assignees != null)
{
ret.assignees = response.assignees.stream()
.map(a -> new GithubTicketAssignee(a.id, a.login))
.collect(Collectors.toSet());
}
if (response.labels != null)
{
ret.labels = response.labels.stream()
.map(l -> l.name)
.collect(Collectors.toSet());
}
return ret;
}
protected GithubTicket(GithubTicketSystem parent)
{
super(parent);
}
@Override
public GithubTicket addAssignee(String identifier)
{
this.assignees.add(new GithubTicketAssignee(0, identifier));
this.updatedFields.add(FieldNames.ASSIGNEES.name());
return this;
}
@Override
public GithubTicket removeAssignee(String identifier)
{
this.assignees.removeIf(a -> Objects.equals(a.username, identifier));
this.updatedFields.add(FieldNames.ASSIGNEES.name());
return null;
}
protected OkHttpClient getHttpClient() { return new OkHttpClient(); }
@Override
public GithubTicket save()
{
if (updatedFields.size() == 0)
{
logger.info("No changed fields, no save required");
return this;
}
OkHttpClient client = this.getHttpClient();
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
logger.log(Level.FINEST, String.format(
"[Ticket %s] preparing body for update request",
this.id
));
ObjectNode body = mapper.createObjectNode();
for (String name : this.updatedFields)
{
if (FieldNames.ASSIGNEES.name().equals(name))
{
ArrayNode arrayNode = body.putArray("assignees");
this.assignees.forEach(a -> arrayNode.add(a.username));
}
else if (FieldNames.DESCRIPTION.name().equals(name))
{
body.put("body", this.description);
}
else if (FieldNames.LABELS.name().equals(name))
{
ArrayNode arrayNode = body.putArray("labels");
this.labels.forEach(arrayNode::add);
}
else if (FieldNames.OPEN.name().equals(name))
{
body.put("state", (this.open) ? "open" : "closed");
}
else if (FieldNames.TITLE.name().equals(name))
{
body.put("title", this.title);
}
else
{
logger.log(Level.WARNING, String.format(
"[Ticket %s] unknown field %s will be ignored from update",
this.id,
name
));
continue;
}
logger.log(Level.FINEST, String.format(
"[Ticket %s] %s added to update",
this.id,
name
));
}
logger.log(Level.FINEST, String.format(
"[Ticket %s] request body for update prepared",
this.id
));
Request.Builder builder = new Request.Builder()
.url(String.format("%s/%s", this.parent.baseUrl, this.id))
.addHeader("accept", parent.acceptHeader);
try
{
logger.log(Level.FINEST, String.format(
"[Ticket %s] serializing update request body",
this.id
));
String bodyJson = mapper.writeValueAsString(body);
logger.log(Level.FINEST, String.format(
"[Ticket %s] serialized JSON:\n%s",
this.id,
bodyJson
));
builder
.patch(RequestBody.create(bodyJson, MediaType.get("application/json")));
} catch (JsonProcessingException e)
{
logger.log(Level.SEVERE, String.format(
"[Ticket %s] serializing update request body FAILED!",
this.id
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new SerializationException(e);
}
if (parent.username != null && parent.apiKey != null)
{
builder.addHeader("Authorization", Credentials.basic(parent.username, parent.apiKey));
logger.log(Level.FINEST, String.format(
"[Ticket %s] added token authentication header",
this.id
));
}
Response response;
try
{
Request request = builder.build();
logger.log(Level.FINEST, String.format(
"[Ticket %s] created request:\n%s",
this.id,
(this.parent.apiKey != null)
? request.toString().replace(this.parent.apiKey, "SECRET")
: request.toString()
));
response = client.newCall(request).execute();
}
catch (IOException e)
{
logger.log(Level.SEVERE, String.format(
"[Ticket %s] update request FAILED",
this.id
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpReqeustException(e);
}
if (response.code() >= 400)
{
logger.log(Level.SEVERE, String.format(
"[Ticket %s] update request failed with response code %d",
this.id,
response.code()
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException(
String.format("ticket save failed, error response code: %d", response.code()),
response.code());
}
logger.log(Level.FINEST, String.format(
"[Ticket %s] response received",
this.id
));
ResponseBody responseBody;
responseBody = response.body();
if (responseBody == null)
{
logger.log(Level.SEVERE, String.format(
"[Ticket %s] update request didn't deliver a body in response",
this.id
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException("ticket save failed, no response body", response.code());
}
GithubTicketResponse ticketResponse;
try
{
ticketResponse = mapper.readValue(responseBody.bytes(), GithubTicketResponse.class);
logger.log(Level.FINEST, String.format(
"[Ticket %s] parsed response body to ticketResponse instance",
this.id
));
} catch (IOException e)
{
logger.log(Level.SEVERE, String.format("parsing update response FAILED with: %s", e.getMessage()));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new DeserializationException(e);
}
this.updatedFields.clear();
logger.log(Level.FINEST, String.format(
"[Ticket %s] update mark state reset",
this.id
));
return GithubTicket.fromTicketResponse(this.parent, ticketResponse);
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import de.hftstuttgart.unifiedticketing.core.TicketAssignee;
public class GithubTicketAssignee extends TicketAssignee
{
protected GithubTicketAssignee(int id, String username)
{
super(null, String.valueOf(id), username, null);
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import de.hftstuttgart.unifiedticketing.core.Logging;
import de.hftstuttgart.unifiedticketing.core.TicketBuilder;
import de.hftstuttgart.unifiedticketing.core.TicketSystem;
import de.hftstuttgart.unifiedticketing.exceptions.*;
import okhttp3.*;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GithubTicketBuilder extends TicketBuilder<GithubTicketBuilder, GithubTicket, GithubTicketSystem>
{
private final static Logger logger = Logging.getLogger(GithubTicketBuilder.class.getName());
protected GithubTicketBuilder(GithubTicketSystem parent)
{
super(parent);
}
protected OkHttpClient getHttpClient() { return new OkHttpClient(); }
@Override
public GithubTicket create()
{
logger.log(Level.FINEST, "starting Ticket creation from builder data");
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ObjectNode body = mapper.createObjectNode();
// title is mandatory field
if (this.title == null)
{
String msg = "mandatory field title not set before building ticket";
logger.log(Level.SEVERE, msg);
if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new AssertionException(msg);
}
if (this.description != null)
{
body.put("body", this.description);
logger.log(Level.FINEST, "description set");
}
body.put("title", this.title);
logger.log(Level.FINEST, "title set");
if (this.assignees != null)
{
ArrayNode arrayNode = body.putArray("assignees");
assignees.forEach(arrayNode::add);
logger.log(Level.FINEST, "assignees set");
}
if (this.labels != null)
{
ArrayNode arrayNode = body.putArray("labels");
this.labels.forEach(arrayNode::add);
logger.log(Level.FINEST, "labels set");
}
String jsonBody;
try
{
jsonBody = mapper.writeValueAsString(body);
} catch (JsonProcessingException e)
{
String msg = "json serialization FAILED";
logger.log(Level.SEVERE, msg);
if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new SerializationException(e);
}
OkHttpClient client = getHttpClient();
Request.Builder builder = new Request.Builder()
.url(parent.baseUrl)
.addHeader("accept", parent.acceptHeader)
.post(RequestBody.create(jsonBody, MediaType.get("application/json")));
if (this.parent.username != null && this.parent.apiKey != null)
{
builder.addHeader("Authorization", Credentials.basic(this.parent.username, this.parent.apiKey));
logger.log(Level.FINEST, "added basic auth header with api token");
}
Response response;
try
{
Request request = builder.build();
logger.log(Level.FINEST, String.format(
"created request:\n%s",
(this.parent.apiKey != null)
? request.toString().replace(this.parent.apiKey, "SECRET")
: request.toString()
));
response = client.newCall(request).execute();
} catch (IOException e)
{
logger.log(Level.SEVERE, "create request FAILED");
if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpReqeustException(e);
}
if (response.code() >= 400)
{
logger.log(Level.SEVERE, String.format(
"create request failed with response code %d",
response.code()
));
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException(
String.format("ticket creation failed, error response code %d", response.code()),
response.code());
}
logger.log(Level.FINEST, "response received\n");
ResponseBody responseBody;
responseBody = response.body();
if (responseBody == null)
{
logger.log(Level.SEVERE, "create request didn't deliver a body in response");
if (this.parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new HttpResponseException("ticket creation failed, no response body", response.code());
}
GithubTicketResponse ticketResponse;
try
{
ticketResponse = mapper.readValue(responseBody.bytes(), GithubTicketResponse.class);
logger.log(Level.FINEST, "parsed response to ticketResponse instance");
} catch (IOException e)
{
logger.severe(String.format("parsing create response FAILED with: %s", e.getMessage()));
if (parent.getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new DeserializationException(e);
}
return GithubTicket.fromTicketResponse(parent, ticketResponse);
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import java.util.Set;
public class GithubTicketResponse
{
public Set<Assignee> assignees;
public String body;
public int number;
public Set<Label> labels;
public String state;
public String title;
protected static class Label
{
public String name;
}
protected static class Assignee
{
public int id;
public String login;
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import de.hftstuttgart.unifiedticketing.core.*;
import de.hftstuttgart.unifiedticketing.exceptions.AssertionException;
import de.hftstuttgart.unifiedticketing.exceptions.UnifiedticketingException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GithubTicketSystem extends TicketSystem<GithubTicket, GithubTicketSystem, GithubTicketBuilder, GithubFilter>
{
private final static Logger logger = Logging.getLogger(GithubTicketSystem.class.getName());
protected final String acceptHeader;
protected final String apiKey;
protected final String username;
/**
* creates a new instance of this class from an uri.<br>
* <br>
* <b>Attention:</b> This method should not be called from the enduser!<br>
* Instead call the same method from {@link TicketSystem}.<br>
* To call this method directly, the uri has to be shortend by the {@code "unifiedticketing:github:"} part.
* @param uri gitlab specific part of full uri
* @return new github ticket system instance
*/
public static GithubTicketSystem fromUri(String uri)
{
Matcher matcher = Pattern.compile("^((http|https):\\/\\/)?(.*?(:[0-9]+.*?)?)::(.*?):(.*?)(:(.*?):(.*?))?$").matcher(uri);
if (!matcher.matches())
{
String msg = "uri didn't match regex";
logger.log(Level.SEVERE, msg);
throw new AssertionException(msg);
}
GithubTicketSystemBuilder builder = new GithubTicketSystemBuilder();
if (matcher.group(2) != null && matcher.group(2).length() > 0)
{
if (matcher.group(2).equalsIgnoreCase("http")) builder.withHttp();
else builder.withHttps();
}
if (matcher.group(3) == null || matcher.group(3).length() == 0)
{
String msg = "no base url identified in uri";
throw new AssertionException(msg);
}
builder.withBaseUrl(matcher.group(3));
if (matcher.group(5) == null || matcher.group(5).length() == 0)
{
String msg = "no owner identified in uri";
throw new AssertionException(msg);
}
builder.withOwner(matcher.group(5));
if (matcher.group(6) == null || matcher.group(6).length() == 0)
{
String msg = "no repo identified in uri";
throw new AssertionException(msg);
}
builder.withRepo(matcher.group(6));
if (matcher.group(8) != null && matcher.group(9) != null)
{
builder.withAuthentication(matcher.group(8), matcher.group(9));
}
else logger.log(Level.INFO, "no authentication given, creating anonymous instance");
return builder.build();
}
protected GithubTicketSystem(String acceptHeader, String baseUrl)
{
this(acceptHeader, baseUrl, null, null);
}
protected GithubTicketSystem(String acceptHeader, String baseUrl, String username, String apiKey)
{
super();
this.acceptHeader = acceptHeader;
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.username = username;
}
/**
* starts builder process for new github ticket
*/
@Override
public GithubTicketBuilder createTicket()
{
return new GithubTicketBuilder(this);
}
@Override
public GithubFilter find()
{
return new GithubFilter(this);
}
@Override
public GithubTicket getTicketById(String id)
{
logger.log(Level.FINER, "redirecting request to find method");
List<GithubTicket> ret = this.find()
.withId(id)
.get();
if (ret == null) return null;
else if (ret.size() != 1)
{
if (getConfigTrue(ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
else throw new UnifiedticketingException("more or less than 1 dedicated ticket found");
}
else return ret.get(0);
}
@Override
public boolean hasAssigneeSupport()
{
return true;
}
@Override
public boolean hasDefaultPagination()
{
return true;
}
@Override
public boolean hasLabelSupport()
{
return true;
}
@Override
public boolean hasPaginationSupport()
{
return true;
}
@Override
public boolean hasReturnNullOnErrorSupport()
{
return true;
}
}
package de.hftstuttgart.unifiedticketing.systems.github;
import de.hftstuttgart.unifiedticketing.core.Logging;
import de.hftstuttgart.unifiedticketing.core.TicketSystemBuilder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GithubTicketSystemBuilder extends TicketSystemBuilder<GithubTicketSystemBuilder, GithubTicketSystem>
{
private static final Logger logger = Logging.getLogger(GithubTicketSystemBuilder.class.getName());
protected String acceptHeader;
protected String apiKey;
protected boolean https;
protected String owner;
protected String repo;
protected String username;
/**
* starts builder process for a {@link GithubTicketSystem} instance
*/
public GithubTicketSystemBuilder()
{
super();
acceptHeader = "application/vnd.github.v3+json";
https = true;
logger.log(Level.FINEST, "Builder for Github System instance started");
}
public GithubTicketSystemBuilder withAuthentication(String username, String apiKey)
{
this.username = username;
this.apiKey = apiKey;
logger.log(Level.FINEST, "set authentication values");
return this;
}
public GithubTicketSystemBuilder withHttp()
{
this.https = false;
logger.log(Level.FINEST, "set http");
return this;
}
public GithubTicketSystemBuilder withHttps()
{
this.https = true;
logger.log(Level.FINEST, "set https");
return this;
}
public GithubTicketSystemBuilder withOwner(String owner)
{
this.owner = owner;
logger.log(Level.FINEST, String.format("set owner to %s", this.owner));
return this;
}
public GithubTicketSystemBuilder withRepo(String repo)
{
this.repo = repo;
logger.log(Level.FINEST, String.format("set repo to %s", this.repo));
return this;
}
@Override
public GithubTicketSystem build()
{
return new GithubTicketSystem(
acceptHeader,
String.format(
"%s://%s/repos/%s/%s/issues",
(https) ? "https" : "http",
baseUrl,
owner,
repo
),
username,
apiKey
);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment