001    /**
002     * Copyright 2010-2012 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.lang.reflect.InvocationTargetException;
019    import java.util.ArrayList;
020    import java.util.Arrays;
021    import java.util.List;
022    import java.util.Map;
023    import java.util.Properties;
024    import java.util.Set;
025    
026    import org.apache.commons.beanutils.BeanUtils;
027    import org.apache.commons.lang3.StringUtils;
028    import org.kuali.common.util.property.Constants;
029    import org.slf4j.Logger;
030    import org.slf4j.LoggerFactory;
031    import org.springframework.util.PropertyPlaceholderHelper;
032    
033    /**
034     * 
035     */
036    public class ProjectUtils {
037    
038            private static final Logger logger = LoggerFactory.getLogger(ProjectUtils.class);
039            private static final PropertyPlaceholderHelper PPH = Constants.DEFAULT_PROPERTY_PLACEHOLDER_HELPER;
040    
041            public static Project loadProject(String gav) {
042                    Project project = getProject(gav);
043                    Properties properties = getProperties(project);
044                    return getProject(properties);
045            }
046    
047            public static Project getProject(String gav) {
048                    logger.debug("Processing [{}]", gav);
049                    String[] tokens = StringUtils.split(gav, ":");
050    
051                    Project project = new Project();
052                    if (tokens.length > 0) {
053                            project.setGroupId(RepositoryUtils.toNull(tokens[0]));
054                    }
055                    if (tokens.length > 1) {
056                            project.setArtifactId(RepositoryUtils.toNull(tokens[1]));
057                    }
058                    if (tokens.length > 2) {
059                            project.setPackaging(RepositoryUtils.toNull(tokens[2]));
060                    }
061                    if (tokens.length > 3) {
062                            project.setVersion(RepositoryUtils.toNull(tokens[3]));
063                    }
064                    if (tokens.length > 4) {
065                            project.setClassifier(RepositoryUtils.toNull(tokens[4]));
066                    }
067                    return project;
068            }
069    
070            public static List<Dependency> getDependencies(String csv) {
071                    List<String> tokens = CollectionUtils.getTrimmedListFromCSV(csv);
072                    List<Dependency> dependencies = new ArrayList<Dependency>();
073                    for (String token : tokens) {
074                            Dependency dependency = RepositoryUtils.parseDependency(token);
075                            dependencies.add(dependency);
076                    }
077                    return dependencies;
078            }
079    
080            public static Project getProject(Properties properties) {
081                    List<String> skipKeys = Arrays.asList("project.dependencies");
082                    String startsWith = "project.";
083                    List<String> keys = PropertyUtils.getStartsWithKeys(properties, startsWith);
084                    Project project = new Project();
085                    project.setProperties(properties);
086                    Map<String, Object> description = describe(project);
087                    Set<String> beanProperties = description.keySet();
088                    for (String key : keys) {
089                            if (skipKeys.contains(key)) {
090                                    continue;
091                            }
092                            String value = properties.getProperty(key);
093                            String beanProperty = getBeanProperty(key, startsWith);
094                            if (beanProperties.contains(beanProperty)) {
095                                    copyProperty(project, beanProperty, value);
096                            }
097                    }
098                    String dependenciesCSV = properties.getProperty("project.dependencies");
099                    List<Dependency> dependencies = getDependencies(dependenciesCSV);
100                    project.setDependencies(dependencies);
101                    return project;
102            }
103    
104            protected static String getBeanProperty(String key, String startsWith) {
105                    String s = StringUtils.substring(key, startsWith.length());
106                    String[] tokens = StringUtils.split(s, ".");
107                    StringBuilder sb = new StringBuilder();
108                    for (int i = 0; i < tokens.length; i++) {
109                            String token = tokens[i];
110                            if (i == 0) {
111                                    sb.append(token);
112                            } else {
113                                    sb.append(StringUtils.capitalize(token));
114                            }
115                    }
116                    return sb.toString();
117            }
118    
119            public static Properties getProperties(String gav) {
120                    return getProperties(getProject(gav));
121            }
122    
123            public static Properties getProperties(Project project) {
124                    String location = getPropertiesLocation(project);
125                    if (!LocationUtils.exists(location)) {
126                            throw new IllegalArgumentException("[" + location + "] does not exist");
127                    }
128                    return PropertyUtils.load(location);
129            }
130    
131            public static String getPropertiesLocation(Project project) {
132                    Assert.hasText(project.getGroupId(), "groupId has no text");
133                    Assert.hasText(project.getArtifactId(), "artifactId has no text");
134    
135                    Properties properties = new Properties();
136                    properties.setProperty("project.groupId.path", Str.getPath(project.getGroupId()));
137                    properties.setProperty("project.artifactId", project.getArtifactId());
138    
139                    return PPH.replacePlaceholders(Constants.PROJECT_PROPERTIES_LOCATION, properties);
140            }
141    
142            @SuppressWarnings("unchecked")
143            protected static Map<String, Object> describe(Object bean) {
144                    try {
145                            return BeanUtils.describe(bean);
146                    } catch (IllegalAccessException e) {
147                            throw new IllegalStateException(e);
148                    } catch (InvocationTargetException e) {
149                            throw new IllegalStateException(e);
150                    } catch (NoSuchMethodException e) {
151                            throw new IllegalStateException(e);
152                    }
153            }
154    
155            protected static void copyProperty(Object bean, String name, Object value) {
156                    try {
157                            BeanUtils.copyProperty(bean, name, value);
158                    } catch (IllegalAccessException e) {
159                            throw new IllegalStateException(e);
160                    } catch (InvocationTargetException e) {
161                            throw new IllegalStateException(e);
162                    }
163            }
164    
165    }