/* * Copyright 2008-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nominanuda.urispec; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import static com.nominanuda.urispec.Assert.*; public class StringListModelAdapter implements StringModelAdapter<Map<String,Object>> { @SuppressWarnings("unchecked") /*@Nullable*/ private List<String> multivalue(Object o) throws NullPointerException { if (o == null) { return null; } else if (o instanceof List) { return ((List<String>) o); } else if (o instanceof Collection) { return new LinkedList<String>((Collection<String>) o); } else { return new LinkedList<String>(Arrays.asList(o.toString())); } } public Map<String,Object> createStringModel() { return new LinkedHashMap<String, Object>(); } @SuppressWarnings("unchecked") public void push(Map<String,Object> model, String key, String val) { val = decode(val); Object oldval = model.get(key); if (oldval == null) { model.put(key, val); } else if (oldval instanceof List) { ((List<String>) oldval).add(val); } else { List<String> l = new LinkedList<String>(); l.add((String)oldval); l.add(val); model.put(key, l); } } private String decode(String encodedVal) { try { return URLDecoder.decode(encodedVal, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } } private List<String> decode(List<String> encodedVals) { List<String> l = new LinkedList<String>(); for(String s : encodedVals) { l.add(decode(s)); } return l; } public void set(Map<String,Object> model, String key, String val) { val = decode(val); model.put(key, val); } @SuppressWarnings("unchecked") public boolean validateModel(Object m) { try { isTrue(m instanceof Map<?, ?>); for(Entry<String, Object> e : ((Map<String,Object>)m).entrySet()) { isTrue(e.getKey() instanceof String); Object v = e.getValue(); if(v == null ) { continue; } else if(v instanceof String) { continue; } else if(v instanceof List<?>) { for(Object o : (List<?>)v) { isTrue(o == null || o instanceof String); } } else { fail(); } } } catch(IllegalStateException e) { return false; } return true; } public void set(Map<String, Object> model, String key, List<String> val) { val = decode(val); model.put(key, copyList(val)); } /*@Nullable*/ public List<String> getAsList(Map<String,Object> model, String key) { return multivalue(model.get(key)); } /*@Nullable*/ public String getFirst(Map<String, Object> model, String key) { List<String> l = getAsList(model, key); return l == null || l.isEmpty() ? null : l.get(0); } @SuppressWarnings("unchecked") public void setAll(Map<String,Object> from, Map<String,Object> to) { for (Entry<String, ?> e : from.entrySet()) { String k = e.getKey(); Object val = e.getValue(); if(val == null) { throw new NullPointerException(); } else if(val instanceof String) { set(to, k, (String)val); } else { set(to, k, (List<String>)val); } } } @SuppressWarnings("unchecked") public void pushAll(Map<String,Object> from, Map<String,Object> to) { for (Entry<String, ?> e : from.entrySet()) { String k = e.getKey(); Object v = e.getValue(); if(v instanceof List) { for(Object s : (List<Object>)v) { push(to, k, s.toString()); } } else { push(to, k, v.toString()); } } } private LinkedList<String> copyList(List<?> value) { LinkedList<String> res = new LinkedList<String>(); for(Object o : (List<?>)value) { res.add(o == null ? null : o.toString()); } return res; } }