/* * 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); }