org.mycore.common.processing.MCRAbstractProcessable Maven / Gradle / Ivy
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see .
*/
package org.mycore.common.processing;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.mycore.common.MCRSessionMgr;
/**
* Can be used as base class for an {@link MCRProcessable}. This class offers some
* convenient methods but does not handle everything.
*
*
* If you extend this class make sure to call {@link #setStatus(MCRProcessableStatus)},
* {@link #setProgress(Integer)} and {@link #setProgressText(String)}. Otherwise the
* event handlers are not fired.
*
*
* @author Matthias Eichner
*/
public class MCRAbstractProcessable extends MCRAbstractProgressable implements MCRProcessable {
protected String name;
protected String userId;
protected MCRProcessableStatus status;
protected Throwable error;
protected Instant createTime;
protected Instant startTime;
protected Instant endTime;
protected Map properties;
protected final List statusListener;
public MCRAbstractProcessable() {
super();
this.name = null;
if (MCRSessionMgr.hasCurrentSession()) {
// do not create a new session! (getCurrentSession() is wrong named!)
this.userId = MCRSessionMgr.getCurrentSession().getUserInformation().getUserID();
}
this.status = MCRProcessableStatus.created;
this.error = null;
this.createTime = Instant.now();
this.startTime = null;
this.endTime = null;
this.properties = new HashMap<>();
this.statusListener = Collections.synchronizedList(new ArrayList<>());
}
/**
* Sets the name for this process.
*
* @param name human readable name
*/
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
/**
* Sets the user identifier responsible for this processable.
*
* @param userId the user id
*/
public void setUserId(String userId) {
this.userId = userId;
}
@Override
public String getUserId() {
return this.userId;
}
@Override
public Throwable getError() {
return this.error;
}
/**
* Sets the internal processable error. This will set the status to failed.
*
* @param error the error
*/
public void setError(Throwable error) {
this.error = error;
setStatus(MCRProcessableStatus.failed);
}
/**
* Sets the new status. If the status is equal "processing" the startTime is set, if the status is equal
* "successful", "failed" or "canceled" the endTime is set. This will call the fireStatusChanged method.
*
* @param status the new status
*/
public void setStatus(MCRProcessableStatus status) {
MCRProcessableStatus oldStatus = this.status;
this.status = status;
if (status.equals(MCRProcessableStatus.processing)) {
this.startTime = Instant.now();
}
if (status.equals(MCRProcessableStatus.successful) || status.equals(MCRProcessableStatus.failed) ||
status.equals(MCRProcessableStatus.canceled)) {
this.endTime = Instant.now();
}
fireStatusChanged(oldStatus);
}
@Override
public MCRProcessableStatus getStatus() {
return this.status;
}
@Override
public Instant getStartTime() {
return this.startTime;
}
@Override
public Instant getCreateTime() {
return this.createTime;
}
@Override
public Instant getEndTime() {
return this.endTime;
}
@Override
public Map getProperties() {
return this.properties;
}
@Override
public void addStatusListener(MCRProcessableStatusListener listener) {
this.statusListener.add(listener);
}
@Override
public void removeStatusListener(MCRProcessableStatusListener listener) {
this.statusListener.remove(listener);
}
protected void fireStatusChanged(MCRProcessableStatus oldStatus) {
synchronized (this.statusListener) {
this.statusListener.forEach(listener -> {
try {
listener.onStatusChange(this, oldStatus, getStatus());
} catch (Exception exc) {
LogManager.getLogger().error("Unable to execute onStatusChange() on listener '{}' for '{}'",
listener.getClass().getName(), getName(), exc);
}
});
}
}
}