Created a generalized key-value store,MetaDataMap, for a map of MetaData.
Moved MetaData to wsdef from wsf. Added a Gson type adapter for Id type.
This commit is contained in:
parent
8cbdd8a030
commit
281ed6f866
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 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.gson.webservice.definition.rest;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Metadata associated with a repository for a rest resource
|
||||
*
|
||||
* @author inder
|
||||
*
|
||||
* @param <R> The resource
|
||||
*/
|
||||
public final class MetaData<R extends RestResource<R>> {
|
||||
|
||||
private final Map<String, String> map;
|
||||
|
||||
public static <RS extends RestResource<RS>> MetaData<RS> create() {
|
||||
return new MetaData<RS>();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static MetaData<?> createTypeUnsafe(Map<String, String> values) {
|
||||
return new MetaData(values);
|
||||
}
|
||||
|
||||
public MetaData() {
|
||||
this(new HashMap<String, String>());
|
||||
}
|
||||
|
||||
private MetaData(Map<String, String> values) {
|
||||
this.map = values;
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
return (String) map.get(key);
|
||||
}
|
||||
|
||||
public void putString(String key, String value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key) {
|
||||
String value = map.get(key);
|
||||
return value == null ? false : Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
public void putBoolean(String key, boolean value) {
|
||||
map.put(key, String.valueOf(value));
|
||||
}
|
||||
|
||||
public void remove(String key) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gson Type adapter for {@link MetaData}. The serialized representation on wire is just a
|
||||
* Map<String, String>
|
||||
*/
|
||||
public static final class GsonTypeAdapter implements JsonSerializer<MetaData<?>>,
|
||||
JsonDeserializer<MetaData<?>>{
|
||||
|
||||
private static final Type MAP_TYPE = new TypeToken<Map<String, String>>(){}.getType();
|
||||
|
||||
@Override
|
||||
public MetaData<?> deserialize(JsonElement json, Type typeOfT,
|
||||
JsonDeserializationContext context) throws JsonParseException {
|
||||
Map<String, String> map = context.deserialize(json, MAP_TYPE);
|
||||
return MetaData.createTypeUnsafe(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(MetaData<?> src, Type typeOfSrc,
|
||||
JsonSerializationContext context) {
|
||||
return context.serialize(src.map, MAP_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,5 +23,4 @@ package com.google.gson.webservice.definition.rest;
|
||||
* @param <R> the rest resource type
|
||||
*/
|
||||
public interface RestResource<R> extends HasId<R> {
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 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.gson.webservice.typeadapters;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.webservice.definition.rest.Id;
|
||||
|
||||
/**
|
||||
* Type adapter for converting an Id to its serialized form
|
||||
*
|
||||
* @author inder
|
||||
*
|
||||
*/
|
||||
public final class IdTypeAdapter implements JsonSerializer<Id<?>>, JsonDeserializer<Id<?>> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Id<?> src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
if (!(typeOfT instanceof ParameterizedType)) {
|
||||
throw new JsonParseException("Id of unknown type: " + typeOfT);
|
||||
}
|
||||
ParameterizedType parameterizedType = (ParameterizedType) typeOfT;
|
||||
// Since Id takes only one TypeVariable, the actual type corresponding to the first
|
||||
// TypeVariable is the Type we are looking for
|
||||
Type typeOfId = parameterizedType.getActualTypeArguments()[0];
|
||||
return Id.get(json.getAsLong(), typeOfId);
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 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.gson.webservice.typeadapters;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.webservice.definition.rest.Id;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link IdTypeAdapter}
|
||||
*
|
||||
* @author inder
|
||||
*/
|
||||
public class IdTypeAdapterTest extends TestCase {
|
||||
private static final Id<Student> STUDENT1_ID = Id.get(5L, Student.class);
|
||||
private static final Id<Student> STUDENT2_ID = Id.get(6L, Student.class);
|
||||
private static final Student STUDENT1 = new Student(STUDENT1_ID, "first");
|
||||
private static final Student STUDENT2 = new Student(STUDENT2_ID, "second");
|
||||
private static final Type TYPE_COURSE_HISTORY =
|
||||
new TypeToken<Course<HistoryCourse>>(){}.getType();
|
||||
private static final Id<Course<HistoryCourse>> COURSE_ID = Id.get(10L, TYPE_COURSE_HISTORY);
|
||||
|
||||
private Gson gson;
|
||||
private Course<HistoryCourse> course;
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Id.class, new IdTypeAdapter())
|
||||
.create();
|
||||
course = new Course<HistoryCourse>(COURSE_ID, 4,
|
||||
new Assignment<HistoryCourse>(null, null), createList(STUDENT1, STUDENT2));
|
||||
}
|
||||
|
||||
public void testSerializeId() {
|
||||
String json = gson.toJson(course, TYPE_COURSE_HISTORY);
|
||||
System.out.println(json);
|
||||
assertTrue(json.contains(String.valueOf(COURSE_ID.getValue())));
|
||||
assertTrue(json.contains(String.valueOf(STUDENT1_ID.getValue())));
|
||||
assertTrue(json.contains(String.valueOf(STUDENT2_ID.getValue())));
|
||||
}
|
||||
|
||||
public void testDeserializeId() {
|
||||
String json = "{courseId:1,students:[{id:1,name:'first'},{id:6,name:'second'}],"
|
||||
+ "numAssignments:4,assignment:{}}";
|
||||
Course<HistoryCourse> target = gson.fromJson(json, TYPE_COURSE_HISTORY);
|
||||
assertEquals(1, target.getStudents().get(0).id.getValue());
|
||||
assertEquals(6, target.getStudents().get(1).id.getValue());
|
||||
assertEquals(1, target.getId().getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class Student {
|
||||
Id<Student> id;
|
||||
String name;
|
||||
|
||||
private Student() {
|
||||
this(null, null);
|
||||
}
|
||||
public Student(Id<Student> id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
private static class Course<T> {
|
||||
final List<Student> students;
|
||||
private final Id<Course<T>> courseId;
|
||||
private final int numAssignments;
|
||||
private final Assignment<T> assignment;
|
||||
|
||||
private Course() {
|
||||
this(null, 0, null, new ArrayList<Student>());
|
||||
}
|
||||
|
||||
public Course(Id<Course<T>> courseId, int numAssignments,
|
||||
Assignment<T> assignment, List<Student> players) {
|
||||
this.courseId = courseId;
|
||||
this.numAssignments = numAssignments;
|
||||
this.assignment = assignment;
|
||||
this.students = players;
|
||||
}
|
||||
public Id<Course<T>> getId() {
|
||||
return courseId;
|
||||
}
|
||||
List<Student> getStudents() {
|
||||
return students;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class Assignment<T> {
|
||||
private final Id<Assignment<T>> id;
|
||||
private final T data;
|
||||
|
||||
private Assignment() {
|
||||
this(null, null);
|
||||
}
|
||||
public Assignment(Id<Assignment<T>> id, T data) {
|
||||
this.id = id;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class HistoryCourse {
|
||||
int numClasses;
|
||||
}
|
||||
|
||||
private static <T> List<T> createList(T ...items) {
|
||||
return Arrays.asList(items);
|
||||
}
|
||||
}
|
@ -15,24 +15,33 @@
|
||||
*/
|
||||
package com.google.gson.wsf.server.rest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.webservice.definition.rest.Id;
|
||||
import com.google.gson.webservice.definition.rest.MetaData;
|
||||
import com.google.gson.webservice.definition.rest.RestResource;
|
||||
|
||||
/**
|
||||
* Metadata associated with a repository for a rest resource
|
||||
* A map of resources to their MetaData
|
||||
*
|
||||
* @author inder
|
||||
*
|
||||
* @param <R> The resource
|
||||
* @param <R> the rest resource for whic the metadata is being stored
|
||||
*/
|
||||
public final class MetaData<R extends RestResource<R>> {
|
||||
public class MetaDataMap<R extends RestResource<R>> {
|
||||
private final Map<Id<R>, MetaData<R>> map;
|
||||
|
||||
final boolean freshlyAssignedId;
|
||||
|
||||
public MetaData(boolean freshlyAssignedId) {
|
||||
this.freshlyAssignedId = freshlyAssignedId;
|
||||
public MetaDataMap() {
|
||||
this.map = new HashMap<Id<R>, MetaData<R>>();
|
||||
}
|
||||
|
||||
public boolean isFreshlyAssignedId() {
|
||||
return freshlyAssignedId;
|
||||
public MetaData<R> get(Id<R> resourceId) {
|
||||
MetaData<R> metaData = map.get(resourceId);
|
||||
if (metaData == null) {
|
||||
metaData = MetaData.create();
|
||||
map.put(resourceId, metaData);
|
||||
}
|
||||
return metaData;
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ package com.google.gson.wsf.server.rest;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.webservice.definition.rest.Id;
|
||||
import com.google.gson.webservice.definition.rest.MetaData;
|
||||
import com.google.gson.webservice.definition.rest.RestResource;
|
||||
import com.google.inject.internal.Maps;
|
||||
import com.google.inject.internal.Preconditions;
|
||||
@ -30,12 +31,14 @@ import com.google.inject.internal.Preconditions;
|
||||
* @param <R> Type variable for the resource
|
||||
*/
|
||||
public class RepositoryInMemory<R extends RestResource<R>> implements Repository<R> {
|
||||
private static final String METADATA_KEY_IS_FRESHLY_ASSIGNED_ID = "isFreshlyAssignedId";
|
||||
|
||||
private final IdMap<R> resources;
|
||||
private final Map<Id<R>, MetaData<R>> metaDataMap;
|
||||
private final MetaDataMap<R> metaDataMap;
|
||||
|
||||
public RepositoryInMemory(Class<? super R> classOfResource) {
|
||||
this.resources = IdMap.create(classOfResource);
|
||||
this.metaDataMap = Maps.newHashMap();
|
||||
this.metaDataMap = new MetaDataMap<R>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +51,7 @@ public class RepositoryInMemory<R extends RestResource<R>> implements Repository
|
||||
if (metaData == null) {
|
||||
return false;
|
||||
}
|
||||
return metaData.isFreshlyAssignedId();
|
||||
return metaData.getBoolean(METADATA_KEY_IS_FRESHLY_ASSIGNED_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,7 +67,7 @@ public class RepositoryInMemory<R extends RestResource<R>> implements Repository
|
||||
}
|
||||
}
|
||||
resource = resources.put(resource);
|
||||
metaDataMap.remove(resource.getId());
|
||||
metaDataMap.get(resource.getId()).remove(METADATA_KEY_IS_FRESHLY_ASSIGNED_ID);
|
||||
return resource;
|
||||
}
|
||||
|
||||
@ -88,7 +91,7 @@ public class RepositoryInMemory<R extends RestResource<R>> implements Repository
|
||||
if (resource.getId() == null) {
|
||||
Id<R> id = resources.getNextId();
|
||||
resource.setId(id);
|
||||
metaDataMap.put(id, new MetaData<R>(true));
|
||||
metaDataMap.get(id).putBoolean(METADATA_KEY_IS_FRESHLY_ASSIGNED_ID, true);
|
||||
}
|
||||
return resource.getId();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user