| /* |
| * 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.server; |
| |
| import com.google.gwt.requestfactory.shared.SimpleEnum; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.Time; |
| import java.sql.Timestamp; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.validation.constraints.Size; |
| |
| /** |
| * Domain object for SimpleFooRequest. |
| */ |
| public class SimpleFoo { |
| /** |
| * DO NOT USE THIS UGLY HACK DIRECTLY! Call {@link #get} instead. |
| */ |
| private static Map<Long, SimpleFoo> jreTestSingleton; |
| |
| private static Long nextId = 1L; |
| |
| public static Integer add(Integer a, int b) { |
| return a + b; |
| } |
| |
| public static Long countSimpleFoo() { |
| return (long) get().size(); |
| } |
| |
| public static SimpleFoo echo(SimpleFoo simpleFoo) { |
| return simpleFoo; |
| } |
| |
| public static SimpleFoo echoComplex(SimpleFoo simpleFoo, SimpleBar simpleBar) { |
| simpleFoo.setBarField(simpleBar); |
| return simpleFoo; |
| } |
| |
| public static SimpleFoo fetchDoubleReference() { |
| SimpleFoo foo = new SimpleFoo(); |
| SimpleFoo foo2 = new SimpleFoo(); |
| foo.setFooField(foo2); |
| foo.setSelfOneToManyField(Arrays.asList(foo2)); |
| foo.persist(); |
| foo2.persist(); |
| return foo; |
| } |
| |
| public static List<SimpleFoo> findAll() { |
| return new ArrayList<SimpleFoo>(get().values()); |
| } |
| |
| public static SimpleFoo findSimpleFoo(Long id) { |
| return findSimpleFooById(id); |
| } |
| |
| public static SimpleFoo findSimpleFooById(Long id) { |
| return get().get(id); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static synchronized Map<Long, SimpleFoo> get() { |
| HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest(); |
| if (req == null) { |
| // May be in a JRE test case, use the singleton |
| if (jreTestSingleton == null) { |
| jreTestSingleton = resetImpl(); |
| } |
| return jreTestSingleton; |
| } else { |
| /* |
| * This will not behave entirely correctly unless we have a servlet filter |
| * that doesn't allow any requests to be processed unless they're |
| * associated with an existing session. |
| */ |
| Map<Long, SimpleFoo> value = (Map<Long, SimpleFoo>) req.getSession().getAttribute( |
| SimpleFoo.class.getCanonicalName()); |
| if (value == null) { |
| value = resetImpl(); |
| } |
| return value; |
| } |
| } |
| |
| public static List<Integer> getNumberList() { |
| ArrayList<Integer> list = new ArrayList<Integer>(); |
| list.add(1); |
| list.add(2); |
| list.add(3); |
| return list; |
| } |
| |
| public static Set<Integer> getNumberSet() { |
| Set<Integer> list = new HashSet<Integer>(); |
| list.add(1); |
| list.add(2); |
| list.add(3); |
| return list; |
| } |
| |
| /** |
| * This tests that the server detects and disallows the use of persisted |
| * objects with a null version property. |
| */ |
| public static SimpleFoo getSimpleFooWithNullVersion() { |
| SimpleFoo foo = new SimpleFoo(); |
| foo.setVersion(null); |
| return foo; |
| } |
| |
| public static SimpleFoo getSimpleFooWithSubPropertyCollection() { |
| SimpleFoo foo = new SimpleFoo(); |
| SimpleFoo subFoo = new SimpleFoo(); |
| SimpleFoo subSubFoo = new SimpleFoo(); |
| subFoo.setFooField(subSubFoo); |
| subSubFoo.setUserName("I'm here"); |
| subSubFoo.persist(); |
| subFoo.persist(); |
| foo.persist(); |
| foo.setSelfOneToManyField(Arrays.asList(subFoo)); |
| return foo; |
| } |
| |
| public static SimpleFoo getTripletReference() { |
| SimpleFoo foo1 = new SimpleFoo(); |
| SimpleFoo foo2 = new SimpleFoo(); |
| SimpleFoo foo3 = new SimpleFoo(); |
| ArrayList<SimpleFoo> foos = new ArrayList<SimpleFoo>(); |
| foos.add(foo2); |
| ArrayList<SimpleFoo> subFoos = new ArrayList<SimpleFoo>(); |
| subFoos.add(foo3); |
| foo1.setSelfOneToManyField(foos); |
| foo2.setSelfOneToManyField(subFoos); |
| foo3.setFooField(foo2); |
| foo1.persist(); |
| foo2.persist(); |
| foo3.persist(); |
| return foo1; |
| } |
| |
| public static SimpleFoo getUnpersistedInstance() { |
| SimpleFoo foo = new SimpleFoo(); |
| foo.setUnpersisted(true); |
| return foo; |
| } |
| |
| public static void pleaseCrash(Integer crashIf42or43) throws Exception { |
| if (crashIf42or43 == 42) { |
| throw new UnsupportedOperationException( |
| "THIS EXCEPTION IS EXPECTED BY A TEST"); |
| } |
| if (crashIf42or43 == 43) { |
| throw new Exception("THIS EXCEPTION IS EXPECTED BY A TEST"); |
| } |
| } |
| |
| /** |
| * Check client-side upcasting to BigDecimal and return a list of BigDecimals |
| * that should be upcast. |
| */ |
| public static List<BigDecimal> processBigDecimalList(List<BigDecimal> values) { |
| List<BigDecimal> toReturn = new ArrayList<BigDecimal>(); |
| toReturn.add(BigDecimal.TEN); |
| toReturn.add(new BigDecimal("12345.6789") { |
| // This is an anonymous subtype |
| }); |
| if (!toReturn.equals(values)) { |
| throw new IllegalArgumentException(toReturn + " != " + values); |
| } |
| return toReturn; |
| } |
| |
| /** |
| * Check client-side upcasting to BigInteger and return a list of BigIntegers |
| * that should be upcast. |
| */ |
| public static List<BigInteger> processBigIntegerList(List<BigInteger> values) { |
| List<BigInteger> toReturn = new ArrayList<BigInteger>(); |
| toReturn.add(BigInteger.TEN); |
| toReturn.add(new BigInteger("12345") { |
| // This is an anonymous subtype |
| }); |
| if (!toReturn.equals(values)) { |
| throw new IllegalArgumentException(toReturn + " != " + values); |
| } |
| return toReturn; |
| } |
| |
| public static Boolean processBooleanList(List<Boolean> values) { |
| return values.get(0); |
| } |
| |
| /** |
| * Check client-side upcasting to Date and return a list of Dates that should |
| * be upcast. |
| */ |
| @SuppressWarnings("deprecation") |
| public static List<Date> processDateList(List<Date> values) { |
| // Keep these values in sync with SimpleFoo.processDateList |
| Date date = new Date(90, 0, 1); |
| java.sql.Date sqlDate = new java.sql.Date(90, 0, 2); |
| Time sqlTime = new Time(1, 2, 3); |
| Timestamp sqlTimestamp = new Timestamp(12345L); |
| List<Date> toReturn = Arrays.asList(date, sqlDate, sqlTime, sqlTimestamp); |
| |
| if (toReturn.size() != values.size()) { |
| throw new IllegalArgumentException("size"); |
| } |
| |
| Iterator<Date> expected = toReturn.iterator(); |
| Iterator<Date> actual = values.iterator(); |
| while (expected.hasNext()) { |
| Date expectedDate = expected.next(); |
| long expectedTime = expectedDate.getTime(); |
| long actualTime = actual.next().getTime(); |
| if (expectedTime != actualTime) { |
| throw new IllegalArgumentException(expectedDate.getClass().getName() |
| + " " + expectedTime + " != " + actualTime); |
| } |
| } |
| |
| return toReturn; |
| } |
| |
| public static SimpleEnum processEnumList(List<SimpleEnum> values) { |
| return values.get(0); |
| } |
| |
| public static String processString(String string) { |
| return string; |
| } |
| |
| public static void receiveNullList(List<SimpleFoo> value) { |
| if (value != null) { |
| throw new IllegalArgumentException( |
| "Expected value to be null. Actual value: \"" + value + "\""); |
| } |
| } |
| |
| public static void receiveNullSimpleFoo(SimpleFoo value) { |
| if (value != null) { |
| throw new IllegalArgumentException( |
| "Expected value to be null. Actual value: \"" + value + "\""); |
| } |
| } |
| |
| public static void receiveNullString(String value) { |
| if (value != null) { |
| throw new IllegalArgumentException( |
| "Expected value to be null. Actual value: \"" + value + "\""); |
| } |
| } |
| |
| public static void receiveNullValueInEntityList(List<SimpleFoo> list) { |
| if (list == null) { |
| throw new IllegalArgumentException("Expected list to be non null."); |
| } else if (list.size() != 2) { |
| throw new IllegalArgumentException("Expected list to contain two items."); |
| } else if (list.get(0) == null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(0) to return non null."); |
| } else if (list.get(1) != null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(1) to return null. Actual: " + list.get(1)); |
| } |
| } |
| |
| public static void receiveNullValueInIntegerList(List<Integer> list) { |
| if (list == null) { |
| throw new IllegalArgumentException("Expected list to be non null."); |
| } else if (list.size() != 3) { |
| throw new IllegalArgumentException( |
| "Expected list to contain three items."); |
| } else if (list.get(0) == null || list.get(1) == null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(0)/get(1) to return non null."); |
| } else if (list.get(2) != null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(2) to return null. Actual: \"" + list.get(2) |
| + "\""); |
| } |
| } |
| |
| public static void receiveNullValueInStringList(List<String> list) { |
| if (list == null) { |
| throw new IllegalArgumentException("Expected list to be non null."); |
| } else if (list.size() != 3) { |
| throw new IllegalArgumentException( |
| "Expected list to contain three items."); |
| } else if (list.get(0) == null || list.get(1) == null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(0)/get(1) to return non null."); |
| } else if (list.get(2) != null) { |
| throw new IllegalArgumentException( |
| "Expected list.get(2) to return null. Actual: \"" + list.get(2) |
| + "\""); |
| } |
| } |
| |
| public static void reset() { |
| resetImpl(); |
| } |
| |
| public static synchronized Map<Long, SimpleFoo> resetImpl() { |
| Map<Long, SimpleFoo> instance = new HashMap<Long, SimpleFoo>(); |
| // fixtures |
| SimpleFoo s1 = new SimpleFoo(); |
| s1.setId(1L); |
| s1.isNew = false; |
| instance.put(s1.getId(), s1); |
| |
| SimpleFoo s2 = new SimpleFoo(); |
| s2.setId(999L); |
| s2.isNew = false; |
| instance.put(s2.getId(), s2); |
| |
| HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest(); |
| if (req == null) { |
| jreTestSingleton = instance; |
| } else { |
| req.getSession().setAttribute(SimpleFoo.class.getCanonicalName(), |
| instance); |
| } |
| return instance; |
| } |
| |
| public static List<SimpleFoo> returnNullList() { |
| return null; |
| } |
| |
| public static SimpleFoo returnNullSimpleFoo() { |
| return null; |
| } |
| |
| public static String returnNullString() { |
| return null; |
| } |
| |
| public static SimpleFoo returnSimpleFooSubclass() { |
| return new SimpleFoo() { |
| }; |
| } |
| |
| public static SimpleValue returnValueProxy() { |
| SimpleValue toReturn = new SimpleValue(); |
| toReturn.setNumber(42); |
| toReturn.setString("Hello world!"); |
| toReturn.setDate(new Date()); |
| return toReturn; |
| } |
| |
| @SuppressWarnings("unused") |
| private static Integer privateMethod() { |
| return 0; |
| } |
| |
| Integer version = 1; |
| |
| private Long id = 1L; |
| private boolean isNew = true; |
| |
| @Size(min = 3, max = 30) |
| private String userName; |
| private String password; |
| |
| private Character charField; |
| private Long longField; |
| |
| private BigDecimal bigDecimalField; |
| |
| private BigInteger bigIntField; |
| private Integer intId = -1; |
| private Short shortField; |
| |
| private Byte byteField; |
| |
| private Date created; |
| private Double doubleField; |
| |
| private Float floatField; |
| |
| private SimpleEnum enumField; |
| private Boolean boolField; |
| |
| private Boolean otherBoolField; |
| private Integer pleaseCrash; |
| |
| private SimpleBar barField; |
| private SimpleFoo fooField; |
| |
| private String nullField; |
| private SimpleBar barNullField; |
| |
| private List<SimpleBar> oneToManyField; |
| private List<SimpleFoo> selfOneToManyField; |
| private Set<SimpleBar> oneToManySetField; |
| |
| private List<Integer> numberListField; |
| |
| private SimpleValue simpleValueField; |
| |
| /* |
| * isChanged is just a quick-and-dirty way to get version-ing for now. |
| * Currently, only set by setUserName and setIntId. TODO for later: Use a |
| * cleaner solution to figure out when to increment version numbers. |
| */ |
| boolean isChanged; |
| |
| private boolean unpersisted; |
| |
| public SimpleFoo() { |
| intId = 42; |
| version = 1; |
| userName = "GWT"; |
| longField = 8L; |
| enumField = SimpleEnum.FOO; |
| created = new Date(); |
| barField = SimpleBar.getSingleton(); |
| boolField = true; |
| oneToManyField = new ArrayList<SimpleBar>(); |
| oneToManyField.add(barField); |
| oneToManyField.add(barField); |
| numberListField = new ArrayList<Integer>(); |
| numberListField.add(42); |
| numberListField.add(99); |
| selfOneToManyField = new ArrayList<SimpleFoo>(); |
| selfOneToManyField.add(this); |
| oneToManySetField = new HashSet<SimpleBar>(); |
| oneToManySetField.add(barField); |
| nullField = null; |
| barNullField = null; |
| pleaseCrash = 0; |
| isChanged = false; |
| } |
| |
| public Long countSimpleFooWithUserNameSideEffect() { |
| findSimpleFoo(1L).setUserName(userName); |
| version++; |
| return countSimpleFoo(); |
| } |
| |
| public void deleteBar() { |
| if (barField != null) { |
| isChanged = true; |
| barField.delete(); |
| } |
| barField = null; |
| persist(); |
| } |
| |
| public SimpleBar getBarField() { |
| return barField; |
| } |
| |
| public SimpleBar getBarNullField() { |
| return barNullField; |
| } |
| |
| /** |
| * Returns the bigDecimalField. |
| */ |
| public BigDecimal getBigDecimalField() { |
| return bigDecimalField; |
| } |
| |
| /** |
| * Returns the bigIntegerField. |
| */ |
| public BigInteger getBigIntField() { |
| return bigIntField; |
| } |
| |
| public Boolean getBoolField() { |
| return boolField; |
| } |
| |
| /** |
| * Returns the byteField. |
| */ |
| public Byte getByteField() { |
| return byteField; |
| } |
| |
| /** |
| * Returns the charField. |
| */ |
| public Character getCharField() { |
| return charField; |
| } |
| |
| public Date getCreated() { |
| return created; |
| } |
| |
| /** |
| * Returns the doubleField. |
| */ |
| public Double getDoubleField() { |
| return doubleField; |
| } |
| |
| public SimpleEnum getEnumField() { |
| return enumField; |
| } |
| |
| /** |
| * Returns the floatField. |
| */ |
| public Float getFloatField() { |
| return floatField; |
| } |
| |
| public SimpleFoo getFooField() { |
| return fooField; |
| } |
| |
| public Long getId() { |
| return unpersisted ? null : id; |
| } |
| |
| public Integer getIntId() { |
| return intId; |
| } |
| |
| public Long getLongField() { |
| return longField; |
| } |
| |
| public String getNullField() { |
| return nullField; |
| } |
| |
| public List<Integer> getNumberListField() { |
| return numberListField; |
| } |
| |
| public List<SimpleBar> getOneToManyField() { |
| return oneToManyField; |
| } |
| |
| public Set<SimpleBar> getOneToManySetField() { |
| return oneToManySetField; |
| } |
| |
| /** |
| * Returns the otherBoolField. |
| */ |
| public Boolean getOtherBoolField() { |
| return otherBoolField; |
| } |
| |
| public String getPassword() { |
| return password; |
| } |
| |
| public Integer getPleaseCrash() { |
| return pleaseCrash; |
| } |
| |
| public List<SimpleFoo> getSelfOneToManyField() { |
| return selfOneToManyField; |
| } |
| |
| /** |
| * Returns the shortField. |
| */ |
| public Short getShortField() { |
| return shortField; |
| } |
| |
| public SimpleValue getSimpleValue() { |
| return simpleValueField; |
| } |
| |
| public List<SimpleValue> getSimpleValues() { |
| return Arrays.asList(simpleValueField); |
| } |
| |
| public boolean getUnpersisted() { |
| return unpersisted; |
| } |
| |
| public String getUserName() { |
| return userName; |
| } |
| |
| public Integer getVersion() { |
| return unpersisted ? null : version; |
| } |
| |
| public String hello(SimpleBar bar) { |
| return "Greetings " + bar.getUserName() + " from " + getUserName(); |
| } |
| |
| public void persist() { |
| if (isNew) { |
| setId(nextId++); |
| isNew = false; |
| get().put(getId(), this); |
| } |
| if (isChanged) { |
| version++; |
| isChanged = false; |
| } |
| } |
| |
| public SimpleFoo persistAndReturnSelf() { |
| persist(); |
| return this; |
| } |
| |
| public SimpleFoo persistCascadingAndReturnSelf() { |
| persistCascadingAndReturnSelfImpl(new HashSet<SimpleFoo>()); |
| return this; |
| } |
| |
| public String processList(List<SimpleFoo> values) { |
| String result = ""; |
| for (SimpleFoo n : values) { |
| result += n.getUserName(); |
| } |
| return result; |
| } |
| |
| public void receiveNull(String value) { |
| if (value != null) { |
| throw new IllegalArgumentException( |
| "Expected value to be null. Actual value: \"" + value + "\""); |
| } |
| } |
| |
| public void setBarField(SimpleBar barField) { |
| this.barField = barField; |
| } |
| |
| public void setBarNullField(SimpleBar barNullField) { |
| this.barNullField = barNullField; |
| } |
| |
| /** |
| * @param bigDecimalField the bigDecimalField to set |
| */ |
| public void setBigDecimalField(BigDecimal bigDecimalField) { |
| this.bigDecimalField = bigDecimalField; |
| } |
| |
| /** |
| * @param bigIntegerField the bigIntegerField to set |
| */ |
| public void setBigIntField(BigInteger bigIntegerField) { |
| this.bigIntField = bigIntegerField; |
| } |
| |
| public void setBoolField(Boolean bool) { |
| boolField = bool; |
| } |
| |
| /** |
| * @param byteField the byteField to set |
| */ |
| public void setByteField(Byte byteField) { |
| this.byteField = byteField; |
| } |
| |
| /** |
| * @param charField the charField to set |
| */ |
| public void setCharField(Character charField) { |
| this.charField = charField; |
| } |
| |
| public void setCreated(Date created) { |
| this.created = created; |
| } |
| |
| /** |
| * @param doubleField the doubleField to set |
| */ |
| public void setDoubleField(Double doubleField) { |
| this.doubleField = doubleField; |
| } |
| |
| public void setEnumField(SimpleEnum enumField) { |
| this.enumField = enumField; |
| } |
| |
| /** |
| * @param floatField the floatField to set |
| */ |
| public void setFloatField(Float floatField) { |
| this.floatField = floatField; |
| } |
| |
| public void setFooField(SimpleFoo fooField) { |
| this.fooField = fooField; |
| } |
| |
| public void setId(Long id) { |
| this.id = id; |
| } |
| |
| public void setIntId(Integer id) { |
| if (!this.intId.equals(id)) { |
| this.intId = id; |
| isChanged = true; |
| } |
| } |
| |
| public void setLongField(Long longField) { |
| this.longField = longField; |
| } |
| |
| public void setNullField(String nullField) { |
| this.nullField = nullField; |
| } |
| |
| public void setNumberListField(List<Integer> numberListField) { |
| this.numberListField = numberListField; |
| } |
| |
| public void setOneToManyField(List<SimpleBar> oneToManyField) { |
| this.oneToManyField = oneToManyField; |
| } |
| |
| public void setOneToManySetField(Set<SimpleBar> oneToManySetField) { |
| this.oneToManySetField = oneToManySetField; |
| } |
| |
| /** |
| * @param otherBoolField the otherBoolField to set |
| */ |
| public void setOtherBoolField(Boolean otherBoolField) { |
| this.otherBoolField = otherBoolField; |
| } |
| |
| public void setPassword(String password) { |
| this.password = password; |
| } |
| |
| public void setPleaseCrash(Integer crashIf42or43) throws Exception { |
| pleaseCrash(crashIf42or43); |
| pleaseCrash = crashIf42or43; |
| } |
| |
| public void setSelfOneToManyField(List<SimpleFoo> selfOneToManyField) { |
| this.selfOneToManyField = selfOneToManyField; |
| } |
| |
| /** |
| * @param shortField the shortField to set |
| */ |
| public void setShortField(Short shortField) { |
| this.shortField = shortField; |
| } |
| |
| public void setSimpleValue(SimpleValue simpleValueField) { |
| this.simpleValueField = simpleValueField; |
| } |
| |
| public void setSimpleValues(List<SimpleValue> simpleValueField) { |
| this.simpleValueField = simpleValueField.get(0); |
| } |
| |
| public void setUnpersisted(boolean unpersisted) { |
| this.unpersisted = unpersisted; |
| } |
| |
| public void setUserName(String userName) { |
| if (!this.userName.equals(userName)) { |
| this.userName = userName; |
| isChanged = true; |
| } |
| } |
| |
| public void setVersion(Integer version) { |
| this.version = version; |
| } |
| |
| public Integer sum(List<Integer> values) { |
| int sum = 0; |
| for (int n : values) { |
| sum += n; |
| } |
| return sum; |
| } |
| |
| /** |
| * Persist this entity and all child entities. This method can handle loops. |
| * |
| * @param processed the entities that have been processed |
| */ |
| private void persistCascadingAndReturnSelfImpl(Set<SimpleFoo> processed) { |
| if (processed.contains(this)) { |
| return; |
| } |
| |
| // Persist this entity. |
| processed.add(this); |
| persist(); |
| |
| // Persist SimpleBar children. |
| // We don't need to keep track of the processed SimpleBars because persist() |
| // is a no-op if the SimpleBar has already been persisted. |
| if (barField != null) { |
| barField.persist(); |
| } |
| if (barNullField != null) { |
| barNullField.persist(); |
| } |
| if (oneToManySetField != null) { |
| for (SimpleBar child : oneToManySetField) { |
| if (child != null) { |
| child.persist(); |
| } |
| } |
| } |
| if (oneToManyField != null) { |
| for (SimpleBar child : oneToManyField) { |
| if (child != null) { |
| child.persist(); |
| } |
| } |
| } |
| |
| // Persist SimpleFoo children. |
| if (fooField != null) { |
| fooField.persistCascadingAndReturnSelfImpl(processed); |
| } |
| if (selfOneToManyField != null) { |
| for (SimpleFoo child : selfOneToManyField) { |
| if (child != null) { |
| child.persistCascadingAndReturnSelfImpl(processed); |
| } |
| } |
| } |
| } |
| } |