View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.xml.config.spring;
17  
18  import com.google.common.base.Optional;
19  import com.google.common.collect.ImmutableList;
20  import com.google.common.collect.Lists;
21  import com.google.common.collect.Maps;
22  import org.apache.commons.lang3.StringUtils;
23  import org.kuali.common.util.metainf.model.MetaInfContext;
24  import org.kuali.common.util.metainf.model.MetaInfResource;
25  import org.kuali.common.util.metainf.model.MetaInfResourcePathComparator;
26  import org.kuali.common.util.metainf.service.MetaInfUtils;
27  import org.kuali.common.util.metainf.spring.MetaInfConfigUtils;
28  import org.kuali.common.util.metainf.spring.MetaInfContextsConfig;
29  import org.kuali.common.util.metainf.spring.MetaInfDataLocation;
30  import org.kuali.common.util.metainf.spring.MetaInfDataType;
31  import org.kuali.common.util.metainf.spring.MetaInfExecutableConfig;
32  import org.kuali.common.util.metainf.spring.MetaInfGroup;
33  import org.kuali.common.util.nullify.NullUtils;
34  import org.kuali.common.util.project.ProjectUtils;
35  import org.kuali.common.util.project.model.Build;
36  import org.kuali.common.util.project.model.Project;
37  import org.kuali.common.util.project.spring.AutowiredProjectConfig;
38  import org.kuali.common.util.spring.SpringUtils;
39  import org.kuali.common.util.spring.env.EnvironmentService;
40  import org.kuali.common.util.spring.service.SpringServiceConfig;
41  import org.springframework.beans.factory.annotation.Autowired;
42  import org.springframework.context.annotation.Bean;
43  import org.springframework.context.annotation.Configuration;
44  import org.springframework.context.annotation.Import;
45  
46  import java.io.File;
47  import java.util.Comparator;
48  import java.util.List;
49  import java.util.Map;
50  
51  /**
52   * Defines the configuration for creating the xml property files that define how the database is created.
53   *
54   * @author Kuali Rice Team (rice.collab@kuali.org)
55   */
56  @Configuration
57  @Import({ AutowiredProjectConfig.class, MetaInfExecutableConfig.class, SpringServiceConfig.class })
58  public class RiceXmlConfig implements MetaInfContextsConfig {
59  
60      private static final Boolean DEFAULT_GENERATE_RELATIVE_PATHS = Boolean.TRUE;
61      private static final String RELATIVE_KEY = MetaInfUtils.PROPERTY_PREFIX + ".xml.relative";
62      private static final String PREFIX = "xml";
63      private static final String INGEST_FILENAME = "ingest";
64  
65      // All paths must have the hardcoded separator to be consistent for deployment
66      private static final String PATH_SEPARATOR = "/";
67  
68      private static final String INITIAL_XML_PATH = "initial-xml" + PATH_SEPARATOR + "2.3.0";
69      private static final String UPGRADE_XML_PATH = "upgrades" + PATH_SEPARATOR + "*";
70      private static final String ALL_XML_PATH = "**" + PATH_SEPARATOR + "*.xml";
71  
72      /**
73       * The Spring environment.
74       */
75      @Autowired
76      EnvironmentService env;
77  
78      /**
79       * The Rice Maven project.
80       */
81      @Autowired
82      Project project;
83  
84      /**
85       * The build information.
86       */
87      @Autowired
88      Build build;
89  
90      /**
91       * {@inheritDoc}
92       */
93      @Override
94      @Bean
95      public List<MetaInfContext> metaInfContexts() {
96          List<MetaInfContext> metaInfContexts = Lists.newArrayList();
97  
98          List<MetaInfDataType> types = Lists.newArrayList(MetaInfDataType.BOOTSTRAP, MetaInfDataType.DEMO, MetaInfDataType.TEST);
99          List<String> qualifiers = Lists.newArrayList(INITIAL_XML_PATH, UPGRADE_XML_PATH);
100 
101         for (MetaInfDataType type : types) {
102             for (String qualifier : qualifiers) {
103                 List<MetaInfContext> contexts = getMetaInfContexts(MetaInfGroup.OTHER, qualifier, type);
104                 metaInfContexts.addAll(contexts);
105             }
106         }
107 
108         return ImmutableList.copyOf(metaInfContexts);
109     }
110 
111     /**
112      * Creates a list of META-INF contexts for the given {@code group}, {@code qualifier}, and {@code type}.
113      *
114      * @param group the group of the data to create the contexts for
115      * @param qualifier the prefix to add to the initial resource path
116      * @param type the type of data to create the contexts for
117      *
118      * @return a list of META-INF contexts
119      */
120     protected List<MetaInfContext> getMetaInfContexts(MetaInfGroup group, String qualifier, MetaInfDataType type) {
121         List<MetaInfContext> metaInfContexts = Lists.newArrayList();
122 
123         File scanDir = build.getOutputDir();
124         String encoding = build.getEncoding();
125 
126         Comparator<MetaInfResource> comparator = new MetaInfResourcePathComparator();
127 
128         String includesKey = MetaInfConfigUtils.getIncludesKey(group, PREFIX);
129         String excludesKey = MetaInfConfigUtils.getExcludesKey(group, PREFIX);
130 
131         Boolean relativePaths = env.getBoolean(RELATIVE_KEY, DEFAULT_GENERATE_RELATIVE_PATHS);
132 
133         List<String> pathQualifiers = MetaInfUtils.getQualifiers(scanDir, project, Lists.newArrayList(qualifier), Lists.<String> newArrayList());
134 
135         for (String pathQualifier : pathQualifiers) {
136             File outputFile = MetaInfUtils.getOutputFile(project, build, Optional.of(pathQualifier),
137                     Optional.<MetaInfDataLocation> absent(), Optional.of(type), INGEST_FILENAME);
138 
139             Map<MetaInfGroup, String> defaultIncludes = getDefaultIncludes(pathQualifier, type);
140             Map<MetaInfGroup, String> defaultExcludes = getDefaultExcludes();
141             List<String> includes = SpringUtils.getNoneSensitiveListFromCSV(env, includesKey, defaultIncludes.get(group));
142             List<String> excludes = SpringUtils.getNoneSensitiveListFromCSV(env, excludesKey, defaultExcludes.get(group));
143 
144             MetaInfContext context = MetaInfContext.builder(outputFile, encoding, scanDir).comparator(comparator)
145                     .includes(includes).excludes(excludes).relativePaths(relativePaths.booleanValue()).build();
146             metaInfContexts.add(context);
147         }
148 
149         return metaInfContexts;
150     }
151 
152     /**
153      * Generates the default mapping of included paths from the given {@code qualifier} and {@code type}.
154      *
155      * @param qualifier the prefix to add to the initial resource path
156      * @param type the type of data to include
157      *
158      * @return the map of included paths
159      */
160     protected Map<MetaInfGroup, String> getDefaultIncludes(String qualifier, MetaInfDataType type) {
161         Map<MetaInfGroup, String> defaultIncludes = Maps.newEnumMap(MetaInfGroup.class);
162 
163         String resourcePath = ProjectUtils.getResourcePath(project.getGroupId(), project.getArtifactId());
164         List<String> paths = Lists.newArrayList(resourcePath, qualifier, type.name().toLowerCase(), ALL_XML_PATH);
165 
166         defaultIncludes.put(MetaInfGroup.OTHER, StringUtils.join(paths, PATH_SEPARATOR));
167 
168         return defaultIncludes;
169     }
170 
171     /**
172      * Generates the default mapping of excluded paths.
173      *
174      * @return the map of excluded paths
175      */
176     protected Map<MetaInfGroup, String> getDefaultExcludes() {
177         Map<MetaInfGroup, String> defaultExcludes = Maps.newEnumMap(MetaInfGroup.class);
178 
179         defaultExcludes.put(MetaInfGroup.OTHER, NullUtils.NONE);
180 
181         return defaultExcludes;
182     }
183 
184 }