/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.api.image;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.weasis.core.api.Messages;
import org.weasis.core.api.image.ImageOpNode.Param;
public class SimpleOpManager implements OpManager {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleOpManager.class);
public static final String IMAGE_OP_NAME = Messages.getString("SimpleOpManager.img_op"); //$NON-NLS-1$
public enum Position {
BEFORE, AFTER
}
private final HashMap<String, ImageOpNode> nodes;
private final List<ImageOpNode> operations;
private String name;
public SimpleOpManager() {
this(IMAGE_OP_NAME);
}
public SimpleOpManager(String name) {
this.operations = new ArrayList<>();
this.nodes = new HashMap<>();
setName(name);
}
public SimpleOpManager(SimpleOpManager som) {
this.operations = new ArrayList<>();
this.nodes = new HashMap<>();
setName(som.name);
som.nodes.entrySet().forEach(el -> {
Optional.ofNullable(el.getValue()).ifPresent(n -> {
ImageOpNode node = n.copy();
operations.add(node);
nodes.put(el.getKey(), node);
});
});
}
public synchronized String getName() {
return name;
}
public synchronized void setName(String name) {
this.name = name == null ? IMAGE_OP_NAME : name;
}
@Override
public String toString() {
return name;
}
@Override
public List<ImageOpNode> getOperations() {
return operations;
}
public void addImageOperationAction(ImageOpNode action) {
addImageOperationAction(action, null, null);
}
public void addImageOperationAction(ImageOpNode action, Position pos, ImageOpNode positionRef) {
if (action != null) {
String title = action.getName();
int k = 2;
while (nodes.get(title) != null) {
title += " " + k; //$NON-NLS-1$
k++;
}
if (k > 2) {
action.setName(title);
LOGGER.warn("This name already exists, rename to {}.", title); //$NON-NLS-1$
}
nodes.put(title, action);
if (positionRef != null) {
int index = operations.indexOf(positionRef);
if (Position.AFTER.equals(pos)) {
index++;
}
if (index >= 0) {
operations.add(index, action);
} else {
operations.add(action);
}
} else {
operations.add(action);
}
}
}
public void removeImageOperationAction(ImageOpNode action) {
if (action != null) {
boolean remove = operations.remove(action);
if (nodes.remove(action.getName()) == null && remove) {
for (Entry<String, ImageOpNode> entry : nodes.entrySet()) {
if (entry.getValue() == action) {
nodes.remove(entry.getKey());
break;
}
}
}
}
}
@Override
public void removeAllImageOperationAction() {
clearNodeParams();
operations.clear();
nodes.clear();
}
@Override
public void clearNodeParams() {
for (ImageOpNode node : operations) {
node.clearParams();
}
}
@Override
public void clearNodeIOCache() {
for (ImageOpNode node : operations) {
node.clearIOCache();
}
}
@Override
public void setFirstNode(RenderedImage imgSource) {
ImageOpNode node = getFirstNode();
if (node != null) {
node.setParam(Param.INPUT_IMG, imgSource);
}
}
@Override
public RenderedImage getFirstNodeInputImage() {
ImageOpNode node = getFirstNode();
if (node != null) {
return (RenderedImage) node.getParam(Param.INPUT_IMG);
}
return null;
}
@Override
public ImageOpNode getFirstNode() {
int size = operations.size();
if (size > 0) {
return operations.get(0);
}
return null;
}
@Override
public ImageOpNode getNode(String opName) {
if (opName == null) {
return null;
}
return nodes.get(opName);
}
@Override
public ImageOpNode getLastNode() {
int size = operations.size();
if (size > 0) {
return operations.get(size - 1);
}
return null;
}
@Override
public RenderedImage getLastNodeOutputImage() {
ImageOpNode node = getLastNode();
if (node != null) {
return (RenderedImage) node.getParam(Param.OUTPUT_IMG);
}
return null;
}
/**
* Allow to remove the preprocessing cache
*
* @param imgSource
*/
public void resetLastNodeOutputImage() {
ImageOpNode node = getLastNode();
if (node != null) {
node.setParam(Param.OUTPUT_IMG, null);
}
}
@Override
public RenderedImage process() {
RenderedImage source = getFirstNodeInputImage();
if (source != null) {
for (int i = 0; i < operations.size(); i++) {
ImageOpNode op = operations.get(i);
try {
if (i > 0) {
op.setParam(Param.INPUT_IMG, operations.get(i - 1).getParam(Param.OUTPUT_IMG));
}
if (op.isEnabled()) {
op.process();
} else {
// Skip this operation
op.setParam(Param.OUTPUT_IMG, op.getParam(Param.INPUT_IMG));
}
} catch (Exception e) {
LOGGER.error("Image {} failed: {}", op.getParam(Param.NAME), e); //$NON-NLS-1$
op.setParam(Param.OUTPUT_IMG, op.getParam(Param.INPUT_IMG));
}
}
} else {
clearNodeIOCache();
}
return getLastNodeOutputImage();
}
@Override
public Object getParamValue(String opName, String param) {
if (opName != null && param != null) {
ImageOpNode node = getNode(opName);
if (node != null) {
return node.getParam(param);
}
}
return null;
}
@Override
public boolean setParamValue(String opName, String param, Object value) {
if (opName != null && param != null) {
ImageOpNode node = getNode(opName);
if (node != null) {
node.setParam(param, value);
return true;
}
}
return false;
}
@Override
public void removeParam(String opName, String param) {
if (opName != null && param != null) {
ImageOpNode node = getNode(opName);
if (node != null) {
node.removeParam(param);
}
}
}
@Override
public void handleImageOpEvent(ImageOpEvent event) {
for (ImageOpNode node : operations) {
node.handleImageOpEvent(event);
}
}
@Override
public SimpleOpManager copy() {
return new SimpleOpManager(this);
}
}