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}