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;
017    
018    import java.util.ArrayList;
019    import java.util.Arrays;
020    import java.util.List;
021    import java.util.Properties;
022    
023    import org.apache.commons.lang3.StringUtils;
024    import org.kuali.common.util.property.Constants;
025    import org.kuali.common.util.property.GlobalPropertiesMode;
026    import org.kuali.common.util.property.ProjectProperties;
027    import org.kuali.common.util.property.PropertiesContext;
028    import org.kuali.common.util.property.processor.ProjectProcessor;
029    import org.kuali.common.util.property.processor.PropertyProcessor;
030    import org.kuali.common.util.property.processor.VersionProcessor;
031    import org.kuali.common.util.service.PropertySourceContext;
032    import org.kuali.common.util.service.SpringContext;
033    import org.kuali.common.util.service.SpringService;
034    import org.kuali.common.util.spring.SpringUtils;
035    import org.slf4j.Logger;
036    import org.slf4j.LoggerFactory;
037    import org.springframework.core.env.Environment;
038    import org.springframework.core.env.PropertySource;
039    
040    public class MavenUtils {
041    
042            private static final Logger logger = LoggerFactory.getLogger(MavenUtils.class);
043    
044            public static final String POM = "pom";
045            public static final String INCLUDE = "properties.maven.include";
046            public static final String EXCLUDE = "properties.maven.exclude";
047            public static final String PROJECT_VERSION_KEY = "project.version";
048    
049            public static SpringContext getMavenizedSpringContext(SpringService service, Properties mavenProperties, Class<?> propertySourceConfig) {
050                    // This PropertySource object is backed by a set of properties that has been
051                    // 1 - fully resolved
052                    // 2 - contains all properties needed by Spring
053                    // 3 - contains system/environment properties where system/env properties override loaded properties
054                    PropertySource<?> source = getPropertySource(service, mavenProperties, propertySourceConfig);
055    
056                    // Setup a property source context such that our single property source is the only one registered with Spring
057                    // This will make it so our PropertySource is the ONLY thing to resolve placeholders
058                    PropertySourceContext psc = new PropertySourceContext(source, true);
059    
060                    // Setup a Spring context
061                    SpringContext context = new SpringContext();
062    
063                    // Supply Spring with our PropertySource
064                    context.setPropertySourceContext(psc);
065    
066                    // Return a Spring context configured with a single property source
067                    return context;
068            }
069    
070            protected static PropertySource<?> getPropertySource(SpringService service, Properties mavenProperties, Class<?> annotatedClass) {
071                    return getPropertySource(service, annotatedClass, Constants.DEFAULT_MAVEN_PROPERTIES_BEAN_NAME, mavenProperties);
072            }
073    
074            protected static PropertySource<?> getPropertySource(SpringService service, Class<?> annotatedClass, String mavenPropertiesBeanName, Properties mavenProperties) {
075                    List<PropertySource<?>> sources = SpringUtils.getPropertySources(service, annotatedClass, mavenPropertiesBeanName, mavenProperties);
076                    if (sources.size() > 1) {
077                            throw new IllegalStateException("More than one PropertySource was registered in the context");
078                    } else {
079                            return sources.get(0);
080                    }
081            }
082    
083            /**
084             * Add organization, group, and path properties and tokenize the version number adding properties for each token along with a boolean property indicating if this is a SNAPSHOT
085             * build
086             */
087            public static void augmentProjectProperties(Properties mavenProperties) {
088                    // Setup some processors
089                    List<PropertyProcessor> processors = new ArrayList<PropertyProcessor>();
090    
091                    // Add some organization, group, and path properties
092                    processors.add(new ProjectProcessor());
093    
094                    // Tokenize the version number and add properties for each token (major/minor/incremental)
095                    // Also add a boolean property indicating if this is a SNAPSHOT build
096                    processors.add(new VersionProcessor(Arrays.asList(PROJECT_VERSION_KEY), true));
097    
098                    // Process default Maven properties and add in our custom properties
099                    PropertyUtils.process(mavenProperties, processors);
100    
101                    // Make sure system/environment properties still always win
102                    PropertyUtils.overrideWithGlobalValues(mavenProperties, GlobalPropertiesMode.BOTH);
103            }
104    
105            public static void trim(Environment env, Properties mavenProperties) {
106                    List<String> excludes = getList(env, mavenProperties, EXCLUDE);
107                    List<String> includes = getList(env, mavenProperties, INCLUDE);
108                    PropertyUtils.trim(mavenProperties, includes, excludes);
109            }
110    
111            public static ProjectProperties getMavenProjectProperties(Environment env, Properties mavenProperties) {
112                    Project project = ProjectUtils.getProject(mavenProperties);
113    
114                    trim(env, mavenProperties);
115    
116                    PropertiesContext pc = new PropertiesContext();
117                    pc.setProperties(mavenProperties);
118    
119                    ProjectProperties pp = new ProjectProperties();
120                    pp.setProject(project);
121                    pp.setPropertiesContext(pc);
122                    return pp;
123            }
124    
125            protected static List<String> getList(Environment env, Properties properties, String key) {
126                    String csv1 = env.getProperty(key);
127                    String csv2 = properties.getProperty(key);
128                    List<String> list = new ArrayList<String>();
129                    list.addAll(CollectionUtils.getTrimmedListFromCSV(csv1));
130                    list.addAll(CollectionUtils.getTrimmedListFromCSV(csv2));
131                    return list;
132            }
133    
134            /**
135             * Always return false if <code>forceMojoExecution</code> is true, otherwise return true only if <code>skip</code> is true or <code>packaging</code> is pom.
136             */
137            public static final boolean skip(boolean forceMojoExecution, boolean skip, String packaging) {
138                    if (forceMojoExecution) {
139                            logger.info("Forced mojo execution");
140                            return false;
141                    }
142                    if (skip) {
143                            logger.info("Skipping mojo execution");
144                            return true;
145                    }
146                    if (StringUtils.equalsIgnoreCase(packaging, POM)) {
147                            logger.info("Skipping mojo execution for project with packaging type '{}'", POM);
148                            return true;
149                    } else {
150                            return false;
151                    }
152            }
153    
154    }