View Javadoc
1   package org.apache.maven.project;
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 org.codehaus.plexus.util.ReaderFactory;
23  import org.codehaus.plexus.util.xml.Xpp3Dom;
24  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
25  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
26  
27  import java.io.BufferedInputStream;
28  import java.io.File;
29  import java.io.FileInputStream;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.util.ArrayList;
33  import java.util.List;
34  import java.util.jar.JarFile;
35  import java.util.zip.ZipEntry;
36  
37  /**
38   * Creates an extension descriptor from some XML stream.
39   *
40   * @author Benjamin Bentmann
41   */
42  public class ExtensionDescriptorBuilder
43  {
44  
45      /**
46       * @since 3.3.0
47       */
48      public String getExtensionDescriptorLocation()
49      {
50          return "META-INF/maven/extension.xml";
51      }
52  
53      /**
54       * Extracts the extension descriptor (if any) from the specified JAR file.
55       *
56       * @param extensionJar The JAR file or directory to extract the descriptor from, must not be {@code null}.
57       * @return The extracted descriptor or {@code null} if no descriptor was found.
58       * @throws IOException If the descriptor is present but could not be parsed.
59       */
60      public ExtensionDescriptor build( File extensionJar )
61          throws IOException
62      {
63          ExtensionDescriptor extensionDescriptor = null;
64  
65          if ( extensionJar.isFile() )
66          {
67              try ( JarFile pluginJar = new JarFile( extensionJar, false ) )
68              {
69                  ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getExtensionDescriptorLocation() );
70  
71                  if ( pluginDescriptorEntry != null )
72                  {
73                      try ( InputStream is = pluginJar.getInputStream( pluginDescriptorEntry ) )
74                      {
75                          extensionDescriptor = build( is );
76                      }
77                  }
78              }
79          }
80          else
81          {
82              File pluginXml = new File( extensionJar, getExtensionDescriptorLocation() );
83  
84              if ( pluginXml.canRead() )
85              {
86                  try ( InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) ) )
87                  {
88                      extensionDescriptor = build( is );
89                  }
90              }
91          }
92  
93          return extensionDescriptor;
94      }
95  
96      /**
97       * @since 3.3.0
98       */
99      public ExtensionDescriptor build( InputStream is )
100         throws IOException
101     {
102         ExtensionDescriptor extensionDescriptor = new ExtensionDescriptor();
103 
104         Xpp3Dom dom;
105         try
106         {
107             dom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( is ) );
108         }
109         catch ( XmlPullParserException e )
110         {
111             throw (IOException) new IOException( e.getMessage() ).initCause( e );
112         }
113 
114         if ( !"extension".equals( dom.getName() ) )
115         {
116             throw new IOException( "Unexpected root element \"" + dom.getName() + "\", expected \"extension\"" );
117         }
118 
119         extensionDescriptor.setExportedPackages( parseStrings( dom.getChild( "exportedPackages" ) ) );
120 
121         extensionDescriptor.setExportedArtifacts( parseStrings( dom.getChild( "exportedArtifacts" ) ) );
122 
123         return extensionDescriptor;
124     }
125 
126     private List<String> parseStrings( Xpp3Dom dom )
127     {
128         List<String> strings = null;
129 
130         if ( dom != null )
131         {
132             strings = new ArrayList<>();
133 
134             for ( Xpp3Dom child : dom.getChildren() )
135             {
136                 String string = child.getValue();
137                 if ( string != null )
138                 {
139                     string = string.trim();
140                     if ( string.length() > 0 )
141                     {
142                         strings.add( string );
143                     }
144                 }
145             }
146         }
147 
148         return strings;
149     }
150 
151 }