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.metainf.spring;
017
018import java.io.File;
019import java.util.ArrayList;
020import java.util.Comparator;
021import java.util.List;
022import java.util.Map;
023
024import com.google.common.base.Optional;
025import com.google.common.collect.Lists;
026import org.apache.commons.lang3.StringUtils;
027import org.kuali.common.util.metainf.model.*;
028import org.kuali.common.util.metainf.service.MetaInfUtils;
029import org.kuali.common.util.nullify.NullUtils;
030import org.kuali.common.util.project.ProjectUtils;
031import org.kuali.common.util.project.model.Build;
032import org.kuali.common.util.project.model.Project;
033import org.kuali.common.util.project.spring.AutowiredProjectConfig;
034import org.kuali.common.util.spring.SpringUtils;
035import org.kuali.common.util.spring.env.EnvironmentService;
036import org.kuali.common.util.spring.service.SpringServiceConfig;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.context.annotation.Bean;
039import org.springframework.context.annotation.Configuration;
040import org.springframework.context.annotation.Import;
041
042import com.google.common.collect.Maps;
043
044/**
045 * 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
046 * 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.
047 */
048@Configuration
049@Import({ AutowiredProjectConfig.class, MetaInfExecutableConfig.class, SpringServiceConfig.class })
050public class RiceXmlConfig implements MetaInfContextsConfig {
051
052        private static final boolean DEFAULT_GENERATE_RELATIVE_PATHS = true;
053        private static final String RELATIVE_KEY = MetaInfUtils.PROPERTY_PREFIX + ".xml.relative";
054        private static final String PREFIX = "xml";
055
056        // This is used in the rice-xml module to help locate the correct .resources file containing the XML to ingest
057        public static final String INGEST_FILENAME = "ingest";
058
059        @Autowired
060        EnvironmentService env;
061
062        @Autowired
063        Project project;
064
065        @Autowired
066        Build build;
067
068        @Override
069        @Bean
070        public List<MetaInfContext> metaInfContexts() {
071        List<MetaInfContext> metaInfContexts = new ArrayList<MetaInfContext>();
072        List<String> includeStrings = Lists.newArrayList("/initial-xml/", "/upgrades/*/");
073        for (String includeString : includeStrings) {
074            for (MetaInfDataType type : getTypes()) {
075                List<MetaInfContext> contexts = getMetaInfContexts(MetaInfGroup.OTHER, includeString, type);
076                metaInfContexts.addAll(contexts);
077            }
078        }
079                return metaInfContexts;
080        }
081
082        protected List<MetaInfContext> getMetaInfContexts(MetaInfGroup group, String includeString, MetaInfDataType type) {
083                List<MetaInfContext> metaInfContexts = Lists.newArrayList();
084                String includesKey = MetaInfConfigUtils.getIncludesKey(group, PREFIX);
085                String excludesKey = MetaInfConfigUtils.getExcludesKey(group, PREFIX);
086                File scanDir = build.getOutputDir();
087                String encoding = build.getEncoding();
088                Comparator<MetaInfResource> comparator = getComparator();
089        boolean relativePaths = env.getBoolean(RELATIVE_KEY, DEFAULT_GENERATE_RELATIVE_PATHS);
090        List<String> qualifiers = MetaInfUtils.getQualifiers(scanDir, project, Lists.<String>newArrayList(includeString), Lists.<String>newArrayList());
091        for (String qualifier : qualifiers) {
092            File outputFile = MetaInfUtils.getOutputFile(project, build, Optional.of(qualifier), Optional.<MetaInfDataLocation> absent(), Optional.of(type), INGEST_FILENAME);
093            Map<MetaInfGroup, String> defaultIncludes = getDefaultIncludes(project, qualifier, type);
094            Map<MetaInfGroup, String> defaultExcludes = getDefaultExcludes();
095            List<String> includes = SpringUtils.getNoneSensitiveListFromCSV(env, includesKey, defaultIncludes.get(group));
096            List<String> excludes = SpringUtils.getNoneSensitiveListFromCSV(env, excludesKey, defaultExcludes.get(group));
097            MetaInfContext context = new MetaInfContext.Builder(outputFile, encoding, scanDir).comparator(comparator).includes(includes).excludes(excludes).relativePaths(relativePaths).build();
098            metaInfContexts.add(context);
099        }
100        return metaInfContexts;
101        }
102
103    protected List<MetaInfDataType> getTypes() {
104        return Lists.newArrayList(MetaInfDataType.BOOTSTRAP, MetaInfDataType.DEMO, MetaInfDataType.TEST);
105    }
106
107        protected Comparator<MetaInfResource> getComparator() {
108                return new MetaInfResourcePathComparator();
109        }
110
111        protected Map<MetaInfGroup, String> getDefaultIncludes(Project project, String qualifier, MetaInfDataType type) {
112                String resourcePath = ProjectUtils.getResourcePath(project.getGroupId(), project.getArtifactId());
113                Map<MetaInfGroup, String> map = Maps.newHashMap();
114        List<String> paths = Lists.newArrayList(resourcePath, qualifier, type.name().toLowerCase(), "**/*.xml");
115                map.put(MetaInfGroup.OTHER, StringUtils.join(paths, "/"));
116                return map;
117        }
118
119        protected Map<MetaInfGroup, String> getDefaultExcludes() {
120                Map<MetaInfGroup, String> map = Maps.newHashMap();
121                map.put(MetaInfGroup.OTHER, NullUtils.NONE);
122                return map;
123        }
124
125}