001 package org.apache.maven.usability.plugin;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.maven.usability.plugin.io.xpp3.ParamdocXpp3Reader;
023 import org.codehaus.plexus.util.IOUtil;
024 import org.codehaus.plexus.util.ReaderFactory;
025 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
026
027 import java.io.BufferedReader;
028 import java.io.File;
029 import java.io.IOException;
030 import java.io.InputStream;
031 import java.io.Reader;
032 import java.net.MalformedURLException;
033 import java.net.URL;
034 import java.net.URLClassLoader;
035 import java.util.HashMap;
036 import java.util.Iterator;
037 import java.util.List;
038 import java.util.Map;
039
040 public class ExpressionDocumenter
041 {
042
043 private static final String[] EXPRESSION_ROOTS = { "project", "settings", "session", "plugin", "rootless" };
044
045 private static final String EXPRESSION_DOCO_ROOTPATH = "META-INF/maven/plugin-expressions/";
046
047 private static Map expressionDocumentation;
048
049 public static Map load()
050 throws ExpressionDocumentationException
051 {
052 if ( expressionDocumentation == null )
053 {
054 expressionDocumentation = new HashMap();
055
056 ClassLoader docLoader = initializeDocLoader();
057
058 for ( String EXPRESSION_ROOT : EXPRESSION_ROOTS )
059 {
060 InputStream docStream = null;
061 try
062 {
063 docStream =
064 docLoader.getResourceAsStream( EXPRESSION_DOCO_ROOTPATH + EXPRESSION_ROOT + ".paramdoc.xml" );
065
066 if ( docStream != null )
067 {
068 Map doco = parseExpressionDocumentation( docStream );
069
070 expressionDocumentation.putAll( doco );
071 }
072 }
073 catch ( IOException e )
074 {
075 throw new ExpressionDocumentationException(
076 "Failed to read documentation for expression root: " + EXPRESSION_ROOT, e );
077 }
078 catch ( XmlPullParserException e )
079 {
080 throw new ExpressionDocumentationException(
081 "Failed to parse documentation for expression root: " + EXPRESSION_ROOT, e );
082 }
083 finally
084 {
085 IOUtil.close( docStream );
086 }
087 }
088 }
089
090 return expressionDocumentation;
091 }
092
093 /**
094 * <expressions>
095 * <expression>
096 * <syntax>project.distributionManagementArtifactRepository</syntax>
097 * <origin><![CDATA[
098 * <distributionManagement>
099 * <repository>
100 * <id>some-repo</id>
101 * <url>scp://host/path</url>
102 * </repository>
103 * <snapshotRepository>
104 * <id>some-snap-repo</id>
105 * <url>scp://host/snapshot-path</url>
106 * </snapshotRepository>
107 * </distributionManagement>
108 * ]]></origin>
109 * <usage><![CDATA[
110 * The repositories onto which artifacts should be deployed.
111 * One is for releases, the other for snapshots.
112 * ]]></usage>
113 * </expression>
114 * <expressions>
115 * @throws IOException
116 * @throws XmlPullParserException
117 */
118 private static Map parseExpressionDocumentation( InputStream docStream )
119 throws IOException, XmlPullParserException
120 {
121 Reader reader = new BufferedReader( ReaderFactory.newXmlReader( docStream ) );
122
123 ParamdocXpp3Reader paramdocReader = new ParamdocXpp3Reader();
124
125 ExpressionDocumentation documentation = paramdocReader.read( reader, true );
126
127 List expressions = documentation.getExpressions();
128
129 Map bySyntax = new HashMap();
130
131 if ( expressions != null && !expressions.isEmpty() )
132 {
133 for ( Object expression : expressions )
134 {
135 Expression expr = (Expression) expression;
136
137 bySyntax.put( expr.getSyntax(), expr );
138 }
139 }
140
141 return bySyntax;
142 }
143
144 private static ClassLoader initializeDocLoader()
145 throws ExpressionDocumentationException
146 {
147 String myResourcePath = ExpressionDocumenter.class.getName().replace( '.', '/' ) + ".class";
148
149 URL myResource = ExpressionDocumenter.class.getClassLoader().getResource( myResourcePath );
150
151 String myClasspathEntry = myResource.getPath();
152
153 myClasspathEntry = myClasspathEntry.substring( 0, myClasspathEntry.length() - ( myResourcePath.length() + 2 ) );
154
155 if ( myClasspathEntry.startsWith( "file:" ) )
156 {
157 myClasspathEntry = myClasspathEntry.substring( "file:".length() );
158 }
159
160 URL docResource;
161 try
162 {
163 docResource = new File( myClasspathEntry ).toURL();
164 }
165 catch ( MalformedURLException e )
166 {
167 throw new ExpressionDocumentationException(
168 "Cannot construct expression documentation classpath resource base.",
169 e );
170 }
171
172 return new URLClassLoader( new URL[] { docResource } );
173 }
174
175 }