001    /*
002     * Copyright 2005 Stephen J. McConnell
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
013     * implied.
014     *
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package net.dpml.tools.tasks;
020    
021    import java.io.File;
022    
023    import net.dpml.lang.Version;
024    
025    import net.dpml.library.Resource;
026    import net.dpml.library.Type;
027    
028    import org.apache.tools.ant.BuildException;
029    import org.apache.tools.ant.taskdefs.Jar;
030    import org.apache.tools.ant.taskdefs.Manifest;
031    import org.apache.tools.ant.taskdefs.ManifestException;
032    import org.apache.tools.ant.taskdefs.Copy;
033    
034    /**
035     * Execute all plugins relative to the current build phase.
036     *
037     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
038     * @version 1.2.0
039     */
040    public class JarTask extends GenericTask
041    {
042       /**
043        * Constant key for the manifest main class value.
044        */
045        public static final String JAR_MAIN_KEY = "project.jar.main.class";
046    
047       /**
048        * Constant key for the manifest classpath value.
049        */
050        public static final String JAR_CLASSPATH_KEY = "project.jar.classpath";
051        
052        private File m_source;
053        private File m_destination;
054        
055       /**
056        * Task initialization.
057        */
058        public void init()
059        {
060            if( !isInitialized() )
061            {
062                super.init();
063            }
064        }
065        
066       /**
067        * Set the src directory.
068        * @param source the source directory
069        */
070        public void setSrc( File source )
071        {
072            if( source.isDirectory() )
073            {
074                m_source = source;
075            }
076            else
077            {
078                final String error = 
079                  "Jar task src must be a directory.";
080                throw new BuildException( error, getLocation() );
081            }
082        }
083        
084       /**
085        * Set the destination file.
086        * @param destination the destination file
087        */
088        public void setDest( File destination )
089        {
090            m_destination = destination;
091        }
092        
093        private File getSource()
094        {
095            if( null == m_source )
096            {
097                final String error = 
098                  "Missing 'src' attribute in jar task.";
099                throw new BuildException( error, getLocation() );
100            }
101            else
102            {
103                return m_source;
104            }
105        }
106        
107        private File getDestination()
108        {
109            if( null == m_destination )
110            {
111                final String error = 
112                  "Missing 'dest' attribute in jar task.";
113                throw new BuildException( error, getLocation() );
114            }
115            else
116            {
117                return m_destination;
118            }
119        }
120        
121       /**
122        * Execute the task.
123        */
124        public void execute()
125        {
126            File source = getSource();
127            if( !source.exists() )
128            {
129                return;
130            }
131            File jar  = createJarFile( source );
132            checksum( jar );
133            asc( jar );
134        }
135        
136        private File createJarFile( final File classes )
137        {   
138            final File temp = getTempFile();
139            
140            final Jar jar = (Jar) getProject().createTask( "jar" );
141            jar.setTaskName( getTaskName() );
142            jar.setDestFile( temp );
143            jar.setBasedir( classes );
144            jar.setIndex( true );
145            addManifest( jar );
146            jar.init();
147            jar.execute();
148            
149            File dest = getDestination();
150            final File dir = dest.getParentFile();
151            mkDir( dir );
152    
153            final Copy copy = (Copy) getProject().createTask( "copy" );
154            copy.setTaskName( getTaskName() );
155            copy.setFile( temp );
156            copy.setTofile( dest );
157            copy.init();
158            copy.execute();
159            
160            return dest;
161        }
162        
163        private File getTempFile()
164        {
165            final File target = getContext().getTargetDirectory();
166            final String path = getTempFilename();
167            return new File( target, path );
168        }
169        
170        private String getTempFilename()
171        {
172            Resource resource = getResource();
173            String name = resource.getName();
174            Version version = resource.getDecimalVersion();
175            if( null != version )
176            {
177                return name + "-" + version.toString() + ".jar";
178            }
179            else
180            {
181                String spec = resource.getVersion();
182                return name + "-" + spec + ".jar";
183            }
184        }
185        
186        private Type getType()
187        {
188            Resource resource = getResource();
189            return resource.getType( "jar" );
190        }
191    
192        private void addManifest( final Jar jar )
193        {
194            try
195            {
196                Type type = getType();
197                Resource resource = getResource();
198                
199                final Manifest manifest = new Manifest();
200                final Manifest.Section main = manifest.getMainSection();
201    
202                String publisher = resource.getProperty( "project.publisher.name" );
203                if( null != publisher )
204                {
205                    addAttribute( main, "Created-By", publisher );
206                }
207                
208                addAttribute( main, "Built-By", System.getProperty( "user.name" ) );
209                final String classpath = getProject().getProperty( JAR_CLASSPATH_KEY );
210                if( null != classpath )
211                {
212                    addAttribute( main, "Class-Path", classpath );
213                }
214                
215                final String mainClass = resource.getProperty( JAR_MAIN_KEY );
216                if( null != mainClass )
217                {
218                    addAttribute( main, "Main-Class", mainClass );
219                }
220    
221                addAttribute( main, "Extension-Name", getResource().getResourcePath() );
222                String specificationVendor = resource.getProperty( "project.specification.vendor" );
223                if( null != specificationVendor )
224                {
225                    addAttribute( main, "Specification-Vendor", specificationVendor );
226                }
227    
228                String version = resource.getProperty( "project.specification.version" );
229                if( null != version )
230                {
231                    addAttribute( main, "Specification-Version", version );
232                }
233                
234                String implementationVendor = resource.getProperty( "project.implementation.vendor" );
235                if( null != implementationVendor )
236                {
237                    addAttribute( main, "Implementation-Vendor", implementationVendor );
238                }
239    
240                String implementationVendorID = resource.getProperty( "project.implementation.vendor-id" );
241                if( null != implementationVendorID )
242                {
243                    addAttribute( main, "Implementation-Vendor-Id", implementationVendorID );
244                }
245    
246                final Version spec = resource.getDecimalVersion();
247                if( null != spec )
248                {
249                    String implementationVersion = spec.toString();
250                    addAttribute( main, "Implementation-Version", implementationVersion );
251                }
252    
253                jar.addConfiguredManifest( manifest );
254            }
255            catch( Throwable e )
256            {
257                throw new BuildException( e );
258            }
259        }
260        
261        private void addAttribute(
262          final Manifest.Section section, final String name, final String value )
263          throws ManifestException
264        {
265            final Manifest.Attribute attribute = new Manifest.Attribute( name, value );
266            section.addConfiguredAttribute( attribute );
267        }
268    }