001/* 002 * Copyright 2011 Atteo. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014package org.atteo.classindex; 015 016import java.io.ByteArrayInputStream; 017import java.io.ByteArrayOutputStream; 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.HashMap; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Map; 024import java.util.jar.JarEntry; 025import java.util.jar.JarOutputStream; 026 027import org.apache.maven.plugins.shade.resource.ResourceTransformer; 028import org.codehaus.plexus.util.IOUtil; 029 030public class ClassIndexTransformer implements ResourceTransformer { 031 public static final String SUBCLASS_INDEX_PREFIX = "META-INF/services/"; 032 public static final String ANNOTATED_INDEX_PREFIX = "META-INF/annotations/"; 033 public static final String PACKAGE_INDEX_NAME = "jaxb.index"; 034 035 private ByteArrayOutputStream data; 036 037 private Map serviceEntries = new HashMap(); 038 039 @Override 040 public boolean canTransformResource(String resource) { 041 if (resource.startsWith(SUBCLASS_INDEX_PREFIX) || resource.startsWith(ANNOTATED_INDEX_PREFIX) 042 || resource.endsWith("/" + PACKAGE_INDEX_NAME)) { 043 data = (ByteArrayOutputStream) serviceEntries.get(resource); 044 045 if (data == null) { 046 data = new ByteArrayOutputStream(); 047 serviceEntries.put(resource, data); 048 } 049 return true; 050 } 051 052 return false; 053 } 054 055 @Override 056 public void processResource(String resource, InputStream is, List relocators) 057 throws IOException { 058 IOUtil.copy(is, data); 059 is.close(); 060 } 061 062 @Override 063 public boolean hasTransformedResource() { 064 return serviceEntries.size() > 0; 065 } 066 067 @Override 068 public void modifyOutputStream(JarOutputStream jos) 069 throws IOException { 070 for (Iterator i = serviceEntries.keySet().iterator(); i.hasNext();) { 071 String key = (String) i.next(); 072 ByteArrayOutputStream stream = (ByteArrayOutputStream) serviceEntries.get(key); 073 jos.putNextEntry(new JarEntry(key)); 074 IOUtil.copy(new ByteArrayInputStream(stream.toByteArray()), jos); 075 stream.reset(); 076 } 077 } 078}