| /* |
| * Copyright 2010 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.gwt.requestfactory.client.impl; |
| |
| import com.google.gwt.requestfactory.shared.EntityProxy; |
| |
| import com.google.gwt.requestfactory.shared.EntityProxyId; |
| import com.google.gwt.requestfactory.shared.impl.CollectionProperty; |
| import com.google.gwt.requestfactory.shared.impl.Property; |
| |
| /** |
| * <p> |
| * <span style="color:red">Experimental API: This class is still under rapid |
| * development, and is very likely to be deleted. Use it at your own risk. |
| * </span> |
| * </p> |
| * Base class for implementations of {@link EntityProxy}. It wraps a |
| * {@link ProxyJsoImpl} that does all the actual work. This class has little |
| * reason to exist except to allow client code to make instanceof checks, and to |
| * work around issue 4859 (JSOs cannot have abstract superclasses). If the issue |
| * is fixed it might be worth abandoning the instanceof capability, needs |
| * thinking. |
| */ |
| public class ProxyImpl implements EntityProxy { |
| |
| protected static String getWireFormatId(String id, boolean isFuture, |
| ProxySchema<?> schema) { |
| return id + "@" + (isFuture ? "IS" : "NO") + "@" + schema.getToken(); |
| } |
| |
| private final ProxyJsoImpl jso; |
| private final boolean isFuture; |
| |
| private DeltaValueStoreJsonImpl deltaValueStore; |
| |
| /** |
| * For use by generated subclasses only. Other code should use |
| * {@link ProxySchema#create(ProxyJsoImpl, boolean)}, typically: |
| * <code><pre>proxyJsoImpl.getSchema().create(proxyJsoImpl.getSchema(), isFuture); |
| * </pre></code> |
| */ |
| protected ProxyImpl(ProxyJsoImpl jso, boolean isFuture) { |
| /* |
| * A funny place for these asserts, but it's proved hard to control in the |
| * JSO itself |
| */ |
| assert jso.getRequestFactory() != null; |
| assert jso.getSchema() != null; |
| this.jso = jso; |
| this.isFuture = isFuture; |
| deltaValueStore = null; |
| } |
| |
| public ProxyJsoImpl asJso() { |
| return jso; |
| } |
| |
| public String encodedId() { |
| return jso.encodedId(); |
| } |
| |
| /** |
| * Get this proxy's value for the given property. Behavior is undefined if |
| * the proxy has no such property, or if the property has never been set. It |
| * is unusual to call this method directly. Rather it is expected to be called |
| * by bean-style getter methods provided by implementing classes. |
| * |
| * @param <V> the type of the property's value |
| * @param property the property to fetch |
| * @return the value |
| */ |
| @SuppressWarnings("unchecked") |
| public <V> V get(Property<V> property) { |
| if (property instanceof CollectionProperty) { |
| V toReturn = (V) jso.getCollection((CollectionProperty) property); |
| if (toReturn != null) { |
| ((JsoCollection) toReturn).setDependencies(deltaValueStore, property, |
| this); |
| } |
| return toReturn; |
| } |
| return jso.<V> get(property); |
| } |
| |
| public <V> V get(String propertyName, Class<?> propertyType) { |
| // javac 1.6.0_20 on mac has problems without the explicit parameterization |
| return jso.<V> get(propertyName, propertyType); |
| } |
| |
| public ProxySchema<?> getSchema() { |
| return jso.getSchema(); |
| } |
| |
| public String getWireFormatId() { |
| return getWireFormatId(jso.encodedId(), isFuture, jso.getSchema()); |
| } |
| |
| public boolean isChanged() { |
| if (deltaValueStore == null) { |
| return false; |
| } |
| return deltaValueStore.isChanged(); |
| } |
| |
| public boolean isFuture() { |
| return isFuture; |
| } |
| |
| public <V> void set(Property<V> property, ProxyImpl record, V value) { |
| if (deltaValueStore == null) { |
| throw new UnsupportedOperationException( |
| "Setter methods can't be called before calling edit()"); |
| } |
| deltaValueStore.set(property, record, value); |
| } |
| |
| // Allow the generated subclass to return the specific type its public interface probably demands |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| public EntityProxyId stableId() { |
| if (!isFuture) { |
| return new EntityProxyIdImpl<ProxyImpl>( |
| encodedId(), |
| getSchema(), |
| false, |
| jso.getRequestFactory().datastoreToFutureMap.get(encodedId(), getSchema())); |
| } |
| return new EntityProxyIdImpl(encodedId(), getSchema(), isFuture, null); |
| } |
| |
| public Integer version() { |
| return jso.version(); |
| } |
| |
| protected ValueStoreJsonImpl getValueStore() { |
| return jso.getRequestFactory().getValueStore(); |
| } |
| |
| void setDeltaValueStore(DeltaValueStoreJsonImpl deltaValueStore) { |
| this.deltaValueStore = deltaValueStore; |
| } |
| } |