001    package org.apache.maven.tools.plugin.extractor.beanshell;
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 bsh.EvalError;
023    import bsh.Interpreter;
024    import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
025    import org.apache.maven.plugin.descriptor.MojoDescriptor;
026    import org.apache.maven.tools.plugin.PluginToolsRequest;
027    import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor;
028    import org.apache.maven.tools.plugin.extractor.ExtractionException;
029    import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
030    import org.codehaus.plexus.component.annotations.Component;
031    
032    import java.io.File;
033    import java.io.InputStreamReader;
034    import java.io.UnsupportedEncodingException;
035    import java.util.ArrayList;
036    import java.util.List;
037    import java.util.Map;
038    import java.util.Set;
039    
040    /**
041     * Extracts Mojo descriptors from <a href="http://www.beanshell.org/">BeanShell</a> sources.
042     *
043     * @version $Id: BeanshellMojoDescriptorExtractor.java 1338290 2012-05-14 16:54:01Z olamy $
044     * @todo share constants
045     * @todo add example usage tag that can be shown in the doco
046     * @todo need to add validation directives so that systems embedding maven2 can
047     * get validation directives to help users in IDEs.
048     */
049    @Component( role = MojoDescriptorExtractor.class, hint = "bsh" )
050    public class BeanshellMojoDescriptorExtractor
051        extends AbstractScriptedMojoDescriptorExtractor
052        implements MojoDescriptorExtractor
053    {
054        /**
055         * {@inheritDoc}
056         */
057        protected String getScriptFileExtension( PluginToolsRequest request )
058        {
059            return ".bsh";
060        }
061    
062        /**
063         * {@inheritDoc}
064         */
065        protected List<MojoDescriptor> extractMojoDescriptors( Map<String, Set<File>> scriptFilesKeyedByBasedir,
066                                                               PluginToolsRequest request )
067            throws ExtractionException, InvalidPluginDescriptorException
068        {
069            List<MojoDescriptor> descriptors = new ArrayList<MojoDescriptor>();
070    
071            for ( Map.Entry<String, Set<File>> entry : scriptFilesKeyedByBasedir.entrySet() )
072            {
073                String basedir = entry.getKey();
074                Set<File> metadataFiles = entry.getValue();
075    
076                for ( File scriptFile : metadataFiles )
077                {
078                    String relativePath = null;
079    
080                    if ( basedir.endsWith( "/" ) )
081                    {
082                        basedir = basedir.substring( 0, basedir.length() - 2 );
083                    }
084    
085                    relativePath = scriptFile.getPath().substring( basedir.length() );
086    
087                    relativePath = relativePath.replace( '\\', '/' );
088    
089                    MojoDescriptor mojoDescriptor = createMojoDescriptor( basedir, relativePath, request );
090                    descriptors.add( mojoDescriptor );
091                }
092            }
093    
094            return descriptors;
095        }
096    
097        /**
098         * @param basedir  not null
099         * @param resource not null
100         * @param request  not null
101         * @return a new Mojo descriptor instance
102         * @throws InvalidPluginDescriptorException
103         *          if any
104         */
105        private MojoDescriptor createMojoDescriptor( String basedir, String resource, PluginToolsRequest request )
106            throws InvalidPluginDescriptorException
107        {
108            MojoDescriptor mojoDescriptor = new MojoDescriptor();
109            mojoDescriptor.setPluginDescriptor( request.getPluginDescriptor() );
110    
111            mojoDescriptor.setLanguage( "bsh" );
112            mojoDescriptor.setComponentConfigurator( "bsh" );
113    
114            mojoDescriptor.setImplementation( resource );
115    
116            Interpreter interpreter = new Interpreter();
117    
118            try
119            {
120                interpreter.set( "file", new File( basedir, resource ) );
121    
122                interpreter.set( "mojoDescriptor", mojoDescriptor );
123    
124                interpreter.set( "encoding", "UTF-8" );
125    
126                interpreter.eval( new InputStreamReader( getClass().getResourceAsStream( "/extractor.bsh" ), "UTF-8" ) );
127            }
128            catch ( EvalError evalError )
129            {
130                throw new InvalidPluginDescriptorException( "Error scanning beanshell script", evalError );
131            }
132            catch ( UnsupportedEncodingException uee )
133            {
134                // should not occur...
135                throw new InvalidPluginDescriptorException( "Unsupported encoding while reading beanshell script", uee );
136            }
137    
138            return mojoDescriptor;
139        }
140    }