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 }