/*******************************************************************************
* This file is part of Goko.
*
* Goko 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.
*
* Goko 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 Goko. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package org.goko.core.gcode.execution;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.collections.CollectionUtils;
import org.goko.core.common.exception.GkException;
import org.goko.core.common.exception.GkTechnicalException;
import org.goko.core.common.utils.CacheById;
import org.goko.core.common.utils.SequentialIdGenerator;
/**
* @author PsyKo
* @date 18 oct. 2015
*/
public class ExecutionQueue<S extends IExecutionTokenState, T extends IExecutionToken<S>> implements IExecutionQueue<S, T> {
/** The list of execution tokens */
private LinkedBlockingQueue<T> remainingExecutionTokens;
/** The list of execution tokens */
private CacheById<T> executionTokens;
/** The current token */
private T currentToken;
/** The type of queue */
private ExecutionQueueType type;
/**
* Constructor
*/
public ExecutionQueue(ExecutionQueueType type) {
remainingExecutionTokens = new LinkedBlockingQueue<T>();
executionTokens = new CacheById<T>(new SequentialIdGenerator());
this.type = type;
}
/** (inheritDoc)
* @see oldorg.goko.core.gcode.bean.execution.IExecutionQueue#hasNext()
*/
@Override
public boolean hasNext(){
return CollectionUtils.isNotEmpty(remainingExecutionTokens);
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionQueue#add(org.goko.core.gcode.execution.IExecutionToken)
*/
@Override
public void add(T token)throws GkException{
token.setExecutionOrder(executionTokens.size());
executionTokens.add(token);
remainingExecutionTokens.offer(token);
}
/** (inheritDoc)
* @see oldorg.goko.core.gcode.bean.execution.IExecutionQueue#beginNextTokenExecution()
*/
@Override
public void beginNextTokenExecution() throws GkException{
try {
currentToken = remainingExecutionTokens.take();
} catch (InterruptedException e) {
throw new GkTechnicalException(e);
}
}
/** (inheritDoc)
* @see oldorg.goko.core.gcode.bean.execution.IExecutionQueue#endCurrentTokenExecution()
*/
@Override
public void endCurrentTokenExecution() throws GkException{
if(currentToken != null){
currentToken = null;
}
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionQueue#getCurrentToken()
*/
@Override
public T getCurrentToken() {
return currentToken;
}
/** (inheritDoc)
* @see oldorg.goko.core.gcode.bean.execution.IExecutionQueue#clear()
*/
@Override
public void clear() throws GkException{
endCurrentTokenExecution();
remainingExecutionTokens.clear();
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionQueue#waitNext()
*/
@Override
public T waitNext() throws GkException {
try {
return remainingExecutionTokens.take();
} catch (InterruptedException e) {
throw new GkTechnicalException(e);
}
}
public void delete(Integer idExecutionToken) throws GkException{
T tokenToRemove = executionTokens.get(idExecutionToken);
remainingExecutionTokens.remove(tokenToRemove);
executionTokens.remove(tokenToRemove);
}
/** (inheritDoc)
* @see org.goko.core.gcode.execution.IExecutionQueue#getExecutionToken()
*/
@Override
public List<T> getExecutionToken() throws GkException {
List<T> lst = executionTokens.get();
Collections.sort(lst, new ExecutionOrderComparator());
return lst;
}
/**
* Reset the execution queue for execution
* @throws GkException GkException
*/
public void reset() throws GkException{
remainingExecutionTokens = new LinkedBlockingQueue<T>();
remainingExecutionTokens.addAll(getExecutionToken());
for (T token : getExecutionToken()) {
token.reset();
}
}
public T getExecutionToken(Integer idExecutionToken) throws GkException{
return executionTokens.get(idExecutionToken);
}
/**
* @return the type
*/
public ExecutionQueueType getType() {
return type;
}
}