blob: 46230a43ea6e3549312095802f27f959d969dd38 [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.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);
}