001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.client.tide.data.impl; 036 037import java.util.HashSet; 038import java.util.List; 039import java.util.Map; 040import java.util.Set; 041import java.util.concurrent.ConcurrentHashMap; 042import java.util.concurrent.ConcurrentMap; 043 044import org.granite.client.persistence.Persistence; 045import org.granite.client.platform.Platform; 046import org.granite.client.tide.data.EntityManager; 047import org.granite.client.tide.data.PersistenceManager; 048import org.granite.client.tide.data.spi.DataManager; 049import org.granite.logging.Logger; 050import org.granite.messaging.reflect.Property; 051import org.granite.util.UUIDUtil; 052 053/** 054 * @author William DRAI 055 */ 056public abstract class AbstractDataManager implements DataManager { 057 058 private static final Logger log = Logger.getLogger(AbstractDataManager.class); 059 060 private static ConcurrentMap<Class<?>, Set<String>> lazyPropertiesByClass = new ConcurrentHashMap<Class<?>, Set<String>>(50); 061 062 063 protected Persistence persistence = null; 064 065 public AbstractDataManager() { 066 initPersistence(); 067 } 068 069 protected void initPersistence() { 070 persistence = Platform.persistence(); 071 } 072 073 public boolean isEntity(Object entity) { 074 return entity != null && persistence.isEntity(entity.getClass()); 075 } 076 077 public Object getId(Object entity) { 078 return persistence.getId(entity); 079 } 080 081 public boolean hasIdProperty(Object entity) { 082 if (entity == null) 083 return false; 084 return persistence.hasIdProperty(entity.getClass()); 085 } 086 087 public String getDetachedState(Object entity) { 088 return persistence.getDetachedState(entity); 089 } 090 091 public Object getVersion(Object entity) { 092 return persistence.getVersion(entity); 093 } 094 095 public boolean hasVersionProperty(Object entity) { 096 if (entity == null) 097 return false; 098 return persistence.hasVersionProperty(entity.getClass()); 099 } 100 101 public String getVersionPropertyName(Object entity) { 102 if (entity == null) 103 return null; 104 Property property = persistence.getVersionProperty(entity.getClass()); 105 return property != null ? property.getName() : null; 106 } 107 108 public Object getPropertyValue(Object entity, String name) { 109 if (entity == null) 110 return null; 111 return persistence.getPropertyValue(entity, name, true); 112 } 113 114 public void setPropertyValue(Object entity, String name, Object value) { 115 if (entity == null) 116 return; 117 persistence.setPropertyValue(entity, name, value); 118 } 119 120 public String getUid(Object entity) { 121 if (entity == null) 122 return null; 123 124 if (persistence.hasUidProperty(entity.getClass())) { 125 String uid = persistence.getUid(entity); 126 if (uid == null) { 127 uid = UUIDUtil.randomUUID(); 128 persistence.setUid(entity, uid); 129 } 130 return uid; 131 } 132 Object id = persistence.getId(entity); 133 if (id != null) 134 return entity.getClass().getSimpleName() + ":" + id.toString(); 135 return entity.getClass().getSimpleName() + "::" + System.identityHashCode(entity); 136 } 137 138 public String getCacheKey(Object entity) { 139 if (entity == null) 140 return null; 141 142 return entity.getClass().getName() + ":" + getUid(entity); 143 } 144 145 public boolean isInitialized(Object object) { 146 return persistence.isInitialized(object); 147 } 148 149 150 public void copyUid(Object dest, Object obj) { 151 if (isEntity(obj) && persistence.hasUidProperty(obj.getClass())) 152 persistence.setUid(dest, persistence.getUid(obj)); 153 } 154 155 public boolean defineProxy(Object dest, Object obj) { 156 if (!isEntity(dest)) 157 return false; 158 159 try { 160 if (obj != null) { 161 if (persistence.getDetachedState(obj) == null) 162 return false; 163 persistence.setId(dest, persistence.getId(obj)); 164 persistence.setDetachedState(dest, persistence.getDetachedState(obj)); 165 } 166 persistence.setInitialized(dest, false); 167 return true; 168 } 169 catch (Exception e) { 170 throw new RuntimeException("Could not proxy class " + obj.getClass()); 171 } 172 } 173 174 public void copyProxyState(Object dest, Object obj) { 175 try { 176 persistence.setInitialized(dest, persistence.isInitialized(obj)); 177 persistence.setDetachedState(dest, persistence.getDetachedState(obj)); 178 } 179 catch (Exception e) { 180 log.error(e, "Could not copy internal state of object " + ObjectUtil.toString(obj)); 181 } 182 } 183 184 public Map<String, Object> getPropertyValues(Object entity, boolean excludeVersion, boolean includeReadOnly) { 185 return persistence.getPropertyValues(entity, true, false, excludeVersion, includeReadOnly); 186 } 187 188 public Map<String, Object> getPropertyValues(Object entity, boolean excludeIdUid, boolean excludeVersion, boolean includeReadOnly) { 189 return persistence.getPropertyValues(entity, true, excludeIdUid, excludeVersion, includeReadOnly); 190 } 191 192 193 private Set<String> getLazyPropertyNames(Class<?> entityClass) { 194 Set<String> lazyPropertyNames = lazyPropertiesByClass.get(entityClass); 195 if (lazyPropertyNames == null) { 196 List<Property> lazyProperties = persistence.getLazyProperties(entityClass); 197 lazyPropertyNames = new HashSet<String>(); 198 for (Property lazyProperty : lazyProperties) 199 lazyPropertyNames.add(lazyProperty.getName()); 200 201 lazyPropertiesByClass.putIfAbsent(entityClass, lazyPropertyNames); 202 } 203 return lazyPropertyNames; 204 } 205 206 public boolean isLazyProperty(Object entity, String propertyName) { 207 return getLazyPropertyNames(entity.getClass()).contains(propertyName); 208 } 209 210 public void setLazyProperty(Object entity, String propertyName) { 211 getLazyPropertyNames(entity.getClass()).add(propertyName); 212 } 213 214 215 public boolean isDirtyEntity(Object entity) { 216 EntityManager entityManager = PersistenceManager.getEntityManager(entity); 217 if (entityManager == null) 218 throw new IllegalStateException("Non managed entity: " + entity); 219 return entityManager.isDirtyEntity(entity); 220 } 221 222 public boolean isDeepDirtyEntity(Object entity) { 223 EntityManager entityManager = PersistenceManager.getEntityManager(entity); 224 if (entityManager == null) 225 throw new IllegalStateException("Non managed entity: " + entity); 226 return entityManager.isDeepDirtyEntity(entity); 227 } 228 229}