/* * Copyright (C) 2014 Divide.io * * 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 io.divide.dao.orientdb; import io.divide.shared.util.ReflectionUtils; import io.divide.shared.transitory.TransientObject; import com.orientechnologies.orient.core.index.OIndexFactory; import com.orientechnologies.orient.core.index.OIndexes; import com.orientechnologies.orient.core.metadata.schema.OClass; import com.orientechnologies.orient.core.metadata.schema.OType; import com.orientechnologies.orient.core.record.impl.ODocument; import java.lang.reflect.Constructor; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import static io.divide.dao.orientdb.OIndexHighLander.ID; public class ODocumentWrapper extends ODocument { public static final String indexAttribute = "index"; protected ODocumentWrapper(){ this.setAllowChainedAccess(true); this.setLazyLoad(false); } public ODocumentWrapper(ODocument doc){ this(); doc.copyTo(this); } public <B extends TransientObject> ODocumentWrapper(B b){ super(); String className = b.getObjectType(); this.setAllowChainedAccess(true); this.setLazyLoad(false); // dirty unreliable hack to add HighLanderIndexFactory to the list. if(!OIndexes.getIndexTypes().contains(ID)) try { HighLanderIndexFactory f = new HighLanderIndexFactory(); Set<OIndexFactory> set = new HashSet<OIndexFactory>(); Iterator<OIndexFactory> ite = OIndexes.getAllFactories(); while (ite.hasNext()) { set.add(ite.next()); } set.add(f); ReflectionUtils.setFinalStatic(ReflectionUtils.getClassField(OIndexes.class, "FACTORIES"), set); } catch (Exception e) { throw new RuntimeException("Unable to create OrientDBWrapper"); } if(getDatabase().getClusterIdByName(className) == -1){ OClass object = getDatabase().getMetadata().getSchema().getOrCreateClass(className); object.createProperty(indexAttribute, OType.STRING) .setMandatory(true) .setNotNull(true) .setReadonly(true); object.createIndex(className, ID, indexAttribute); getDatabase().getMetadata().getSchema().save(); } Map user = b.getUserData(); Map meta = b.getMetaData(); field(indexAttribute, b.getObjectKey(), OType.STRING); field("user_data", user); field("meta_data", meta); super.setClassNameIfExists(className); System.out.println("DB: " + getDatabase().getName() + " : " + this.getClassName() + " : " + getDatabase().getClusterIdByName(className)); } public String getKey(){ return field("meta_data." + TransientObject.OBJECT_KEY); } public static <B extends TransientObject> B toObject(ODocument doc, Class<B> type){ ODocumentWrapper w = new ODocumentWrapper(doc); return w.toObject(type); } public <B extends TransientObject> B toObject(Class<B> type){ try { Constructor<B> constructor = type.getDeclaredConstructor(); constructor.setAccessible(true); B b = constructor.newInstance(); Map user_data = (Map) ReflectionUtils.getObjectField(b, TransientObject.USER_DATA); Map meta_data = (Map) ReflectionUtils.getObjectField(b, TransientObject.META_DATA); user_data.clear(); meta_data.clear(); ReflectionUtils.setObjectField(b,TransientObject.USER_DATA,field(TransientObject.USER_DATA)); ReflectionUtils.setObjectField(b, TransientObject.META_DATA, field(TransientObject.META_DATA)); return b; } catch (Exception e) { e.printStackTrace(); return null; } } }