
io.continual.services.model.impl.common.SimpleTraversal Maven / Gradle / Ivy
package io.continual.services.model.impl.common;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeSet;
import io.continual.services.model.core.Model;
import io.continual.services.model.core.ModelItemFilter;
import io.continual.services.model.core.ModelPathList;
import io.continual.services.model.core.ModelRelation;
import io.continual.services.model.core.ModelRequestContext;
import io.continual.services.model.core.ModelTraversal;
import io.continual.services.model.core.data.BasicModelObject;
import io.continual.services.model.core.data.ModelObject;
import io.continual.services.model.core.exceptions.ModelRequestException;
import io.continual.services.model.core.exceptions.ModelServiceException;
import io.continual.util.naming.Path;
/**
* A simple, non-optimized traversal implementation
*/
public class SimpleTraversal implements ModelTraversal
{
public SimpleTraversal ( Model m )
{
fModel = m;
fStart = null;
fSteps = new LinkedList<>();
}
@Override
public ModelTraversal startAt ( Path p )
{
fStart = Collections.singleton ( p );
return this;
}
@Override
public ModelTraversal startWith ( Set p )
{
fStart = p;
return this;
}
@Override
public ModelTraversal traverseOutbound ( String relation )
{
fSteps.add ( new Step ()
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException
{
final TreeSet result = new TreeSet<> ();
for ( Path p : sc.fCurrentSet )
{
for ( ModelRelation mr : fModel.selectRelations ( p )
.named ( relation )
.outboundOnly ()
.getRelations ( sc.fMrc )
)
{
result.add ( mr.getTo () );
}
}
sc.replaceSet ( result );
}
} );
return this;
}
@Override
public ModelTraversal traverseInbound ( String relation )
{
fSteps.add ( new Step ()
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException
{
final TreeSet result = new TreeSet<> ();
for ( Path p : sc.fCurrentSet )
{
for ( ModelRelation mr : fModel.selectRelations ( p )
.named ( relation )
.inboundOnly ()
.getRelations ( sc.fMrc )
)
{
result.add ( mr.getFrom () );
}
}
sc.replaceSet ( result );
}
} );
return this;
}
@Override
public ModelTraversal labelSet ( String label )
{
fSteps.add ( new Step ()
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException
{
final TreeSet capture = new TreeSet<> ();
capture.addAll ( sc.fCurrentSet );
sc.fCaptures.put ( label, capture );
}
} );
return this;
}
@Override
public ModelTraversal excludeSet ( String label )
{
fSteps.add ( new Step ()
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException
{
final TreeSet captured = sc.fCaptures.get ( label );
if ( captured != null )
{
final TreeSet newSet = new TreeSet<> ();
for ( Path p : sc.fCurrentSet )
{
if ( !captured.contains ( p ) )
{
newSet.add ( p );
}
}
sc.replaceSet ( newSet );
}
}
} );
return this;
}
@Override
public ModelTraversal filterSet ( ModelItemFilter filter )
{
fSteps.add ( new Step ()
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException
{
final TreeSet newSet = new TreeSet<> ();
for ( Path p : sc.fCurrentSet )
{
final BasicModelObject mo = fModel.load ( sc.fMrc, p );
final ModelObject moda = mo.getData ();
if ( filter.matches ( moda ) )
{
newSet.add ( p );
}
}
sc.replaceSet ( newSet );
}
} );
return this;
}
@Override
public ModelPathList execute ( ModelRequestContext context ) throws ModelRequestException, ModelServiceException
{
if ( fStart.isEmpty () ) throw new ModelRequestException ( "Traversal has no start node." );
final StepContext sc = new StepContext ( context );
sc.fCurrentSet.addAll ( fStart );
for ( Step s : fSteps )
{
s.execute ( sc );
if ( sc.fCurrentSet.size () == 0 )
{
// short circuit this traversal
break;
}
}
return ModelPathList.wrap ( sc.fCurrentSet );
}
private final Model fModel;
private final LinkedList fSteps;
private Set fStart;
private class StepContext
{
public StepContext ( ModelRequestContext mrc ) { fMrc = mrc; }
public void replaceSet ( TreeSet set )
{
fCurrentSet = set;
}
final ModelRequestContext fMrc;
TreeSet fCurrentSet = new TreeSet<> ();
HashMap> fCaptures = new HashMap<>();
};
private interface Step
{
public void execute ( StepContext sc ) throws ModelRequestException, ModelServiceException;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy