package org.simantics.db.layer0.util; import java.util.ArrayList; import org.simantics.databoard.util.URIStringUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.uri.UnescapedChildMapOfResource; import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; public class RelativeReference { public final Resource base; public final String path; public RelativeReference(Resource base, String path) { this.base = base; this.path = path; } public Resource resolve(ReadGraph graph) throws DatabaseException { return resolve(graph, base, path); } public static Resource resolve(ReadGraph graph, Resource base, String path) throws DatabaseException { String[] splitPath = path.split("/"); for(String name : splitPath) { base = graph.syncRequest(new UnescapedChildMapOfResource(base)).get( URIStringUtils.unescape(name) ); if(base == null) return null; } return base; } public static RelativeReference createReference(ReadGraph graph, Resource baseType, Resource resource) throws DatabaseException { ArrayList path = new ArrayList(); Layer0 L0 = Layer0.getInstance(graph); try { while(!graph.isInstanceOf(resource, baseType)) { path.add((String)graph.getRelatedValue(resource, L0.HasName)); resource = graph.getSingleObject(resource, L0.PartOf); } } catch(DatabaseException e) { return null; } StringBuilder b = new StringBuilder(); for(int i=path.size()-1;i>=0;--i) { b.append(URIStringUtils.escape(path.get(i))); if(i > 0) b.append('/'); } return new RelativeReference(resource, b.toString()); } }