X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Futils%2FTGResourceUtil.java;h=fea3be9859a49a1eb00b7b10d846f85207c3ab03;hb=1941a8f086ccdc3017c84dd149418114a499aee4;hp=245f2683852eeec240415962115939aa03a3aad2;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/utils/TGResourceUtil.java b/bundles/org.simantics.graph/src/org/simantics/graph/utils/TGResourceUtil.java index 245f26838..fea3be985 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/utils/TGResourceUtil.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/utils/TGResourceUtil.java @@ -1,398 +1,398 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 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.graph.utils; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import org.simantics.databoard.Accessors; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.accessor.Accessor; -import org.simantics.databoard.accessor.ArrayAccessor; -import org.simantics.databoard.accessor.LongAccessor; -import org.simantics.databoard.accessor.MapAccessor; -import org.simantics.databoard.accessor.OptionalAccessor; -import org.simantics.databoard.accessor.RecordAccessor; -import org.simantics.databoard.accessor.UnionAccessor; -import org.simantics.databoard.accessor.VariantAccessor; -import org.simantics.databoard.accessor.error.AccessorConstructionException; -import org.simantics.databoard.accessor.error.AccessorException; -import org.simantics.databoard.accessor.reference.ChildReference; -import org.simantics.databoard.accessor.reference.ComponentReference; -import org.simantics.databoard.accessor.reference.IndexReference; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.LongType; -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.type.VariantType; -import org.simantics.databoard.util.DatatypeVisitorAdapter; - -/** - * Util for converting all the Long values in a TG, that have metadata "resource=true". - * - * @author toni.kalajainen - */ -public class TGResourceUtil { - - public static final Datatype RESOURCE_TYPE; - - Map items = new HashMap(); - int index = 0; - - /** - * Add type to the cache and get some info. - * - * @param type - * @return - */ - public Item createItem( Datatype type ) - { - Item item = new Item(); - item.index = index++; - item.type = type; - HasResVisitor v = new HasResVisitor(); - type.accept( v, item ); - if ( v.hasRes || v.hasVariant ) { - GetRefsVisitor vv = new GetRefsVisitor(); - type.accept( vv, item ); - } - return item; - } - - - /** - * Find all resources in the value. The resources are added to the result-collection. - * It may be good to idea to use a Set to avoid duplicate values. - * - * @param type - * @param value - * @param result - * @throws AccessorException - * @throws AccessorConstructionException - */ - public void findResources( Datatype type, byte[] value, final Collection result) throws AccessorConstructionException, AccessorException - { - LongAdapter la = new LongAdapter() { - @Override - public long adapt(long in) { - result.add(in); - // Return same value - return in; - } - }; - - adaptValue( type, value, la ); - } - - public void findResources( Binding binding, Object value, final Collection result) throws AccessorConstructionException, AccessorException - { - LongAdapter la = new LongAdapter() { - @Override - public long adapt(long in) { - result.add(in); - // Return same value - return in; - } - }; - - adaptValue( binding, value, la ); - } - - /** - * Add type to the util. - * @param type - * @return - */ - public Item addType( Datatype type ) - { - Item i = items.get( type ); - if ( i==null ) { - i = createItem(type); - items.put(type, i); - } - return i; - } - - public void adaptValue( Datatype type, byte[] value, LongAdapter adapter ) throws AccessorException - { - Item i = addType( type ); - if (!i.mayHaveResource()) return; - try { - Accessor a = Accessors.getAccessor(value, type); - adaptValue(i, a, adapter); - } catch (AccessorConstructionException e) { - throw new AccessorException(e); - } - } - - public boolean mayHaveResource( Datatype type ) { - Item i = addType( type ); - return i.mayHaveResource(); - } - - public void adaptValue( Binding binding, Object value, LongAdapter adapter ) throws AccessorException - { - Item i = addType( binding.type() ); - if (!i.mayHaveResource()) return; - try { - Accessor a = Accessors.getAccessor(binding, value); - adaptValue(i, a, adapter); - } catch (AccessorConstructionException e) { - throw new AccessorException(e); - } - } - - void adaptValue( Item i, Accessor a, LongAdapter adapter ) throws AccessorException, AccessorConstructionException - { - if ( i.resources != null ) { - for (ChildReference r : i.resources) - { - adaptValue(a, r, adapter); - } - } - if ( i.variants != null ) { - for (ChildReference r : i.variants) - { - adaptValue(a, r, adapter); - } - } - } - - void adaptValue( Accessor a, ChildReference r, LongAdapter adapter ) throws AccessorException, AccessorConstructionException - { - if ( a instanceof LongAccessor ) { - LongAccessor x = (LongAccessor) a; - long value = x.getValue(); - long newValue = adapter.adapt( value ); - if ( newValue != value ) x.setValue( newValue ); - } - - if ( a instanceof VariantAccessor ) { - VariantAccessor x = (VariantAccessor) a; - Item i = createItem( x.getContentType() ); - adaptValue(i, x.getContentAccessor(), adapter); - } - - if ( a instanceof MapAccessor ) { - MapAccessor x = (MapAccessor) a; - if (r instanceof IndexReference) { - IndexReference ir = (IndexReference) r; - // Resource is in the Key - if (ir.index==0) { - // Read the key as whole - Binding keyBinding = Bindings.getBinding( x.type().keyType ); - Binding valueBinding = Bindings.getBinding( x.type().valueType ); - Object[] keys = x.getKeys(keyBinding); - for ( Object key : keys ) { - Object value = x.get(keyBinding, key, valueBinding); - // Fix the key - Accessor ka = Accessors.getAccessor(keyBinding, key); - adaptValue(ka, r.childReference, adapter); - - // Write - x.remove(keyBinding, key); - x.put(keyBinding, key, valueBinding, value); - } - } - - // Resource is in the value - if (ir.index==1) { - Binding keyBinding = Bindings.getBinding( x.type().keyType ); - Object[] keys = x.getKeys(keyBinding); - for ( Object key : keys ) { - Accessor va = x.getValueAccessor(keyBinding, key); - adaptValue(va, r.childReference, adapter); - } - } - } - } - - if ( a instanceof ArrayAccessor ) { - ArrayAccessor x = (ArrayAccessor) a; - int len = x.size(); - for (int i=0; i variants; - // Locations of resources in Datatype - List resources; - - public boolean mayHaveResource() { - return (variants!=null&&!variants.isEmpty()) || - (resources!=null&&!resources.isEmpty()); - } - - void addVariant(ChildReference ref) { - if ( variants == null ) variants = new ArrayList(); - variants.add(ref); - } - - void addResource(ChildReference ref) { - if ( resources == null ) resources = new ArrayList(); - resources.add( ref ); - } - } - - static { - RESOURCE_TYPE = new LongType(); - RESOURCE_TYPE.metadata.put("resource", "true"); - } - - /** - * This visitor makes a quick peek to see if there is resource or variants. - */ - static class HasResVisitor extends DatatypeVisitorAdapter { - - boolean hasRes = false, hasVariant = false; - - @Override - public void visit(VariantType b, Object obj) { - hasVariant = true; - } - - @Override - public void visit(LongType b, Object obj) { - String s = b.metadata.get("unit"); - hasRes |= s!=null && s.equals("resource"); - } - - } - - static class GetRefsVisitor extends DatatypeVisitorAdapter { - - Stack stack = new Stack(); - - @Override - public void visit(ArrayType b, Object obj) { - if ( !visited.add(b) ) return; - - ComponentReference r = new ComponentReference(); - stack.push(r); - b.componentType.accept(this, obj); - stack.pop(); - } - - @Override - public void visit(LongType b, Object obj) { - String s = b.metadata.get("unit"); - boolean isRes = s!=null && s.equals("resource"); - if ( isRes ) { - Item item = (Item) obj; - item.addResource( toRef() ); - } - } - @Override - public void visit(MapType b, Object obj) { - if ( !visited.add(b) ) return; - - IndexReference r = new IndexReference(0); - stack.push(r); - b.keyType.accept(this, obj); - stack.pop(); - r.index = 1; - stack.push(r); - b.valueType.accept(this, obj); - stack.pop(); - } - @Override - public void visit(OptionalType b, Object obj) { - if ( !visited.add(b) ) return; - - ComponentReference r = new ComponentReference(); - stack.push(r); - b.componentType.accept(this, obj); - stack.pop(); - } - @Override - public void visit(RecordType b, Object obj) { - if ( !visited.add(b) ) return; - - IndexReference r = new IndexReference(0); - stack.push(r); - for (int i=0; i items = new HashMap(); + int index = 0; + + /** + * Add type to the cache and get some info. + * + * @param type + * @return + */ + public Item createItem( Datatype type ) + { + Item item = new Item(); + item.index = index++; + item.type = type; + HasResVisitor v = new HasResVisitor(); + type.accept( v, item ); + if ( v.hasRes || v.hasVariant ) { + GetRefsVisitor vv = new GetRefsVisitor(); + type.accept( vv, item ); + } + return item; + } + + + /** + * Find all resources in the value. The resources are added to the result-collection. + * It may be good to idea to use a Set to avoid duplicate values. + * + * @param type + * @param value + * @param result + * @throws AccessorException + * @throws AccessorConstructionException + */ + public void findResources( Datatype type, byte[] value, final Collection result) throws AccessorConstructionException, AccessorException + { + LongAdapter la = new LongAdapter() { + @Override + public long adapt(long in) { + result.add(in); + // Return same value + return in; + } + }; + + adaptValue( type, value, la ); + } + + public void findResources( Binding binding, Object value, final Collection result) throws AccessorConstructionException, AccessorException + { + LongAdapter la = new LongAdapter() { + @Override + public long adapt(long in) { + result.add(in); + // Return same value + return in; + } + }; + + adaptValue( binding, value, la ); + } + + /** + * Add type to the util. + * @param type + * @return + */ + public Item addType( Datatype type ) + { + Item i = items.get( type ); + if ( i==null ) { + i = createItem(type); + items.put(type, i); + } + return i; + } + + public void adaptValue( Datatype type, byte[] value, LongAdapter adapter ) throws AccessorException + { + Item i = addType( type ); + if (!i.mayHaveResource()) return; + try { + Accessor a = Accessors.getAccessor(value, type); + adaptValue(i, a, adapter); + } catch (AccessorConstructionException e) { + throw new AccessorException(e); + } + } + + public boolean mayHaveResource( Datatype type ) { + Item i = addType( type ); + return i.mayHaveResource(); + } + + public void adaptValue( Binding binding, Object value, LongAdapter adapter ) throws AccessorException + { + Item i = addType( binding.type() ); + if (!i.mayHaveResource()) return; + try { + Accessor a = Accessors.getAccessor(binding, value); + adaptValue(i, a, adapter); + } catch (AccessorConstructionException e) { + throw new AccessorException(e); + } + } + + void adaptValue( Item i, Accessor a, LongAdapter adapter ) throws AccessorException, AccessorConstructionException + { + if ( i.resources != null ) { + for (ChildReference r : i.resources) + { + adaptValue(a, r, adapter); + } + } + if ( i.variants != null ) { + for (ChildReference r : i.variants) + { + adaptValue(a, r, adapter); + } + } + } + + void adaptValue( Accessor a, ChildReference r, LongAdapter adapter ) throws AccessorException, AccessorConstructionException + { + if ( a instanceof LongAccessor ) { + LongAccessor x = (LongAccessor) a; + long value = x.getValue(); + long newValue = adapter.adapt( value ); + if ( newValue != value ) x.setValue( newValue ); + } + + if ( a instanceof VariantAccessor ) { + VariantAccessor x = (VariantAccessor) a; + Item i = createItem( x.getContentType() ); + adaptValue(i, x.getContentAccessor(), adapter); + } + + if ( a instanceof MapAccessor ) { + MapAccessor x = (MapAccessor) a; + if (r instanceof IndexReference) { + IndexReference ir = (IndexReference) r; + // Resource is in the Key + if (ir.index==0) { + // Read the key as whole + Binding keyBinding = Bindings.getBinding( x.type().keyType ); + Binding valueBinding = Bindings.getBinding( x.type().valueType ); + Object[] keys = x.getKeys(keyBinding); + for ( Object key : keys ) { + Object value = x.get(keyBinding, key, valueBinding); + // Fix the key + Accessor ka = Accessors.getAccessor(keyBinding, key); + adaptValue(ka, r.childReference, adapter); + + // Write + x.remove(keyBinding, key); + x.put(keyBinding, key, valueBinding, value); + } + } + + // Resource is in the value + if (ir.index==1) { + Binding keyBinding = Bindings.getBinding( x.type().keyType ); + Object[] keys = x.getKeys(keyBinding); + for ( Object key : keys ) { + Accessor va = x.getValueAccessor(keyBinding, key); + adaptValue(va, r.childReference, adapter); + } + } + } + } + + if ( a instanceof ArrayAccessor ) { + ArrayAccessor x = (ArrayAccessor) a; + int len = x.size(); + for (int i=0; i variants; + // Locations of resources in Datatype + List resources; + + public boolean mayHaveResource() { + return (variants!=null&&!variants.isEmpty()) || + (resources!=null&&!resources.isEmpty()); + } + + void addVariant(ChildReference ref) { + if ( variants == null ) variants = new ArrayList(); + variants.add(ref); + } + + void addResource(ChildReference ref) { + if ( resources == null ) resources = new ArrayList(); + resources.add( ref ); + } + } + + static { + RESOURCE_TYPE = new LongType(); + RESOURCE_TYPE.metadata.put("resource", "true"); + } + + /** + * This visitor makes a quick peek to see if there is resource or variants. + */ + static class HasResVisitor extends DatatypeVisitorAdapter { + + boolean hasRes = false, hasVariant = false; + + @Override + public void visit(VariantType b, Object obj) { + hasVariant = true; + } + + @Override + public void visit(LongType b, Object obj) { + String s = b.metadata.get("unit"); + hasRes |= s!=null && s.equals("resource"); + } + + } + + static class GetRefsVisitor extends DatatypeVisitorAdapter { + + Stack stack = new Stack(); + + @Override + public void visit(ArrayType b, Object obj) { + if ( !visited.add(b) ) return; + + ComponentReference r = new ComponentReference(); + stack.push(r); + b.componentType.accept(this, obj); + stack.pop(); + } + + @Override + public void visit(LongType b, Object obj) { + String s = b.metadata.get("unit"); + boolean isRes = s!=null && s.equals("resource"); + if ( isRes ) { + Item item = (Item) obj; + item.addResource( toRef() ); + } + } + @Override + public void visit(MapType b, Object obj) { + if ( !visited.add(b) ) return; + + IndexReference r = new IndexReference(0); + stack.push(r); + b.keyType.accept(this, obj); + stack.pop(); + r.index = 1; + stack.push(r); + b.valueType.accept(this, obj); + stack.pop(); + } + @Override + public void visit(OptionalType b, Object obj) { + if ( !visited.add(b) ) return; + + ComponentReference r = new ComponentReference(); + stack.push(r); + b.componentType.accept(this, obj); + stack.pop(); + } + @Override + public void visit(RecordType b, Object obj) { + if ( !visited.add(b) ) return; + + IndexReference r = new IndexReference(0); + stack.push(r); + for (int i=0; i