X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FRVI.java;h=a5f22c83c1a44233bcce46550aefdab8a1b39dec;hb=48bb50bb6640506d1f150ca8e4fa5a6e878464be;hp=d42a4e6bde07e035a7248d96d1905595747c47eb;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java index d42a4e6bd..a5f22c83c 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java @@ -1,436 +1,436 @@ -package org.simantics.db.layer0.variable; - -import java.util.Arrays; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Databoard; -import org.simantics.databoard.annotations.Union; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.util.Bean; -import org.simantics.databoard.util.URIStringUtils; -import org.simantics.db.ReadGraph; -import org.simantics.db.RequestProcessor; -import org.simantics.db.Resource; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.AdaptionException; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.ServiceException; -import org.simantics.db.exception.ValidationException; -import org.simantics.db.layer0.variable.Variables.Role; -import org.simantics.db.service.SerialisationSupport; -import org.simantics.layer0.Layer0; - -/** - * Relative Value Indicator is a parent-child reference inside variable-tree - * address space. - * - * @See RVIBuilder - * @author toni.kalajainen - */ -public class RVI extends Bean { - - private static final RVIPart[] NONE = {}; - - public RVIPart[] parts; - - public RVI() { - super(); - } - - public RVI(Binding rviBinding) { - super(rviBinding); - } - - public static RVI empty(Binding rviBinding) { - RVI result = new RVI(rviBinding); - result.parts = NONE; - return result; - } - - public boolean isEmpty() { - return parts.length == 0; - } - - public Variable resolve(ReadGraph graph, Variable base) throws DatabaseException { - for(RVIPart part : parts) { - base = base.resolve(graph, part); - } - return base; - } - - public Variable resolvePossible(ReadGraph graph, Variable base) throws DatabaseException { - for(RVIPart part : parts) { - base = base.resolvePossible(graph, part); - if (base == null) - return null; - } - return base; - } - - @Override - public int hashCode() { - return Arrays.hashCode(parts); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RVI other = (RVI) obj; - return Arrays.equals(parts, other.parts); - } - - /** - * Returns a string representation of the all the parts of this RVI for - * visualization purposes. This representation of the RVI does not withstand - * moving the RVI-referenced resource between model composites unlike the - * databoard serialization of this class. - * - *
- * Implementation takes the RVI part of a Variable resolved using this RVI
- * and the specified Variable as a base for the resolution.
- *
- * @param graph transaction handle
- * @param base base resource to use for resolving the variable
- * @return this RVI as a String
- * @throws DatabaseException
- */
- public String asString(ReadGraph graph, Variable base) throws DatabaseException {
- String baseURI = base.getURI(graph);
- Variable resolved = resolve(graph, base);
- return resolved.getURI(graph).substring(baseURI.length());
- }
-
- public UniqueRead
+ * Implementation takes the RVI part of a Variable resolved using this RVI
+ * and the specified Variable as a base for the resolution.
+ *
+ * @param graph transaction handle
+ * @param base base resource to use for resolving the variable
+ * @return this RVI as a String
+ * @throws DatabaseException
+ */
+ public String asString(ReadGraph graph, Variable base) throws DatabaseException {
+ String baseURI = base.getURI(graph);
+ Variable resolved = resolve(graph, base);
+ return resolved.getURI(graph).substring(baseURI.length());
+ }
+
+ public UniqueReadnull
if resolution of the string form fails because of the
- * database contents.
- *
- * @param graph transaction handle
- * @param base base resource to use for resolving the variable
- * @return this RVI as a String
- * @throws DatabaseException
- */
- public String asPossibleString(ReadGraph graph, Variable base) throws DatabaseException {
- try {
- return asString(graph, base);
- } catch (DatabaseException e) {
- return null;
- }
- }
-
- /**
- * Print as persistent string
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (RVIPart p : parts) {
- if (p instanceof ResourceRVIPart) {
- sb.append(p.toString());
- } else if (p instanceof StringRVIPart) {
- sb.append(((StringRVIPart) p).toEscapedString());
- } else if (p instanceof GuidRVIPart) {
- sb.append(((GuidRVIPart) p).toEscapedString());
- }
- }
- return sb.toString();
- }
-
- /**
- * Resolves this RVI into a string with a best effort method that tries to
- * resolve the RVI parts into variables for as long as it can. After
- * resolution is finished the remaining RVI parts are simply concatenated
- * into the result string as strings without resolving them into variables.
- * This is different from {@link #asString(ReadGraph, Variable)} or
- * {@link #asPossibleString(ReadGraph, Variable)} in that it doesn't demand
- * that the RVI resolves completely. Still at least the first RVI part must
- * resolve, otherwise null
is returned, since this means that
- * the variable no longer exists at all.
- *
- * @param graph
- * database read handle
- * @param base
- * the base of resolution for the RVI
- * @return The RVI of the referenced entity as a string or null
- * if zero parts of this RVI can be resolved, i.e. the resources
- * referenced by it no longer exist.
- * @throws DatabaseException
- */
- public String toPossibleString(ReadGraph graph, Variable base) throws DatabaseException {
- String baseURI = base.getURI(graph);
-
- Variable resolved = null;
- int i = 0;
- for (; i < parts.length; ++i) {
- RVIPart p = parts[i];
- base = base.resolvePossible(graph, p);
- if (base == null)
- break;
- resolved = base;
- }
- if (resolved == null)
- return null;
-
- StringBuilder sb = new StringBuilder();
- String resolvedURI = resolved.getURI(graph);
- sb.append(resolvedURI, baseURI.length(), resolvedURI.length());
- if (i < parts.length) {
- // The tail didn't resolve into a Variable synchronously
- // so let's just concatenate the rest by hand into the
- // result string.
- Layer0 L0 = Layer0.getInstance(graph);
- for (; i < parts.length; ++i) {
- RVIPart p = parts[i];
- if (p instanceof ResourceRVIPart) {
- Resource r = ((ResourceRVIPart) p).resource;
- String str = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
- if (str == null)
- return null;
- sb.append(p.getRole().getIdentifier()).append(URIStringUtils.escape(str));
- } else if (p instanceof StringRVIPart) {
- sb.append(p.getRole().getIdentifier()).append(URIStringUtils.escape(((StringRVIPart) p).string));
- } else if (p instanceof GuidRVIPart) {
- sb.append(p.getRole().getIdentifier()).append(((GuidRVIPart)p).mostSignificant).append(":").append(((GuidRVIPart)p).leastSignificant);
- }
- }
- }
-
- return sb.toString();
- }
-
- /**
- * Print for USER. Not the real RVI
- *
- * @param graph
- * @return
- * @throws AdaptionException
- * @throws ValidationException
- * @throws ServiceException
- */
- public String toString(ReadGraph graph) throws DatabaseException {
- StringBuilder sb = new StringBuilder();
- for (RVIPart p : parts) {
- if (p instanceof ResourceRVIPart) {
- Resource r = ((ResourceRVIPart) p).resource;
- String str = NameUtils.getSafeName(graph, r);
- sb.append(p.getRole().getIdentifier()).append(str);
- } else if (p instanceof StringRVIPart) {
- String str = p.toString();
- sb.append(str);
- } else if (p instanceof GuidRVIPart) {
- String str = p.toString();
- sb.append(str);
- }
- }
- return sb.toString();
- }
-
- // Enumeration | ResourceRVIPart | StringRVIPart | GuidRVIPart
- @Union({ResourceRVIPart.class, StringRVIPart.class, GuidRVIPart.class})
- public static interface RVIPart { public Role getRole(); }
-
- public static class ResourceRVIPart implements RVIPart {
- public Role role;
- public Resource resource;
- @Override
- public Role getRole() {
- return role;
- }
- public ResourceRVIPart() {}
- public ResourceRVIPart(Role role, Resource resource) {
- if (resource == null)
- throw new NullPointerException("null resource");
- this.role = role;
- this.resource = resource;
- }
- @Override
- public String toString() {
- return role.getIdentifier()+"r"+Long.toString( resource.getResourceId() );
- }
- @Override
- public int hashCode() {
- return resource.hashCode() * 31 + role.hashCode();
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- ResourceRVIPart other = (ResourceRVIPart) obj;
- return role == other.role && resource.equals(other.resource);
- }
- }
-
- public static class StringRVIPart implements RVIPart {
- public Role role;
- public String string;
- @Override
- public Role getRole() {
- return role;
- }
- public StringRVIPart() {}
- public StringRVIPart(Role role, String string) {
- if (string == null)
- throw new NullPointerException("null string");
- this.role = role;
- this.string = string;
- }
- @Override
- public String toString() {
- return role.getIdentifier()+string;
- }
- public String toEscapedString() {
- return role.getIdentifier()+URIStringUtils.escape(string);
- }
- @Override
- public int hashCode() {
- return string.hashCode() * 31 + role.hashCode();
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- StringRVIPart other = (StringRVIPart) obj;
- return role == other.role && string.equals(other.string);
- }
- }
-
- public static class GuidRVIPart implements RVIPart {
- public Role role;
- public long mostSignificant;
- public long leastSignificant;
- public transient Resource resource;
- @Override
- public Role getRole() {
- return role;
- }
- public GuidRVIPart() {}
- public GuidRVIPart(Role role, Resource resource, long mostSignificant, long leastSignificant) {
- this.role = role;
- this.resource = resource;
- this.mostSignificant = mostSignificant;
- this.leastSignificant = leastSignificant;
- }
- @Override
- public String toString() {
- return role.getIdentifier()+mostSignificant+":"+leastSignificant;
- }
- public String toEscapedString() {
- String rid = resource != null ? Long.toString( resource.getResourceId() ) : "0";
- return role.getIdentifier()+mostSignificant+":"+leastSignificant+":"+rid;
- }
- @Override
- public int hashCode() {
- return (longHashCode(leastSignificant) * 51 + longHashCode(mostSignificant)) * 31 + role.hashCode();
- }
- /*
- * TODO: remove this when switched into Java 1.8
- */
- private static int longHashCode(long value) {
- return (int)(value ^ (value >>> 32));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- GuidRVIPart other = (GuidRVIPart) obj;
- return role == other.role && leastSignificant == other.leastSignificant && mostSignificant == other.mostSignificant;
- }
-
- }
-
- public static RVI fromResourceFormat( RequestProcessor proc, String str ) {
- SerialisationSupport support = proc.getService(SerialisationSupport.class);
- if (support == null) throw new RuntimeException("No serialization support in Session");
- Databoard databoard = proc.getService(Databoard.class);
- if (databoard == null) throw new RuntimeException("No databoard support in Session");
-
- Binding rviBinding = databoard.getBindingUnchecked( RVI.class );
- RVIBuilder rb = new RVIBuilder( rviBinding );
- int pos = 0, len = str.length();
- while (posnull
if resolution of the string form fails because of the
+ * database contents.
+ *
+ * @param graph transaction handle
+ * @param base base resource to use for resolving the variable
+ * @return this RVI as a String
+ * @throws DatabaseException
+ */
+ public String asPossibleString(ReadGraph graph, Variable base) throws DatabaseException {
+ try {
+ return asString(graph, base);
+ } catch (DatabaseException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Print as persistent string
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (RVIPart p : parts) {
+ if (p instanceof ResourceRVIPart) {
+ sb.append(p.toString());
+ } else if (p instanceof StringRVIPart) {
+ sb.append(((StringRVIPart) p).toEscapedString());
+ } else if (p instanceof GuidRVIPart) {
+ sb.append(((GuidRVIPart) p).toEscapedString());
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Resolves this RVI into a string with a best effort method that tries to
+ * resolve the RVI parts into variables for as long as it can. After
+ * resolution is finished the remaining RVI parts are simply concatenated
+ * into the result string as strings without resolving them into variables.
+ * This is different from {@link #asString(ReadGraph, Variable)} or
+ * {@link #asPossibleString(ReadGraph, Variable)} in that it doesn't demand
+ * that the RVI resolves completely. Still at least the first RVI part must
+ * resolve, otherwise null
is returned, since this means that
+ * the variable no longer exists at all.
+ *
+ * @param graph
+ * database read handle
+ * @param base
+ * the base of resolution for the RVI
+ * @return The RVI of the referenced entity as a string or null
+ * if zero parts of this RVI can be resolved, i.e. the resources
+ * referenced by it no longer exist.
+ * @throws DatabaseException
+ */
+ public String toPossibleString(ReadGraph graph, Variable base) throws DatabaseException {
+ String baseURI = base.getURI(graph);
+
+ Variable resolved = null;
+ int i = 0;
+ for (; i < parts.length; ++i) {
+ RVIPart p = parts[i];
+ base = base.resolvePossible(graph, p);
+ if (base == null)
+ break;
+ resolved = base;
+ }
+ if (resolved == null)
+ return null;
+
+ StringBuilder sb = new StringBuilder();
+ String resolvedURI = resolved.getURI(graph);
+ sb.append(resolvedURI, baseURI.length(), resolvedURI.length());
+ if (i < parts.length) {
+ // The tail didn't resolve into a Variable synchronously
+ // so let's just concatenate the rest by hand into the
+ // result string.
+ Layer0 L0 = Layer0.getInstance(graph);
+ for (; i < parts.length; ++i) {
+ RVIPart p = parts[i];
+ if (p instanceof ResourceRVIPart) {
+ Resource r = ((ResourceRVIPart) p).resource;
+ String str = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
+ if (str == null)
+ return null;
+ sb.append(p.getRole().getIdentifier()).append(URIStringUtils.escape(str));
+ } else if (p instanceof StringRVIPart) {
+ sb.append(p.getRole().getIdentifier()).append(URIStringUtils.escape(((StringRVIPart) p).string));
+ } else if (p instanceof GuidRVIPart) {
+ sb.append(p.getRole().getIdentifier()).append(((GuidRVIPart)p).mostSignificant).append(":").append(((GuidRVIPart)p).leastSignificant);
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Print for USER. Not the real RVI
+ *
+ * @param graph
+ * @return
+ * @throws AdaptionException
+ * @throws ValidationException
+ * @throws ServiceException
+ */
+ public String toString(ReadGraph graph) throws DatabaseException {
+ StringBuilder sb = new StringBuilder();
+ for (RVIPart p : parts) {
+ if (p instanceof ResourceRVIPart) {
+ Resource r = ((ResourceRVIPart) p).resource;
+ String str = NameUtils.getSafeName(graph, r);
+ sb.append(p.getRole().getIdentifier()).append(str);
+ } else if (p instanceof StringRVIPart) {
+ String str = p.toString();
+ sb.append(str);
+ } else if (p instanceof GuidRVIPart) {
+ String str = p.toString();
+ sb.append(str);
+ }
+ }
+ return sb.toString();
+ }
+
+ // Enumeration | ResourceRVIPart | StringRVIPart | GuidRVIPart
+ @Union({ResourceRVIPart.class, StringRVIPart.class, GuidRVIPart.class})
+ public static interface RVIPart { public Role getRole(); }
+
+ public static class ResourceRVIPart implements RVIPart {
+ public Role role;
+ public Resource resource;
+ @Override
+ public Role getRole() {
+ return role;
+ }
+ public ResourceRVIPart() {}
+ public ResourceRVIPart(Role role, Resource resource) {
+ if (resource == null)
+ throw new NullPointerException("null resource");
+ this.role = role;
+ this.resource = resource;
+ }
+ @Override
+ public String toString() {
+ return role.getIdentifier()+"r"+Long.toString( resource.getResourceId() );
+ }
+ @Override
+ public int hashCode() {
+ return resource.hashCode() * 31 + role.hashCode();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ResourceRVIPart other = (ResourceRVIPart) obj;
+ return role == other.role && resource.equals(other.resource);
+ }
+ }
+
+ public static class StringRVIPart implements RVIPart {
+ public Role role;
+ public String string;
+ @Override
+ public Role getRole() {
+ return role;
+ }
+ public StringRVIPart() {}
+ public StringRVIPart(Role role, String string) {
+ if (string == null)
+ throw new NullPointerException("null string");
+ this.role = role;
+ this.string = string;
+ }
+ @Override
+ public String toString() {
+ return role.getIdentifier()+string;
+ }
+ public String toEscapedString() {
+ return role.getIdentifier()+URIStringUtils.escape(string);
+ }
+ @Override
+ public int hashCode() {
+ return string.hashCode() * 31 + role.hashCode();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StringRVIPart other = (StringRVIPart) obj;
+ return role == other.role && string.equals(other.string);
+ }
+ }
+
+ public static class GuidRVIPart implements RVIPart {
+ public Role role;
+ public long mostSignificant;
+ public long leastSignificant;
+ public transient Resource resource;
+ @Override
+ public Role getRole() {
+ return role;
+ }
+ public GuidRVIPart() {}
+ public GuidRVIPart(Role role, Resource resource, long mostSignificant, long leastSignificant) {
+ this.role = role;
+ this.resource = resource;
+ this.mostSignificant = mostSignificant;
+ this.leastSignificant = leastSignificant;
+ }
+ @Override
+ public String toString() {
+ return role.getIdentifier()+mostSignificant+":"+leastSignificant;
+ }
+ public String toEscapedString() {
+ String rid = resource != null ? Long.toString( resource.getResourceId() ) : "0";
+ return role.getIdentifier()+mostSignificant+":"+leastSignificant+":"+rid;
+ }
+ @Override
+ public int hashCode() {
+ return (longHashCode(leastSignificant) * 51 + longHashCode(mostSignificant)) * 31 + role.hashCode();
+ }
+ /*
+ * TODO: remove this when switched into Java 1.8
+ */
+ private static int longHashCode(long value) {
+ return (int)(value ^ (value >>> 32));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ GuidRVIPart other = (GuidRVIPart) obj;
+ return role == other.role && leastSignificant == other.leastSignificant && mostSignificant == other.mostSignificant;
+ }
+
+ }
+
+ public static RVI fromResourceFormat( RequestProcessor proc, String str ) {
+ SerialisationSupport support = proc.getService(SerialisationSupport.class);
+ if (support == null) throw new RuntimeException("No serialization support in Session");
+ Databoard databoard = proc.getService(Databoard.class);
+ if (databoard == null) throw new RuntimeException("No databoard support in Session");
+
+ Binding rviBinding = databoard.getBindingUnchecked( RVI.class );
+ RVIBuilder rb = new RVIBuilder( rviBinding );
+ int pos = 0, len = str.length();
+ while (pos