| /* |
| * 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.editor.rebind.model; |
| |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.JPrimitiveType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.dev.CompilerContext; |
| import com.google.gwt.dev.javac.CompilationState; |
| import com.google.gwt.dev.javac.CompilationStateBuilder; |
| import com.google.gwt.dev.javac.testing.impl.JavaResourceBase; |
| import com.google.gwt.dev.javac.testing.impl.MockJavaResource; |
| import com.google.gwt.dev.resource.Resource; |
| import com.google.gwt.dev.util.UnitTestTreeLogger; |
| import com.google.gwt.dev.util.Util; |
| import com.google.gwt.dev.util.log.PrintWriterTreeLogger; |
| import com.google.gwt.editor.client.CompositeEditor; |
| 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.HasEditorDelegate; |
| import com.google.gwt.editor.client.HasEditorErrors; |
| import com.google.gwt.editor.client.IsEditor; |
| import com.google.gwt.editor.client.LeafValueEditor; |
| import com.google.gwt.editor.client.ValueAwareEditor; |
| import com.google.gwt.editor.client.adapters.SimpleEditor; |
| import com.google.gwt.event.shared.EventBus; |
| import com.google.gwt.user.client.TakesValue; |
| import com.google.gwt.user.client.ui.HasText; |
| import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; |
| import com.google.web.bindery.requestfactory.shared.EntityProxy; |
| import com.google.web.bindery.requestfactory.shared.Request; |
| import com.google.web.bindery.requestfactory.shared.RequestContext; |
| import com.google.web.bindery.requestfactory.shared.RequestFactory; |
| |
| import junit.framework.TestCase; |
| |
| import java.io.InputStream; |
| import java.io.PrintWriter; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import javax.validation.ConstraintViolation; |
| |
| /** |
| * Test case for {@link EditorModel} that uses mock CompilationStates. |
| */ |
| public class EditorModelTest extends TestCase { |
| |
| /** |
| * Constructs an empty interface representation of a type. |
| */ |
| private static class EmptyMockJavaResource extends MockJavaResource { |
| private final StringBuilder code = new StringBuilder(); |
| |
| public EmptyMockJavaResource(Class<?> clazz) { |
| super(clazz.getName()); |
| |
| code.append("package ").append(clazz.getPackage().getName()).append(";\n"); |
| code.append("public interface ").append(clazz.getSimpleName()); |
| |
| int numParams = clazz.getTypeParameters().length; |
| if (numParams != 0) { |
| code.append("<"); |
| for (int i = 0; i < numParams; i++) { |
| if (i != 0) { |
| code.append(","); |
| } |
| code.append("T").append(i); |
| } |
| code.append(">"); |
| } |
| |
| code.append("{}\n"); |
| } |
| |
| @Override |
| public CharSequence getContent() { |
| return code; |
| } |
| } |
| |
| /** |
| * Loads the actual source of a type. This should be used only for types |
| * directly tested by this test. Note that use of this class requires your |
| * source files to be on your classpath. |
| */ |
| private static class RealJavaResource extends |
| MockJavaResource { |
| public RealJavaResource(Class<?> clazz) { |
| super(clazz.getName()); |
| } |
| |
| @Override |
| public CharSequence getContent() { |
| String resourceName = getTypeName().replace('.', '/') + ".java"; |
| InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream( |
| resourceName); |
| return Util.readStreamAsString(stream); |
| } |
| } |
| |
| private static TreeLogger createCompileLogger() { |
| PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter( |
| System.err, true)); |
| logger.setMaxDetail(TreeLogger.ERROR); |
| return logger; |
| } |
| |
| private TreeLogger logger; |
| private JClassType rfedType; |
| private TypeOracle types; |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| logger = createCompileLogger(); |
| CompilationState state = |
| CompilationStateBuilder.buildFrom(logger, new CompilerContext(), getJavaResources()); |
| types = state.getTypeOracle(); |
| rfedType = types.findType(RequestFactoryEditorDriver.class.getName()); |
| assertNotNull(rfedType); |
| } |
| |
| /** |
| * Test the simple getters on the Model object. |
| */ |
| public void testBasicAttributes() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.PersonEditorDriver"), rfedType); |
| |
| assertEquals(types.findType("t.PersonEditor"), m.getEditorType()); |
| assertEquals(types.findType("t.PersonProxy"), m.getProxyType()); |
| } |
| |
| /** |
| * Verify that we correctly descend into a subeditor of a CompositeEditor that |
| * also is a LeafValueEditor (as is the case of OptionalFieldEditor). |
| */ |
| public void testCompositeAndLeafValueEditor() |
| throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.CompositeAndLeafEditorDriver"), rfedType); |
| |
| assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AProxy"), |
| m.getProxyType()); |
| assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AEditor"), |
| m.getEditorType()); |
| |
| EditorData[] data = m.getEditorData(); |
| assertEquals(1, data.length); |
| |
| assertTrue(data[0].isCompositeEditor()); |
| |
| EditorData composed = data[0].getComposedData(); |
| assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BProxy"), |
| composed.getEditedType()); |
| assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BEditor"), |
| composed.getEditorType()); |
| |
| // Nonsensical for the optional editor to have any data |
| EditorData[] optionalEditorData = m.getEditorData(data[0].getEditorType()); |
| assertEquals(0, optionalEditorData.length); |
| |
| // Make sure we have EditorData for the sub-editor |
| EditorData[] subEditorData = m.getEditorData(composed.getEditorType()); |
| assertEquals(1, subEditorData.length); |
| } |
| |
| public void testCompositeDriver() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.CompositeEditorDriver"), rfedType); |
| |
| EditorData[] data = m.getEditorData(); |
| assertEquals(9, data.length); |
| |
| String[] paths = new String[data.length]; |
| String[] expressions = new String[data.length]; |
| for (int i = 0, j = paths.length; i < j; i++) { |
| paths[i] = data[i].getPath(); |
| expressions[i] = data[i].getExpression(); |
| } |
| assertEquals(Arrays.asList("address", "address.city", "address.street", "person", "person.has", |
| "person.is", "person.lastModified", "person.name", "person.readonly"), Arrays.asList(paths)); |
| // address is a property, person is a method in CompositeEditor |
| assertEquals(Arrays.asList("address", "address.city", "address.street", "person()", |
| "person().has", "person().is", "person().lastModified", "person().name", |
| "person().readonly"), Arrays.asList(expressions)); |
| assertTrue(data[0].isDelegateRequired()); |
| assertFalse(data[0].isLeafValueEditor() || data[0].isValueAwareEditor()); |
| assertTrue(data[3].isDelegateRequired()); |
| assertFalse(data[3].isLeafValueEditor() || data[3].isValueAwareEditor()); |
| int fieldNum = 4; |
| checkPersonHasHas(data[fieldNum++]); |
| checkPersonIsIs(data[fieldNum++]); |
| checkPersonLastModified(data[fieldNum++]); |
| checkPersonName(data[fieldNum++]); |
| checkPersonReadonly(data[fieldNum++]); |
| } |
| |
| public void testCyclicDriver() { |
| UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder(); |
| builder.setLowestLogLevel(TreeLogger.ERROR); |
| builder.expectError( |
| EditorModel.cycleErrorMessage( |
| types.findType("t.CyclicEditorDriver.AEditor"), "<Root Object>", |
| "b.a"), null); |
| builder.expectError(EditorModel.poisonedMessage(), null); |
| UnitTestTreeLogger testLogger = builder.createLogger(); |
| try { |
| new EditorModel(testLogger, types.findType("t.CyclicEditorDriver"), |
| rfedType); |
| fail("Should have complained about cycle"); |
| } catch (UnableToCompleteException expected) { |
| } |
| testLogger.assertCorrectLogEntries(); |
| } |
| |
| public void testDottedPath() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.DottedPathEditorDriver"), rfedType); |
| EditorData[] fields = m.getEditorData(); |
| assertEquals(2, fields.length); |
| assertEquals("name", fields[0].getPath()); |
| assertFalse(fields[0].isDeclaredPathNested()); |
| assertEquals("", fields[0].getBeanOwnerExpression()); |
| assertEquals("true", fields[0].getBeanOwnerGuard("object")); |
| assertEquals(".getName()", fields[0].getGetterExpression()); |
| assertEquals("address.street", fields[1].getPath()); |
| assertEquals(".getAddress()", fields[1].getBeanOwnerExpression()); |
| assertEquals("object.getAddress() != null", |
| fields[1].getBeanOwnerGuard("object")); |
| assertEquals(".getStreet()", fields[1].getGetterExpression()); |
| assertEquals("setStreet", fields[1].getSetterName()); |
| assertEquals("street", fields[1].getPropertyName()); |
| assertTrue(fields[1].isDeclaredPathNested()); |
| assertEquals(types.findType("t.AddressProxy"), |
| fields[1].getPropertyOwnerType()); |
| } |
| |
| /** |
| * Make sure we find all field-based editors. |
| */ |
| public void testFieldEditors() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.PersonEditorDriver"), rfedType); |
| EditorData[] fields = m.getEditorData(); |
| assertEquals(5, fields.length); |
| |
| int fieldNum = 0; |
| // hasHas |
| checkPersonHasHas(fields[fieldNum++]); |
| // isIs |
| checkPersonIsIs(fields[fieldNum++]); |
| // lastModified |
| checkPersonLastModified(fields[fieldNum++]); |
| // name |
| checkPersonName(fields[fieldNum++]); |
| // readonly |
| checkPersonReadonly(fields[fieldNum++]); |
| } |
| |
| public void testFlatData() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.CompositeEditorDriver"), rfedType); |
| |
| assertNotNull(m.getEditorData(types.getJavaLangObject())); |
| assertEquals(0, m.getEditorData(types.getJavaLangObject()).length); |
| |
| EditorData[] composite = m.getEditorData(types.findType("t.CompositeEditor")); |
| assertEquals(2, composite.length); |
| assertEquals("address", composite[0].getPropertyName()); |
| assertEquals("person", composite[1].getPropertyName()); |
| |
| EditorData[] person = m.getEditorData(types.findType("t.PersonEditor")); |
| assertEquals(5, person.length); |
| int fieldNum = 0; |
| assertEquals("has", person[fieldNum++].getPropertyName()); |
| assertEquals("is", person[fieldNum++].getPropertyName()); |
| assertEquals("lastModified", person[fieldNum++].getPropertyName()); |
| assertEquals("name", person[fieldNum++].getPropertyName()); |
| assertEquals("readonly", person[fieldNum++].getPropertyName()); |
| |
| EditorData[] address = m.getEditorData(types.findType("t.AddressEditor")); |
| assertEquals("city", address[0].getPropertyName()); |
| assertEquals("street", address[1].getPropertyName()); |
| } |
| |
| /** |
| * Tests a plain IsEditor that allows the editor instance to be swapped in by |
| * a view object. |
| */ |
| public void testIsEditor() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.UsesIsEditorDriver"), rfedType); |
| |
| EditorData[] data = m.getEditorData(); |
| assertNotNull(data); |
| assertEquals(2, data.length); |
| assertEquals(Arrays.asList("b", "b.string"), |
| Arrays.asList(data[0].getPath(), data[1].getPath())); |
| assertEquals( |
| Arrays.asList("bEditor().asEditor()", "stringEditor()"), |
| Arrays.asList(data[0].getSimpleExpression(), |
| data[1].getSimpleExpression())); |
| } |
| |
| /** |
| * Tests the case where an IsEditor also implements the Editor interface. |
| */ |
| public void testIsEditorAndEditor() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.UsesIsEditorAndEditorDriver"), rfedType); |
| |
| EditorData[] data = m.getEditorData(); |
| assertNotNull(data); |
| assertEquals(4, data.length); |
| assertEquals(Arrays.asList("b", "b.string", "b", "b.string"), |
| Arrays.asList(data[0].getPath(), data[1].getPath(), data[2].getPath(), |
| data[3].getPath())); |
| assertEquals(Arrays.asList("bEditor().asEditor()", |
| "bEditor().asEditor().coEditor()", "bEditor()", |
| "bEditor().viewEditor()"), Arrays.asList(data[0].getExpression(), |
| data[1].getExpression(), data[2].getExpression(), |
| data[3].getExpression())); |
| assertEquals( |
| Arrays.asList(true, false, true, false), |
| Arrays.asList(data[0].isDelegateRequired(), |
| data[1].isDelegateRequired(), data[2].isDelegateRequired(), |
| data[3].isDelegateRequired())); |
| } |
| |
| public void testListDriver() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.ListEditorDriver"), rfedType); |
| assertEquals(types.findType("t.PersonProxy"), m.getProxyType()); |
| assertEquals(types.findType("t.ListEditor"), m.getEditorType()); |
| |
| EditorData data = m.getRootData(); |
| assertTrue(data.isCompositeEditor()); |
| |
| EditorData composed = data.getComposedData(); |
| assertEquals(types.findType("t.AddressProxy"), composed.getEditedType()); |
| assertEquals(types.findType("t.AddressEditor"), composed.getEditorType()); |
| |
| // Nonsensical for the list editor to have any data |
| EditorData[] listEditorData = m.getEditorData(m.getEditorType()); |
| assertEquals(0, listEditorData.length); |
| |
| // Make sure we have EditorData for the sub-editor |
| EditorData[] subEditorData = m.getEditorData(composed.getEditorType()); |
| assertEquals(2, subEditorData.length); |
| } |
| |
| /** |
| * Make sure we can find all method-based editors. |
| */ |
| public void testMethodEditors() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.PersonEditorDriverUsingMethods"), rfedType); |
| EditorData[] fields = m.getEditorData(); |
| assertEquals(2, fields.length); |
| |
| // nameEditor() |
| checkPersonName(fields[0]); |
| checkPersonReadonly(fields[1]); |
| } |
| |
| /** |
| * Tests the case where an Editor wants to editor a property that is not |
| * provided by its associated Proxy type. |
| */ |
| public void testMissingGetter() { |
| UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder(); |
| builder.setLowestLogLevel(TreeLogger.ERROR); |
| builder.expectError( |
| EditorModel.noGetterMessage("missing", |
| types.findType("t.MissingGetterEditorDriver.AProxy")), null); |
| builder.expectError( |
| EditorModel.noGetterMessage("yetAgain", |
| types.findType("t.MissingGetterEditorDriver.AProxy")), null); |
| builder.expectError(EditorModel.poisonedMessage(), null); |
| UnitTestTreeLogger testLogger = builder.createLogger(); |
| try { |
| new EditorModel(testLogger, |
| types.findType("t.MissingGetterEditorDriver"), rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expecetd) { |
| } |
| testLogger.assertCorrectLogEntries(); |
| } |
| |
| /** |
| * Tests the sanity-check error messages emitted by the constructor. |
| */ |
| public void testSanityErrorMessages() { |
| UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder(); |
| builder.setLowestLogLevel(TreeLogger.ERROR); |
| builder.expectError( |
| EditorModel.unexpectedInputTypeMessage(rfedType, |
| types.getJavaLangObject()), null); |
| builder.expectError(EditorModel.mustExtendMessage(rfedType), null); |
| builder.expectError( |
| EditorModel.tooManyInterfacesMessage(types.findType("t.TooManyInterfacesEditorDriver")), |
| null); |
| builder.expectError(EditorModel.foundPrimitiveMessage(JPrimitiveType.LONG, |
| "", "lastModified.foo"), null); |
| builder.expectError(EditorModel.poisonedMessage(), null); |
| UnitTestTreeLogger testLogger = builder.createLogger(); |
| |
| try { |
| new EditorModel(testLogger, types.getJavaLangObject(), rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expected) { |
| } |
| try { |
| new EditorModel(testLogger, rfedType, rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expected) { |
| } |
| try { |
| new EditorModel(testLogger, |
| types.findType("t.TooManyInterfacesEditorDriver"), rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expected) { |
| } |
| try { |
| new EditorModel(testLogger, |
| types.findType("t.PersonEditorWithBadPrimitiveAccessDriver"), |
| rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expected) { |
| } |
| testLogger.assertCorrectLogEntries(); |
| } |
| |
| public void testUnparameterizedEditor() { |
| UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder(); |
| builder.setLowestLogLevel(TreeLogger.ERROR); |
| builder.expectError( |
| EditorModel.noEditorParameterizationMessage( |
| types.findType(Editor.class.getName()), |
| types.findType(SimpleEditor.class.getName()).isGenericType().getRawType()), |
| null); |
| UnitTestTreeLogger testLogger = builder.createLogger(); |
| try { |
| new EditorModel(testLogger, |
| types.findType("t.UnparameterizedEditorEditorDriver"), rfedType); |
| fail("Should have thrown exception"); |
| } catch (UnableToCompleteException expecetd) { |
| } |
| testLogger.assertCorrectLogEntries(); |
| } |
| |
| /** |
| * Verify that {@code @Path("")} is valid. |
| */ |
| public void testZeroLengthPath() throws UnableToCompleteException { |
| EditorModel m = new EditorModel(logger, |
| types.findType("t.PersonEditorWithAliasedSubEditorsDriver"), rfedType); |
| EditorData[] fields = m.getEditorData(); |
| assertEquals(12, fields.length); |
| } |
| |
| private void checkPersonHasHas(EditorData editorField) { |
| assertNotNull(editorField); |
| assertEquals(types.findType(SimpleEditor.class.getName()), |
| editorField.getEditorType().isParameterized().getBaseType()); |
| assertTrue(editorField.isLeafValueEditor()); |
| assertFalse(editorField.isDelegateRequired()); |
| assertFalse(editorField.isValueAwareEditor()); |
| assertEquals(".hasHas()", editorField.getGetterExpression()); |
| assertEquals("setHas", editorField.getSetterName()); |
| } |
| |
| private void checkPersonIsIs(EditorData editorField) { |
| assertNotNull(editorField); |
| assertEquals(types.findType(SimpleEditor.class.getName()), |
| editorField.getEditorType().isParameterized().getBaseType()); |
| assertTrue(editorField.isLeafValueEditor()); |
| assertFalse(editorField.isDelegateRequired()); |
| assertFalse(editorField.isValueAwareEditor()); |
| assertEquals(".isIs()", editorField.getGetterExpression()); |
| assertEquals("setIs", editorField.getSetterName()); |
| } |
| |
| private void checkPersonLastModified(EditorData editorField) { |
| assertNotNull(editorField); |
| assertEquals(types.findType(SimpleEditor.class.getName()), |
| editorField.getEditorType().isParameterized().getBaseType()); |
| assertTrue(editorField.isLeafValueEditor()); |
| assertFalse(editorField.isDelegateRequired()); |
| assertFalse(editorField.isValueAwareEditor()); |
| assertEquals(".getLastModified()", editorField.getGetterExpression()); |
| assertEquals("setLastModified", editorField.getSetterName()); |
| } |
| |
| private void checkPersonName(EditorData editorField) { |
| assertNotNull(editorField); |
| assertEquals(types.findType(SimpleEditor.class.getName()), |
| editorField.getEditorType().isParameterized().getBaseType()); |
| assertTrue(editorField.isLeafValueEditor()); |
| assertFalse(editorField.isDelegateRequired()); |
| assertFalse(editorField.isValueAwareEditor()); |
| assertEquals(".getName()", editorField.getGetterExpression()); |
| assertEquals("setName", editorField.getSetterName()); |
| } |
| |
| /** |
| * @param editorField |
| */ |
| private void checkPersonReadonly(EditorData editorField) { |
| assertNotNull(editorField); |
| assertEquals(types.findType(SimpleEditor.class.getName()), |
| editorField.getEditorType().isParameterized().getBaseType()); |
| assertTrue(editorField.isLeafValueEditor()); |
| assertFalse(editorField.isDelegateRequired()); |
| assertFalse(editorField.isValueAwareEditor()); |
| assertEquals(".getReadonly()", editorField.getGetterExpression()); |
| assertNull(editorField.getSetterName()); |
| } |
| |
| @SuppressWarnings("deprecation") |
| private Set<Resource> getDeprecatedResources() { |
| return Collections.<Resource> singleton(new EmptyMockJavaResource( |
| com.google.web.bindery.requestfactory.shared.Violation.class)); |
| } |
| |
| private Set<Resource> getJavaResources() { |
| MockJavaResource[] javaFiles = {new MockJavaResource("t.AddressProxy") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("interface AddressProxy extends EntityProxy {\n"); |
| code.append("String getCity();\n"); |
| code.append("void setCity(String city);\n"); |
| code.append("String getStreet();\n"); |
| code.append("void setStreet(String street);\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.AddressEditor") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("class AddressEditor implements Editor<AddressProxy> {\n"); |
| code.append("public SimpleEditor<String> city;\n"); |
| code.append("public SimpleEditor<String> street;\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.CompositeProxy") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("interface CompositeProxy extends EntityProxy {\n"); |
| code.append("AddressProxy getAddress();\n"); |
| code.append("PersonProxy getPerson();\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.CompositeEditor") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("class CompositeEditor implements Editor<CompositeProxy> {\n"); |
| code.append("AddressEditor address;\n"); |
| code.append("PersonEditor person(){return null;}\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.CompositeEditorDriver") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface CompositeEditorDriver extends RequestFactoryEditorDriver<CompositeProxy, CompositeEditor> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.CyclicEditorDriver") { |
| // Tests error-detection when the editor graph isn't a DAG |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface CyclicEditorDriver extends" |
| + " RequestFactoryEditorDriver<CyclicEditorDriver.AProxy," |
| + " CyclicEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy { BProxy getB(); }"); |
| code.append(" interface BProxy extends EntityProxy { AProxy getA(); }"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" BEditor bEditor();"); |
| code.append(" }"); |
| code.append(" interface BEditor extends Editor<BProxy> {"); |
| code.append(" AEditor aEditor();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.DottedPathEditorDriver") { |
| // Tests error-detection when the editor graph isn't a DAG |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("interface DottedPathEditorDriver extends" |
| + " RequestFactoryEditorDriver<PersonProxy," |
| + " DottedPathEditorDriver.PersonEditor> {\n"); |
| code.append(" interface PersonEditor extends Editor<PersonProxy> {"); |
| code.append(" SimpleEditor<String> nameEditor();"); |
| code.append(" @Editor.Path(\"address.street\")"); |
| code.append(" SimpleEditor<String> streetEditor();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.ListEditor") { |
| // Tests error-detection when the editor graph isn't a DAG |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + CompositeEditor.class.getName() + ";\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("interface ListEditor extends CompositeEditor<PersonProxy, AddressProxy, AddressEditor>, Editor<PersonProxy> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.ListEditorDriver") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface ListEditorDriver extends RequestFactoryEditorDriver<PersonProxy, ListEditor> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.MissingGetterEditorDriver") { |
| // Tests error-detection when the editor structure doesn't match the |
| // proxy |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("interface MissingGetterEditorDriver extends" |
| + " RequestFactoryEditorDriver<MissingGetterEditorDriver.AProxy," |
| + " MissingGetterEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy {}"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" SimpleEditor<String> missingEditor();"); |
| code.append(" SimpleEditor<String> yetAgain();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonProxy") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("interface PersonProxy extends EntityProxy {\n"); |
| code.append("AddressProxy getAddress();\n"); |
| code.append("String getName();\n"); |
| code.append("long getLastModified();\n"); |
| code.append("String getReadonly();\n"); |
| code.append("boolean hasHas();\n"); |
| code.append("boolean isIs();\n"); |
| code.append("void setHas(boolean has);\n"); |
| code.append("void setIs(boolean is);\n"); |
| code.append("void setName(String name);\n"); |
| code.append("void setLastModified(long value);\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditor") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("class PersonEditor implements Editor<PersonProxy> {\n"); |
| code.append("SimpleEditor<Boolean> has;\n"); |
| code.append("SimpleEditor<Boolean> is;\n"); |
| code.append("SimpleEditor<Long> lastModified;\n"); |
| code.append("public SimpleEditor<String> name;\n"); |
| code.append("SimpleEditor<String> readonly;\n"); |
| code.append("public static SimpleEditor ignoredStatic;\n"); |
| code.append("private SimpleEditor<String> ignoredPrivate;\n"); |
| code.append("@Editor.Ignore public SimpleEditor<String> ignoredPublic;\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorWithAliasedSubEditors") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("class PersonEditorWithAliasedSubEditors implements Editor<PersonProxy> {\n"); |
| code.append("@Path(\"\") PersonEditor e1;\n"); |
| code.append("@Path(\"\") PersonEditor e2;\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorWithAliasedSubEditorsDriver") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface PersonEditorWithAliasedSubEditorsDriver extends" |
| + " RequestFactoryEditorDriver<PersonProxy, t.PersonEditorWithAliasedSubEditors> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccess") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("class PersonEditorWithBadPrimitiveAccess implements Editor<PersonProxy> {\n"); |
| code.append("@Path(\"lastModified.foo\") SimpleEditor<String> bad;\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccessDriver") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface PersonEditorWithBadPrimitiveAccessDriver extends" |
| + " RequestFactoryEditorDriver<PersonProxy, t.PersonEditorWithBadPrimitiveAccess> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorUsingMethods") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("abstract class PersonEditorUsingMethods implements Editor<PersonProxy> {\n"); |
| code.append("public abstract SimpleEditor<String> nameEditor();\n"); |
| code.append("protected abstract SimpleEditor<String> readonlyEditor();\n"); |
| code.append("public static SimpleEditor<String> ignoredStatic() {return null;}\n"); |
| code.append("private SimpleEditor<String> ignoredPrivate() {return null;}\n"); |
| code.append("@Editor.Ignore public abstract SimpleEditor<String> ignoredPublic();\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorDriver") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface PersonEditorDriver extends" |
| + " RequestFactoryEditorDriver<PersonProxy, PersonEditor> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonEditorDriverUsingMethods") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface PersonEditorDriverUsingMethods extends" |
| + " RequestFactoryEditorDriver<PersonProxy, PersonEditorUsingMethods> {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.PersonRequestFactory") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactory.class.getName() + ";\n"); |
| code.append("interface PersonRequestFactory extends RequestFactory {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.TooManyInterfacesEditorDriver") { |
| // Tests a Driver interface that extends more than RFED |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("interface TooManyInterfacesEditorDriver extends" |
| + " RequestFactoryEditorDriver<CompositeProxy, CompositeEditor>," |
| + " java.io.Serializable {\n"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.UnparameterizedEditorEditorDriver") { |
| // Tests error-detection when the editor structure doesn't match the |
| // proxy |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("interface UnparameterizedEditorEditorDriver extends" |
| + " RequestFactoryEditorDriver<UnparameterizedEditorEditorDriver.AProxy," |
| + " UnparameterizedEditorEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy {}"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" SimpleEditor needsParameterization();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.UsesIsEditorDriver") { |
| // Tests error-detection when the editor structure doesn't match the |
| // proxy |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + IsEditor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("interface UsesIsEditorDriver extends" |
| + " RequestFactoryEditorDriver<UsesIsEditorDriver.AProxy," |
| + " UsesIsEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy { BProxy getB();}"); |
| code.append(" interface BProxy extends EntityProxy { String getString();}"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" BView bEditor();"); |
| code.append(" }"); |
| code.append(" interface BView extends IsEditor<BEditor> {"); |
| code.append(" @Editor.Path(\"string\") BEditor unseen();"); |
| code.append(" }"); |
| code.append(" interface BEditor extends Editor<BProxy> {"); |
| code.append(" SimpleEditor<String> stringEditor();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.UsesIsEditorAndEditorDriver") { |
| // Tests error-detection when the editor structure doesn't match the |
| // proxy |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + HasEditorErrors.class.getName() + ";\n"); |
| code.append("import " + IsEditor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("interface UsesIsEditorAndEditorDriver extends" |
| + " RequestFactoryEditorDriver<UsesIsEditorAndEditorDriver.AProxy," |
| + " UsesIsEditorAndEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy { BProxy getB();}"); |
| code.append(" interface BProxy extends EntityProxy { String getString();}"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" BView bEditor();"); |
| code.append(" }"); |
| code.append(" interface BView extends IsEditor<BEditor>, Editor<BProxy>, HasEditorErrors {"); |
| code.append(" @Editor.Path(\"string\") SimpleEditor<String> viewEditor();"); |
| code.append(" }"); |
| code.append(" interface BEditor extends Editor<BProxy> {"); |
| code.append(" @Editor.Path(\"string\") SimpleEditor<String> coEditor();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }, new MockJavaResource("t.CompositeAndLeafEditorDriver") { |
| /* |
| * Tests that we descend into sub-editor of a CompositeEditor that also is |
| * a LeafValueEditor (this is the case for the |
| * c.g.g.editor.client.adapters.OptionalFieldEditor). Also test that any |
| * editor-like fields within the LeafValueEditor are ignored. |
| */ |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package t;\n"); |
| code.append("import " + Editor.class.getName() + ";\n"); |
| code.append("import " + IsEditor.class.getName() + ";\n"); |
| code.append("import " + EntityProxy.class.getName() + ";\n"); |
| code.append("import " + RequestFactoryEditorDriver.class.getName() |
| + ";\n"); |
| code.append("import " + SimpleEditor.class.getName() + ";\n"); |
| code.append("import " + CompositeEditor.class.getName() + ";\n"); |
| code.append("import " + LeafValueEditor.class.getName() + ";\n"); |
| code.append("interface CompositeAndLeafEditorDriver extends" |
| + " RequestFactoryEditorDriver<CompositeAndLeafEditorDriver.AProxy," |
| + " CompositeAndLeafEditorDriver.AEditor> {\n"); |
| code.append(" interface AProxy extends EntityProxy { BProxy getB();}"); |
| code.append(" interface BProxy extends EntityProxy { String getString();}"); |
| code.append(" interface AEditor extends Editor<AProxy> {"); |
| code.append(" OptionalBEditor bEditor();"); |
| code.append(" }"); |
| code.append(" interface OptionalBEditor extends CompositeEditor<BProxy, BProxy, BEditor>, LeafValueEditor<BProxy> {"); |
| code.append(" LeafValueEditor<String> ignored();"); |
| code.append(" }"); |
| code.append(" interface BEditor extends Editor<BProxy> {"); |
| code.append(" @Editor.Path(\"string\") SimpleEditor<String> coEditor();"); |
| code.append(" }"); |
| code.append("}"); |
| return code; |
| } |
| }}; |
| |
| Set<Resource> toReturn = new HashSet<Resource>(Arrays.asList(javaFiles)); |
| toReturn.addAll(Arrays.asList(new Resource[] { |
| new RealJavaResource(CompositeEditor.class), |
| new EmptyMockJavaResource(ConstraintViolation.class), |
| new RealJavaResource(Editor.class), |
| new EmptyMockJavaResource(EditorDriver.class), |
| new RealJavaResource(EditorError.class), |
| new EmptyMockJavaResource(EntityProxy.class), |
| new EmptyMockJavaResource(EventBus.class), |
| new EmptyMockJavaResource(com.google.web.bindery.event.shared.EventBus.class), |
| new EmptyMockJavaResource(HasEditorDelegate.class), |
| new EmptyMockJavaResource(HasEditorErrors.class), |
| new RealJavaResource(HasText.class), |
| new RealJavaResource(IsEditor.class), |
| new EmptyMockJavaResource(Iterable.class), |
| new RealJavaResource(LeafValueEditor.class), |
| new EmptyMockJavaResource(RequestFactory.class), |
| new RealJavaResource(RequestFactoryEditorDriver.class), |
| new EmptyMockJavaResource(Request.class), |
| new EmptyMockJavaResource(RequestContext.class), |
| new RealJavaResource(SimpleEditor.class), |
| new RealJavaResource(TakesValue.class), |
| new EmptyMockJavaResource(ValueAwareEditor.class)})); |
| toReturn.addAll(getDeprecatedResources()); |
| toReturn.addAll(Arrays.asList(JavaResourceBase.getStandardResources())); |
| return toReturn; |
| } |
| } |