/******************************************************************************* * 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 gnu.trove.map.hash.TObjectIntHashMap; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; 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.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; 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.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; import org.simantics.g2d.image.DefaultImages; import org.simantics.g2d.image.Image; public class CompositeClassFactory extends ElementFactoryAdapter { private static final StaticSymbolImpl STATIC_SYMBOL = new StaticSymbolImpl(DefaultImages.COMPOSITION.get()); private static ElementClass build(Resource elementType) { String id = "Composite: " + elementType.getResourceId(); return ElementClass.compile( TextImpl.INSTANCE, new StaticObjectAdapter(elementType), DefaultTransform.INSTANCE, StaticSymbolImageInitializer.INSTANCE, STATIC_SYMBOL, ImageClass.ImageElementHandler.INSTANCE) .setId(id); } @Override public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, AsyncProcedure procedure) { procedure.execute(graph, build(elementType)); } @Override public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, AsyncProcedure procedure) { final GuardedAsyncProcedureWrapper guard = new GuardedAsyncProcedureWrapper(procedure, 1); e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE); final List elements = new ArrayList(); final TObjectIntHashMap elementOrderMap = new TObjectIntHashMap(); final AtomicInteger ready = new AtomicInteger(1); final AtomicInteger indexCounter = new AtomicInteger(0); graph.forOrderedSet(element, new AsyncMultiProcedure() { @Override public void exception(AsyncReadGraph graph, Throwable throwable) { guard.exception(graph, throwable); } @Override public void execute(AsyncReadGraph graph, Resource r) { ready.incrementAndGet(); final int childIndex = indexCounter.getAndIncrement(); graph.asyncRequest(new NodeRequest(canvas, diagram, r, null), new TransientCacheAsyncListener() { @Override public void exception(AsyncReadGraph graph, Throwable throwable) { guard.exception(graph, throwable); } @Override public void execute(AsyncReadGraph graph, IElement child) { elementReady(graph, child, childIndex); } }); } @Override public void finished(AsyncReadGraph graph) { elementReady(graph, null, -1); } void elementReady(AsyncReadGraph graph, IElement child, int index) { if (child != null) { synchronized (elements) { elements.add(child); elementOrderMap.put(child, index); } } if (ready.decrementAndGet() == 0) { // Children ready, sort them and go! Collections.sort(elements, new Comparator() { @Override public int compare(IElement o1, IElement o2) { int thisVal = elementOrderMap.get(o1); int anotherVal = elementOrderMap.get(o2); return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); } }); Image img = new CompositeImage(elements); e.setHint(ElementHints.KEY_IMAGE, img); guard.execute(graph, e); } } }); } }