package org.skyscreamer.yoga.listener;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import org.skyscreamer.yoga.annotations.URITemplate;
import org.skyscreamer.yoga.configuration.DefaultEntityConfigurationRegistry;
import org.skyscreamer.yoga.configuration.EntityConfigurationRegistry;
import org.skyscreamer.yoga.configuration.YogaEntityConfiguration;
import org.skyscreamer.yoga.selector.Property;
import org.skyscreamer.yoga.uri.URICreator;
import org.skyscreamer.yoga.uri.URIDecorator;
import org.skyscreamer.yoga.util.ValueReader;
public class UriGenerator
{
private EntityConfigurationRegistry _entityConfigurationRegistry = new DefaultEntityConfigurationRegistry();
private ConcurrentHashMap<Class<?>, String> templates = new ConcurrentHashMap<Class<?>, String>();
public UriGenerator()
{
}
public UriGenerator( EntityConfigurationRegistry _entityConfigurationRegistry)
{
this._entityConfigurationRegistry = _entityConfigurationRegistry;
}
public void setEntityConfigurationRegistry( EntityConfigurationRegistry entityConfigurationRegistry)
{
this._entityConfigurationRegistry = entityConfigurationRegistry;
}
public <T> String getUrl( RenderingEvent<T> event, String suffix ) throws IOException
{
String urlTemplate = determineTemplate( event.getValueType() );
return urlTemplate != null ? getUrl( urlTemplate, suffix, event ) : null;
}
public String determineTemplate( Class<?> instanceType )
{
String uriTemplate = templates.get(instanceType);
if(uriTemplate != null)
{
return uriTemplate;
}
YogaEntityConfiguration<?> entityConfiguration = _entityConfigurationRegistry == null ? null
: _entityConfigurationRegistry.getEntityConfiguration( instanceType );
// YogaEntityConfiguration trumps annotation
if (entityConfiguration != null && entityConfiguration.getURITemplate() != null)
{
uriTemplate = entityConfiguration.getURITemplate();
}
// Annotation based config
else if (instanceType.isAnnotationPresent( URITemplate.class ))
{
uriTemplate = instanceType.getAnnotation( URITemplate.class ).value();
}
else
{
uriTemplate = determineTemplateForUnknownType( instanceType );
}
if(uriTemplate != null)
{
String existing = templates.putIfAbsent(instanceType, uriTemplate);
if(existing != null)
{
uriTemplate = existing;
}
}
return uriTemplate;
}
/** override this if you want custom behavior */
protected String determineTemplateForUnknownType( Class<?> instanceType )
{
return null;
}
public <T> String getUrl( String uriTemplate, final String suffix, final RenderingEvent<T> event )
{
String url = getUrlVal(uriTemplate, suffix, event);
return event.getRequestContext().getResponse().encodeURL(url);
}
protected <T> String getUrlVal(String uriTemplate, final String suffix, final RenderingEvent<T> event)
{
ValueReader reader = new ValueReader()
{
@Override
public Object getValue( String propertyName )
{
Property<T> property = event.getSelector().getProperty( event.getValueType(), propertyName );
return property == null ? null : property.getValue( event.getValue() );
}
};
if(suffix != null)
{
return URICreator.getHref( uriTemplate, reader, new URIDecorator()
{
@Override
public StringBuilder decorate(StringBuilder uri)
{
return uri.append(".").append(suffix);
}
} );
}
else
{
return URICreator.getHref( uriTemplate, reader );
}
}
}