/* * Copyright 2011 Google Inc. * * 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.google.web.bindery.autobean.gwt.client.impl; import com.google.web.bindery.autobean.shared.AutoBeanVisitor.CollectionPropertyContext; import com.google.web.bindery.autobean.shared.AutoBeanVisitor.MapPropertyContext; import com.google.web.bindery.autobean.shared.AutoBeanVisitor.ParameterizationVisitor; import com.google.web.bindery.autobean.shared.AutoBeanVisitor.PropertyContext; import com.google.web.bindery.autobean.shared.impl.AbstractAutoBean; import com.google.gwt.core.client.JavaScriptObject; import java.util.List; import java.util.Map; import java.util.Set; /** * Provides base methods for generated implementations of PropertyContext. */ public final class ClientPropertyContext implements PropertyContext, CollectionPropertyContext, MapPropertyContext { /** * A reference to an instance setter method. */ public static final class Setter extends JavaScriptObject { /** * Create a trivial Setter that calls {@link AbstractAutoBean#setProperty()} * . */ public static native Setter beanSetter(AbstractAutoBean<?> bean, String key) /*-{ return function(value) { bean.@com.google.web.bindery.autobean.shared.impl.AbstractAutoBean::setProperty(*)(key, value); }; }-*/; protected Setter() { } public native void call(Object instance, Object value) /*-{ this.call(instance, value); }-*/; } private final Object instance; private final int[] paramCounts; private final Class<?>[] paramTypes; private final Setter setter; private final Class<?> simpleType; public ClientPropertyContext(Object instance, Setter setter, Class<?> type) { this.instance = instance; this.setter = setter; this.simpleType = type; this.paramTypes = null; this.paramCounts = null; } public ClientPropertyContext(Object instance, Setter setter, Class<?>[] types, int[] paramCounts) { this.instance = instance; this.setter = setter; this.simpleType = null; this.paramTypes = types; this.paramCounts = paramCounts; /* * Verify input arrays of same length and that the total parameter count, * plus one for the root type, equals the total number of types passed in. */ if (ClientPropertyContext.class.desiredAssertionStatus()) { assert types.length == paramCounts.length : "Length mismatch " + types.length + " != " + paramCounts.length; int count = 1; for (int i = 0, j = paramCounts.length; i < j; i++) { count += paramCounts[i]; } assert count == types.length : "Mismatch in total parameter count " + count + " != " + types.length; } } public void accept(ParameterizationVisitor visitor) { traverse(visitor, 0); } public boolean canSet() { return setter != null; } public Class<?> getElementType() { if (paramTypes == null || paramTypes.length < 2) { return null; } if (List.class.equals(paramTypes[0]) || Set.class.equals(paramTypes[0])) { return paramTypes[1]; } return null; } public Class<?> getKeyType() { if (paramTypes == null || paramTypes.length < 3) { return null; } if (Map.class.equals(paramTypes[0])) { return paramTypes[1]; } return null; } public Class<?> getType() { return simpleType == null ? paramTypes[0] : simpleType; } public Class<?> getValueType() { if (paramTypes == null || paramTypes.length < 3) { return null; } if (Map.class.equals(paramTypes[0])) { return paramTypes[2]; } return null; } public void set(Object value) { setter.call(instance, value); } private int traverse(ParameterizationVisitor visitor, int count) { if (simpleType != null) { visitor.visitType(simpleType); visitor.endVisitType(simpleType); return 0; } Class<?> type = paramTypes[count]; int paramCount = paramCounts[count]; ++count; if (visitor.visitType(type)) { for (int i = 0; i < paramCount; i++) { if (visitor.visitParameter()) { count = traverse(visitor, count); } visitor.endVisitParameter(); } } visitor.endVisitType(type); return count; } }