/******************************************************************************* * 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.modeling.ui.features; import java.util.ArrayList; import java.util.List; import org.eclipse.ui.IEditorInput; import org.simantics.NameLabelMode; import org.simantics.NameLabelUtil; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.ResourceArray; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.modeling.ModelingResources; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.ui.workbench.IEditorNamingService; import org.simantics.ui.workbench.IResourceEditorInput; import org.simantics.ui.workbench.IResourceEditorInput2; import org.simantics.utils.strings.EString; /** * A basic {@link IEditorNamingService} implementation for structural models. * * @author Tuukka Lehtonen */ public class EditorNamingService2 implements IEditorNamingService { private static final boolean DEBUG = false; @Override public String getName(ReadGraph g, String editorId, IEditorInput in) throws DatabaseException { if (!(in instanceof IResourceEditorInput)) return "Unsupported input: " + in; IResourceEditorInput input = (IResourceEditorInput) in; ResourceArray a = input.getResourceArray(); if (DEBUG) { System.out.println("EditorNamingService2.getName: " + input); for (int i = 0; i < a.resources.length; ++i) System.out.println(" [" + i + "] " + NameUtils.getURIOrSafeNameInternal(g, a.resources[i])); } if (a.isEmpty()) return "(empty input)"; StructuralResource2 sr = StructuralResource2.getInstance(g); DiagramResource dr = DiagramResource.getInstance(g); ModelingResources mr = ModelingResources.getInstance(g); Resource mainInput = a.resources[0]; NameLabelMode mode = NameLabelUtil.getNameLabelMode(g); if (g.isInstanceOf(mainInput, dr.Diagram)) { if (DEBUG) System.out.println("input resource[0] is a diagram "); if (a.size() == 1) { String name = nameSingleDiagramInput(g, mainInput, in, mode); // Component type configuration diagram? Resource composite = g.getPossibleObject(mainInput, mr.DiagramToComposite); if (composite != null) { Resource defines = g.getPossibleObject(composite, sr.Defines); if (defines != null && g.isInstanceOf(defines, sr.ComponentType)) { if (in instanceof IResourceEditorInput2) { IResourceEditorInput2 in2 = (IResourceEditorInput2) in; String rvi = in2.getRVI(); String ctName = NameLabelUtil.modalName(g, defines, mode); if (rvi == null || rvi.isEmpty()) { return ctName + " (Configuration)"; } else { return name + " : " + ctName; } } } } // Just a normal configuration diagram. return name; } else { return namePathInput(g, input, in, mode); } } else if (g.isInstanceOf(mainInput, dr.Composite)) { // Symbol? Resource defines = g.getPossibleObject(mainInput, sr.Defines); if (defines != null && g.isInheritedFrom(defines, dr.DefinedElement)) { Resource componentType = g.getPossibleObject(defines, mr.SymbolToComponentType); if (componentType != null) { String symbolName = NameLabelUtil.modalName(g, defines, mode); String cName = NameLabelUtil.modalName(g, componentType, mode); return symbolName + " (Symbol of " + cName + ")"; } } } String name = NameLabelUtil.modalName(g, mainInput, mode); if (name == null) name = "(no name)"; return name; } protected String nameSingleDiagramInput(ReadGraph g, Resource input, IEditorInput in, NameLabelMode mode) throws DatabaseException { ModelingResources mr = ModelingResources.getInstance(g); StructuralResource2 sr = StructuralResource2.getInstance(g); if (in instanceof IResourceEditorInput2) { IResourceEditorInput2 in2 = (IResourceEditorInput2) in; String rvi = in2.getRVI(); if (rvi != null && !rvi.isEmpty()) { String compositeName = getPossibleCompositeName(g, in2, mode); if (compositeName != null) return compositeName; } } // Prefer composite name over diagram name. Resource composite = g.getPossibleObject(input, mr.DiagramToComposite); if (composite == null) return getSafeLabel(g, input, mode); // Prefer the name of what the composite defines if it defines something. Resource defines = g.getPossibleObject(composite, sr.Defines); if (defines != null) return getSafeLabel(g, defines, mode); return getSafeLabel(g, composite, mode); } protected Variable getPossibleConfigurationCompositeVariable(ReadGraph graph, IResourceEditorInput2 in) throws DatabaseException { try { if (in.getRVI() != null) return in.getVariable(graph); } catch (DatabaseException e) { } return null; } protected String getPossibleCompositeName(ReadGraph g, IResourceEditorInput2 in, NameLabelMode mode) throws DatabaseException { Variable composite = getPossibleConfigurationCompositeVariable(g, in); return composite == null ? null : NameLabelUtil.modalName(g, composite, mode); } protected String namePathInput(ReadGraph g, IResourceEditorInput input, IEditorInput in, NameLabelMode mode) throws DatabaseException { StringBuilder sb = new StringBuilder(); Resource composite = input.getResourceArray().resources[1]; sb.append(getSafeLabel(g, composite, mode)); sb.append(" "); pathSuffix(g, input.getResourceArray(), mode, 2, sb); return sb.toString(); } protected void pathSuffix(ReadGraph g, ResourceArray a, NameLabelMode mode, int dropFromTail, StringBuilder result) throws DatabaseException { path(g, a, mode, 0, dropFromTail, true, ".", result); } protected void path(ReadGraph g, ResourceArray a, NameLabelMode mode, int dropFromHead, int dropFromTail, boolean addParenthesis, String separator, StringBuilder result) throws DatabaseException { if (a.resources.length > 1) { @SuppressWarnings("unused") int level = 0; List pathNames = new ArrayList(a.size() + 1); for (int i = a.resources.length - 1 - dropFromHead; i >= dropFromTail; --i) { String pathElementName = truncated(getSafeLabel(g, a.resources[i], mode), 256); // System.out.println("name for path element " + i + ": " + a.resources[i] + ": " + pathElementName); if (pathElementName.contains(separator)) pathElementName = '"' + pathElementName + '"'; pathNames.add(pathElementName); ++level; } path(pathNames, addParenthesis, separator, result); } } protected void path(List segments, boolean addParenthesis, String separator, StringBuilder result) throws DatabaseException { if (!segments.isEmpty()) { if (addParenthesis) result.append("("); result.append(EString.implode(segments, separator)); if (addParenthesis) result.append(')'); } } protected String getSafeLabel(ReadGraph graph, Resource r, NameLabelMode mode) throws DatabaseException { return NameLabelUtil.modalName(graph, r, mode); } protected String limitedName(ReadGraph graph, String name, IEditorInput in) throws DatabaseException { // Keep the workbench safe from harm by trimming too long titles. // The workbench will get very stuck if it is given a title of tens of // thousands of characters. if (name.length() < 256) return name; if (!(in instanceof IResourceEditorInput)) return "Unsupported input: " + in; IResourceEditorInput input = (IResourceEditorInput) in; return NameUtils.getSafeName(graph, input.getResource()); } protected String truncated(String name, int maxLength) throws DatabaseException { if (name.length() <= maxLength) return name; return name.substring(0, Math.max(0, maxLength - 3)) + "..."; } }