blob: 08c753c70e8b6a735eeef1d3d3bd71a7aebfa13d [file] [log] [blame]
/*
* 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;
}
}