/* * Copyright 2002-2004 the original author or authors. * * 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 org.springframework.beans.factory.dynamic.persist; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.dao.DataAccessException; import org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource; /** * * @author Rod Johnson */ public abstract class AbstractPersistenceStoreRefreshableTargetSource extends AbstractRefreshableTargetSource implements DatabaseBean, BeanFactoryAware { // TODO non-object PK support private long pk; private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; private Class persistentClass; private AutowireCapableBeanFactory aabf; public AbstractPersistenceStoreRefreshableTargetSource() { // Don't want introduction to expose this SPI interface //suppressInterface(BeanFactoryAware.class); } /** * @return Returns the autowireMode. */ public int getAutowireMode() { return autowireMode; } /** * Set the type of autowiring to apply to the bean once it's * returned from the persistent store. * @param autowireMode The autowireMode to set. * 0 means no autowiring. */ public void setAutowireMode(int autowireMode) { if (autowireMode != AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE && autowireMode != AutowireCapableBeanFactory.AUTOWIRE_BY_NAME) { throw new IllegalArgumentException("Autowiring only supported by type or name"); } this.autowireMode = autowireMode; } public void setBeanFactory(BeanFactory bf) { if (bf instanceof AutowireCapableBeanFactory) { aabf = (AutowireCapableBeanFactory) bf; logger.info("Will autowire instances: running in an AutowireCapableBeanFactory"); } else { logger.warn("Cannot autowire bean instances: not in an AutowireCapableBeanFactory"); } refresh(); } /** * @return Returns the persistentClass. */ public Class getPersistentClass() { return persistentClass; } public final String getStoreDetails() { return "class=" + persistentClass + "; pk=" + pk + "; " + storeDetails(); } protected abstract String storeDetails(); /** * @param persistentClass The persistentClass to set. */ public void setPersistentClass(Class persistentClass) { this.persistentClass = persistentClass; } public synchronized long getPrimaryKey() { return pk; } public synchronized void setPrimaryKey(long pk) throws DataAccessException { this.pk = pk; } /** */ protected Object freshTarget() throws DataAccessException { // Use Hibernate to load the object logger.info("Loading persistent object with class=" + persistentClass.getName() + " and pk=" + pk); Object o = loadFromPersistentStore(); // If we have an autowire capable factory and autowiring is not switched off, // wire the instance up if (aabf != null && autowireMode != 0) { // TODO What if duping between ORM populated and BF populated?? // BF will win logger.info("Autowiring properties of persistent object with class=" + persistentClass.getName() + " and pk=" + pk); aabf.autowireBeanProperties(o, autowireMode, false); } // TODO what about publishing with the factory the dependencies of the persistent object? return o; } /** * Subclasses must implement this using Hibernate/another ORM tool. * @return */ protected abstract Object loadFromPersistentStore() throws DataAccessException; }