Java tutorial
/* * Copyright 2011 Impetus Infotech. * * 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.impetus.kundera.mongodb; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.PersistenceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.impetus.kundera.ejb.EntityManagerImpl; import com.impetus.kundera.metadata.EntityMetadata; import com.impetus.kundera.metadata.EntityMetadata.Column; import com.impetus.kundera.metadata.EntityMetadata.Relation; import com.impetus.kundera.property.PropertyAccessException; import com.impetus.kundera.property.PropertyAccessorHelper; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; /** * Provides utility methods for handling data held in MongoDB * @author amresh.singh */ public class MongoDBDataHandler { private static Log log = LogFactory.getLog(MongoDBDataHandler.class); public Object getEntityFromDocument(EntityManagerImpl em, Class<?> entityClass, EntityMetadata m, DBObject document) { Object entity = null; try { entity = entityClass.newInstance(); //Populate entity columns List<Column> columns = m.getColumnsAsList(); for (Column column : columns) { PropertyAccessorHelper.set(entity, column.getField(), document.get(column.getName())); } //Populate embedded relationship object List<Relation> relations = m.getRelations(); for (Relation relation : relations) { Class<?> embeddedEntityClass = relation.getTargetEntity(); //Embedded entity class Field embeddedPropertyField = relation.getProperty(); //Mapped to this property boolean optional = relation.isOptional(); // Is it optional? TODO: Where to use this? EntityMetadata relMetadata = em.getMetadataManager().getEntityMetadata(embeddedEntityClass); relMetadata.addColumn(relMetadata.getIdColumn().getName(), relMetadata.getIdColumn()); //Add PK column Object embeddedObject = document.get(embeddedPropertyField.getName()); if (embeddedObject != null) { if (relation.isUnary()) { BasicDBObject relDBObj = (BasicDBObject) embeddedObject; Object embeddedEntity = new MongoDBDataHandler().getEntityFromDocument(em, embeddedEntityClass, relMetadata, relDBObj); PropertyAccessorHelper.set(entity, embeddedPropertyField, embeddedEntity); } else if (relation.isCollection()) { BasicDBList relList = (BasicDBList) embeddedObject; //List of embedded objects Collection<Object> embeddedEntities = null; //Collection of embedded entities if (relation.getPropertyType().equals(Set.class)) { embeddedEntities = new HashSet<Object>(); } else if (relation.getPropertyType().equals(List.class)) { embeddedEntities = new ArrayList<Object>(); } for (int i = 0; i < relList.size(); i++) { BasicDBObject relObj = (BasicDBObject) relList.get(i); Object embeddedEntity = new MongoDBDataHandler().getEntityFromDocument(em, embeddedEntityClass, relMetadata, relObj); embeddedEntities.add(embeddedEntity); } PropertyAccessorHelper.set(entity, embeddedPropertyField, embeddedEntities); } } } } catch (InstantiationException e) { log.error("Error while instantiating " + entityClass + ". Details:" + e.getMessage()); return entity; } catch (IllegalAccessException e) { log.error("Error while Getting entity from Document. Details:" + e.getMessage()); return entity; } catch (PropertyAccessException e) { log.error("Error while Getting entity from Document. Details:" + e.getMessage()); return entity; } return entity; } public BasicDBObject getDocumentFromEntity(EntityManagerImpl em, EntityMetadata m, Object entity) throws PropertyAccessException { List<Column> columns = m.getColumnsAsList(); BasicDBObject dbObj = new BasicDBObject(); //Populate columns for (Column column : columns) { try { extractEntityField(entity, dbObj, column); } catch (PropertyAccessException e1) { log.error("Can't access property " + column.getField().getName()); } } //Populate Relationship fields List<Relation> relations = m.getRelations(); for (Relation relation : relations) { // Cascade? if (!relation.getCascades().contains(CascadeType.ALL) && !relation.getCascades().contains(CascadeType.PERSIST)) { continue; } Class<?> embeddedEntityClass = relation.getTargetEntity(); //Target entity Field embeddedEntityField = relation.getProperty(); //Mapped to this property boolean optional = relation.isOptional(); // Is it optional Object embeddedObject = PropertyAccessorHelper.getObject(entity, embeddedEntityField); // Value EntityMetadata relMetadata = em.getMetadataManager().getEntityMetadata(embeddedEntityClass); relMetadata.addColumn(relMetadata.getIdColumn().getName(), relMetadata.getIdColumn()); //Add PK column if (embeddedObject == null) { if (!optional) { throw new PersistenceException( "Field " + embeddedEntityField + " is not optional, and hence must be set."); } } else { if (relation.isUnary()) { BasicDBObject relDBObj = getDocumentFromEntity(em, relMetadata, embeddedObject); dbObj.put(embeddedEntityField.getName(), relDBObj); } else if (relation.isCollection()) { Collection collection = (Collection) embeddedObject; BasicDBObject[] relDBObjects = new BasicDBObject[collection.size()]; int count = 0; for (Object o : collection) { relDBObjects[count] = getDocumentFromEntity(em, relMetadata, o); count++; } dbObj.put(embeddedEntityField.getName(), relDBObjects); } } } return dbObj; } /** * @param entity * @param dbObj * @param column * @throws PropertyAccessException */ private void extractEntityField(Object entity, BasicDBObject dbObj, Column column) throws PropertyAccessException { //A column field may be a collection(not defined as 1-to-M relationship) if (column.getField().getType().equals(List.class) || column.getField().getType().equals(Set.class)) { Collection collection = (Collection) PropertyAccessorHelper.getObject(entity, column.getField()); BasicDBList basicDBList = new BasicDBList(); for (Object o : collection) { basicDBList.add(o); } dbObj.put(column.getName(), basicDBList); } else { dbObj.put(column.getName(), PropertyAccessorHelper.getString(entity, column.getField())); } } }