/* * Copyright 2014 mango.jfaster.org * * The Mango Project licenses this file to you 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 org.jfaster.mango.mapper; import org.jfaster.mango.invoker.GetterInvoker; import org.jfaster.mango.invoker.InvokerCache; import org.jfaster.mango.invoker.SetterInvoker; import org.jfaster.mango.invoker.UnreachablePropertyException; import org.jfaster.mango.util.PropertyTokenizer; /** * @author ash */ public class FunctionalSetterInvokerGroup implements SetterInvokerGroup { private final Class<?> originalType; private final String propertyPath; private final Class<?> targetType; private FunctionalSetterInvokerGroup(Class<?> originalType, String propertyPath) { this.originalType = originalType; this.propertyPath = propertyPath; PropertyTokenizer prop = new PropertyTokenizer(propertyPath); if (!prop.hasNext()) { throw new IllegalStateException("property path '" + propertyPath + "' error"); } Class<?> currentType = originalType; while (prop.hasCurrent()) { String propertyName = prop.getName(); SetterInvoker setter = InvokerCache.getSetterInvoker(currentType, propertyName); if (prop.hasNext()) { // 后续还有属性则需检测set方法 GetterInvoker getter = InvokerCache.getGetterInvoker(currentType, propertyName); if (!setter.getParameterType().equals(getter.getReturnType())) { // 有set方法,但get方法不对,抛出异常 throw new UnreachablePropertyException("Inconsistent setter/getter type for property named '" + propertyName + "' in '" + currentType + "'"); } } currentType = setter.getParameterRawType(); prop = prop.next(); } targetType = currentType; } public static FunctionalSetterInvokerGroup create(Class<?> originalType, String propertyPath) { return new FunctionalSetterInvokerGroup(originalType, propertyPath); } @Override public Class<?> getOriginalType() { return originalType; } @Override public Class<?> getTargetType() { return targetType; } @Override public void invoke(Object obj, Object value) { MetaObject mo = MetaObject.forObject(obj); mo.setValue(propertyPath, value); } }