/*******************************************************************************
* Copyright (c) 2007, 2010 Association for Decentralized Information Management
* in Industry THTH ry.
* 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:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
package org.simantics.diagram.adapter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import org.simantics.databoard.Bindings;
import org.simantics.db.AsyncReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
import org.simantics.db.common.procedure.guarded.GuardedAsyncProcedureWrapper;
import org.simantics.db.common.request.BinaryAsyncRead;
import org.simantics.db.procedure.AsyncProcedure;
import org.simantics.diagram.stubs.G2DResource;
import org.simantics.diagram.synchronization.SynchronizationHints;
import org.simantics.diagram.synchronization.graph.TransformSynchronizer;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.diagram.IDiagram;
import org.simantics.g2d.element.ElementClass;
import org.simantics.g2d.element.ElementHints;
import org.simantics.g2d.element.IElement;
import org.simantics.g2d.element.handler.impl.DefaultTransform;
import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;
import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
import org.simantics.g2d.element.handler.impl.TextImpl;
import org.simantics.g2d.elementclass.ImageClass.ImageElementHandler;
import org.simantics.g2d.image.DefaultImages;
import org.simantics.g2d.image.impl.AWTImage;
import org.simantics.utils.datastructures.cache.ProvisionException;
import org.simantics.utils.ui.ErrorLogger;
/**
* An {@link ElementFactory} for DIA.SVGElement instances.
*
*
* Loads element layers, transform and SVG document.
*
* @author Tuukka Lehtonen
*/
public class RasterElementClassFactory extends ElementFactoryAdapter {
public static final ElementFactory INSTANCE = new RasterElementClassFactory();
private static final StaticSymbolImpl STATIC_SYMBOL = new StaticSymbolImpl(DefaultImages.HOURGLASS.get());
static class ClassRequest extends BinaryAsyncRead {
final private IDiagram diagram;
public ClassRequest(Resource elementType, ICanvasContext canvas, IDiagram diagram) {
super(elementType, canvas);
this.diagram = diagram;
}
@Override
public void perform(AsyncReadGraph graph, AsyncProcedure procedure) {
createClass(graph, parameter2, diagram, parameter, procedure);
}
}
@Override
public void create(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
final Resource elementType, final AsyncProcedure procedure) {
graph.asyncRequest(new ClassRequest(elementType, canvas, diagram), new TransientCacheAsyncListener() {
@Override
public void exception(AsyncReadGraph graph, Throwable t) {
t.printStackTrace();
procedure.exception(graph, t);
}
@Override
public void execute(AsyncReadGraph graph, ElementClass result) {
procedure.execute(graph, result);
}
});
}
static void createClass(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
final Resource elementType, final AsyncProcedure procedure) {
String id = "RasterElement: " + elementType.getResourceId();
procedure.execute(graph, ElementClass.compile(
TextImpl.INSTANCE,
new StaticObjectAdapter(elementType),
DefaultTransform.INSTANCE,
StaticSymbolImageInitializer.INSTANCE,
STATIC_SYMBOL,
ImageElementHandler.INSTANCE,
SimpleElementLayers.INSTANCE)
.setId(id));
}
@Override
public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure procedure) {
e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);
final GuardedAsyncProcedureWrapper guard = new GuardedAsyncProcedureWrapper(procedure, 3);
loadRaster(graph, diagram, element, e, guard);
ElementFactoryUtil.loadLayersForElement(graph, diagram, e, element, guard);
ElementFactoryUtil.readTransform(graph, element, e, guard);
}
private void loadRaster(AsyncReadGraph graph, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure guard) {
G2DResource G2D = graph.getService(G2DResource.class);
graph.forPossibleRelatedValue(element, G2D.HasRasterImage, Bindings.BYTE_ARRAY, new AsyncProcedure() {
@Override
public void exception(AsyncReadGraph graph, Throwable throwable) {
guard.exception(graph, throwable);
}
@Override
public void execute(AsyncReadGraph graph, final byte[] data) {
if (data != null) {
try {
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
e.setHint(ElementHints.KEY_IMAGE, new AWTImage(bi));
guard.execute(graph, e);
} catch (ProvisionException ex) {
ErrorLogger.defaultLogError(ex);
e.setHint(ElementHints.KEY_IMAGE, DefaultImages.SVG.get());
guard.execute(graph, e);
} catch (MalformedURLException e1) {
ErrorLogger.defaultLogError(e1);
e.setHint(ElementHints.KEY_IMAGE, DefaultImages.SVG.get());
guard.execute(graph, e);
} catch (IOException e1) {
ErrorLogger.defaultLogError(e1);
e.setHint(ElementHints.KEY_IMAGE, DefaultImages.SVG.get());
guard.execute(graph, e);
}
} else {
e.setHint(ElementHints.KEY_IMAGE, DefaultImages.UNKNOWN.get());
guard.execute(graph, e);
}
}
});
}
}