1 /*******************************************************************************
2 * Copyright (c) 2013 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.layer0.adapter.impl;
14 import gnu.trove.map.hash.THashMap;
16 import java.util.Collections;
19 import org.simantics.databoard.Bindings;
20 import org.simantics.db.ReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.WriteGraph;
23 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
24 import org.simantics.db.common.utils.Versions;
25 import org.simantics.db.exception.DatabaseException;
26 import org.simantics.db.layer0.adapter.StringModifier;
27 import org.simantics.db.layer0.util.Layer0Utils;
28 import org.simantics.db.layer0.variable.Variable;
29 import org.simantics.layer0.Layer0;
32 * Makes sure that two things apply for L0.HasName of any entity:
34 * <li>An entity must not have the same name as any of its
35 * L0.PartOf/L0.ConsistsOf related siblings</li>
36 * <li>An entity's name must not begin with one or more dots ('.'). Due to
37 * limitations imposed by the Variable specification no resources in the
38 * simantics database should be named beginning with one or more dots. '.' is
39 * variable browsing syntax for "parent" (see
40 * {@link Variable#browse(ReadGraph, String)}). This is comparable to file
41 * systems and the use of '.' and '..' therein.</li>
44 * @author Tuukka Lehtonen
46 public final class EntityNameModifier implements StringModifier {
48 private Resource entity;
49 private Resource property;
51 private boolean hasUri;
52 private Map<String, Resource> namesInUse = Collections.emptyMap();
56 final private String initial;
57 final private String version;
59 public EntityNameModifier(ReadGraph graph, Resource entity, Resource property) throws DatabaseException {
61 this.property = property;
63 this.initial = Versions.getBaseName(graph, entity);
64 this.version = Versions.getVersion(graph, entity);
68 public String getValue() {
72 private void initialize(ReadGraph graph) throws DatabaseException {
73 this.L0 = Layer0.getInstance(graph);
74 refreshUsedSiblingNames(graph);
75 if(Layer0Utils.isPublished(graph, entity)) throw new DatabaseException("Published resources cannot be renamed.");
76 if(Layer0Utils.isContainerPublished(graph, entity)) throw new DatabaseException("Cannot rename in a published shared library.");
79 private void refreshUsedSiblingNames(ReadGraph graph) throws DatabaseException {
80 String uri = graph.getPossibleURI(entity);
81 this.hasUri = uri != null;
83 Map<String, Resource> used = new THashMap<String, Resource>();
84 for (Resource partOf : graph.getObjects(entity, L0.PartOf)) {
85 Map<String, Resource> childMap = graph.syncRequest(new UnescapedChildMapOfResource(partOf));
86 used.putAll(childMap);
88 String originalName = graph.getPossibleValue(property, Bindings.STRING);
89 // System.out.println("used names:" + used);
90 // System.out.println("original name:" + originalName);
91 used.remove(originalName);
93 this.namesInUse = used;
94 // System.out.println("final used names:" + used);
97 public String finalValue(String value) {
98 return version != null ? value + "@" + version : value;
102 public String isValid(String value_) {
103 String value = finalValue(value_);
105 return "Name is empty.";
106 if (namesInUse.containsKey(value))
107 return "Name is already used by a sibling.";
108 if (hasUri && value.startsWith("."))
109 return "Name of an entity with URI must not begin with a dot ('.')";
114 final public void modify(WriteGraph graph, String value_) throws DatabaseException {
115 String value = finalValue(value_);
116 graph.claimLiteral(entity, L0.HasName, L0.NameOf, value, Bindings.STRING);