001package org.kuali.common.util.metainf.spring; 002 003import java.io.File; 004import java.util.ArrayList; 005import java.util.Comparator; 006import java.util.List; 007import java.util.Map; 008 009import com.google.common.base.Optional; 010import com.google.common.collect.Lists; 011import org.apache.commons.lang3.StringUtils; 012import org.kuali.common.util.metainf.model.*; 013import org.kuali.common.util.metainf.service.MetaInfUtils; 014import org.kuali.common.util.nullify.NullUtils; 015import org.kuali.common.util.project.ProjectUtils; 016import org.kuali.common.util.project.model.Build; 017import org.kuali.common.util.project.model.Project; 018import org.kuali.common.util.project.spring.AutowiredProjectConfig; 019import org.kuali.common.util.spring.SpringUtils; 020import org.kuali.common.util.spring.env.EnvironmentService; 021import org.kuali.common.util.spring.service.SpringServiceConfig; 022import org.springframework.beans.factory.annotation.Autowired; 023import org.springframework.context.annotation.Bean; 024import org.springframework.context.annotation.Configuration; 025import org.springframework.context.annotation.Import; 026 027import com.google.common.collect.Maps; 028 029/** 030 * TODO Should not be a class called {@code RiceXmlConfig} down here in kuali-util. Create a rice-util and move this there? Main issue preventing this from living in the rice-xml 031 * module itself is that it gets tricky having software used very early in the build lifecycle reside in the same project that makes use of it. 032 */ 033@Configuration 034@Import({ AutowiredProjectConfig.class, MetaInfExecutableConfig.class, SpringServiceConfig.class }) 035public class RiceXmlConfig implements MetaInfContextsConfig { 036 037 private static final boolean DEFAULT_GENERATE_RELATIVE_PATHS = true; 038 private static final String RELATIVE_KEY = MetaInfUtils.PROPERTY_PREFIX + ".xml.relative"; 039 private static final String PREFIX = "xml"; 040 041 // This is used in the rice-xml module to help locate the correct .resources file containing the XML to ingest 042 public static final String INGEST_FILENAME = "ingest"; 043 044 @Autowired 045 EnvironmentService env; 046 047 @Autowired 048 Project project; 049 050 @Autowired 051 Build build; 052 053 @Override 054 @Bean 055 public List<MetaInfContext> metaInfContexts() { 056 List<MetaInfContext> metaInfContexts = new ArrayList<MetaInfContext>(); 057 List<String> includeStrings = Lists.newArrayList("/initial-xml/", "/upgrades/*/"); 058 for (String includeString : includeStrings) { 059 for (MetaInfDataType type : getTypes()) { 060 List<MetaInfContext> contexts = getMetaInfContexts(MetaInfGroup.OTHER, includeString, type); 061 metaInfContexts.addAll(contexts); 062 } 063 } 064 return metaInfContexts; 065 } 066 067 protected List<MetaInfContext> getMetaInfContexts(MetaInfGroup group, String includeString, MetaInfDataType type) { 068 List<MetaInfContext> metaInfContexts = Lists.newArrayList(); 069 String includesKey = MetaInfConfigUtils.getIncludesKey(group, PREFIX); 070 String excludesKey = MetaInfConfigUtils.getExcludesKey(group, PREFIX); 071 File scanDir = build.getOutputDir(); 072 String encoding = build.getEncoding(); 073 Comparator<MetaInfResource> comparator = getComparator(); 074 boolean relativePaths = env.getBoolean(RELATIVE_KEY, DEFAULT_GENERATE_RELATIVE_PATHS); 075 List<String> qualifiers = MetaInfUtils.getQualifiers(scanDir, project, Lists.<String>newArrayList(includeString), Lists.<String>newArrayList()); 076 for (String qualifier : qualifiers) { 077 File outputFile = MetaInfUtils.getOutputFile(project, build, Optional.of(qualifier), Optional.<MetaInfDataLocation> absent(), Optional.of(type), INGEST_FILENAME); 078 Map<MetaInfGroup, String> defaultIncludes = getDefaultIncludes(project, qualifier, type); 079 Map<MetaInfGroup, String> defaultExcludes = getDefaultExcludes(); 080 List<String> includes = SpringUtils.getNoneSensitiveListFromCSV(env, includesKey, defaultIncludes.get(group)); 081 List<String> excludes = SpringUtils.getNoneSensitiveListFromCSV(env, excludesKey, defaultExcludes.get(group)); 082 MetaInfContext context = new MetaInfContext.Builder(outputFile, encoding, scanDir).comparator(comparator).includes(includes).excludes(excludes).relativePaths(relativePaths).build(); 083 metaInfContexts.add(context); 084 } 085 return metaInfContexts; 086 } 087 088 protected List<MetaInfDataType> getTypes() { 089 return Lists.newArrayList(MetaInfDataType.BOOTSTRAP, MetaInfDataType.DEMO, MetaInfDataType.TEST); 090 } 091 092 protected Comparator<MetaInfResource> getComparator() { 093 return new MetaInfResourcePathComparator(); 094 } 095 096 protected Map<MetaInfGroup, String> getDefaultIncludes(Project project, String qualifier, MetaInfDataType type) { 097 String resourcePath = ProjectUtils.getResourcePath(project.getGroupId(), project.getArtifactId()); 098 Map<MetaInfGroup, String> map = Maps.newHashMap(); 099 List<String> paths = Lists.newArrayList(resourcePath, qualifier, type.name().toLowerCase(), "**/*.xml"); 100 map.put(MetaInfGroup.OTHER, StringUtils.join(paths, "/")); 101 return map; 102 } 103 104 protected Map<MetaInfGroup, String> getDefaultExcludes() { 105 Map<MetaInfGroup, String> map = Maps.newHashMap(); 106 map.put(MetaInfGroup.OTHER, NullUtils.NONE); 107 return map; 108 } 109 110}