/******************************************************************************* * 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.binding.util; import java.util.IdentityHashMap; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.BooleanType; import org.simantics.databoard.type.ByteType; import org.simantics.databoard.type.Component; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.type.Datatype.Visitor; import org.simantics.databoard.type.DoubleType; import org.simantics.databoard.type.FloatType; import org.simantics.databoard.type.IntegerType; 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.StringType; import org.simantics.databoard.type.UnionType; import org.simantics.databoard.type.VariantType; public class IsReferableQuery implements Visitor { public static Result isReferable(Datatype type) { IsReferableQuery query = new IsReferableQuery(); Result result = type.accept(query); return result; } IdentityHashMap visited = new IdentityHashMap(); @Override public Result visit(ArrayType b) { visited.put(b, Result.No); Datatype ct = b.componentType(); Result cr = visited.get(ct); if (cr!=null) return cr; cr = ct.accept(this); if (cr!=Result.No) visited.put(b, cr); return cr; } @Override public Result visit(BooleanType b) { return null; } @Override public Result visit(DoubleType b) { return null; } @Override public Result visit(FloatType b) { return null; } @Override public Result visit(IntegerType b) { return null; } @Override public Result visit(ByteType b) { return null; } @Override public Result visit(LongType b) { return null; } @Override public Result visit(OptionalType b) { visited.put(b, Result.No); Datatype ct = b.getComponentType(); Result cr = visited.get(ct); if (cr!=null) return cr; cr = ct.accept(this); if (cr!=Result.No) visited.put(b, cr); return cr; } @Override public Result visit(RecordType b) { if (b.isReferable()) { visited.put(b, Result.Yes); return Result.Yes; } Result result = Result.No; visited.put(b, result); for (Component c : b.getComponents()) { Datatype ct = c.type; Result cr = visited.get(ct); if (cr==null) cr = ct.accept(this); if (cr!=null) { if (cr == Result.Yes) { result = cr; break; } if (cr == Result.Possible) { result = cr; } } } if (result!=Result.No) visited.put(b, result); return result; } @Override public Result visit(StringType b) { return Result.No; } @Override public Result visit(UnionType b) { Result result = Result.No; visited.put(b, result); for (Component c : b.getComponents()) { Datatype ct = c.type; Result cr = visited.get(ct); if (cr==null) cr = ct.accept(this); if (cr!=null) { if (cr == Result.Yes) { result = cr; break; } if (cr == Result.Possible) { result = cr; } } } if (result!=Result.No) visited.put(b, result); return result; } @Override public Result visit(VariantType b) { return Result.Possible; } @Override public Result visit(MapType b) { visited.put(b, Result.No); Datatype kt = b.keyType; Result kr = visited.get(kt); if (kr == null) kr = kt.accept(this); Datatype vt = b.valueType; Result vr = visited.get(vt); if (vr == null) vr = vt.accept(this); Result result = Result.No; if (kr==Result.Yes || vr==Result.Yes) result = Result.Yes; else if (kr==Result.Possible || vr==Result.Possible) result = Result.Possible; if (result!=Result.No) visited.put(b, Result.No); return result; } }