View Javadoc
1   package org.apache.maven.plugins.shade.resource;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.StringReader;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.jar.JarEntry;
28  import java.util.jar.JarOutputStream;
29  
30  import org.apache.maven.plugins.shade.relocation.Relocator;
31  import org.jdom2.Attribute;
32  import org.jdom2.Content;
33  import org.jdom2.Document;
34  import org.jdom2.Element;
35  import org.jdom2.JDOMException;
36  import org.jdom2.input.SAXBuilder;
37  import org.jdom2.output.Format;
38  import org.jdom2.output.XMLOutputter;
39  import org.xml.sax.EntityResolver;
40  import org.xml.sax.InputSource;
41  import org.xml.sax.SAXException;
42  
43  /**
44   * Appends multiple occurrences of some XML file.
45   */
46  public class XmlAppendingTransformer
47      extends AbstractCompatibilityTransformer
48  {
49      public static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
50  
51      boolean ignoreDtd = true;
52  
53      String resource;
54  
55      Document doc;
56  
57      private long time = Long.MIN_VALUE;
58  
59      public boolean canTransformResource( String r )
60      {
61          if ( resource != null && resource.equalsIgnoreCase( r ) )
62          {
63              return true;
64          }
65  
66          return false;
67      }
68  
69      public void processResource( String resource, InputStream is, List<Relocator> relocators, long time )
70          throws IOException
71      {
72          Document r;
73          try
74          {
75              SAXBuilder builder = new SAXBuilder( false );
76              builder.setExpandEntities( false );
77              if ( ignoreDtd )
78              {
79                  builder.setEntityResolver( new EntityResolver()
80                  {
81                      public InputSource resolveEntity( String publicId, String systemId )
82                          throws SAXException, IOException
83                      {
84                          return new InputSource( new StringReader( "" ) );
85                      }
86                  } );
87              }
88              r = builder.build( is );
89          }
90          catch ( JDOMException e )
91          {
92              throw new RuntimeException( "Error processing resource " + resource + ": " + e.getMessage(), e );
93          }
94  
95          if ( doc == null )
96          {
97              doc = r;
98          }
99          else
100         {
101             Element root = r.getRootElement();
102 
103             for ( Iterator<Attribute> itr = root.getAttributes().iterator(); itr.hasNext(); )
104             {
105                 Attribute a = itr.next();
106                 itr.remove();
107 
108                 Element mergedEl = doc.getRootElement();
109                 Attribute mergedAtt = mergedEl.getAttribute( a.getName(), a.getNamespace() );
110                 if ( mergedAtt == null )
111                 {
112                     mergedEl.setAttribute( a );
113                 }
114             }
115 
116             for ( Iterator<Element> itr = root.getChildren().iterator(); itr.hasNext(); )
117             {
118                 Content n = itr.next();
119                 itr.remove();
120 
121                 doc.getRootElement().addContent( n );
122             }
123         }
124 
125         if ( time > this.time )
126         {
127             this.time = time;        
128         }
129     }
130 
131     public boolean hasTransformedResource()
132     {
133         return doc != null;
134     }
135 
136     public void modifyOutputStream( JarOutputStream jos )
137         throws IOException
138     {
139         JarEntry jarEntry = new JarEntry( resource );
140         jarEntry.setTime( time );
141         jos.putNextEntry( jarEntry );
142 
143         new XMLOutputter( Format.getPrettyFormat() ).output( doc, jos );
144 
145         doc = null;
146     }
147 }