/******************************************************************************* * 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.db.layer0.adapter.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.CopyHandler; import org.simantics.db.layer0.adapter.CopyHandler2; import org.simantics.db.layer0.util.ClipboardUtils; import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; import org.simantics.db.layer0.util.SimanticsClipboard.Representation; import org.simantics.db.layer0.util.SimanticsClipboardBuilder; import org.simantics.db.layer0.util.TGRepresentation; import org.simantics.db.layer0.util.TGRepresentationUtils; import org.simantics.db.layer0.util.TGSourceRepresentation; import org.simantics.db.layer0.util.TransferableGraphConfiguration2; import org.simantics.graph.db.TransferableGraphSource; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.operation.Layer0X; import org.slf4j.LoggerFactory; public class DefaultCopyHandler implements CopyHandler, CopyHandler2 { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DefaultCopyHandler.class); protected Collection resources; public DefaultCopyHandler(Resource resource) { this.resources = Collections.singletonList(resource); } public DefaultCopyHandler(Collection resources) { this.resources = resources; } public Resource getResource() { if(resources.size() != 1) throw new IllegalStateException(); return resources.iterator().next(); } protected CopyHandler2 create(Collection resources) { return new DefaultCopyHandler(resources); } protected boolean ignoreVirtualResources() { return true; } @Override public CopyHandler2 combine(CopyHandler2 other_) { if(other_ instanceof DefaultCopyHandler) { DefaultCopyHandler other = (DefaultCopyHandler)other_; ArrayList allResources = new ArrayList(); allResources.addAll(resources); allResources.addAll(other.resources); return create(allResources); } return null; } protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException { if(cut) return null; return new TransferableGraphConfiguration2(graph, resources, ignoreVirtualResources(), false); } protected TransferableGraphSource computeSource(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException { return graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); } protected TransferableGraph1 compute(ReadGraph graph, TransferableGraphConfiguration2 conf) throws DatabaseException { return TransferableGraphs.create(graph, computeSource(graph, conf)); } protected Representation createTransferableGraph(ReadGraph graph, Collection resources, boolean cut) throws DatabaseException { final TransferableGraphConfiguration2 conf = createConfiguration(graph, cut); if(conf == null) return null; return new TGRepresentation(resources.toArray(new Resource[resources.size()])) { @Override public TransferableGraph1 compute(ReadGraph graph, Map hints) throws DatabaseException { conf.exclusionFunction = TGRepresentationUtils.computeExclusionFunction(graph, resources, hints); return DefaultCopyHandler.this.compute(graph, conf); } }; } protected Representation createTransferableGraphSource(ReadGraph graph, Collection resources, boolean cut) throws DatabaseException { final TransferableGraphConfiguration2 conf = createConfiguration(graph, cut); if(conf == null) return null; return new TGSourceRepresentation(resources.toArray(new Resource[resources.size()])) { @Override public TransferableGraphSource compute(ReadGraph graph, Map hints) throws DatabaseException { conf.exclusionFunction = TGRepresentationUtils.computeExclusionFunction(graph, resources, hints); return DefaultCopyHandler.this.computeSource(graph, conf); } }; } protected void fillTG(ReadGraph graph, HashSet items, boolean cut, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor, 10); subMonitor.subTask("Fill tg"); try { Representation tgRepresentation = createTransferableGraph(graph, resources, cut); if (tgRepresentation != null) items.add(tgRepresentation); subMonitor.worked(2); Representation tgSourceRepresentation = createTransferableGraphSource(graph, resources, cut); if (tgSourceRepresentation != null) items.add(tgSourceRepresentation); subMonitor.worked(2); if (resources.size() == 1) { SubMonitor splittedChild = subMonitor.split(6); Collection representations = graph .syncRequest(new ResourceRead>(resources.iterator().next()) { @Override public Collection perform(ReadGraph graph) throws DatabaseException { ArrayList result = new ArrayList(); Layer0X L0X = Layer0X.getInstance(graph); for (Resource adapter : graph.getObjects(resource, L0X.HasRepresentation)) { result.add(graph.adapt(adapter, Representation.class)); splittedChild.worked(1); } return result; } }); for (Representation r : representations) items.add(r); } else { LOGGER.warn("Invalid amount of resources {} for filling tg", resources); } } catch (DatabaseException e) { Logger.defaultLogError(e); } } protected void fillCopyResource(ReadGraph graph, HashSet items, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor, 1); subMonitor.subTask("Fill copy resources"); items.add(ClipboardUtils.createCopyResources(resources)); subMonitor.worked(1); } protected void fillCutResource(ReadGraph graph, HashSet items, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor, 1); subMonitor.subTask("Fill cut resources"); items.add(ClipboardUtils.createCutResources(resources)); subMonitor.worked(1); } @Override public void copyToClipboard(ReadGraph graph, SimanticsClipboardBuilder clipboard, IProgressMonitor monitor) throws DatabaseException { SubMonitor subMonitor = SubMonitor.convert(monitor, 100); HashSet items = new HashSet(); fillTG(graph, items, false, subMonitor.split(80)); fillCopyResource(graph, items, subMonitor.split(10)); clipboard.addContent(items, subMonitor.split(10)); } @Override public void cutToClipboard(ReadGraph graph, SimanticsClipboardBuilder clipboard, IProgressMonitor monitor) throws DatabaseException { SubMonitor subMonitor = SubMonitor.convert(monitor, 100); HashSet items = new HashSet(); fillTG(graph, items, true, subMonitor.split(80)); fillCutResource(graph, items, subMonitor.split(10)); clipboard.addContent(items, subMonitor.split(10)); } }