package com.venky.swf.db.extensions;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import com.venky.cache.Cache;
import com.venky.core.collections.SequenceSet;
import com.venky.extension.Extension;
import com.venky.extension.Registry;
import com.venky.swf.db.annotations.column.pm.PARTICIPANT;
import com.venky.swf.db.model.Model;
import com.venky.swf.db.model.User;
import com.venky.swf.db.model.reflection.ModelReflector;
public abstract class ParticipantExtension<M extends Model> implements Extension{
protected static <M extends Model> void registerExtension(ParticipantExtension<M> instance){
Class<M> modelClass = getModelClass(instance);
instance.modelClass = modelClass;
instance.ref = ModelReflector.instance(modelClass);
Registry.instance().registerExtension(User.GET_PARTICIPATION_OPTION + "." + modelClass.getSimpleName() , instance);
}
@SuppressWarnings("unchecked")
protected static <M extends Model> Class<M> getModelClass(ParticipantExtension<M> instance){
ParameterizedType pt = (ParameterizedType)instance.getClass().getGenericSuperclass();
return (Class<M>) pt.getActualTypeArguments()[0];
}
private Class<M> modelClass;
private ModelReflector<M> ref ;
protected ParticipantExtension(){
}
public ModelReflector<M> getReflector(){
return ref;
}
public Class<M> getModelClass(){
return modelClass;
}
@SuppressWarnings("unchecked")
public void invoke(Object... context) {
User user = (User)context[0];
M model = (M) context[1];
String fieldName = (String)context[2];
Cache<String,Map<String,List<Integer>>> participatingGroupOptions = (Cache<String,Map<String, List<Integer>>>)context[3];
PARTICIPANT participant = getReflector().getAnnotation(getReflector().getFieldGetter(fieldName), PARTICIPANT.class);
Map<String,List<Integer>> participatingOptions = participatingGroupOptions.get(participant.value());
List<Integer> allowedValues = getAllowedFieldValues(user,model,fieldName);
if (allowedValues != null){
List<Integer> existing = participatingOptions.get(fieldName);
if (existing == null){
existing = new SequenceSet<Integer>();
participatingOptions.put(fieldName, existing);
}
existing.addAll(allowedValues);
}
}
/**
* @param user
* @param fieldName
* @return Allowed field values for passed used. <code>null</code> implies all values are allowed.
*/
protected abstract List<Integer> getAllowedFieldValues(User user, M partiallyFilledModel, String fieldName);
}