public static NamespaceConfig process(final Map<String,?> config) throws ValidationException {
  if (config == null || config.isEmpty()) {
    throw new ValidationException("Null or empty top-level JSON object passed");
  }
  final Context ctx=new Context();
  try {
    final Map<String,Object> ns=cast(get(config,NAMESPACE,Map.class,ctx));
    ctx.push(NAMESPACE);
    final Object salt=ns.get(SALT);
    final NamespaceConfig nsConf=new NamespaceConfig(get(ns,NAME,String.class,ctx),get(ns,SEGMENTS,Integer.class,ctx),get(ns,UNIT,String.class,ctx),(salt == null ? null : salt.toString()));
    nsConf.setConfig(config);
    final List<Map<String,Object>> expDefs=cast(get(config,EXPERIMENT_DEFINITIONS,List.class,ctx));
    ctx.push(EXPERIMENT_DEFINITIONS);
    int i=0;
    ctx.push("");
    for (    Map<String,Object> expDef : expDefs) {
      ctx.replace(format("[%s]",i++));
      final Map<String,Object> assign=cast(get(expDef,ASSIGN,Map.class,ctx));
      nsConf.defineExperiment(get(expDef,DEFINITION,String.class,ctx),assign);
    }
    ctx.pop();
    ctx.pop();
    nsConf.setDefaultExperiment(get(config,DEFAULT_EXPERIMENT,String.class,ctx));
    final List<Map<String,Object>> expSeq=cast(get(config,EXPERIMENT_SEQUENCE,List.class,ctx));
    ctx.push(EXPERIMENT_SEQUENCE);
    i=0;
    ctx.push("");
    for (    Map<String,Object> srcExp : expSeq) {
      ctx.replace(format("[%s]",i++));
      final String expName=get(srcExp,NAME,String.class,ctx);
      final String action=get(srcExp,ACTION,String.class,ctx);
switch (action) {
case ACTION_ADD:
        nsConf.addExperiment(expName,get(srcExp,DEFINITION,String.class,ctx),get(srcExp,SEGMENTS,Integer.class,ctx));
      break;
case ACTION_REMOVE:
    nsConf.removeExperiment(expName);
  break;
default :
throw new IllegalArgumentException(format("Unrecognized action: %s",action));
}
}
ctx.pop();
ctx.pop();
if (LOG.isTraceEnabled()) {
LOG.trace("NS {} has {} active experiments (based on {} definitions) consuming {} segments out of {} total",nsConf.name,nsConf.getActiveExperimentsCount(),nsConf.getExperimentDefsCount(),nsConf.getUsedSegments(),nsConf.getTotalSegments());
}
nsConf.noMoreChanges();
return nsConf;
}
 catch (IllegalArgumentException e) {
final ValidationException ve=new ValidationException(e.getMessage(),e.getCause());
ve.setStackTrace(e.getStackTrace());
throw ve;
}
}

public static NamespaceConfig process ( final Map < String , ? > config ) throws ValidationException { if ( config == null || config . isEmpty ( ) ) { throw new ValidationException ( "Null or empty top-level JSON object passed" ) ; } final Context ctx = new Context ( ) ; try { final Map < String , Object > ns = cast ( get ( config , NAMESPACE , Map . class , ctx ) ) ; ctx . push ( NAMESPACE ) ; final Object salt = ns . get ( SALT ) ; final NamespaceConfig nsConf = new NamespaceConfig ( get ( ns , NAME , String . class , ctx ) , get ( ns , SEGMENTS , Integer . class , ctx ) , get ( ns , UNIT , String . class , ctx ) , ( salt == null ? null : salt . toString ( ) ) ) ; nsConf . setConfig ( config ) ; final List < Map < String , Object > > expDefs = cast ( get ( config , EXPERIMENT_DEFINITIONS , List . class , ctx ) ) ; ctx . push ( EXPERIMENT_DEFINITIONS ) ; int i = 0 ; ctx . push ( "" ) ; for ( Map < String , Object > expDef : expDefs ) { ctx . replace ( format ( "[%s]" , i ++ ) ) ; final Map < String , Object > assign = cast ( get ( expDef , ASSIGN , Map . class , ctx ) ) ; nsConf . defineExperiment ( get ( expDef , DEFINITION , String . class , ctx ) , assign ) ; } ctx . pop ( ) ; ctx . pop ( ) ; nsConf . setDefaultExperiment ( get ( config , DEFAULT_EXPERIMENT , String . class , ctx ) ) ; final List < Map < String , Object > > expSeq = cast ( get ( config , EXPERIMENT_SEQUENCE , List . class , ctx ) ) ; ctx . push ( EXPERIMENT_SEQUENCE ) ; i = 0 ; ctx . push ( "" ) ; for ( Map < String , Object > srcExp : expSeq ) { ctx . replace ( format ( "[%s]" , i ++ ) ) ; final String expName = get ( srcExp , NAME , String . class , ctx ) ; final String action = get ( srcExp , ACTION , String . class , ctx ) ; switch ( action ) { case ACTION_ADD : nsConf . addExperiment ( expName , get ( srcExp , DEFINITION , String . class , ctx ) , get ( srcExp , SEGMENTS , Integer . class , ctx ) ) ; break ; case ACTION_REMOVE : nsConf . removeExperiment ( expName ) ; break ; default : throw new IllegalArgumentException ( format ( "Unrecognized action: %s" , action ) ) ; } } ctx . pop ( ) ; ctx . pop ( ) ; if ( LOG . isTraceEnabled ( ) ) { LOG . trace ( "NS {} has {} active experiments (based on {} definitions) consuming {} segments out of {} total" , nsConf . name , nsConf . getActiveExperimentsCount ( ) , nsConf . getExperimentDefsCount ( ) , nsConf . getUsedSegments ( ) , nsConf . getTotalSegments ( ) ) ; } nsConf . noMoreChanges ( ) ; return nsConf ; } catch ( IllegalArgumentException e ) { final ValidationException ve = new ValidationException ( e . getMessage ( ) , e . getCause ( ) ) ; ve . setStackTrace ( e . getStackTrace ( ) ) ; throw ve ; } }
given loaded yaml config data defining a namespace ( with experiment definitions using planout dsl as well as sequencing ) produce the corresponding json structure . the two main goals are validation of the entire structure and compilation of planout dsl to json .
