MongoStore: refactor with smaller methods
Project: http://git-wip-us.apache.org/repos/asf/gora/repo Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/4ab5a9b1 Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/4ab5a9b1 Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/4ab5a9b1 Branch: refs/heads/master Commit: 4ab5a9b190f8556993813b7afc110ea8b22f4312 Parents: 1d2d061 Author: Damien Raude-Morvan <dam...@dictanova.com> Authored: Fri May 23 12:09:35 2014 +0200 Committer: Damien Raude-Morvan <dam...@dictanova.com> Committed: Fri May 23 12:09:35 2014 +0200 ---------------------------------------------------------------------- .../apache/gora/mongodb/store/MongoMapping.java | 12 +- .../apache/gora/mongodb/store/MongoStore.java | 227 +++++++++++-------- 2 files changed, 136 insertions(+), 103 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/gora/blob/4ab5a9b1/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoMapping.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoMapping.java b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoMapping.java index bbdfb30..f5d2a34 100644 --- a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoMapping.java +++ b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoMapping.java @@ -17,12 +17,18 @@ */ package org.apache.gora.mongodb.store; +import static org.apache.gora.mongodb.store.MongoMapping.DocumentFieldType.DOCUMENT; +import static org.apache.gora.mongodb.store.MongoMapping.DocumentFieldType.LIST; +import static org.apache.gora.mongodb.store.MongoMapping.DocumentFieldType.valueOf; + import java.util.HashMap; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableList; + /** * @author Fabien Poulard <fpoul...@dictanova.com> */ @@ -114,7 +120,8 @@ public class MongoMapping { // Check field exists or not and is of valid type String intermediateFieldName = partialFieldName.toString(); if (documentFields.containsKey(intermediateFieldName)) { - if (documentFields.get(intermediateFieldName) != DocumentFieldType.DOCUMENT) + if (!ImmutableList.of(DOCUMENT, LIST).contains( + documentFields.get(intermediateFieldName))) throw new IllegalStateException("The field '" + intermediateFieldName + "' is already registered in " + "a type not compatible with the new definition of " + "field '" @@ -164,8 +171,7 @@ public class MongoMapping { String docFieldName, String fieldType) { try { // Register a new field for the mongo document - newDocumentField(docFieldName, - DocumentFieldType.valueOf(fieldType.toUpperCase())); + newDocumentField(docFieldName, valueOf(fieldType.toUpperCase())); } catch (final IllegalArgumentException e) { throw new IllegalStateException("Declared '" + fieldType + "' for class field '" + classFieldName http://git-wip-us.apache.org/repos/asf/gora/blob/4ab5a9b1/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java index 9d44291..0f37184 100644 --- a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java +++ b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java @@ -537,46 +537,13 @@ public class MongoStore<K, T extends PersistentBase> extends case MAP: BasicDBObject map = easybson.getDBObject(docf); if (map != null) { - Map<Utf8, Object> rmap = new HashMap<Utf8, Object>(); - for (Entry<String, Object> e : map.entrySet()) { - String mKey = decodeFieldKey(e.getKey()); - Object mValue = e.getValue(); - switch (fieldSchema.getValueType().getType()) { - case STRING: - rmap.put(new Utf8(mKey), new Utf8((String) mValue)); - break; - case BYTES: - rmap.put(new Utf8(mKey), ByteBuffer.wrap((byte[]) mValue)); - break; - default: - rmap.put(new Utf8(mKey), mValue); - break; - } - } - result = new DirtyMapWrapper(rmap); + result = fromMongoMap(fieldSchema, map); } break; case ARRAY: List<Object> list = easybson.getDBList(docf); - switch (fieldSchema.getElementType().getType()) { - case STRING: - List<Utf8> arrS = new ArrayList<Utf8>(); - for (Object o : list) - arrS.add(new Utf8((String) o)); - result = new DirtyListWrapper<Utf8>(arrS); - break; - case BYTES: - List<ByteBuffer> arrB = new ArrayList<ByteBuffer>(); - for (Object o : list) - arrB.add(ByteBuffer.wrap((byte[]) o)); - result = new DirtyListWrapper<ByteBuffer>(arrB); - break; - default: - List<Object> arrT = new ArrayList<Object>(); - for (Object o : list) - arrT.add(o); - result = new DirtyListWrapper<Object>(arrT); - break; + if (list != null) { + result = fromMongoList(fieldSchema, list); } break; case RECORD: @@ -625,24 +592,7 @@ public class MongoStore<K, T extends PersistentBase> extends result = easybson.getLong(docf); break; case STRING: - if (storeType == DocumentFieldType.OBJECTID) { - // Try auto-conversion of BSON data to ObjectId - // It will work if data is stored as String or as ObjectId - Object bin = easybson.get(docf); - ObjectId id = ObjectId.massageToObjectId(bin); - result = new Utf8(id.toString()); - } else if (storeType == DocumentFieldType.DATE) { - Object bin = easybson.get(docf); - if (bin instanceof Date) { - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - calendar.setTime((Date) bin); - result = new Utf8(DatatypeConverter.printDateTime(calendar)); - } else { - result = new Utf8(bin.toString()); - } - } else { - result = easybson.getUtf8String(docf); - } + result = fromMongoString(storeType, docf, easybson); break; case ENUM: result = AvroUtils.getEnumValue(fieldSchema, easybson.getUtf8String(docf) @@ -682,6 +632,77 @@ public class MongoStore<K, T extends PersistentBase> extends return result; } + private Object fromMongoList(Schema fieldSchema, List<Object> list) { + Object result; + switch (fieldSchema.getElementType().getType()) { + case STRING: + List<Utf8> arrS = new ArrayList<Utf8>(); + for (Object o : list) + arrS.add(new Utf8((String) o)); + result = new DirtyListWrapper<Utf8>(arrS); + break; + case BYTES: + List<ByteBuffer> arrB = new ArrayList<ByteBuffer>(); + for (Object o : list) + arrB.add(ByteBuffer.wrap((byte[]) o)); + result = new DirtyListWrapper<ByteBuffer>(arrB); + break; + default: + List<Object> arrT = new ArrayList<Object>(); + for (Object o : list) + arrT.add(o); + result = new DirtyListWrapper<Object>(arrT); + break; + } + return result; + } + + private Object fromMongoMap(Schema fieldSchema, BasicDBObject map) { + Object result; + Map<Utf8, Object> rmap = new HashMap<Utf8, Object>(); + for (Entry<String, Object> e : map.entrySet()) { + String mKey = decodeFieldKey(e.getKey()); + Object mValue = e.getValue(); + switch (fieldSchema.getValueType().getType()) { + case STRING: + rmap.put(new Utf8(mKey), new Utf8((String) mValue)); + break; + case BYTES: + rmap.put(new Utf8(mKey), ByteBuffer.wrap((byte[]) mValue)); + break; + default: + rmap.put(new Utf8(mKey), mValue); + break; + } + } + result = new DirtyMapWrapper(rmap); + return result; + } + + private Object fromMongoString(final DocumentFieldType storeType, + final String docf, final BSONDecorator easybson) { + Object result; + if (storeType == DocumentFieldType.OBJECTID) { + // Try auto-conversion of BSON data to ObjectId + // It will work if data is stored as String or as ObjectId + Object bin = easybson.get(docf); + ObjectId id = ObjectId.massageToObjectId(bin); + result = new Utf8(id.toString()); + } else if (storeType == DocumentFieldType.DATE) { + Object bin = easybson.get(docf); + if (bin instanceof Date) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTime((Date) bin); + result = new Utf8(DatatypeConverter.printDateTime(calendar)); + } else { + result = new Utf8(bin.toString()); + } + } else { + result = easybson.getUtf8String(docf); + } + return result; + } + // ////////////////////////////////////////////////////////// SERIALIZATION /** @@ -757,7 +778,7 @@ public class MongoStore<K, T extends PersistentBase> extends + ": to store a Gora 'map', target Mongo mapping have to be of 'document' type"); } Schema valueSchema = fieldSchema.getValueType(); - result = toMongoMap((Map<CharSequence, ?>) value, valueSchema.getType()); + result = mapToMongo((Map<CharSequence, ?>) value, valueSchema.getType()); break; case ARRAY: if (storeType != null && storeType != DocumentFieldType.LIST) { @@ -767,7 +788,7 @@ public class MongoStore<K, T extends PersistentBase> extends + ": To store a Gora 'array', target Mongo mapping have to be of 'list' type"); } Schema elementSchema = fieldSchema.getElementType(); - result = toMongoList((List<?>) value, elementSchema.getType()); + result = listToMongo((List<?>) value, elementSchema.getType()); break; case BYTES: // Beware of ByteBuffer not being safely serialized @@ -783,46 +804,7 @@ public class MongoStore<K, T extends PersistentBase> extends result = value; break; case STRING: - if (storeType == DocumentFieldType.OBJECTID) { - if (value != null) { - ObjectId id; - try { - id = new ObjectId(value.toString()); - } catch (IllegalArgumentException e1) { - // Unable to parse anything from Utf8 value, throw error - throw new IllegalStateException("Field " + fieldSchema.getType() - + ": Invalid string: unable to convert to ObjectId"); - } - result = id; - } - } else if (storeType == DocumentFieldType.DATE) { - if (value != null) { - // Try to parse date from Utf8 value - Calendar calendar = null; - try { - // Parse as date + time - calendar = DatatypeConverter.parseDateTime(value.toString()); - } catch (IllegalArgumentException e1) { - try { - // Parse as date only - calendar = DatatypeConverter.parseDate(value.toString()); - } catch (IllegalArgumentException e2) { - // No-op - } - } - if (calendar == null) { - // Unable to parse anything from Utf8 value, throw error - throw new IllegalStateException("Field " + fieldSchema.getType() - + ": Invalid date format '" + value + "'"); - } - result = calendar.getTime(); - } - } else { - // Beware of Utf8 not being safely serialized - if (value != null) { - result = value.toString(); - } - } + result = stringToMongo(fieldSchema, storeType, value); break; case ENUM: // Beware of Utf8 not being safely serialized @@ -880,6 +862,52 @@ public class MongoStore<K, T extends PersistentBase> extends return result; } + private Object stringToMongo(final Schema fieldSchema, + final DocumentFieldType storeType, final Object value) { + Object result = null; + if (storeType == DocumentFieldType.OBJECTID) { + if (value != null) { + ObjectId id; + try { + id = new ObjectId(value.toString()); + } catch (IllegalArgumentException e1) { + // Unable to parse anything from Utf8 value, throw error + throw new IllegalStateException("Field " + fieldSchema.getType() + + ": Invalid string: unable to convert to ObjectId"); + } + result = id; + } + } else if (storeType == DocumentFieldType.DATE) { + if (value != null) { + // Try to parse date from Utf8 value + Calendar calendar = null; + try { + // Parse as date + time + calendar = DatatypeConverter.parseDateTime(value.toString()); + } catch (IllegalArgumentException e1) { + try { + // Parse as date only + calendar = DatatypeConverter.parseDate(value.toString()); + } catch (IllegalArgumentException e2) { + // No-op + } + } + if (calendar == null) { + // Unable to parse anything from Utf8 value, throw error + throw new IllegalStateException("Field " + fieldSchema.getType() + + ": Invalid date format '" + value + "'"); + } + result = calendar.getTime(); + } + } else { + // Beware of Utf8 not being safely serialized + if (value != null) { + result = value.toString(); + } + } + return result; + } + /** * Convert a Java Map as used in Gora generated classes to a Map that can * safely be serialized into MongoDB. @@ -891,7 +919,7 @@ public class MongoStore<K, T extends PersistentBase> extends * @return a {@link BasicDBObject} version of the {@link Map} that can be * safely serialized into MongoDB. */ - private BasicDBObject toMongoMap(Map<CharSequence, ?> jmap, Type type) { + private BasicDBObject mapToMongo(Map<CharSequence, ?> jmap, Type type) { // Handle null case if (jmap == null) return null; @@ -909,10 +937,9 @@ public class MongoStore<K, T extends PersistentBase> extends // Beware of ByteBuffer not being safely serialized map.put(mKey, ((ByteBuffer) mValue).array()); break; - break; // FIXME Record ? default: - map.put(vKey, e.getValue()); + map.put(mKey, e.getValue()); break; } } @@ -930,7 +957,7 @@ public class MongoStore<K, T extends PersistentBase> extends * @return a {@link BasicDBList} version of the {@link GenericArray} that can * be safely serialized into MongoDB. */ - private BasicDBList toMongoList(Collection<?> array, Type type) { + private BasicDBList listToMongo(Collection<?> array, Type type) { // Handle null case if (array == null) return null;