package org.skyscreamer.yoga.listener;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import org.skyscreamer.yoga.model.MapHierarchicalModel;
import org.skyscreamer.yoga.selector.Property;
import org.skyscreamer.yoga.selector.Selector;
import org.skyscreamer.yoga.selector.parser.GDataSelectorParser;
import org.skyscreamer.yoga.selector.parser.LinkedInSelectorParser;
import org.skyscreamer.yoga.selector.parser.SelectorParser;
public class NavigationLinksListener implements RenderingListener
{
private UriGenerator uriGenerator;
public NavigationLinksListener()
{
this( new UriGenerator() );
}
@Deprecated
/** use the UriGenerator constructor */
public NavigationLinksListener( HrefListener hrefListener )
{
setUriGenerator( hrefListener.getUriGenerator() );
}
public NavigationLinksListener( UriGenerator uriGenerator )
{
setUriGenerator( uriGenerator );
}
@Deprecated
/** use setUriGenerator instead */
public void setHrefListener( HrefListener hrefListener )
{
setUriGenerator( hrefListener.getUriGenerator() );
}
public void setUriGenerator( UriGenerator uriGenerator )
{
this.uriGenerator = uriGenerator;
}
@Override
public <T> void eventOccurred( RenderingEvent<T> event ) throws IOException
{
Selector selector = event.getSelector();
if (event.getType() != RenderingEventType.POJO_CHILD || selector.isInfluencedExternally())
{
return;
}
Class<T> instanceType = event.getValueType();
T instance = event.getValue();
String urlSuffix = event.getRequestContext().getUrlSuffix();
MapHierarchicalModel<?> navigationLinks = ( ( MapHierarchicalModel<?> ) event.getModel() )
.createChildMap( "navigationLinks" );
Collection<Property<T>> fieldNames = getNonSelectedFields( selector, instanceType, instance );
SelectorParser selectorParser = event.getRequestContext().getSelectorParser();
String format;
if (selectorParser instanceof LinkedInSelectorParser)
{
format = "%s?selector=:(%s)";
}
else if (selectorParser instanceof GDataSelectorParser)
{
format = "%s?selector=%s";
}
else
{
throw new IllegalStateException( "Unknown selector type: " + selectorParser.getClass().getName() );
}
for ( Property<?> field : fieldNames )
{
String fieldName = field.name();
MapHierarchicalModel<?> navModel = navigationLinks.createChildMap( fieldName );
navModel.addProperty( SelectorParser.HREF,
uriGenerator.getUrl( event, String.format( format, urlSuffix, fieldName ) ) );
navModel.addProperty( "name", fieldName );
navModel.finished();
}
navigationLinks.finished();
}
public <T> Collection<Property<T>> getNonSelectedFields( Selector selector, Class<T> instanceType, Object instance )
{
HashMap<String, Property<T>> fields = new HashMap<String, Property<T>>(
selector.getAllPossibleFieldMap( instanceType ) );
for ( Property<T> selected : selector.getSelectedFields( instanceType ) )
{
fields.remove( selected.name() );
}
return fields.values();
}
}