| /* |
| * 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.editor.client.Editor; |
| import com.google.gwt.editor.client.impl.AbstractEditorDelegate; |
| import com.google.gwt.editor.client.impl.Refresher; |
| import com.google.gwt.event.shared.EventBus; |
| import com.google.gwt.event.shared.HandlerRegistration; |
| import com.google.gwt.requestfactory.shared.BaseProxy; |
| import com.google.gwt.requestfactory.shared.EntityProxy; |
| import com.google.gwt.requestfactory.shared.EntityProxyChange; |
| import com.google.gwt.requestfactory.shared.EntityProxyId; |
| import com.google.gwt.requestfactory.shared.Receiver; |
| import com.google.gwt.requestfactory.shared.RequestContext; |
| import com.google.gwt.requestfactory.shared.RequestFactory; |
| import com.google.gwt.requestfactory.shared.WriteOperation; |
| import com.google.gwt.requestfactory.shared.impl.AbstractRequestContext; |
| |
| import java.util.List; |
| |
| /** |
| * Base class for generated EditorDelegates using a RequestFactory as the |
| * backend. |
| * |
| * @param <P> the type of Proxy |
| * @param <E> the type of Editor |
| */ |
| public abstract class RequestFactoryEditorDelegate<P, E extends Editor<P>> |
| extends AbstractEditorDelegate<P, E> { |
| private class SubscriptionHandler implements |
| EntityProxyChange.Handler<EntityProxy> { |
| |
| public void onProxyChange(EntityProxyChange<EntityProxy> event) { |
| if (event.getWriteOperation().equals(WriteOperation.UPDATE) |
| && event.getProxyId().equals(((EntityProxy) getObject()).stableId())) { |
| PathCollector collector = new PathCollector(); |
| accept(collector); |
| EntityProxyId<?> id = event.getProxyId(); |
| doFind(collector.getPaths(), id); |
| } |
| } |
| |
| @SuppressWarnings(value = {"rawtypes", "unchecked"}) |
| private void doFind(List<String> paths, EntityProxyId id) { |
| factory.find(id).with(paths.toArray(new String[paths.size()])).fire( |
| new SubscriptionReceiver()); |
| } |
| } |
| |
| private class SubscriptionReceiver extends Receiver<EntityProxy> { |
| @Override |
| public void onSuccess(EntityProxy response) { |
| @SuppressWarnings("unchecked") |
| P cast = (P) response; |
| setObject(cast); |
| accept(new Refresher()); |
| } |
| } |
| |
| protected EventBus eventBus; |
| protected RequestFactory factory; |
| protected RequestContext request; |
| |
| public void setRequestContext(RequestContext request) { |
| this.request = request; |
| } |
| |
| @Override |
| public HandlerRegistration subscribe() { |
| if (factory == null) { |
| /* |
| * They called the no-subscriptions version of |
| * RequestFactoryEditorDriver#initialize |
| */ |
| return null; |
| } |
| |
| if (!(getObject() instanceof EntityProxy)) { |
| /* |
| * This is kind of weird. The user is asking for notifications on a |
| * String, which means there's a HasEditorDelegate<String> in play and not |
| * the usual LeafValueEditor<String>. |
| */ |
| return null; |
| } |
| |
| // Can't just use getObject().getClass() because it's not the proxy type |
| EntityProxyId<?> stableId = ((EntityProxy) getObject()).stableId(); |
| @SuppressWarnings("unchecked") |
| Class<EntityProxy> clazz = (Class<EntityProxy>) stableId.getProxyClass(); |
| HandlerRegistration toReturn = EntityProxyChange.<EntityProxy> registerForProxyType( |
| eventBus, clazz, new SubscriptionHandler()); |
| return toReturn; |
| } |
| |
| @Override |
| protected <R, S extends Editor<R>> void addSubDelegate( |
| AbstractEditorDelegate<R, S> subDelegate, String path, S subEditor) { |
| RequestFactoryEditorDelegate<R, S> d = (RequestFactoryEditorDelegate<R, S>) subDelegate; |
| d.initialize(eventBus, factory, path, subEditor); |
| } |
| |
| @Override |
| protected <T> T ensureMutable(T object) { |
| if (request == null) { |
| // Read-only mode |
| return object; |
| } |
| if (object instanceof BaseProxy) { |
| @SuppressWarnings("unchecked") |
| T toReturn = (T) request.edit((BaseProxy) object); |
| return toReturn; |
| } |
| return object; |
| } |
| |
| protected void initialize(EventBus eventBus, RequestFactory factory, |
| String pathSoFar, E editor) { |
| this.eventBus = eventBus; |
| this.factory = factory; |
| super.initialize(pathSoFar, editor); |
| } |
| |
| /** |
| * Must call four-arg version instead. |
| */ |
| @Override |
| protected void initialize(String pathSoFar, E editor) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| protected boolean shouldFlush() { |
| if (request == null) { |
| return false; |
| } |
| if (request instanceof AbstractRequestContext) { |
| return !((AbstractRequestContext) request).isLocked(); |
| } |
| return true; |
| } |
| } |