001    package org.shiftone.jrat.inject.ant;
002    
003    
004    import org.apache.tools.ant.BuildException;
005    import org.apache.tools.ant.Project;
006    import org.apache.tools.ant.taskdefs.Copy;
007    import org.apache.tools.ant.types.FilterSet;
008    import org.apache.tools.ant.types.FilterSetCollection;
009    import org.shiftone.jrat.core.criteria.IncludeExcludeMethodCriteria;
010    import org.shiftone.jrat.core.criteria.MatcherMethodCriteria;
011    import org.shiftone.jrat.inject.Injector;
012    import org.shiftone.jrat.inject.process.ArchiveFileProcessor;
013    import org.shiftone.jrat.util.io.IOUtil;
014    import org.shiftone.jrat.util.log.Logger;
015    
016    import java.io.File;
017    import java.util.Enumeration;
018    import java.util.Iterator;
019    import java.util.Map;
020    import java.util.TreeMap;
021    
022    
023    /**
024     * Apache Ant Task that extends the common Copy task.
025     *
026     * @author jeff@shiftone.org (Jeff Drost)
027     */
028    public class InjectCopyTask extends Copy {
029    
030        private static final Logger LOG = Logger.getLogger(InjectCopyTask.class);
031        private Injector injector;
032        private IncludeExcludeMethodCriteria methodCriteria;
033    
034        public InjectCopyTask() {
035    
036            injector = new Injector();
037            methodCriteria = new IncludeExcludeMethodCriteria();
038    
039            injector.setMethodCriteria(methodCriteria);
040        }
041    
042    
043        public MatcherMethodCriteria createInclude() {
044    
045            MatcherMethodCriteria newCriteria = new MatcherMethodCriteria();
046    
047            methodCriteria.addPositive(newCriteria);
048    
049            return newCriteria;
050        }
051    
052    
053        public MatcherMethodCriteria createExclude() {
054    
055            MatcherMethodCriteria newCriteria = new MatcherMethodCriteria();
056    
057            methodCriteria.addNegative(newCriteria);
058    
059            return newCriteria;
060        }
061    
062    
063        private void copyOrInjectFile(String fromFile, String toFile, FilterSetCollection executionFilters)
064                throws Exception {
065    
066            String extention = IOUtil.getExtention(fromFile);
067    
068            if ((extention != null)
069                    && ("class".equalsIgnoreCase(extention) || ArchiveFileProcessor.isArchiveExtention(extention))) {
070                injector.inject(fromFile, toFile);
071            } else {
072                if (fromFile.equals(toFile)) {
073                    log("Skipping self-copy of " + fromFile, verbosity);
074                } else {
075    
076                    //log("Copying " + fromFile, Project.MSG_VERBOSE);
077                    getFileUtils().copyFile(     //
078                            fromFile,                //
079                            toFile,                  //
080                            executionFilters,        // token filtering
081                            getFilterChains(),       // token filtering
082                            forceOverwrite,          //
083                            preserveLastModified,    //
084                            getEncoding(),           //
085                            getProject());
086                }
087            }
088        }
089    
090    
091        private String getString(Object to) {
092    
093            // http://sourceforge.net/tracker/index.php?func=detail&aid=1011493&group_id=41841&atid=431431
094            if (to instanceof String) {
095                return (String) to;
096            } else if (to instanceof String[]) {
097                return ((String[]) to)[0];
098            } else {
099                throw new RuntimeException("Error - please report a bug : " + to.getClass().getName());
100            }
101        }
102    
103    
104        /**
105         * Actually does the file (and possibly empty directory) copies. This is a
106         * good method for subclasses to override.
107         */
108        protected void doFileOperations() {
109    
110            Iterator sourceFiles;
111            Map orderedCopyMap = new TreeMap(fileCopyMap);
112    
113            if (orderedCopyMap.size() > 0) {
114                log("Copying " + orderedCopyMap.size() + " file" + ((orderedCopyMap.size() == 1)
115                        ? ""
116                        : "s") + " to " + destDir.getAbsolutePath(), verbosity);
117    
118                sourceFiles = orderedCopyMap.keySet().iterator();
119    
120                // injector.setForceOverwrite(forceOverwrite);
121                // injector.setPreserveLastModified(preserveLastModified);
122                while (sourceFiles.hasNext()) {
123                    String fromFile = (String) sourceFiles.next();
124                    Object to = orderedCopyMap.get(fromFile);
125                    String toFile;
126    
127                    // http://sourceforge.net/tracker/index.php?func=detail&aid=1011493&group_id=41841&atid=431431
128                    toFile = getString(to);
129    
130                    //log(fromFile, verbosity);
131                    try {
132                        FilterSetCollection executionFilters = new FilterSetCollection();
133    
134                        if (filtering) {
135                            executionFilters.addFilterSet(getProject().getGlobalFilterSet());
136                        }
137    
138                        for (Enumeration filterEnum = getFilterSets().elements(); filterEnum.hasMoreElements();) {
139                            executionFilters.addFilterSet((FilterSet) filterEnum.nextElement());
140                        }
141    
142                        copyOrInjectFile(fromFile, toFile, executionFilters);
143                    }
144                    catch (Exception e) {
145                        LOG.error("InjectCopyTask error", e);
146    
147                        throw new BuildException("Error instramenting " + fromFile, e, getLocation());
148                    }
149                }
150            }
151    
152            if (includeEmpty) {
153                copyEmptyDirectories();
154            }
155        }
156    
157    
158        private void copyEmptyDirectories() {
159    
160            Enumeration e = dirCopyMap.elements();
161            int count = 0;
162    
163            while (e.hasMoreElements()) {
164                File d = new File(getString(e.nextElement()));
165    
166                if (!d.exists()) {
167                    if (!d.mkdirs()) {
168                        log("Unable to column directory " + d.getAbsolutePath(), Project.MSG_ERR);
169                    } else {
170                        count++;
171                    }
172                }
173            }
174    
175            if (count > 0) {
176                log("Copied " + count + " empty director" + ((count == 1)
177                        ? "y"
178                        : "ies") + " to " + destDir.getAbsolutePath(), verbosity);
179            }
180        }
181    
182    
183        public void execute() throws BuildException {
184    
185            try {
186                super.execute();
187            }
188            catch (BuildException e) {
189                LOG.error("copy failed", e);
190    
191                throw e;
192            }
193            catch (Throwable e) {
194                LOG.error("copy failed", e);
195    
196                throw new BuildException(e);
197            }
198        }
199    }