/**
* Copyright 2011 Juan Gabriel Carrera Otero
*
* 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 net.xan.taskstack;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.xan.easyjtable.Editable;
import net.xan.easyjtable.Title;
import net.xan.easyjtable.Visible;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.Converter;
import org.eclipse.persistence.annotations.PrivateOwned;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
*
* @author xandacona
*/
@Data
@Entity
@NoArgsConstructor
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Editable(value = false)
@Title(value = "Task Id")
protected Integer id;
@ManyToOne
@Editable(value = false)
@Title(value = "Owner")
protected Person owner;
@Transient
@Editable(value = true)
@Visible(value = false)
protected List<Task> interruptions = new ArrayList<Task>();
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@PrivateOwned
@JoinColumn(name = "task_id")
@Editable(value = false)
@Visible(value = false)
protected List<Session> sessions;
@Title(value = "Task")
protected String name;
@Column(columnDefinition = "TIMESTAMP")
@Converter(name = "dateTimeConverter", converterClass = net.xan.taskstack.JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
@Editable(value = false)
@Title(value = "Init Time")
protected DateTime initTime;
@Column(columnDefinition = "TIMESTAMP")
@Converter(name = "dateTimeConverter", converterClass = net.xan.taskstack.JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
@Title(value = "Finish Time")
protected DateTime endTime;
@Transient
@Editable(value = false)
@Title(value = "Duration")
protected Duration duration;
@Title(value = "State")
protected TaskState state;
public Task(Person owner, String name) {
this.owner = owner;
this.name = name;
this.initTime = new DateTime();
this.endTime = null;
this.duration = null;
this.state = TaskState.Running;
this.sessions = new ArrayList<Session>();
this.interruptions = new ArrayList<Task>();
}
public void close() {
if (this.state == TaskState.Running) {
closeCurrentSession();
}
this.state = TaskState.Closed;
}
public void interrupt(Task task) {
this.state = TaskState.Stalled;
this.interruptions.add(task);
closeCurrentSession();
}
public Session closeCurrentSession() {
switch (this.state) {
case Running:
return closeCurrentSession(new DateTime());
case Stalled:
return closeCurrentSession(this.sessions.get(this.sessions.size() - 1).getEndTime());
default:
return null;
}
}
private Session closeCurrentSession(DateTime end) {
if (this.sessions.isEmpty()) {
return null;
}
// TODO: TO LESS STEPS
Session last = this.sessions.remove(this.sessions.size() - 1);
last.setEndTime(end);
this.sessions.add(last);
recalculateDuration();
this.endTime = end;
return last;
}
public Session startSession(Person person) {
return startSession(new DateTime(), person);
}
public Session startSession(DateTime init, Person person) {
// closeCurrentSession(init);
Session session = new Session(init, (DateTime) null, person);
this.sessions.add(session);
return session;
}
@PostLoad
public Duration recalculateDuration() {
this.duration = new Duration(0);
for (Session i : this.sessions) {
this.duration = this.duration.plus(new Duration(i.getStartTime(), i.getEndTime()));
}
return this.duration;
}
public Duration interruptionsDuration() {
Duration d = new Duration(Duration.ZERO);
if (this.interruptions != null) {
for (Task t : this.interruptions) {
if (t.duration != null) {
d = d.plus(t.duration);
}
}
}
return d;
}
@Override
public boolean equals(Object obj) {
return obj instanceof Task && this.id.equals(((Task) obj).id);
}
public String toLog() {
recalculateDuration();
StringBuffer sb = new StringBuffer();
sb.append("\n >>id=" + this.id);
sb.append("\n name=" + this.name);
sb.append("\n initTime=" + this.initTime);
sb.append("\n endTime=" + this.endTime);
sb.append("\n duration=" + TSDurationCellRender.format(this.duration));
sb.append("\n state=" + this.state);
sb.append("\n SESSIONS:");
for (Session i : this.sessions) {
sb.append("\n " + i);
}
sb.append("\n Interruptions");
for (Task t : this.interruptions) {
sb.append("\n " + t.id + " -- " + t.name);
}
return sb.toString();
}
}