com.google.web.bindery.requestfactory.gwt.client.impl.AbstractRequestFactoryEditorDriver Maven / Gradle / Ivy
/*
* 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.web.bindery.requestfactory.gwt.client.impl;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorVisitor;
import com.google.gwt.editor.client.impl.AbstractEditorDelegate;
import com.google.gwt.editor.client.impl.BaseEditorDriver;
import com.google.gwt.editor.client.impl.DelegateMap;
import com.google.gwt.editor.client.impl.DelegateMap.KeyMethod;
import com.google.gwt.editor.client.impl.SimpleViolation;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanUtils;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.ValueProxy;
import com.google.web.bindery.requestfactory.shared.impl.Constants;
import java.util.Iterator;
import java.util.List;
/**
* Contains utility methods for top-level driver implementations.
*
* @param the type being edited
* @param the type of Editor
*/
public abstract class AbstractRequestFactoryEditorDriver> extends
BaseEditorDriver implements RequestFactoryEditorDriver {
/**
* Adapts a RequestFactory Violation object to the SimpleViolation interface.
*/
@SuppressWarnings("deprecation")
static class SimpleViolationAdapter extends SimpleViolation {
private final com.google.web.bindery.requestfactory.shared.Violation v;
/**
* @param v
*/
private SimpleViolationAdapter(com.google.web.bindery.requestfactory.shared.Violation v) {
this.v = v;
}
@Override
public Object getKey() {
return v.getOriginalProxy();
}
@Override
public String getMessage() {
return v.getMessage();
}
@Override
public String getPath() {
return v.getPath();
}
@Override
public Object getUserDataObject() {
return v;
}
}
/**
* Provides a source of SimpleViolation objects based on RequestFactory's
* simplified Violation interface.
*/
@SuppressWarnings("deprecation")
static class ViolationIterable implements Iterable {
private final Iterable violations;
public ViolationIterable(
Iterable violations) {
this.violations = violations;
}
public Iterator iterator() {
final Iterator source =
violations.iterator();
return new Iterator() {
public boolean hasNext() {
return source.hasNext();
}
public SimpleViolation next() {
return new SimpleViolationAdapter(source.next());
}
public void remove() {
source.remove();
}
};
}
}
/**
* Since the ValueProxy is being mutated in-place, we need a way to stabilize
* its hashcode for future equality checks.
*/
private static class ValueProxyHolder {
private final ValueProxy proxy;
public ValueProxyHolder(ValueProxy proxy) {
this.proxy = proxy;
}
@Override
public boolean equals(Object o) {
return proxy.equals(((ValueProxyHolder) o).proxy);
}
@Override
public int hashCode() {
return proxy.getClass().hashCode();
}
}
private static final DelegateMap.KeyMethod PROXY_ID_KEY = new DelegateMap.KeyMethod() {
public Object key(Object object) {
if (object instanceof EntityProxy) {
return ((EntityProxy) object).stableId();
} else if (object instanceof ValueProxy) {
AutoBean bean = AutoBeanUtils.getAutoBean(object);
// Possibly replace an editable ValueProxy with its immutable base
AutoBean parent = bean.getTag(Constants.PARENT_OBJECT);
if (parent != null) {
object = parent.as();
}
return new ValueProxyHolder((ValueProxy) object);
}
return null;
}
};
private EventBus eventBus;
private List paths;
private RequestFactory factory;
private RequestContext saveRequest;
public void display(R object) {
edit(object, null);
}
public void edit(R object, RequestContext saveRequest) {
this.saveRequest = saveRequest;
/*
* Provide the delegate with the RequestContext so ensureMutable works as
* expected Editor will be provided the delegate by the Initializer visitor.
*/
((RequestFactoryEditorDelegate) getDelegate()).setRequestContext(saveRequest);
doEdit(object);
}
public RequestContext flush() {
checkSaveRequest();
doFlush();
return saveRequest;
}
public String[] getPaths() {
return paths.toArray(new String[paths.size()]);
}
public void initialize(E editor) {
doInitialize(null, null, editor);
}
public void initialize(EventBus eventBus, RequestFactory requestFactory, E editor) {
assert eventBus != null : "eventBus must not be null";
assert requestFactory != null : "requestFactory must not be null";
doInitialize(eventBus, requestFactory, editor);
}
public void initialize(RequestFactory requestFactory, E editor) {
initialize(requestFactory.getEventBus(), requestFactory, editor);
}
@SuppressWarnings("deprecation")
public boolean setViolations(
Iterable violations) {
return doSetViolations(violations == null ? null : new ViolationIterable(violations));
}
protected void checkSaveRequest() {
if (saveRequest == null) {
throw new IllegalStateException("edit() was called with a null Request");
}
}
@Override
protected void configureDelegate(AbstractEditorDelegate rootDelegate) {
((RequestFactoryEditorDelegate) rootDelegate).initialize(eventBus, factory, "",
getEditor());
}
@Override
protected EditorVisitor createInitializerVisitor() {
return new Initializer(saveRequest);
}
protected void doInitialize(EventBus eventBus, RequestFactory requestFactory, E editor) {
this.eventBus = eventBus;
this.factory = requestFactory;
super.doInitialize(editor);
PathCollector c = new PathCollector();
accept(c);
this.paths = c.getPaths();
}
@Override
protected KeyMethod getViolationKeyMethod() {
return PROXY_ID_KEY;
}
}