blob: dddb011c239429f262333dbdfce1daeb035c8e14 [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.gwt.editor.client.impl;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDriver;
import com.google.gwt.editor.client.EditorError;
import com.google.gwt.editor.client.EditorVisitor;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.impl.DelegateMap.KeyMethod;
import com.google.gwt.editor.client.testing.EditorHierarchyPrinter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.validation.ConstraintViolation;
/**
* Contains common code shared between the SimpleBeanEditorDriver and
* RequestFactoryEditorDriver.
*
* @param <T> the type of data being edited
* @param <E> the type of editor
*/
public abstract class BaseEditorDriver<T, E extends Editor<T>> {
private AbstractEditorDelegate<T, E> delegate;
/**
* Used for {@link #isDirty()} computations.
*/
private Map<LeafValueEditor<?>, Object> leafValueMap;
private E editor;
private List<EditorError> errors;
private T object;
public abstract void accept(EditorVisitor visitor);
public List<EditorError> getErrors() {
return errors;
}
public boolean hasErrors() {
return !errors.isEmpty();
}
public boolean isDirty() {
DirtCollector c = new DirtCollector();
accept(c);
return c.isDirty() || !leafValueMap.equals(c.getLeafValues());
}
public boolean setConstraintViolations(
final Iterable<ConstraintViolation<?>> violations) {
return doSetViolations(SimpleViolation.iterableFromConstrantViolations(violations));
}
@Override
public String toString() {
if (GWT.isProdMode()) {
return super.toString();
} else {
return editor == null ? "Uninitialized"
: EditorHierarchyPrinter.toString(asEditorDriver());
}
}
protected void configureDelegate(AbstractEditorDelegate<T, E> rootDelegate) {
rootDelegate.initialize("", getEditor());
}
protected abstract AbstractEditorDelegate<T, E> createDelegate();
protected void doEdit(T object) {
checkEditor();
object = delegate.ensureMutable(object);
this.object = object;
delegate.setObject(object);
accept(new Initializer());
DirtCollector c = new DirtCollector();
accept(c);
leafValueMap = c.getLeafValues();
}
protected void doFlush() {
checkObject();
errors = new ArrayList<EditorError>();
accept(new Flusher());
accept(new ErrorCollector(errors));
}
protected void doInitialize(E editor) {
this.editor = editor;
delegate = createDelegate();
configureDelegate(delegate);
}
protected boolean doSetViolations(Iterable<SimpleViolation> violations) {
checkObject();
SimpleViolation.pushViolations(violations, asEditorDriver(),
getViolationKeyMethod());
// Collect the errors, which will take care of co-editor chains.
errors = new ArrayList<EditorError>();
accept(new ErrorCollector(errors));
return hasErrors();
}
protected AbstractEditorDelegate<T, E> getDelegate() {
return delegate;
}
protected E getEditor() {
return editor;
}
protected T getObject() {
return object;
}
protected KeyMethod getViolationKeyMethod() {
return DelegateMap.IDENTITY;
}
/**
* This cast avoids the need to add another parameterization to
* BaseEditorDriver since the class cannot be declared to extend an unbound
* interface.
*/
private EditorDriver<?> asEditorDriver() {
return (EditorDriver<?>) this;
}
private void checkEditor() {
if (editor == null) {
throw new IllegalStateException("Must call initialize() first");
}
}
private void checkObject() {
if (object == null) {
throw new IllegalStateException("Must call edit() first");
}
}
}