| /* |
| * 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.sample.dynatablerf.server; |
| |
| import com.google.gwt.sample.dynatablerf.domain.Schedule; |
| import com.google.gwt.sample.dynatablerf.domain.TimeSlot; |
| |
| import java.util.ArrayList; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Provides a number of Schedule objects as a demonstration datasource. Many of |
| * the operations in this implementation would be much more efficient in a real |
| * database, but are implemented is a straightforward fashion because they're |
| * not really important for understanding the RequestFactory framework. |
| */ |
| public abstract class ScheduleSource { |
| |
| private static int serial = 0; |
| |
| /** |
| * Backing store of schedule entities. |
| */ |
| static class Backing extends ScheduleSource { |
| |
| @Override |
| public Schedule create(Class<? extends Schedule> clazz) { |
| return new Schedule(); |
| } |
| |
| @Override |
| public Schedule find(Class<? extends Schedule> clazz, String id) { |
| if (!Schedule.class.equals(clazz)) { |
| return null; |
| } |
| return schedules.get(makeKey(id)); |
| } |
| |
| @Override |
| public Class<Schedule> getDomainType() { |
| return Schedule.class; |
| } |
| |
| @Override |
| public String getId(Schedule domainObject) { |
| return Integer.toString(domainObject.getKey()); |
| } |
| |
| @Override |
| public Class<String> getIdType() { |
| return String.class; |
| } |
| |
| @Override |
| public Object getVersion(Schedule domainObject) { |
| return domainObject.getRevision(); |
| } |
| |
| @Override |
| public void persist(Schedule domainObject) { |
| if (domainObject.getKey() == null) { |
| domainObject.setKey(newSerial()); |
| } |
| domainObject.setRevision(newSerial()); |
| Schedule existing = schedules.get(domainObject.getKey()); |
| if (existing == null) { |
| schedules.put(domainObject.getKey(), domainObject); |
| } else { |
| copyScheduleFields(domainObject, existing); |
| } |
| } |
| } |
| |
| /** |
| * Provides copy-on-read access to a ScheduleLocator. |
| */ |
| public static class CopyOnRead extends Backing { |
| private final ScheduleSource backingStore; |
| |
| public CopyOnRead(ScheduleSource backingStore) { |
| this.backingStore = backingStore; |
| } |
| |
| @Override |
| public Schedule find(Class<? extends Schedule> clazz, String id) { |
| if (!Schedule.class.equals(clazz)) { |
| return null; |
| } |
| Integer key = makeKey(id); |
| Schedule toReturn = schedules.get(key); |
| if (toReturn == null) { |
| Schedule original = backingStore.find(clazz, id); |
| if (original != null) { |
| toReturn = makeCopy(original); |
| } |
| schedules.put(key, toReturn); |
| } |
| return toReturn; |
| } |
| |
| @Override |
| public void persist(Schedule domainObject) { |
| backingStore.persist(domainObject); |
| } |
| |
| private Schedule makeCopy(Schedule source) { |
| Schedule destination = new Schedule(); |
| copyScheduleFields(source, destination); |
| return destination; |
| } |
| } |
| |
| static void copyScheduleFields(Schedule source, Schedule destination) { |
| destination.setKey(source.getKey()); |
| destination.setRevision(source.getRevision()); |
| destination.setTimeSlots(new ArrayList<TimeSlot>(source.getTimeSlots())); |
| } |
| |
| public static Backing createBacking() { |
| return new Backing(); |
| } |
| |
| public static ScheduleSource getThreadLocalObject() { |
| return SchoolCalendarService.SCHEDULE_SOURCE.get(); |
| } |
| |
| /** |
| * Create a ScheduleLocator that will act directly on the given list. |
| */ |
| public static ScheduleSource of(List<Schedule> schedules) { |
| ScheduleSource backing = createBacking(); |
| for (Schedule schedule : schedules) { |
| backing.persist(schedule); |
| } |
| return backing; |
| } |
| |
| /** |
| * Create a ScheduleLocator that will read through to the given source and make |
| * copies of any objects that are requested. |
| */ |
| public static ScheduleSource of(ScheduleSource backing) { |
| return new CopyOnRead(backing); |
| } |
| |
| private static Integer makeKey(String id) { |
| return Integer.valueOf(id); |
| } |
| |
| private static int newSerial() { |
| return ++serial; |
| } |
| |
| final Map<Integer, Schedule> schedules = new LinkedHashMap<Integer, Schedule>(); |
| |
| public abstract Schedule create(Class<? extends Schedule> clazz); |
| |
| public Schedule find(Integer key) { |
| return find(Schedule.class, key.toString()); |
| } |
| |
| public abstract Schedule find(Class<? extends Schedule> clazz, String id); |
| |
| public abstract Class<Schedule> getDomainType(); |
| |
| public abstract String getId(Schedule domainObject); |
| |
| public abstract Class<String> getIdType(); |
| |
| public abstract Object getVersion(Schedule domainObject); |
| |
| public abstract void persist(Schedule domainObject); |
| |
| } |