001    /*
002     * #%L
003     * License Maven Plugin
004     * 
005     * $Id: LicenseRepository.java 14741 2011-09-20 08:31:41Z tchemit $
006     * $HeadURL: http://svn.codehaus.org/mojo/tags/license-maven-plugin-1.0/src/main/java/org/codehaus/mojo/license/model/LicenseRepository.java $
007     * %%
008     * Copyright (C) 2008 - 2011 CodeLutin, Codehaus, Tony Chemit
009     * %%
010     * This program is free software: you can redistribute it and/or modify
011     * it under the terms of the GNU Lesser General Public License as 
012     * published by the Free Software Foundation, either version 3 of the 
013     * License, or (at your option) any later version.
014     * 
015     * This program is distributed in the hope that it will be useful,
016     * but WITHOUT ANY WARRANTY; without even the implied warranty of
017     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
018     * GNU General Lesser Public License for more details.
019     * 
020     * You should have received a copy of the GNU General Lesser Public 
021     * License along with this program.  If not, see
022     * <http://www.gnu.org/licenses/lgpl-3.0.html>.
023     * #L%
024     */
025    
026    package org.codehaus.mojo.license.model;
027    
028    import org.apache.commons.lang.StringUtils;
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    import org.codehaus.mojo.license.MojoHelper;
032    
033    import java.io.IOException;
034    import java.net.URL;
035    import java.net.URLConnection;
036    import java.util.*;
037    import java.util.Map.Entry;
038    import java.util.regex.Matcher;
039    import java.util.regex.Pattern;
040    
041    /**
042     * @author tchemit <chemit@codelutin.com>
043     * @since 1.0
044     */
045    public class LicenseRepository
046        implements Iterable<License>
047    {
048    
049        /**
050         * Logger
051         */
052        private static final Log log = LogFactory.getLog( LicenseRepository.class );
053    
054        public static final String REPOSITORY_DEFINITION_FILE = "licenses.properties";
055    
056        public static final Pattern LICENSE_DESCRIPTION_PATTERN =
057            Pattern.compile( "(.*)\\s*~~\\s*license\\s*:\\s*(.*)\\s*~~\\s*header\\s*:\\s*(.*)\\s*" );
058    
059        /**
060         * the base url of the licenses repository
061         */
062        protected URL baseURL;
063    
064        /**
065         * licenses of this repository
066         */
067        protected List<License> licenses;
068    
069        /**
070         * flag to known if repository was init (pass to {@code true} when invoking
071         * the method {@link #load()}).
072         */
073        protected boolean init;
074    
075        public LicenseRepository()
076        {
077        }
078    
079        public URL getBaseURL()
080        {
081            return baseURL;
082        }
083    
084        public void setBaseURL( URL baseURL )
085        {
086            checkNotInit( "setBaseURL" );
087            this.baseURL = baseURL;
088        }
089    
090        public void load()
091            throws IOException
092        {
093            checkNotInit( "load" );
094            try
095            {
096                if ( baseURL == null || StringUtils.isEmpty( baseURL.toString() ) )
097                {
098                    throw new IllegalStateException( "no baseURL defined in " + this );
099                }
100    
101                URL definitionURL = MojoHelper.getUrl( getBaseURL(), REPOSITORY_DEFINITION_FILE );
102                if ( licenses != null )
103                {
104                    licenses.clear();
105                }
106                else
107                {
108                    licenses = new ArrayList<License>();
109                }
110    
111                if ( !checkExists( definitionURL ) )
112                {
113                    throw new IllegalArgumentException(
114                        "no licenses.properties found with url [" + definitionURL + "] for resolver " + this );
115                }
116                Properties p = new Properties();
117                p.load( definitionURL.openStream() );
118    
119                for ( Entry<Object, Object> entry : p.entrySet() )
120                {
121                    String licenseName = (String) entry.getKey();
122                    licenseName = licenseName.trim().toLowerCase();
123                    URL licenseBaseURL = MojoHelper.getUrl( baseURL, licenseName );
124    
125                    License license = new License();
126                    license.setName( licenseName );
127                    license.setBaseURL( licenseBaseURL );
128    
129                    String licenseDescription = (String) entry.getValue();
130                    Matcher matcher = LICENSE_DESCRIPTION_PATTERN.matcher( licenseDescription );
131                    String licenseFile;
132                    String headerFile;
133    
134                    if ( matcher.matches() )
135                    {
136                        licenseDescription = matcher.group( 1 );
137                        licenseFile = matcher.group( 2 );
138                        headerFile = matcher.group( 3 );
139                    }
140                    else
141                    {
142                        licenseFile = License.LICENSE_CONTENT_FILE;
143                        headerFile = License.LICENSE_HEADER_FILE;
144                    }
145    
146                    URL licenseURL = MojoHelper.getUrl( licenseBaseURL, licenseFile );
147                    if ( !checkExists( licenseURL ) )
148                    {
149                        throw new IllegalArgumentException(
150                            "Could not find license (" + license + ") content file at [" + licenseURL + "] for resolver " +
151                                this );
152                    }
153                    license.setLicenseURL( licenseURL );
154    
155                    URL headerURL = MojoHelper.getUrl( licenseBaseURL, headerFile );
156                    if ( !checkExists( headerURL ) )
157                    {
158                        throw new IllegalArgumentException(
159                            "Could not find license (" + license + ") header file at [" + headerURL + "] for resolver " +
160                                this );
161                    }
162                    license.setHeaderURL( headerURL );
163    
164                    license.setDescription( licenseDescription );
165    
166                    if ( log.isInfoEnabled() )
167                    {
168                        log.info( "register " + license.getDescription() );
169                    }
170                    if ( log.isDebugEnabled() )
171                    {
172                        log.debug( license );
173                    }
174                    licenses.add( license );
175                }
176                licenses = Collections.unmodifiableList( licenses );
177            }
178            finally
179            {
180                // mark repository as available
181                init = true;
182            }
183        }
184    
185        public String[] getLicenseNames()
186        {
187            checkInit( "getLicenseNames" );
188            List<String> result = new ArrayList<String>( licenses.size() );
189            for ( License license : this )
190            {
191                result.add( license.getName() );
192            }
193            return result.toArray( new String[result.size()] );
194        }
195    
196        public License[] getLicenses()
197        {
198            checkInit( "getLicenses" );
199            return licenses.toArray( new License[licenses.size()] );
200        }
201    
202        public License getLicense( String licenseName )
203        {
204            checkInit( "getLicense" );
205            if ( StringUtils.isEmpty( licenseName ) )
206            {
207                throw new IllegalArgumentException( "licenceName can not be null, nor empty" );
208            }
209    
210            License license = null;
211            for ( License l : this )
212            {
213                if ( licenseName.equals( l.getName() ) )
214                {
215                    // got it
216                    license = l;
217                    break;
218                }
219            }
220            return license;
221        }
222    
223        public Iterator<License> iterator()
224        {
225            checkInit( "iterator" );
226            return licenses.iterator();
227        }
228    
229        protected boolean checkExists( URL url )
230            throws IOException
231        {
232            URLConnection openConnection = url.openConnection();
233            return openConnection.getContentLength() > 0;
234        }
235    
236        protected void checkInit( String operation )
237            throws IllegalStateException
238        {
239            if ( !init )
240            {
241                throw new IllegalStateException(
242                    "repository " + this + " was not init, operation [" + operation + "] not possible." );
243            }
244        }
245    
246        protected void checkNotInit( String operation )
247            throws IllegalStateException
248        {
249            if ( init )
250            {
251                throw new IllegalStateException(
252                    "repository " + this + "was init, operation [" + operation + "+] not possible." );
253            }
254        }
255    
256    }