Java tutorial
/* * Copyright 2013-2014 ReConf Team * * 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 reconf.client.constructors; import java.lang.reflect.*; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.*; import org.apache.commons.lang.*; import reconf.client.factory.*; import reconf.infra.i18n.*; public class MapConstructor implements ObjectConstructor { private static final MessagesBundle msg = MessagesBundle.getBundle(MapConstructor.class); public Object construct(MethodData data) throws Throwable { if (data.hasAdapter()) { return data.getAdapter().adapt(data.getValue()); } Class<?> returnClass = null; Type keyType = null; Type valueType = null; if (data.getReturnType() instanceof ParameterizedType) { ParameterizedType parameterized = (ParameterizedType) data.getReturnType(); returnClass = (Class<?>) parameterized.getRawType(); if (parameterized.getActualTypeArguments().length == 1) { Type first = parameterized.getActualTypeArguments()[0]; if (returnClass.getGenericSuperclass() != null && returnClass.getGenericSuperclass() instanceof ParameterizedType) { parameterized = (ParameterizedType) returnClass.getGenericSuperclass(); if (parameterized.getActualTypeArguments().length != 2) { throw new IllegalArgumentException( msg.format("error.cant.build.type", data.getReturnType(), data.getMethod())); } if (parameterized.getActualTypeArguments()[0] instanceof TypeVariable) { keyType = first; valueType = parameterized.getActualTypeArguments()[1]; } else if (parameterized.getActualTypeArguments()[1] instanceof TypeVariable) { valueType = first; keyType = parameterized.getActualTypeArguments()[0]; } else { throw new IllegalArgumentException( msg.format("error.cant.build.type", data.getReturnType(), data.getMethod())); } } } else { keyType = parameterized.getActualTypeArguments()[0]; valueType = parameterized.getActualTypeArguments()[1]; } } else if (data.getReturnType() instanceof Class) { returnClass = (Class<?>) data.getReturnType(); if (returnClass.getGenericSuperclass() != null && returnClass.getGenericSuperclass() instanceof ParameterizedType) { ParameterizedType parameterized = (ParameterizedType) returnClass.getGenericSuperclass(); if (parameterized.getActualTypeArguments().length != 2) { throw new IllegalArgumentException( msg.format("error.cant.build.type", data.getReturnType(), data.getMethod())); } keyType = parameterized.getActualTypeArguments()[0]; valueType = parameterized.getActualTypeArguments()[1]; } else { keyType = Object.class; valueType = Object.class; } } else { throw new IllegalArgumentException(msg.format("error.return", data.getMethod())); } if (returnClass.isInterface()) { returnClass = getDefaultImplementation(data, returnClass); } Constructor<?> constructor = returnClass.getConstructor(ArrayUtils.EMPTY_CLASS_ARRAY); Map<Object, Object> mapInstance = (Map<Object, Object>) constructor .newInstance(ArrayUtils.EMPTY_OBJECT_ARRAY); if (null == data.getValue() || StringUtils.isEmpty(data.getValue())) { return mapInstance; } if ((!(keyType instanceof Class)) || (!StringUtils.startsWith(data.getValue(), "[") || !StringUtils.endsWith(data.getValue(), "]"))) { throw new IllegalArgumentException(msg.format("error.build", data.getValue(), data.getMethod())); } StringParser parser = new StringParser(data); for (Entry<String, String> each : parser.getTokensAsMap().entrySet()) { Object value = ObjectConstructorFactory.get(valueType) .construct(new MethodData(data.getMethod(), valueType, each.getValue())); mapInstance.put(ObjectConstructorFactory.get(keyType) .construct(new MethodData(data.getMethod(), keyType, each.getKey())), value); } return mapInstance; } private Class<?> getDefaultImplementation(MethodData data, Class<?> returnClass) { if (Map.class.equals(returnClass)) { return HashMap.class; } if (ConcurrentMap.class.equals(returnClass)) { return ConcurrentHashMap.class; } if (ConcurrentNavigableMap.class.equals(returnClass)) { return ConcurrentSkipListMap.class; } if (NavigableMap.class.equals(returnClass) || SortedMap.class.equals(returnClass)) { return TreeMap.class; } throw new UnsupportedOperationException(msg.format("error.implementation", returnClass, data.getMethod())); } }