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