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