001    /*
002     * Copyright 2001,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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    
017    package org.apache.commons.jjar;
018    
019    import java.net.URL;
020    import java.net.URLConnection;
021    import java.util.List;
022    import java.util.Iterator;
023    
024    import org.apache.tools.ant.BuildException;
025    import org.apache.tools.ant.Task;
026    import org.apache.tools.ant.types.Path;
027    
028    /**
029     * An ant task for doing JJAR stuff
030     *
031     * @version $Id: JJARTask.java 155454 2005-02-26 13:23:34Z dirkv $
032     */
033    public class JJARTask extends Task
034    {
035        private static String defaultRepository = ClasspathUtil.getDefaultRepository();
036        private String pkg = null;
037        private String ver = null;
038        private String localrep = ".";
039        private boolean verifyignore = true;
040        private boolean onlydependencies = false;
041        private String classpath = null;
042        private String pathrefid = null;
043    
044        /**
045         *  [REQUIRED] sets the package and version.  ver can be 
046         *  null to get the default
047         */
048        public void setPackage( String pkg)
049        {
050            this.pkg = pkg;
051        }
052    
053        public void setVersion( String version )
054        {
055            this.ver = version;
056        }
057    
058        public void setLocalrepository( String localrep )
059        {
060            this.localrep = localrep;
061        }
062    
063        public void setVerifyignore( boolean b )
064        {
065            this.verifyignore = b;
066        }
067    
068        public void setOnlyDependencies( boolean b )
069        {
070            this.onlydependencies = b;
071        }
072    
073        public void setRepository( String rep )
074        {
075            this.defaultRepository = rep;
076        }
077    
078        public void setClasspath( String classpath )
079        {
080            this.classpath = classpath;
081        }
082    
083        public void setPathrefid( String pathrefid )
084        {
085            this.pathrefid = pathrefid;
086        }
087    
088        /**
089         * Execute the input script with Velocity
090         *
091         * @throws BuildException  
092         * BuildExceptions are thrown when required attributes are missing.
093         * Exceptions thrown by Velocity are rethrown as BuildExceptions.
094         */
095        public void execute () 
096            throws BuildException
097        {
098            /*
099             *  make sure that we at least have a package name
100             */
101            if( pkg == null)
102                throw new BuildException("Need to specify a package to fetch");
103        
104            /*
105             *  get the repository
106             */
107            Repository repository = null;
108    
109            try
110            {
111                repository = new RepositoryXML();
112                repository.load(  new URL( defaultRepository + "repository.xml") );
113                
114            }
115            catch( Exception e )
116            {
117                throw new BuildException("Problem getting repository info", e );
118            }
119    
120            log("Fetching package '" + pkg + "' from repository '" + defaultRepository 
121                + "' into local repository '" + localrep + "'");
122    
123            /*
124             *  create an antpath
125             */
126          
127            Path antpath = new Path( project );
128    
129            try
130            {
131                /*
132                 *  do it : first, see if there is a dependency list
133                 */
134    
135                if( ver == null)
136                    ver = repository.getPackageDefaultVersion( pkg );
137    
138                List deplist = repository.getDependencyList( pkg, ver );
139                
140                Iterator ii = deplist.iterator();
141    
142                while(ii.hasNext())
143                {
144                    /*
145                     *  for now, use the fetchtarget names
146                     */
147    
148                    String depnameuni = (String) ii.next();
149    
150                    JJARPackage jjarp = new JJARPackage( depnameuni );
151    
152                    String depname = jjarp.getName();
153                    String depver = jjarp.getVersionString();
154                    String deptarget = repository.getFetchTarget( depname, depver );
155                             
156                    /*
157                     *  see if the dependent package is already in the classpath
158                     */
159                    
160                    if ( verifyignore && ClasspathUtil.containsVersionedJar( classpath, depname, depver))
161                    {
162                        log("  Dependency '" + depname + "' already in classpath - skipping");
163                        continue;
164                    }
165                    
166                    /*
167                     *  now get it
168                     */
169                    
170                    URL url = new URL( defaultRepository + deptarget );
171                    URLConnection uconn  = (URLConnection) url.openConnection(); 
172                    
173                    log("  Fetching dependency : " + deptarget );
174                    
175                    Transport.fetchJar( uconn, localrep + "/" + deptarget );                
176    
177                    /*
178                     *  now if they want us to add to a classpath, we will have
179                     *  a pathrefid, so for now, pretend it's fresh
180                     */
181    
182                    log("Adding depedency element " + localrep + "/" + deptarget + " to classpath");
183    
184                    antpath.createPathElement().setPath( localrep + "/" + deptarget );
185                }
186                
187                /*
188                 *  now get the actual package.  If all we want were the dependencies
189                 *  for something (example : we are building something...) then
190                 *  bail, because we are done.
191                 */
192    
193                if( onlydependencies )
194                {
195                    log("  Dependency-only mode : not fetching target " + pkg );
196                    return;
197                }
198    
199                /*
200                 *  if we don't have a version, we need to get it from the repository
201                 */
202    
203                if (ver == null)
204                {
205                    ver = repository.getPackageDefaultVersion( pkg );
206                }
207    
208                if( verifyignore && ClasspathUtil.containsVersionedJar( classpath, pkg, ver))
209                {                
210                    log("  Skipping fetch of '" + pkg + "' - already exists in classpath");
211                    // ignore and continue
212                }
213                else
214                {
215                    String fetchTarget = repository.getFetchTarget( pkg, ver );
216    
217                    URL url = new URL( defaultRepository + fetchTarget );
218                    URLConnection uconn  = (URLConnection) url.openConnection(); 
219    
220                    log("  Fetching package : " + pkg );
221                    
222                    Transport.fetchJar( uconn, localrep + "/" + fetchTarget );
223    
224                    log("Adding package element " + localrep + "/" + fetchTarget + " to classpath");
225    
226                    antpath.createPathElement().setPath( localrep + "/" + fetchTarget );
227     
228                }
229            }
230            catch( Exception e )
231            {
232                throw new BuildException("Exception : ",e);
233            }
234            finally
235            {
236                if( pathrefid != null)
237                {
238                    project.addReference( pathrefid, antpath);
239                }
240            }
241        }
242    
243       
244    }