/******************************************************************************* * Copyright (c) 2007, 2011 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.profile; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.NullProgressMonitor; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.ListUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; import org.simantics.db.layer0.util.ClipboardUtils; import org.simantics.db.layer0.util.SimanticsClipboard; import org.simantics.db.layer0.util.SimanticsClipboardImpl; import org.simantics.db.layer0.util.SimanticsKeys; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.service.VirtualGraphSupport; import org.simantics.diagram.profile.ProfileActivityBean.Profile; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.Root; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.utils.datastructures.Arrays; /** * @author Tuukka Lehtonen */ public class Profiles { public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); ArrayList ee = new ArrayList(); Arrays.addAll(ee, entries); Resource list = ListUtils.create(graph, DIA.Profile, ee); // TODO : DIA.Profile is a list, but why it is used in the container? //Resource profile = graph.newResource(); //graph.claim(profile, L0.InstanceOf, null, DIA.Profile); Resource profile = ListUtils.create(graph, DIA.Profile); graph.claimLiteral(profile, L0.HasName, profileName); graph.claim(profile, DIA.HasEntries, null, list); return profile; } public static Resource createEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource entry = graph.newResource(); graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry); graph.claimLiteral(entry, L0.HasName, name); graph.claimLiteral(entry, L0.HasLabel, name); graph.claim(entry, DIA.ProfileEntry_HasStyle, style); graph.claim(entry, DIA.ProfileEntry_HasGroup, group); return entry; } public static Resource createContainerProfile(WriteGraph graph, String name, Resource... children) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource profile = graph.newResource(); graph.claim(profile, L0.InstanceOf, null, DIA.Profile); graph.claim(profile, L0.Abstract, profile); graph.claimLiteral(profile, L0.HasName, name); graph.claimLiteral(profile, L0.HasLabel, name); ArrayList cd = new ArrayList(); Arrays.addAll(cd, children); graph.claim(profile, DIA.HasEntries, null, ListUtils.create(graph, DIA.Profile, cd)); return profile; } public static Variable getMappedVariable(ReadGraph graph, Resource runtimeDiagram, Resource element) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING); Variable activeVariable = org.simantics.db.layer0.variable.Variables.getVariable(graph, variableURI); Resource module = graph.getPossibleObject(element, MOD.ElementToComponent); if (module == null) return null; return activeVariable.browse(graph, module); } public static Resource[] getProfileEntries(ReadGraph graph, Resource profile) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); Resource list = graph.getSingleObject(profile, DIA.HasEntries); List entries = ListUtils.toList(graph, list); return entries.toArray(new Resource[entries.size()]); } /** * Copies profiles from an ontology definition to a model. * * @param graph * @param model * @param sourceProfile * @throws DatabaseException */ public static void addProfiles(WriteGraph graph, Resource model, Resource sourceProfile) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource profile = null; if (graph.isInstanceOf(sourceProfile, DIA.ConfigurableProfile)) profile = copyProfiles(graph, model, sourceProfile); else profile = initProfiles(graph, model, sourceProfile); // connect profile to model graph.claim(model, DIA.HasProfile, profile); graph.claim(model, L0.ConsistsOf, profile); graph.claim(model, DIA.HasActiveProfile, profile); } public static void addProfiles(WriteGraph graph, Resource model, String name, Resource... profileEntries) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource profile = null; profile = initProfiles(graph, model, name, profileEntries); // connect profile to model graph.claim(model, DIA.HasProfile, profile); graph.claim(model, L0.ConsistsOf, profile); graph.claim(model, DIA.HasActiveProfile, profile); } private static Resource initProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource entries[] = getProfileEntries(graph, profile); String name = "Profile"; String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING); if (label != null && label.length() > 0) name = label; return initProfiles(graph, model, name, entries); } private static Resource initProfiles(WriteGraph graph, Resource model, String name, Resource entries[]) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); for (int i = 0; i < entries.length; i++) { Resource entry = entries[i]; if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) { entries[i] = copyProfiles(graph, model, entry); } } return createProfile2(graph, name, entries); } private static Resource createProfile2(WriteGraph graph, String name, Resource[] entries) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); Resource profile = Profiles.createProfile(graph, name, entries); final List enabled = new ArrayList(); for (Resource r : entries) { if (graph.hasStatement(r, DIA.Profile_defaultEnabled)) { enabled.add(r); } } if (enabled.size() > 0) { final Resource p = profile; VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); graph.syncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { @Override public void perform(WriteGraph graph) throws DatabaseException { SimulationResource SIM = SimulationResource.getInstance(graph); for (Resource r : enabled) { graph.claim(p, SIM.IsActive, r); } } }); } return profile; } private static Resource copyProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource entries[] = getProfileEntries(graph, profile); Map groupMap = new HashMap(); for (int i = 0; i < entries.length; i++) { Resource entry = entries[i]; if (graph.isInstanceOf(entry, DIA.Profile)) { entries[i] = initProfiles(graph, model, entry); } else if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) { entries[i] = copyProfiles(graph, model, entry); } else if (graph.isInstanceOf(entry, DIA.ProfileEntry)) { entries[i] = copyProfileEntry(graph, entry, groupMap); } } String name = "Profile"; String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING); if (label != null && label.length() > 0) name = label; return createProfile2(graph, name, entries); } private static Resource copyProfileEntry(WriteGraph graph, Resource entry, Map groupMap) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); String name = graph.getPossibleRelatedValue(entry, L0.HasLabel, Bindings.STRING); Resource group = graph.getSingleObject(entry, DIA.ProfileEntry_HasGroup); Resource copyGroup = groupMap.get(group); if (copyGroup == null) { copyGroup = copyProfileGroup(graph, group); groupMap.put(group, copyGroup); } Resource style = graph.getSingleObject(entry, DIA.ProfileEntry_HasStyle); if (!graph.isInstanceOf(style, DIA.Style)) { style = createProfileStyle(graph, style); } Resource instance = Profiles.createEntry(graph, name, style, copyGroup); graph.claim(instance, L0.InstanceOf, entry); Double priority = graph.getPossibleRelatedValue(entry, DIA.ProfileEntry_HasPriority, Bindings.DOUBLE); if (priority != null) { graph.claimLiteral(instance, DIA.ProfileEntry_HasPriority, priority, Bindings.DOUBLE); } for (Resource template : graph.getObjects(entry, DIA.HasTemplate)) { SimanticsClipboardImpl builder = new SimanticsClipboardImpl(); DefaultCopyHandler handler = new DefaultCopyHandler(template); DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(instance) { @Override public Resource createRoot(WriteOnlyGraph graph, Root root, Resource resource) throws DatabaseException { Layer0 l0 = graph.getService(Layer0.class); DiagramResource DIA = graph.getService(DiagramResource.class); if(resource == null) resource = graph.newResource(); graph.claim(library, DIA.HasTemplate, DIA.HasTemplate_Inverse, resource); String newName = getName(root); graph.addLiteral(resource, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING); addRootInfo(root, newName, resource); return resource; } }; handler.copyToClipboard(graph, builder, new NullProgressMonitor()); for(Set object : builder.getContents()) { TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH); TransferableGraphs.importGraph1(graph, tg, advisor); } } return instance; } private static Resource copyProfileGroup(WriteGraph graph, Resource group) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); Resource instance = graph.newResource(); for (Resource type : graph.getObjects(group, L0.InstanceOf)) { graph.claim(instance, L0.InstanceOf, type); } Resource referredType = graph.getPossibleObject(group, DIA.TypeGroup_HasType); if (referredType != null) graph.claim(instance, DIA.TypeGroup_HasType, referredType); return instance; } private static Resource createProfileStyle(WriteGraph graph, Resource style) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Resource instance = graph.newResource(); graph.claim(instance, L0.InstanceOf, style); return instance; } public static ProfileActivityBean readProfileActivity( RequestProcessor processor, Resource root) throws DatabaseException { return processor.syncRequest(new ProfileActivityBeanRequest(root)); } public static ProfileActivityBean readProfileActivity( RequestProcessor processor, Resource root, Map writeToMap) throws DatabaseException { ProfileActivityBean pab = readProfileActivity(processor, root); if (pab != null && writeToMap != null) writeToMap.put(ProfileActivityBean.EXTENSION_KEY, new Variant(ProfileActivityBean.BINDING, pab)); return pab; } public static void writeProfileActivity( RequestProcessor processor, Resource root, ProfileActivityBean bean) throws DatabaseException { VirtualGraph vg = processor.getService(VirtualGraphSupport.class).getWorkspacePersistent("profiles"); processor.syncRequest(new WriteRequest(vg) { @Override public void perform(WriteGraph graph) throws DatabaseException { writeProfileActivity(graph, root, bean); } }); } private static void writeProfileActivity( WriteGraph graph, Resource root, ProfileActivityBean bean) throws DatabaseException { String rootUri = graph.getPossibleURI(root); if (rootUri == null) return; SimulationResource SIMU = SimulationResource.getInstance(graph); for (Profile p : bean.topLevelProfiles.values()) { Resource pr = resolveRelativeUri(graph, rootUri, p.relativeUri); if (pr == null) continue; for (String active : p.activeEntries) { Resource ar = resolveRelativeUri(graph, rootUri, active); if (ar != null) graph.claim(pr, SIMU.IsActive, ar); } } Resource activeProfile = resolveRelativeUri(graph, rootUri, bean.activeProfile); if (activeProfile != null) { DiagramResource DIA = DiagramResource.getInstance(graph); graph.claim(root, DIA.HasActiveProfile, DIA.HasActiveProfile_Inverse, activeProfile); } } static String possiblyRelativeUri(ReadGraph graph, String rootUri, Resource r) throws DatabaseException { if (r == null) return null; String uri = graph.getPossibleURI(r); if (rootUri != null && uri != null && uri.startsWith(rootUri)) return uri.substring(rootUri.length()); return uri; } static Resource resolveRelativeUri(ReadGraph graph, String rootUri, String possiblyRelativeUri) throws DatabaseException { return possiblyRelativeUri != null ? graph.getPossibleResource( resolveRelativeUri(rootUri, possiblyRelativeUri) ) : null; } private static String resolveRelativeUri(String rootUri, String possiblyRelativeUri) { return possiblyRelativeUri.startsWith("http:/") ? possiblyRelativeUri : rootUri + possiblyRelativeUri; } }