package com.cedarsoft.wicket.breadcrumb;
import com.cedarsoft.commons.struct.Node;
import com.cedarsoft.commons.struct.Path;
import com.cedarsoft.commons.struct.Route;
import org.apache.wicket.Page;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
*
*/
public class BreadCrumbElementProvider implements IDataProvider<BreadCrumbElement> {
private static final long serialVersionUID = 4683740027859662761L;
@NotNull
private final PageStructureProvider pageStructureProvider;
@NotNull
private final IModel<Path> pathModel;
public BreadCrumbElementProvider( @NotNull PageStructureProvider pageStructureProvider, @NotNull IModel<Path> pathModel ) {
this.pageStructureProvider = pageStructureProvider;
this.pathModel = pathModel;
}
@NotNull
public Path getPath() {
return pathModel.getObject();
}
@NotNull
public Iterator<? extends BreadCrumbElement> iterator( int first, int count ) {
//todo add caching...
List<BreadCrumbElement> elements = new ArrayList<BreadCrumbElement>();
for ( Node node : getRoute().getNodes().subList( first, first + count ) ) {
//noinspection unchecked
Class<? extends Page> pageClass = node.getLookup().lookup( Class.class );
if ( pageClass == null ) {
throw new IllegalStateException( "No page class found" );
}
elements.add( new BreadCrumbElement( node.getName(), pageClass ) );
}
return elements.iterator();
}
public int size() {
return getRoute().getNodes().size();
}
public IModel<BreadCrumbElement> model( BreadCrumbElement object ) {
return new Model<BreadCrumbElement>( object );
}
@NotNull
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private transient Route route;
@NotNull
public Route getRoute() {
lock.writeLock().lock();
try {
if ( route == null ) {
try {
route = pageStructureProvider.getPageStructure().getRoute( getPath() );
} catch ( Exception ignore ) {
route = new Route( Collections.singletonList( pageStructureProvider.getPageStructure().getRootNode() ) );
}
}
return route;
} finally {
lock.writeLock().unlock();
}
}
public void detach() {
lock.writeLock().lock();
try {
//noinspection AssignmentToNull
this.route = null;
} finally {
lock.writeLock().unlock();
}
}
}