001    /**
002     * Copyright 2005-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.krad.dao.jdbc;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.ojb.broker.PBKey;
020    import org.apache.ojb.broker.PersistenceBroker;
021    import org.kuali.rice.core.api.config.ConfigurationException;
022    import org.kuali.rice.core.framework.persistence.jdbc.dao.PlatformAwareDaoBaseJdbc;
023    import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
024    import org.kuali.rice.krad.bo.BusinessObject;
025    import org.kuali.rice.krad.bo.DocumentHeader;
026    import org.kuali.rice.krad.bo.ModuleConfiguration;
027    import org.kuali.rice.krad.dao.SequenceAccessorDao;
028    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
029    import org.kuali.rice.krad.service.KualiModuleService;
030    import org.kuali.rice.krad.service.ModuleService;
031    import org.springmodules.orm.ojb.OjbFactoryUtils;
032    
033    import javax.persistence.EntityManager;
034    
035    /**
036     * This class uses the KualiDBPlatform to get the next number from a given sequence.
037     */
038    public class SequenceAccessorDaoJdbc extends PlatformAwareDaoBaseJdbc implements SequenceAccessorDao {
039            private KualiModuleService kualiModuleService;
040            
041            private Long nextAvailableSequenceNumber(String sequenceName, 
042                            Class<? extends BusinessObject> clazz) {
043                    
044            ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(clazz);
045            if ( moduleService == null )
046                    throw new ConfigurationException("moduleService is null");
047                                    
048            ModuleConfiguration moduleConfig = moduleService.getModuleConfiguration();
049            if ( moduleConfig == null )
050                    throw new ConfigurationException("moduleConfiguration is null");
051            
052            if ( OrmUtils.isJpaAnnotated(clazz) && ( OrmUtils.isJpaEnabled() ||     OrmUtils.isJpaEnabled("rice.krad") ) ) {
053                    EntityManager entityManager = moduleConfig.getEntityManager();
054                    
055                if ( entityManager != null ) 
056                    return getDbPlatform().getNextValSQL(sequenceName, entityManager);
057                else
058                    throw new ConfigurationException("EntityManager is null");
059            } 
060            else {
061                    String dataSourceName = moduleConfig.getDataSourceName();
062                    if ( StringUtils.isEmpty(dataSourceName) ) 
063                    throw new ConfigurationException("dataSourceName is not set");
064                    
065                    PBKey key = new PBKey(dataSourceName);
066                    PersistenceBroker broker = OjbFactoryUtils.getPersistenceBroker(key, false);
067                    if ( broker != null )
068                            return getDbPlatform().getNextValSQL(sequenceName, broker);
069                    else
070                            throw new ConfigurationException("PersistenceBroker is null");                                  
071            }
072            }
073            
074            public Long getNextAvailableSequenceNumber(String sequenceName, 
075                            Class<? extends BusinessObject> clazz) {
076                    
077                    // There are situations where a module hasn't been configured with
078                    // a dataSource.  In these cases, this method would have previously
079                    // thrown an error.  Instead, we've opted to factor out the code,
080                    // catch any configuration-related exceptions, and if one occurs,
081                    // attempt to use the dataSource associated with KNS. -- tbradford
082                    
083                    try {
084                            return nextAvailableSequenceNumber(sequenceName, clazz);
085                    }
086                    catch ( ConfigurationException e  ) {
087                    // Use DocumentHeader to get the dataSourceName associated with KNS                     
088                            return nextAvailableSequenceNumber(sequenceName, DocumentHeader.class);                 
089                    }
090            }
091            
092        /**
093         * @see org.kuali.rice.krad.dao.SequenceAccessorDao#getNextAvailableSequenceNumber(java.lang.String)
094         */
095        public Long getNextAvailableSequenceNumber(String sequenceName) {
096            // Use DocumentHeader to get the dataSourceName associated with KNS
097            return nextAvailableSequenceNumber(sequenceName, DocumentHeader.class);
098        }
099        
100        private KualiModuleService getKualiModuleService() {
101            if ( kualiModuleService == null ) 
102                kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
103            return kualiModuleService;
104        }
105    }