/******************************************************************************* * Copyright (c) 2007, 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.db.layer0.adapter.impl; import java.util.ArrayList; import java.util.Collections; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.common.primitiverequest.Superrelations; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncMultiListener; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.ResourceAsyncMultiRead; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.layer0.Layer0; public class EntitySubgraphExtent extends TypeSubgraphExtent { public static boolean DEBUG = false; static class DefinedRelationSet extends ResourceAsyncMultiRead { public DefinedRelationSet(Resource type) { super(type); } public void forType(AsyncReadGraph graph, Resource type, final AsyncMultiProcedure procedure, final AtomicInteger ready) { final Layer0 l0 = graph.getService(Layer0.class); ready.incrementAndGet(); graph.forEachObject(type, l0.HasPropertyDefinition, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, Resource def) { ready.incrementAndGet(); graph.forPossibleObject(def, l0.ConcernsRelation, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource relation) { if(relation != null) procedure.execute(graph, relation); if(ready.decrementAndGet() == 0) procedure.finished(graph); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } }); } @Override public void finished(AsyncReadGraph graph) { if(ready.decrementAndGet() == 0) procedure.finished(graph); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } }); } @Override public void perform(AsyncReadGraph graph, final AsyncMultiProcedure procedure) { final AtomicInteger ready = new AtomicInteger(1); forType(graph, resource, procedure, ready); graph.forSupertypes(resource, new AsyncProcedure>() { @Override public void execute(AsyncReadGraph graph, Set types) { for(Resource type : types) forType(graph, type, procedure, ready); if(ready.decrementAndGet() == 0) procedure.finished(graph); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } }); } } @Override public void accept(AsyncReadGraph graph, final Resource resource, final AsyncProcedure procedure, final Callback callback) { final AtomicInteger ready = new AtomicInteger(1); class Result extends TransientCacheAsyncMultiListener implements Classifier { final ArrayList predicates = new ArrayList(); @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } @Override public void execute(AsyncReadGraph graph, Resource predicate) { synchronized(predicates) { predicates.add(predicate); } } @Override public void finished(AsyncReadGraph graph) { if(ready.decrementAndGet() == 0) procedure.execute(graph, this); } @Override public void classify(AsyncReadGraph graph, final Statement statement, ExtentStatus objectExtent, final Callback callback) { if(DEBUG) { graph.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println("classify " + NameUtils.toString(graph, statement)); } }); } // TODO haxx final Resource p = statement.getPredicate(); if(graph.getService(Layer0.class).PartOf.equals(p) && !ExtentStatus.INTERNAL.equals(objectExtent)) return; // TODO haxx2 if(ExtentStatus.EXCLUDED.equals(objectExtent)) return; if(predicates.contains(p)) { callback.statement(statement, true); if(DEBUG) { graph.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println("-accept " + NameUtils.toString(graph, statement)); } }); } return; } graph.forDirectSuperrelations(p, new AsyncMultiProcedure() { @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } @Override public void execute(AsyncReadGraph graph, final Resource superRelation) { if(predicates.contains(superRelation)) { callback.statement(statement, true); if(DEBUG) { graph.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println("-accept " + NameUtils.toString(graph, statement)); } }); } return; } graph.asyncRequest(new Superrelations(superRelation), new AsyncProcedure>() { @Override public void exception(AsyncReadGraph graph, Throwable t) { t.printStackTrace(); } @Override public void execute(AsyncReadGraph graph, Set supers) { if(!Collections.disjoint(supers, predicates)) { if(DEBUG) { graph.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println("-accept " + NameUtils.toString(graph, statement)); } }); } callback.statement(statement, true); } } }); } @Override public void finished(AsyncReadGraph graph) { } }); } }; final Result result = new Result(); graph.forEachPrincipalType(resource, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, Resource type) { ready.incrementAndGet(); graph.asyncRequest(new DefinedRelationSet(type), result); } @Override public void finished(AsyncReadGraph graph) { if(ready.decrementAndGet() == 0) procedure.execute(graph, result); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); } }); } }