View Javadoc
1   package org.apache.maven.usability.plugin;
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.apache.maven.usability.plugin.io.xpp3.ParamdocXpp3Reader;
23  import org.codehaus.plexus.util.IOUtil;
24  import org.codehaus.plexus.util.ReaderFactory;
25  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
26  
27  import java.io.BufferedReader;
28  import java.io.File;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.io.Reader;
32  import java.net.MalformedURLException;
33  import java.net.URL;
34  import java.net.URLClassLoader;
35  import java.util.HashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  public class ExpressionDocumenter
40  {
41  
42      private static final String[] EXPRESSION_ROOTS = { "project", "settings", "session", "plugin", "rootless" };
43  
44      private static final String EXPRESSION_DOCO_ROOTPATH = "META-INF/maven/plugin-expressions/";
45  
46      private static Map expressionDocumentation;
47  
48      public static Map load()
49          throws ExpressionDocumentationException
50      {
51          if ( expressionDocumentation == null )
52          {
53              expressionDocumentation = new HashMap();
54  
55              ClassLoader docLoader = initializeDocLoader();
56  
57              for ( String EXPRESSION_ROOT : EXPRESSION_ROOTS )
58              {
59                  InputStream docStream = null;
60                  try
61                  {
62                      docStream =
63                          docLoader.getResourceAsStream( EXPRESSION_DOCO_ROOTPATH + EXPRESSION_ROOT + ".paramdoc.xml" );
64  
65                      if ( docStream != null )
66                      {
67                          Map doco = parseExpressionDocumentation( docStream );
68  
69                          expressionDocumentation.putAll( doco );
70                      }
71                  }
72                  catch ( IOException e )
73                  {
74                      throw new ExpressionDocumentationException(
75                          "Failed to read documentation for expression root: " + EXPRESSION_ROOT, e );
76                  }
77                  catch ( XmlPullParserException e )
78                  {
79                      throw new ExpressionDocumentationException(
80                          "Failed to parse documentation for expression root: " + EXPRESSION_ROOT, e );
81                  }
82                  finally
83                  {
84                      IOUtil.close( docStream );
85                  }
86              }
87          }
88  
89          return expressionDocumentation;
90      }
91  
92      /**
93       * <expressions>
94       *   <expression>
95       *     <syntax>project.distributionManagementArtifactRepository</syntax>
96       *     <origin><![CDATA[
97       *   <distributionManagement>
98       *     <repository>
99       *       <id>some-repo</id>
100      *       <url>scp://host/path</url>
101      *     </repository>
102      *     <snapshotRepository>
103      *       <id>some-snap-repo</id>
104      *       <url>scp://host/snapshot-path</url>
105      *     </snapshotRepository>
106      *   </distributionManagement>
107      *   ]]></origin>
108      *     <usage><![CDATA[
109      *   The repositories onto which artifacts should be deployed.
110      *   One is for releases, the other for snapshots.
111      *   ]]></usage>
112      *   </expression>
113      * <expressions>
114      * @throws IOException
115      * @throws XmlPullParserException
116      */
117     private static Map parseExpressionDocumentation( InputStream docStream )
118         throws IOException, XmlPullParserException
119     {
120         Reader reader = new BufferedReader( ReaderFactory.newXmlReader( docStream ) );
121 
122         ParamdocXpp3Reader paramdocReader = new ParamdocXpp3Reader();
123 
124         ExpressionDocumentation documentation = paramdocReader.read( reader, true );
125 
126         List expressions = documentation.getExpressions();
127 
128         Map bySyntax = new HashMap();
129 
130         if ( expressions != null && !expressions.isEmpty() )
131         {
132             for ( Object expression : expressions )
133             {
134                 Expression expr = (Expression) expression;
135 
136                 bySyntax.put( expr.getSyntax(), expr );
137             }
138         }
139 
140         return bySyntax;
141     }
142 
143     private static ClassLoader initializeDocLoader()
144         throws ExpressionDocumentationException
145     {
146         String myResourcePath = ExpressionDocumenter.class.getName().replace( '.', '/' ) + ".class";
147 
148         URL myResource = ExpressionDocumenter.class.getClassLoader().getResource( myResourcePath );
149 
150         assert myResource != null : "The resource is this class itself loaded by its own classloader and must exist";
151 
152         String myClasspathEntry = myResource.getPath();
153 
154         myClasspathEntry = myClasspathEntry.substring( 0, myClasspathEntry.length() - ( myResourcePath.length() + 2 ) );
155 
156         if ( myClasspathEntry.startsWith( "file:" ) )
157         {
158             myClasspathEntry = myClasspathEntry.substring( "file:".length() );
159         }
160 
161         URL docResource;
162         try
163         {
164             docResource = new File( myClasspathEntry ).toURL();
165         }
166         catch ( MalformedURLException e )
167         {
168             throw new ExpressionDocumentationException( "Cannot construct expression documentation classpath"
169                 + " resource base.", e );
170         }
171 
172         return new URLClassLoader( new URL[] { docResource } );
173     }
174 
175 }