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