001/**
002 * Copyright 2010-2014 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 */
016package org.kuali.common.util.project.spring;
017
018import java.util.Properties;
019
020import org.kuali.common.util.maven.MavenConstants;
021import org.kuali.common.util.maven.MavenUtils;
022import org.kuali.common.util.maven.spring.AutowiredMavenProperties;
023import org.kuali.common.util.maven.spring.NoAutowiredMavenProperties;
024import org.kuali.common.util.project.ProjectService;
025import org.kuali.common.util.project.ProjectUtils;
026import org.kuali.common.util.project.model.Build;
027import org.kuali.common.util.project.model.Project;
028import org.kuali.common.util.project.model.ProjectIdentifier;
029import org.springframework.beans.factory.annotation.Autowired;
030import org.springframework.beans.factory.annotation.Qualifier;
031import org.springframework.context.annotation.Bean;
032import org.springframework.context.annotation.Configuration;
033import org.springframework.context.annotation.Import;
034import org.springframework.util.Assert;
035
036/**
037 * <p>
038 * This class automatically wires a <code>Project</code> object into the Spring context:
039 * 
040 * <pre>
041 * &#064;Autowired
042 * Project project;
043 * </pre>
044 * 
045 * </p>
046 * 
047 * <p>
048 * For Spring process launched by Maven via the spring-maven-plugin the project wiring is completed entirely in memory using the <code>java.util.Properties</code> object from the
049 * Maven runtime.
050 * </p>
051 * 
052 * <p>
053 * For Spring process launched using any other method, the project wiring is completed by loading the <code>project.properties</code> file corresponding to the
054 * <code>[groupId:artifactId]</code> for the current project. The properties file for the <code>kuali-util</code> project (for example) is located at:
055 * 
056 * <pre>
057 * classpath:META-INF/org/kuali/common/kuali-util/project.properties
058 * </pre>
059 * 
060 * The <code>project.properties</code> file for every Kuali project is automatically created by Maven early in the default build lifecycle, (the <code>generate-resources</code>
061 * phase) and is thus available to any build process that comes after that. For example, the <code>test</code> phase.
062 * 
063 * </p>
064 */
065@Configuration
066public class AutowiredProjectConfig {
067
068        // There can be only two results here:
069        // 1 - A project object is successfully constructed and wired into the Spring context
070        // 2 - An exception is thrown
071        // The pair of static classes below, are setup to activate via the Spring profiles "autowiredMavenProperties" and "!autowiredMavenProperties"
072        // This makes it so that one (and only one) of them will always load no matter what
073
074        // This config class loads if the Spring profile "autowiredMavenProperties" is NOT active (which will usually be the case)
075        @Configuration
076        @NoAutowiredMavenProperties
077        @Import({ ProjectServiceConfig.class })
078        static class NoAutowiredMavenPropertiesProjectConfig implements ProjectConfig {
079
080                // Something else needs to have wired this in
081                @Autowired
082                ProjectIdentifierConfig projectIdentifierConfig;
083
084                @Autowired
085                ProjectServiceConfig projectServiceConfig;
086
087                @Override
088                @Bean
089                public Project project() {
090
091                        // Get a reference to the project service
092                        ProjectService service = projectServiceConfig.projectService();
093
094                        // Get a reference to a project identifier (groupId + artifactId)
095                        ProjectIdentifier identifier = projectIdentifierConfig.projectIdentifier();
096
097                        // Use the service to load the correct project.properties file and convert to a Project object
098                        return service.getProject(identifier.getGroupId(), identifier.getArtifactId());
099                }
100        }
101
102        // This config class only loads if the Spring profile "autowiredMavenProperties" is active
103        // spring-maven-plugin activates this profile by default when Spring is launched by Maven during a build
104        @Configuration
105        @AutowiredMavenProperties
106        static class AutowiredMavenPropertiesProjectConfig implements ProjectConfig {
107
108                // spring-maven-plugin wires this in for us
109                @Autowired
110                @Qualifier(MavenConstants.PROPERTIES_BEAN_NAME)
111                Properties mavenProperties;
112
113                @Override
114                @Bean
115                public Project project() {
116
117                        // Make sure the maven properties got wired in correctly
118                        Assert.notNull(mavenProperties, "mavenProperties are null");
119
120                        // Enhance the default set of Maven properties
121                        MavenUtils.augmentProjectProperties(mavenProperties);
122
123                        // Convert the augmented properties into a Project object
124                        return ProjectUtils.getProject(mavenProperties);
125                }
126
127                @Bean
128                public Build build() {
129                        return ProjectUtils.getBuild(project());
130                }
131
132        }
133}