]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityNameModifier.java
Fixed index query regression in L0.Entity instance queries
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / adapter / impl / EntityNameModifier.java
1 /*******************************************************************************
2  * Copyright (c) 2013 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.layer0.adapter.impl;
13
14 import gnu.trove.map.hash.THashMap;
15
16 import java.util.Collections;
17 import java.util.Map;
18
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;
30
31 /**
32  * Makes sure that two things apply for L0.HasName of any entity:
33  * <ol>
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>
42  * </ol>
43  * 
44  * @author Tuukka Lehtonen
45  */
46 public final class EntityNameModifier implements StringModifier {
47
48     private Resource              entity;
49     private Resource              property;
50
51     private boolean               hasUri;
52     private Map<String, Resource> namesInUse = Collections.emptyMap();
53
54     private Layer0                L0;
55     
56     final private String                initial;
57     final private String                version;
58
59     public EntityNameModifier(ReadGraph graph, Resource entity, Resource property) throws DatabaseException {
60         this.entity = entity;
61         this.property = property;
62         initialize(graph);
63         this.initial = Versions.getBaseName(graph, entity);
64         this.version = Versions.getVersion(graph, entity);
65     }
66
67     @Override
68     public String getValue() {
69         return initial;
70     }
71     
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.");
77     }
78
79     private void refreshUsedSiblingNames(ReadGraph graph) throws DatabaseException {
80         String uri = graph.getPossibleURI(entity);
81         this.hasUri = uri != null;
82
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);
87         }
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);
92
93         this.namesInUse = used;
94 //        System.out.println("final used names:" + used);
95     }
96
97     public String finalValue(String value) {
98         return version != null ? value + "@" + version : value;
99     }
100     
101     @Override
102     public String isValid(String value_) {
103         String value = finalValue(value_); 
104         if (value.isEmpty())
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 ('.')";
110         return null;
111     }
112
113     @Override
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);
117     }
118
119 }