001    /**
002     * Copyright 2010-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.codehaus.mojo.license.model;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.commons.logging.Log;
020    import org.apache.commons.logging.LogFactory;
021    import org.codehaus.mojo.license.MojoHelper;
022    
023    import java.io.IOException;
024    import java.net.URL;
025    import java.net.URLConnection;
026    import java.util.*;
027    import java.util.Map.Entry;
028    import java.util.regex.Matcher;
029    import java.util.regex.Pattern;
030    
031    /**
032     * @author tchemit <chemit@codelutin.com>
033     * @since 1.0
034     */
035    public class LicenseRepository
036        implements Iterable<License>
037    {
038    
039        /**
040         * Logger
041         */
042        private static final Log log = LogFactory.getLog( LicenseRepository.class );
043    
044        public static final String REPOSITORY_DEFINITION_FILE = "licenses.properties";
045    
046        public static final Pattern LICENSE_DESCRIPTION_PATTERN =
047            Pattern.compile( "(.*)\\s*~~\\s*license\\s*:\\s*(.*)\\s*~~\\s*header\\s*:\\s*(.*)\\s*" );
048    
049        /**
050         * the base url of the licenses repository
051         */
052        protected URL baseURL;
053    
054        /**
055         * licenses of this repository
056         */
057        protected List<License> licenses;
058    
059        /**
060         * flag to known if repository was init (pass to {@code true} when invoking
061         * the method {@link #load()}).
062         */
063        protected boolean init;
064    
065        public LicenseRepository()
066        {
067        }
068    
069        public URL getBaseURL()
070        {
071            return baseURL;
072        }
073    
074        public void setBaseURL( URL baseURL )
075        {
076            checkNotInit( "setBaseURL" );
077            this.baseURL = baseURL;
078        }
079    
080        public void load()
081            throws IOException
082        {
083            checkNotInit( "load" );
084            try
085            {
086                if ( baseURL == null || StringUtils.isEmpty( baseURL.toString() ) )
087                {
088                    throw new IllegalStateException( "no baseURL defined in " + this );
089                }
090    
091                URL definitionURL = MojoHelper.getUrl( getBaseURL(), REPOSITORY_DEFINITION_FILE );
092                if ( licenses != null )
093                {
094                    licenses.clear();
095                }
096                else
097                {
098                    licenses = new ArrayList<License>();
099                }
100    
101                if ( !checkExists( definitionURL ) )
102                {
103                    throw new IllegalArgumentException(
104                        "no licenses.properties found with url [" + definitionURL + "] for resolver " + this );
105                }
106                Properties p = new Properties();
107                p.load( definitionURL.openStream() );
108    
109                for ( Entry<Object, Object> entry : p.entrySet() )
110                {
111                    String licenseName = (String) entry.getKey();
112                    licenseName = licenseName.trim().toLowerCase();
113                    URL licenseBaseURL = MojoHelper.getUrl( baseURL, licenseName );
114    
115                    License license = new License();
116                    license.setName( licenseName );
117                    license.setBaseURL( licenseBaseURL );
118    
119                    String licenseDescription = (String) entry.getValue();
120                    Matcher matcher = LICENSE_DESCRIPTION_PATTERN.matcher( licenseDescription );
121                    String licenseFile;
122                    String headerFile;
123    
124                    if ( matcher.matches() )
125                    {
126                        licenseDescription = matcher.group( 1 );
127                        licenseFile = matcher.group( 2 );
128                        headerFile = matcher.group( 3 );
129                    }
130                    else
131                    {
132                        licenseFile = License.LICENSE_CONTENT_FILE;
133                        headerFile = License.LICENSE_HEADER_FILE;
134                    }
135    
136                    URL licenseURL = MojoHelper.getUrl( licenseBaseURL, licenseFile );
137                    if ( !checkExists( licenseURL ) )
138                    {
139                        throw new IllegalArgumentException(
140                            "Could not find license (" + license + ") content file at [" + licenseURL + "] for resolver " +
141                                this );
142                    }
143                    license.setLicenseURL( licenseURL );
144    
145                    URL headerURL = MojoHelper.getUrl( licenseBaseURL, headerFile );
146                    if ( !checkExists( headerURL ) )
147                    {
148                        throw new IllegalArgumentException(
149                            "Could not find license (" + license + ") header file at [" + headerURL + "] for resolver " +
150                                this );
151                    }
152                    license.setHeaderURL( headerURL );
153    
154                    license.setDescription( licenseDescription );
155    
156                    if ( log.isInfoEnabled() )
157                    {
158                        log.info( "register " + license.getDescription() );
159                    }
160                    if ( log.isDebugEnabled() )
161                    {
162                        log.debug( license );
163                    }
164                    licenses.add( license );
165                }
166                licenses = Collections.unmodifiableList( licenses );
167            }
168            finally
169            {
170                // mark repository as available
171                init = true;
172            }
173        }
174    
175        public String[] getLicenseNames()
176        {
177            checkInit( "getLicenseNames" );
178            List<String> result = new ArrayList<String>( licenses.size() );
179            for ( License license : this )
180            {
181                result.add( license.getName() );
182            }
183            return result.toArray( new String[result.size()] );
184        }
185    
186        public License[] getLicenses()
187        {
188            checkInit( "getLicenses" );
189            return licenses.toArray( new License[licenses.size()] );
190        }
191    
192        public License getLicense( String licenseName )
193        {
194            checkInit( "getLicense" );
195            if ( StringUtils.isEmpty( licenseName ) )
196            {
197                throw new IllegalArgumentException( "licenceName can not be null, nor empty" );
198            }
199    
200            License license = null;
201            for ( License l : this )
202            {
203                if ( licenseName.equals( l.getName() ) )
204                {
205                    // got it
206                    license = l;
207                    break;
208                }
209            }
210            return license;
211        }
212    
213        public Iterator<License> iterator()
214        {
215            checkInit( "iterator" );
216            return licenses.iterator();
217        }
218    
219        protected boolean checkExists( URL url )
220            throws IOException
221        {
222            URLConnection openConnection = url.openConnection();
223            return openConnection.getContentLength() > 0;
224        }
225    
226        protected void checkInit( String operation )
227            throws IllegalStateException
228        {
229            if ( !init )
230            {
231                throw new IllegalStateException(
232                    "repository " + this + " was not init, operation [" + operation + "] not possible." );
233            }
234        }
235    
236        protected void checkNotInit( String operation )
237            throws IllegalStateException
238        {
239            if ( init )
240            {
241                throw new IllegalStateException(
242                    "repository " + this + "was init, operation [" + operation + "+] not possible." );
243            }
244        }
245    
246    }