001    /**
002     * Copyright 2010-2013 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.common.util.spring;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    import java.util.Map;
021    import java.util.Properties;
022    
023    import org.kuali.common.util.Assert;
024    import org.kuali.common.util.FormatUtils;
025    import org.kuali.common.util.PropertyUtils;
026    import org.kuali.common.util.property.ProjectProperties;
027    import org.kuali.common.util.property.ProjectPropertiesComparator;
028    import org.kuali.common.util.property.PropertiesContext;
029    import org.slf4j.Logger;
030    import org.slf4j.LoggerFactory;
031    import org.springframework.beans.factory.FactoryBean;
032    import org.springframework.util.CollectionUtils;
033    
034    /**
035     * 
036     */
037    public class ProjectPropertiesLoaderFactoryBean implements FactoryBean<Properties> {
038    
039            private static final Logger logger = LoggerFactory.getLogger(ProjectPropertiesLoaderFactoryBean.class);
040    
041            List<String> locations;
042            boolean singleton = true;
043            ProjectPropertiesComparator comparator;
044    
045            @Override
046            public Properties getObject() {
047                    Assert.isFalse(CollectionUtils.isEmpty(locations), "locations is empty");
048                    long start = System.currentTimeMillis();
049                    List<ProjectProperties> pps = new ArrayList<ProjectProperties>();
050                    // Extract any ProjectProperties beans anywhere in the context
051                    for (String location : locations) {
052                            Map<String, ProjectProperties> beans = SpringUtils.getAllBeans(location, ProjectProperties.class);
053                            logger.info("Located {} sets of project properties", beans.size());
054    
055                            List<ProjectProperties> list = new ArrayList<ProjectProperties>();
056                            // Add them to a list
057                            for (ProjectProperties bean : beans.values()) {
058                                    list.add(bean);
059                            }
060                            // Sort them by sequence (only relevant if there is more than one which there typically is not)
061                            pps.addAll(list);
062                    }
063    
064                    // Cycle through the list we have adding in properties as we go
065                    Properties properties = new Properties();
066                    for (ProjectProperties pp : pps) {
067                            PropertiesContext ctx = pp.getPropertiesContext();
068                            Properties combined = PropertyUtils.combine(properties, ctx.getProperties());
069                            ctx.setProperties(combined);
070                            Properties loaded = PropertyUtils.load(ctx);
071                            properties.putAll(loaded);
072                    }
073                    String elapsed = FormatUtils.getTime(System.currentTimeMillis() - start);
074                    logger.info("Loaded {} properties.  Total time: {}", properties.size(), elapsed);
075                    return properties;
076            }
077    
078            @Override
079            public Class<Properties> getObjectType() {
080                    return Properties.class;
081            }
082    
083            @Override
084            public boolean isSingleton() {
085                    return singleton;
086            }
087    
088            public void setSingleton(boolean singleton) {
089                    this.singleton = singleton;
090            }
091    
092            public List<String> getLocations() {
093                    return locations;
094            }
095    
096            public void setLocations(List<String> locations) {
097                    this.locations = locations;
098            }
099    
100            public ProjectPropertiesComparator getComparator() {
101                    return comparator;
102            }
103    
104            public void setComparator(ProjectPropertiesComparator comparator) {
105                    this.comparator = comparator;
106            }
107    
108    }