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=035118aa5f35c9e5acd1f34d22065055dfdee486;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 asStringRequest(final Resource base) { - return new UniqueRead() { - @Override - public String perform(ReadGraph graph) throws DatabaseException { - Variable v = Variables.getConfigurationContext(graph, base); - return asString(graph, v); - } - }; - } - - /** - * Works like {@link #asString(ReadGraph, Variable)} but returns - * null 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 -1) { - String x = str.substring(pos+1, end); - if (!x.isEmpty()) { - String[] parts = x.split(":"); - if (parts.length == 3) { - try { - long res = (int) Long.parseLong(parts[2]); - long mostSignificant = Long.parseLong(parts[0]); - long leastSignificant = Long.parseLong(parts[1]); - Resource r = support.getResource( res ); - rb.append( role, r, mostSignificant, leastSignificant); - pos = end; - continue; - } catch (NumberFormatException nfe) { - } catch (DatabaseException e) { - } - } - } - } - String text = URIStringUtils.unescape( str.substring(pos, end) ); - pos = end; - rb.append( role, text ); - } - return rb.toRVI(); - } - -} +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 asStringRequest(final Resource base) { + return new UniqueRead() { + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Variable v = Variables.getConfigurationContext(graph, base); + return asString(graph, v); + } + }; + } + + /** + * Works like {@link #asString(ReadGraph, Variable)} but returns + * null 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 -1) { + String x = str.substring(pos, end); + if (!x.isEmpty()) { + String[] parts = x.split(":"); + if (parts.length == 3) { + try { + long res = (int) Long.parseLong(parts[2]); + long mostSignificant = Long.parseLong(parts[0]); + long leastSignificant = Long.parseLong(parts[1]); + Resource r = support.getResource( res ); + rb.append( role, r, mostSignificant, leastSignificant); + pos = end; + continue; + } catch (NumberFormatException nfe) { + } catch (DatabaseException e) { + } + } + } + } + String text = URIStringUtils.unescape( str.substring(pos, end) ); + pos = end; + rb.append( role, text ); + } + return rb.toRVI(); + } + +}