All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.llorllale.youtrack.api.IssueTimeTracking Maven / Gradle / Ivy

/*
 * Copyright 2017 George Aristy.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.llorllale.youtrack.api;

import com.jamesmurty.utils.XMLBuilder2;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.llorllale.youtrack.api.session.Session;
import org.llorllale.youtrack.api.session.UnauthorizedException;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * 

API for {@link Issue} timetracking.

* *

Note: timetracking needs to be {@link TimeTracking#enabled() enabled} for the * {@link Project} in YouTrack, otherwise these operations will throw {@link IOException}.

* * @author George Aristy ([email protected]) * @since 0.4.0 */ public interface IssueTimeTracking { /** * Returns a {@link Stream} with all available {@link TimeTrackEntry work entries} for the * {@link Issue}. * * @return a {@link Stream} with all available {@link TimeTrackEntry work entries} for the * {@link Issue} * @throws IOException if the server is unavailable * @throws UnauthorizedException if the user's {@link Session} is not authorized to perform this * operation * @since 0.4.0 */ public Stream stream() throws IOException, UnauthorizedException; /** * Creates a new {@link TimeTrackEntry entry}. * * @param spec the entry's {@link EntrySpec spec} * @return the newly-created {@link TimeTrackEntry entry} * @throws IOException if the server is unavailable * @throws UnauthorizedException if the user's {@link Session} is not authorized to perform this * operation * @since 0.4.0 */ public IssueTimeTracking create(EntrySpec spec) throws IOException, UnauthorizedException; /** *

Specifications for creating a {@link TimeTrackEntry} on an {@link Issue}.

* *

The new entry will always be created on the {@link Issue} attached to this * {@link IssueTimeTracking}.

* * @since 0.4.0 */ public static final class EntrySpec { private final LocalDate date; private final Duration duration; private final Optional description; private final Optional type; /** * Primary ctor. * * @param date the date when the entry was worked * @param duration the duration for the work * @param description description for the work * @param type the work type (eg. "Development") * @since 0.4.0 */ public EntrySpec( LocalDate date, Duration duration, Optional description, Optional type ) { this.date = date; this.duration = duration; this.description = description; this.type = type; } /** * Shorthand constructor that assumes the following: *
    *
  • date is now
  • *
  • description is empty
  • *
  • type is empty
  • *
* * @param duration the work's duration * @since 0.4.0 * @see #EntrySpec(LocalDate, Duration, Optional, Optional) */ public EntrySpec(Duration duration) { this( LocalDate.now(), duration, Optional.empty(), Optional.empty() ); } /** * Returns a new spec with {@code date} and using {@code this} as a prototype. * * @param date the entry's date * @return a new spec with {@code date} and using {@code this} as a prototype * @since 0.4.0 */ public EntrySpec withDate(LocalDate date) { return new EntrySpec( date, this.duration, this.description, this.type ); } /** * Returns a new spec with {@code description} and using {@code this} as a prototype. * * @param description the entry's description * @return a new spec with {@code description} and using {@code this} as a prototype * @since 0.4.0 */ public EntrySpec withDescription(String description) { return new EntrySpec( this.date, this.duration, Optional.of(description), this.type ); } /** * Returns a new spec with {@code type} and using {@code this} as a prototype. * * @param type the entry's type * @return a new spec with {@code type} and using {@code this} as a prototype * @since 0.4.0 */ public EntrySpec withType(TimeTrackEntryType type) { return new EntrySpec( this.date, this.duration, this.description, Optional.of(type) ); } /** * Returns a {@link HttpEntity} representing this spec. * * @return a {@link HttpEntity} representing this spec */ public HttpEntity asHttpEntity() { final XMLBuilder2 builder = XMLBuilder2.create("workItem") .elem("date") .text( String.valueOf( date.atStartOfDay() .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli() ) ) .up() .elem("duration") .text(String.valueOf(duration.toMinutes())) .up() .elem("description") .text(description.orElse("")) .up(); type.ifPresent(type -> builder .elem("worktype") .elem("name") .text(type.asString()) .up() .up() ); return new StringEntity(builder.asString(), ContentType.APPLICATION_XML); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy