package fi.vtt.simantics.procore.internal; import gnu.trove.map.hash.THashMap; import java.lang.ref.SoftReference; import java.util.HashSet; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ValidationException; import org.simantics.db.impl.ClusterBase; import org.simantics.db.impl.ClusterSupport; import org.simantics.db.impl.ResourceImpl; import org.simantics.db.impl.support.BuiltinSupport; import org.simantics.db.procore.cluster.ClusterTraits; import org.simantics.db.service.ClusterUID; import org.simantics.db.service.InitSupport; import org.simantics.graph.db.CoreInitialization; public class BuiltinSupportImpl implements BuiltinSupport { private final boolean DEBUG = false; private final SessionImplSocket session; private ClusterBase builtinCluster; private THashMap builtinMap; BuiltinSupportImpl(SessionImplSocket session) { this.session = session; this.builtinMap = null; this.builtinCluster = null; } @Override public int getBuiltin(String uri) { try { ResourceImpl impl = getBuiltinResource(uri); if (impl != null) return impl.id; } catch (DatabaseException e) { if (DEBUG) e.printStackTrace(); Logger.defaultLogError("Failed to get builtin for " + uri, e); } return 0; } private ResourceImpl getBuiltinResource(String name) throws DatabaseException { Logger.defaultLogTrace("Asking for builtin " + name); synchronized (this) { if (null == builtinMap) { ClusterSupport cs = session.getService(ClusterSupport.class); builtinCluster = cs.getClusterByClusterUIDOrMake(ClusterUID.Builtin); builtinMap = initBuiltinMap(); } } ResourceImpl resource = null; BuiltinData builtin = null; synchronized (this) { builtin = builtinMap.get(name); if (null == builtin) { Logger.defaultLogInfo("Asking for missing builtin " + name); return null; } if (null != builtin.weakResource) { resource = builtin.weakResource.get(); if (resource != null) return resource; } } int id = ClusterTraits.createResourceKey(builtinCluster.getClusterKey(), builtin.index); resource = session.getResource(id); if (null == resource) throw new ValidationException("Builtin not found index=" + builtin.index); builtin.weakResource = new SoftReference(resource); return resource; } private THashMap initBuiltinMap() throws DatabaseException { THashMap builtins = new THashMap(); HashSet t = CoreInitialization.getBuiltins(); int size = t.size(); for (InitSupport.Builtin b : t) { if (b.index < 1 || b.index > size) throw new ValidationException("Illegal builtin resource index=" + b.index); BuiltinData bd = new BuiltinData(b.index); builtins.put(b.uri, bd); } return builtins; } static class BuiltinData { final int index; // resource index SoftReference weakResource = null; BuiltinData(int index) { this.index = index; } } }