X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Faccessor%2Freference%2FChildReference.java;h=975e68e3c6c90669382b5771cfc0b45fc0a39589;hb=39508c529ed6dce08d4ca505c9518e3e82fd6efa;hp=afb2edfa87b12f0398267d6369396c4cbe7e2234;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/reference/ChildReference.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/reference/ChildReference.java index afb2edfa8..975e68e3c 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/reference/ChildReference.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/reference/ChildReference.java @@ -1,39 +1,39 @@ -/******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.databoard.accessor.reference; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.annotations.Optional; -import org.simantics.databoard.annotations.Union; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.mutable.MutableVariant; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.MapType; -import org.simantics.databoard.type.OptionalType; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.type.UnionType; -import org.simantics.databoard.util.URIUtil; +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.annotations.Optional; +import org.simantics.databoard.annotations.Union; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.mutable.MutableVariant; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.MapType; +import org.simantics.databoard.type.OptionalType; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.type.UnionType; +import org.simantics.databoard.util.URIUtil; /** - * Path is a single or multi-level reference to a child node in the tree + * Path is a single or multi-level reference to a child node in the tree * representation of data value.

* * ComponentReference[] is a path from a node to a child or decendent node @@ -47,185 +47,185 @@ import org.simantics.databoard.util.URIUtil; IndexReference.class, KeyReference.class, NameReference.class, - ComponentReference.class, + ComponentReference.class, LabelReference.class }) public abstract class ChildReference implements Cloneable { - - - /** - * Create a concatenation of two references. Prefix part is cloned, - * suffix is linked. - * - * @param pathToBeCloned prefix path, or null - * @param ref suffix path, or null - * @return path - */ - public static ChildReference concatenate(ChildReference pathToBeCloned, ChildReference ref) { - if (pathToBeCloned==null) return ref; - ChildReference result = pathToBeCloned.clone(); - if (ref==null) return result; - result.tail().setChildReference(ref); - return result; - } - - /** - * Creates a compilation of individual a references into a one refence. - * - * @param refs - * @return reference or null if there are no elements - */ - public static ChildReference compile(ChildReference ... refs) { - if (refs.length==0) return null; - ChildReference first = refs[0].clone(); - ChildReference r = first; - for (int i=1; inull if there are no elements - */ - public static ChildReference compile(Collection refs) { - if (refs.isEmpty()) return null; - Iterator itr = refs.iterator(); - ChildReference first = itr.next().clone(); - ChildReference r = first; - for (; itr.hasNext(); ) { - ChildReference next = itr.next().clone(); - r.setChildReference( next ); - r = next; - while(r.childReference!=null) r = r.childReference; - } - return first; - } - - /** - * Get reference path from AccessorReference path. - * Path Notation - * - * @param path - * @return reference path or null if there is no path - */ - public static ChildReference parsePath(String path) { - StringTokenizer st = new StringTokenizer(path, "/", false); - if (!st.hasMoreTokens()) return null; - ChildReference first = createSingleReference( st.nextToken() ); - ChildReference ref = first; - while (st.hasMoreTokens()) { - ref.childReference = createSingleReference(st.nextToken()); - ref = ref.childReference; - } - - return first; - } - - /** - * Attempt to convert value reference to type reference. - * - * @param vref - * @param type - * @return type reference or null - * @throws IllegalArgumentException if conversion fails. - */ - public static ChildReference toTypeReference(ChildReference vref, Datatype type) - throws IllegalArgumentException - { - if (vref==null) return null; - if (type instanceof ArrayType) { - if (vref instanceof IndexReference || vref instanceof LabelReference) { - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); - return new ComponentReference( tail ); - } - } - - if (type instanceof MapType) { - if (vref instanceof KeyReference) { - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(1) ); - return new IndexReference( 1, tail ); - } - } - - if (type instanceof OptionalType) { - if (vref instanceof ComponentReference) { - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); - return new ComponentReference( tail ); - } - if (vref instanceof LabelReference) { - LabelReference lr = (LabelReference) vref; - if (lr.label.equals("v")) { - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); - return new ComponentReference( tail ); - } - } - } - - if (type instanceof RecordType) { - RecordType rt = (RecordType) type; - if (vref instanceof IndexReference) { - IndexReference ir = (IndexReference) vref; - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(ir.index) ); - return new IndexReference( ir.index, tail ); - } - - if (vref instanceof NameReference) { - NameReference ir = (NameReference) vref; - ChildReference tail = toTypeReference( vref.childReference, rt.getComponentType(ir.name) ); - return new NameReference( ir.name, tail ); - } - - if (vref instanceof LabelReference) { - LabelReference ir = (LabelReference) vref; - ChildReference tail = toTypeReference( vref.childReference, rt.getComponentType(ir.label) ); - return new NameReference( ir.label, tail ); - } - } - - if (type instanceof UnionType) { - UnionType ut = (UnionType) type; - if (vref instanceof IndexReference) { - IndexReference ir = (IndexReference) vref; - ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(ir.index) ); - return new IndexReference( ir.index, tail ); - } - - if (vref instanceof NameReference) { - NameReference ir = (NameReference) vref; - ChildReference tail = toTypeReference( vref.childReference, ut.getComponentType(ir.name) ); - return new NameReference( ir.name, tail ); - } - - if (vref instanceof LabelReference) { - LabelReference ir = (LabelReference) vref; - ChildReference tail = toTypeReference( vref.childReference, ut.getComponentType(ir.label) ); - return new NameReference( ir.label, tail ); - } - } - - - throw new IllegalArgumentException(); - } - - public static ChildReference parseBinary(byte[] binaryRef) - throws IOException - { - Binding binding = Bindings.getBindingUnchecked(ChildReference.class); - ChildReference result; - result = (ChildReference) Bindings.getSerializerUnchecked( binding ).deserialize(binaryRef); - return result; - } - - public final static Pattern INDEX_PATTERN = Pattern.compile("i-(\\d*)"); - public final static Pattern MAP_PATTERN = Pattern.compile("k-(\\p{ASCII}*)"); - public final static Pattern NAME_PATTERN = Pattern.compile("n-(\\p{ASCII}*)"); + + + /** + * Create a concatenation of two references. Prefix part is cloned, + * suffix is linked. + * + * @param pathToBeCloned prefix path, or null + * @param ref suffix path, or null + * @return path + */ + public static ChildReference concatenate(ChildReference pathToBeCloned, ChildReference ref) { + if (pathToBeCloned==null) return ref; + ChildReference result = pathToBeCloned.clone(); + if (ref==null) return result; + result.tail().setChildReference(ref); + return result; + } + + /** + * Creates a compilation of individual a references into a one refence. + * + * @param refs + * @return reference or null if there are no elements + */ + public static ChildReference compile(ChildReference ... refs) { + if (refs.length==0) return null; + ChildReference first = refs[0].clone(); + ChildReference r = first; + for (int i=1; inull if there are no elements + */ + public static ChildReference compile(Collection refs) { + if (refs.isEmpty()) return null; + Iterator itr = refs.iterator(); + ChildReference first = itr.next().clone(); + ChildReference r = first; + for (; itr.hasNext(); ) { + ChildReference next = itr.next().clone(); + r.setChildReference( next ); + r = next; + while(r.childReference!=null) r = r.childReference; + } + return first; + } + + /** + * Get reference path from AccessorReference path. + * Path Notation + * + * @param path + * @return reference path or null if there is no path + */ + public static ChildReference parsePath(String path) { + StringTokenizer st = new StringTokenizer(path, "/", false); + if (!st.hasMoreTokens()) return null; + ChildReference first = createSingleReference( st.nextToken() ); + ChildReference ref = first; + while (st.hasMoreTokens()) { + ref.childReference = createSingleReference(st.nextToken()); + ref = ref.childReference; + } + + return first; + } + + /** + * Attempt to convert value reference to type reference. + * + * @param vref + * @param type + * @return type reference or null + * @throws IllegalArgumentException if conversion fails. + */ + public static ChildReference toTypeReference(ChildReference vref, Datatype type) + throws IllegalArgumentException + { + if (vref==null) return null; + if (type instanceof ArrayType) { + if (vref instanceof IndexReference || vref instanceof LabelReference) { + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); + return new ComponentReference( tail ); + } + } + + if (type instanceof MapType) { + if (vref instanceof KeyReference) { + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(1) ); + return new IndexReference( 1, tail ); + } + } + + if (type instanceof OptionalType) { + if (vref instanceof ComponentReference) { + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); + return new ComponentReference( tail ); + } + if (vref instanceof LabelReference) { + LabelReference lr = (LabelReference) vref; + if (lr.label.equals("v")) { + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(0) ); + return new ComponentReference( tail ); + } + } + } + + if (type instanceof RecordType) { + RecordType rt = (RecordType) type; + if (vref instanceof IndexReference) { + IndexReference ir = (IndexReference) vref; + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(ir.index) ); + return new IndexReference( ir.index, tail ); + } + + if (vref instanceof NameReference) { + NameReference ir = (NameReference) vref; + ChildReference tail = toTypeReference( vref.childReference, rt.getComponentType(ir.name) ); + return new NameReference( ir.name, tail ); + } + + if (vref instanceof LabelReference) { + LabelReference ir = (LabelReference) vref; + ChildReference tail = toTypeReference( vref.childReference, rt.getComponentType(ir.label) ); + return new NameReference( ir.label, tail ); + } + } + + if (type instanceof UnionType) { + UnionType ut = (UnionType) type; + if (vref instanceof IndexReference) { + IndexReference ir = (IndexReference) vref; + ChildReference tail = toTypeReference( vref.childReference, type.getComponentType(ir.index) ); + return new IndexReference( ir.index, tail ); + } + + if (vref instanceof NameReference) { + NameReference ir = (NameReference) vref; + ChildReference tail = toTypeReference( vref.childReference, ut.getComponentType(ir.name) ); + return new NameReference( ir.name, tail ); + } + + if (vref instanceof LabelReference) { + LabelReference ir = (LabelReference) vref; + ChildReference tail = toTypeReference( vref.childReference, ut.getComponentType(ir.label) ); + return new NameReference( ir.label, tail ); + } + } + + + throw new IllegalArgumentException(); + } + + public static ChildReference parseBinary(byte[] binaryRef) + throws IOException + { + Binding binding = Bindings.getBindingUnchecked(ChildReference.class); + ChildReference result; + result = (ChildReference) Bindings.getSerializerUnchecked( binding ).deserialize(binaryRef); + return result; + } + + public final static Pattern INDEX_PATTERN = Pattern.compile("i-(\\d*)"); + public final static Pattern MAP_PATTERN = Pattern.compile("k-(\\p{ASCII}*)"); + public final static Pattern NAME_PATTERN = Pattern.compile("n-(\\p{ASCII}*)"); public @Optional ChildReference childReference; @@ -237,74 +237,74 @@ public abstract class ChildReference implements Cloneable { public ChildReference getChildReference() { return childReference; - } - - public boolean hasChildReference() { - return childReference != null; - } + } + + public boolean hasChildReference() { + return childReference != null; + } public void setChildReference(ChildReference childReference) { this.childReference = childReference; - } - - public int getDepth() { - int result = 1; - ChildReference r = this; - while ( r.childReference != null ) { - r = r.childReference; - result++; - } - return result; - } - - public String toPath() { - return toPath(true); - } - - /** - * Converts the reference path into string representation. - * - * @param labelReference if true return label references. - * @return path string representation - */ - public String toPath(boolean labelReference) { - if (childReference == null) return toString(); - StringBuilder sb = new StringBuilder(); - ChildReference ref = this; - while (ref!=null) { - if (sb.length() > 0) sb.append("/"); - sb.append( ref.toString(labelReference) ); - ref = ref.getChildReference(); - } - return sb.toString(); - } - - /** - * Convert the reference into its string representation - * - * @return reference string representation + } + + public int getDepth() { + int result = 1; + ChildReference r = this; + while ( r.childReference != null ) { + r = r.childReference; + result++; + } + return result; + } + + public String toPath() { + return toPath(true); + } + + /** + * Converts the reference path into string representation. + * + * @param labelReference if true return label references. + * @return path string representation + */ + public String toPath(boolean labelReference) { + if (childReference == null) return toString(); + StringBuilder sb = new StringBuilder(); + ChildReference ref = this; + while (ref!=null) { + if (sb.length() > 0) sb.append("/"); + sb.append( ref.toString(labelReference) ); + ref = ref.getChildReference(); + } + return sb.toString(); + } + + /** + * Convert the reference into its string representation + * + * @return reference string representation */ - public String toString() { - return toString(true); - } - - /** - * Convert the reference into string representation.

- * - * If labelReference is true, the string representation is - * more user readable but has weaker typing. It serializes into - * instances of LabelReference. - * - * For instance Record Field Reference is "n-Children", but label reference "Children". - * - * Some references cannot be converted into LabelReference. - * E.g. string representation of FieldNameReference("i-5") is ambiguous with ArrayIndexReference(5). - * - * @param labelReference if true returns - * @return string representation - */ - public abstract String toString(boolean labelReference); - + public String toString() { + return toString(true); + } + + /** + * Convert the reference into string representation.

+ * + * If labelReference is true, the string representation is + * more user readable but has weaker typing. It serializes into + * instances of LabelReference. + * + * For instance Record Field Reference is "n-Children", but label reference "Children". + * + * Some references cannot be converted into LabelReference. + * E.g. string representation of FieldNameReference("i-5") is ambiguous with ArrayIndexReference(5). + * + * @param labelReference if true returns + * @return string representation + */ + public abstract String toString(boolean labelReference); + public abstract ChildReference clone(); public ChildReference tail() { @@ -312,49 +312,49 @@ public abstract class ChildReference implements Cloneable { while (result.childReference!=null) result = result.childReference; return result; } - - /** - * Create accessor reference from string representation. - * This doesn't parse path separators. - * - * @see https://www.simantics.org/wiki/index.php/Databoard_Specification#Accessor_Reference - * - * @param ref - * @return - */ - static ChildReference createSingleReference(String ref) { - Matcher m; - - m = INDEX_PATTERN.matcher( ref ); - if (m.matches()) { - return new IndexReference( Integer.parseInt( m.group(1) ) ); - } - - m = MAP_PATTERN.matcher( ref ); - if (m.matches()) { - String keyStr = m.group(1); - MutableVariant key; - try { - key = (MutableVariant) Bindings.adapt(keyStr, Bindings.STRING, Bindings.MUTABLE_VARIANT); - } catch (AdaptException e) { - throw new IllegalArgumentException("Not string variant "+ref, e); - } - return new KeyReference(key); - } - - m = NAME_PATTERN.matcher( ref ); - if (m.matches()) { - String encoded = m.group(1); - String name = URIUtil.decodeURI(encoded); - return new NameReference( name ); - } - - if (ref.equals("v")) { - return new ComponentReference(); - } - - String text = URIUtil.decodeURI( ref ); - return new LabelReference( text ); + + /** + * Create accessor reference from string representation. + * This doesn't parse path separators. + * + * @see https://www.simantics.org/wiki/index.php/Databoard_Specification#Accessor_Reference + * + * @param ref + * @return + */ + static ChildReference createSingleReference(String ref) { + Matcher m; + + m = INDEX_PATTERN.matcher( ref ); + if (m.matches()) { + return new IndexReference( Integer.parseInt( m.group(1) ) ); + } + + m = MAP_PATTERN.matcher( ref ); + if (m.matches()) { + String keyStr = m.group(1); + MutableVariant key; + try { + key = (MutableVariant) Bindings.adapt(keyStr, Bindings.STRING, Bindings.MUTABLE_VARIANT); + } catch (AdaptException e) { + throw new IllegalArgumentException("Not string variant "+ref, e); + } + return new KeyReference(key); + } + + m = NAME_PATTERN.matcher( ref ); + if (m.matches()) { + String encoded = m.group(1); + String name = URIUtil.decodeURI(encoded); + return new NameReference( name ); + } + + if (ref.equals("v")) { + return new ComponentReference(); + } + + String text = URIUtil.decodeURI( ref ); + return new LabelReference( text ); } }