code_junkie

How do I get my dependencies inject using @Configurable in conjunction with readResolve()

Nov 11th, 2011
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.28 KB | None | 0 0
  1. /*
  2. * Copyright 2008 Brian Thomas Matthews Limited.
  3. * All rights reserved, worldwide.
  4. *
  5. * This software and all information contained herein is the property of
  6. * Brian Thomas Matthews Limited. Any dissemination, disclosure, use, or
  7. * reproduction of this material for any reason inconsistent with the
  8. * express purpose for which it has been disclosed is strictly forbidden.
  9. */
  10.  
  11. package com.btmatthews.dmf.domain.impl.cglib;
  12.  
  13. import java.io.InvalidObjectException;
  14. import java.io.ObjectStreamException;
  15. import java.io.Serializable;
  16. import java.lang.reflect.InvocationTargetException;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19.  
  20. import org.apache.commons.beanutils.PropertyUtils;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import org.springframework.beans.factory.BeanFactory;
  24. import org.springframework.beans.factory.BeanFactoryAware;
  25. import org.springframework.beans.factory.annotation.Configurable;
  26. import org.springframework.util.StringUtils;
  27.  
  28. import com.btmatthews.dmf.domain.IEntity;
  29. import com.btmatthews.dmf.domain.IEntityFactory;
  30. import com.btmatthews.dmf.domain.IEntityID;
  31. import com.btmatthews.dmf.spring.IEntityDefinitionBean;
  32.  
  33. /**
  34. * This class represents the serialized form of a domain object implemented
  35. * using CGLib. The readResolve() method recreates the actual domain object
  36. * after it has been deserialized into Serializable. You must define
  37. * <spring-configured/> in the application context.
  38. *
  39. * @param <S>
  40. * The interface that defines the properties of the base domain
  41. * object.
  42. * @param <T>
  43. * The interface that defines the properties of the derived domain
  44. * object.
  45. * @author <a href="mailto:[email protected]">Brian Matthews</a>
  46. * @version 1.0
  47. */
  48. @Configurable(preConstruction = true)
  49. public final class SerializedCGLibEntity<S extends IEntity<S>, T extends S>
  50. implements Serializable, BeanFactoryAware
  51. {
  52. /**
  53. * Used for logging.
  54. */
  55. private static final Logger LOG = LoggerFactory
  56. .getLogger(SerializedCGLibEntity.class);
  57.  
  58. /**
  59. * The serialization version number.
  60. */
  61. private static final long serialVersionUID = 3830830321957878319L;
  62.  
  63. /**
  64. * The application context. Note this is not serialized.
  65. */
  66. private transient BeanFactory beanFactory;
  67.  
  68. /**
  69. * The domain object name.
  70. */
  71. private String entityName;
  72.  
  73. /**
  74. * The domain object identifier.
  75. */
  76. private IEntityID<S> entityId;
  77.  
  78. /**
  79. * The domain object version number.
  80. */
  81. private long entityVersion;
  82.  
  83. /**
  84. * The attributes of the domain object.
  85. */
  86. private HashMap<?, ?> entityAttributes;
  87.  
  88. /**
  89. * The default constructor.
  90. */
  91. public SerializedCGLibEntity()
  92. {
  93. SerializedCGLibEntity.LOG
  94. .debug("Initializing with default constructor");
  95. }
  96.  
  97. /**
  98. * Initialise with the attributes to be serialised.
  99. *
  100. * @param name
  101. * The entity name.
  102. * @param id
  103. * The domain object identifier.
  104. * @param version
  105. * The entity version.
  106. * @param attributes
  107. * The entity attributes.
  108. */
  109. public SerializedCGLibEntity(final String name, final IEntityID<S> id,
  110. final long version, final HashMap<?, ?> attributes)
  111. {
  112. SerializedCGLibEntity.LOG
  113. .debug("Initializing with parameterized constructor");
  114.  
  115. this.entityName = name;
  116. this.entityId = id;
  117. this.entityVersion = version;
  118. this.entityAttributes = attributes;
  119. }
  120.  
  121. /**
  122. * Inject the bean factory.
  123. *
  124. * @param factory
  125. * The bean factory.
  126. */
  127. public void setBeanFactory(final BeanFactory factory)
  128. {
  129. SerializedCGLibEntity.LOG.debug("Injected bean factory");
  130.  
  131. this.beanFactory = factory;
  132. }
  133.  
  134. /**
  135. * Called after deserialisation. The corresponding entity factory is
  136. * retrieved from the bean application context and BeanUtils methods are
  137. * used to initialise the object.
  138. *
  139. * @return The initialised domain object.
  140. * @throws ObjectStreamException
  141. * If there was a problem creating or initialising the domain
  142. * object.
  143. */
  144. public Object readResolve()
  145. throws ObjectStreamException
  146. {
  147. SerializedCGLibEntity.LOG.debug("Transforming deserialized object");
  148.  
  149. final T entity = this.createEntity();
  150. entity.setId(this.entityId);
  151. try
  152. {
  153. PropertyUtils.setSimpleProperty(entity, "version",
  154. this.entityVersion);
  155. for (Map.Entry<?, ?> entry : this.entityAttributes.entrySet())
  156. {
  157. PropertyUtils.setSimpleProperty(entity, entry.getKey()
  158. .toString(), entry.getValue());
  159. }
  160. }
  161. catch (IllegalAccessException e)
  162. {
  163. throw new InvalidObjectException(e.getMessage());
  164. }
  165. catch (InvocationTargetException e)
  166. {
  167. throw new InvalidObjectException(e.getMessage());
  168. }
  169. catch (NoSuchMethodException e)
  170. {
  171. throw new InvalidObjectException(e.getMessage());
  172. }
  173. return entity;
  174. }
  175.  
  176. /**
  177. * Lookup the entity factory in the application context and create an
  178. * instance of the entity. The entity factory is located by getting the
  179. * entity definition bean and using the factory registered with it or
  180. * getting the entity factory. The name used for the definition bean lookup
  181. * is ${entityName}Definition while ${entityName} is used for the factory
  182. * lookup.
  183. *
  184. * @return The domain object instance.
  185. * @throws ObjectStreamException
  186. * If the entity definition bean or entity factory were not
  187. * available.
  188. */
  189. @SuppressWarnings("unchecked")
  190. private T createEntity()
  191. throws ObjectStreamException
  192. {
  193. SerializedCGLibEntity.LOG.debug("Getting domain object factory");
  194.  
  195. // Try to use the entity definition bean
  196.  
  197. final IEntityDefinitionBean<S, T> entityDefinition = (IEntityDefinitionBean<S, T>)this.beanFactory
  198. .getBean(StringUtils.uncapitalize(this.entityName) + "Definition",
  199. IEntityDefinitionBean.class);
  200.  
  201. if (entityDefinition != null)
  202. {
  203. final IEntityFactory<S, T> entityFactory = entityDefinition
  204. .getFactory();
  205. if (entityFactory != null)
  206. {
  207. SerializedCGLibEntity.LOG
  208. .debug("Domain object factory obtained via enity definition bean");
  209.  
  210. return entityFactory.create();
  211. }
  212. }
  213.  
  214. // Try to use the entity factory
  215.  
  216. final IEntityFactory<S, T> entityFactory = (IEntityFactory<S, T>)this.beanFactory
  217. .getBean(StringUtils.uncapitalize(this.entityName) + "Factory",
  218. IEntityFactory.class);
  219.  
  220. if (entityFactory != null)
  221. {
  222. SerializedCGLibEntity.LOG
  223. .debug("Domain object factory obtained via direct look-up");
  224.  
  225. return entityFactory.create();
  226. }
  227.  
  228. // Neither worked!
  229.  
  230. SerializedCGLibEntity.LOG.warn("Cannot find domain object factory");
  231.  
  232. throw new InvalidObjectException(
  233. "No entity definition or factory found for " + this.entityName);
  234. }
  235. }
Add Comment
Please, Sign In to add comment