001/*
002 * Copyright 2012-2016 the original author or authors.
003 *
004 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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
017package org.springframework.boot.maven;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.util.List;
022import java.util.Map.Entry;
023import java.util.Properties;
024import java.util.jar.JarEntry;
025import java.util.jar.JarOutputStream;
026
027import org.apache.maven.plugins.shade.relocation.Relocator;
028import org.apache.maven.plugins.shade.resource.ResourceTransformer;
029
030/**
031 * Extension for the <a href="http://maven.apache.org/plugins/maven-shade-plugin/">Maven
032 * shade plugin</a> to allow properties files (e.g. {@literal META-INF/spring.factories})
033 * to be merged without losing any information.
034 *
035 * @author Dave Syer
036 * @author Andy Wilkinson
037 */
038public class PropertiesMergingResourceTransformer implements ResourceTransformer {
039
040        // Set this in pom configuration with <resource>...</resource>
041        private String resource;
042
043        private final Properties data = new Properties();
044
045        /**
046         * Return the data the properties being merged.
047         * @return the data
048         */
049        public Properties getData() {
050                return this.data;
051        }
052
053        @Override
054        public boolean canTransformResource(String resource) {
055                if (this.resource != null && this.resource.equalsIgnoreCase(resource)) {
056                        return true;
057                }
058                return false;
059        }
060
061        @Override
062        public void processResource(String resource, InputStream is,
063                        List<Relocator> relocators) throws IOException {
064                Properties properties = new Properties();
065                properties.load(is);
066                is.close();
067                for (Entry<Object, Object> entry : properties.entrySet()) {
068                        String name = (String) entry.getKey();
069                        String value = (String) entry.getValue();
070                        String existing = this.data.getProperty(name);
071                        this.data.setProperty(name,
072                                        existing == null ? value : existing + "," + value);
073                }
074        }
075
076        @Override
077        public boolean hasTransformedResource() {
078                return !this.data.isEmpty();
079        }
080
081        @Override
082        public void modifyOutputStream(JarOutputStream os) throws IOException {
083                os.putNextEntry(new JarEntry(this.resource));
084                this.data.store(os, "Merged by PropertiesMergingResourceTransformer");
085                os.flush();
086                this.data.clear();
087        }
088
089        public String getResource() {
090                return this.resource;
091        }
092
093        public void setResource(String resource) {
094                this.resource = resource;
095        }
096
097}