| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package org.apache.tools.ant.taskdefs.optional; |
| |
| import java.io.File; |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.DirectoryScanner; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.taskdefs.MatchingTask; |
| import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter; |
| import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapterFactory; |
| import org.apache.tools.ant.types.Mapper; |
| import org.apache.tools.ant.types.Path; |
| import org.apache.tools.ant.util.FileNameMapper; |
| import org.apache.tools.ant.util.IdentityMapper; |
| import org.apache.tools.ant.util.SourceFileScanner; |
| import org.apache.tools.ant.util.facade.FacadeTaskHelper; |
| import org.apache.tools.ant.util.facade.ImplementationSpecificArgument; |
| |
| /** |
| * Converts files from native encodings to ASCII. |
| * |
| * @since Ant 1.2 |
| */ |
| public class Native2Ascii extends MatchingTask { |
| |
| private boolean reverse = false; // convert from ascii back to native |
| private String encoding = null; // encoding to convert to/from |
| private File srcDir = null; // Where to find input files |
| private File destDir = null; // Where to put output files |
| private String extension = null; // Extension of output files if different |
| |
| private Mapper mapper; |
| private FacadeTaskHelper facade = null; |
| private Native2AsciiAdapter nestedAdapter = null; |
| |
| /** No args constructor */ |
| public Native2Ascii() { |
| facade = new FacadeTaskHelper(Native2AsciiAdapterFactory.getDefault()); |
| } |
| |
| /** |
| * Flag the conversion to run in the reverse sense, |
| * that is Ascii to Native encoding. |
| * |
| * @param reverse True if the conversion is to be reversed, |
| * otherwise false; |
| */ |
| public void setReverse(boolean reverse) { |
| this.reverse = reverse; |
| } |
| |
| /** |
| * The value of the reverse attribute. |
| * |
| * @return the reverse attribute. |
| * @since Ant 1.6.3 |
| */ |
| public boolean getReverse() { |
| return reverse; |
| } |
| |
| /** |
| * Set the encoding to translate to/from. |
| * If unset, the default encoding for the JVM is used. |
| * |
| * @param encoding String containing the name of the Native |
| * encoding to convert from or to. |
| */ |
| public void setEncoding(String encoding) { |
| this.encoding = encoding; |
| } |
| |
| /** |
| * The value of the encoding attribute. |
| * |
| * @return the encoding attribute. |
| * @since Ant 1.6.3 |
| */ |
| public String getEncoding() { |
| return encoding; |
| } |
| |
| /** |
| * Set the source directory in which to find files to convert. |
| * |
| * @param srcDir directory to find input file in. |
| */ |
| public void setSrc(File srcDir) { |
| this.srcDir = srcDir; |
| } |
| |
| |
| /** |
| * Set the destination directory to place converted files into. |
| * |
| * @param destDir directory to place output file into. |
| */ |
| public void setDest(File destDir) { |
| this.destDir = destDir; |
| } |
| |
| /** |
| * Set the extension which converted files should have. |
| * If unset, files will not be renamed. |
| * |
| * @param ext File extension to use for converted files. |
| */ |
| public void setExt(String ext) { |
| this.extension = ext; |
| } |
| |
| /** |
| * Choose the implementation for this particular task. |
| * |
| * @param impl the name of the implementation |
| * @since Ant 1.6.3 |
| */ |
| public void setImplementation(String impl) { |
| if ("default".equals(impl)) { |
| facade.setImplementation(Native2AsciiAdapterFactory.getDefault()); |
| } else { |
| facade.setImplementation(impl); |
| } |
| } |
| |
| /** |
| * Defines the FileNameMapper to use (nested mapper element). |
| * |
| * @return the mapper to use for file name translations. |
| * @throws BuildException if more than one mapper is defined. |
| */ |
| public Mapper createMapper() throws BuildException { |
| if (mapper != null) { |
| throw new BuildException("Cannot define more than one mapper", |
| getLocation()); |
| } |
| mapper = new Mapper(getProject()); |
| return mapper; |
| } |
| |
| /** |
| * A nested filenamemapper |
| * |
| * @param fileNameMapper the mapper to add |
| * @since Ant 1.6.3 |
| */ |
| public void add(FileNameMapper fileNameMapper) { |
| createMapper().add(fileNameMapper); |
| } |
| |
| /** |
| * Adds an implementation specific command-line argument. |
| * |
| * @return a ImplementationSpecificArgument to be configured |
| * @since Ant 1.6.3 |
| */ |
| public ImplementationSpecificArgument createArg() { |
| ImplementationSpecificArgument arg = |
| new ImplementationSpecificArgument(); |
| facade.addImplementationArgument(arg); |
| return arg; |
| } |
| |
| /** |
| * The classpath to use when loading the native2ascii |
| * implementation if it is not a built-in one. |
| * |
| * @return Path |
| * @since Ant 1.8.0 |
| */ |
| public Path createImplementationClasspath() { |
| return facade.getImplementationClasspath(getProject()); |
| } |
| |
| /** |
| * Set the adapter explicitly. |
| * |
| * @param adapter Native2AsciiAdapter |
| * @since Ant 1.8.0 |
| */ |
| public void add(Native2AsciiAdapter adapter) { |
| if (nestedAdapter != null) { |
| throw new BuildException( |
| "Can't have more than one native2ascii adapter"); |
| } |
| nestedAdapter = adapter; |
| } |
| |
| /** |
| * Execute the task |
| * |
| * @throws BuildException is there is a problem in the task execution. |
| */ |
| @Override |
| public void execute() throws BuildException { |
| |
| DirectoryScanner scanner = null; // Scanner to find our inputs |
| String[] files; // list of files to process |
| |
| // default srcDir to basedir |
| if (srcDir == null) { |
| srcDir = getProject().resolveFile("."); |
| } |
| |
| // Require destDir |
| if (destDir == null) { |
| throw new BuildException("The dest attribute must be set."); |
| } |
| |
| // if src and dest dirs are the same, require the extension |
| // to be set, so we don't stomp every file. One could still |
| // include a file with the same extension, but .... |
| if (srcDir.equals(destDir) && extension == null && mapper == null) { |
| throw new BuildException( |
| "The ext attribute or a mapper must be set if src and dest dirs are the same."); |
| } |
| |
| FileNameMapper m; |
| if (mapper == null) { |
| if (extension == null) { |
| m = new IdentityMapper(); |
| } else { |
| m = new ExtMapper(); |
| } |
| } else { |
| m = mapper.getImplementation(); |
| } |
| |
| scanner = getDirectoryScanner(srcDir); |
| files = scanner.getIncludedFiles(); |
| SourceFileScanner sfs = new SourceFileScanner(this); |
| files = sfs.restrict(files, srcDir, destDir, m); |
| int count = files.length; |
| if (count == 0) { |
| return; |
| } |
| String message = "Converting " + count + " file" |
| + (count != 1 ? "s" : "") + " from "; |
| log(message + srcDir + " to " + destDir); |
| for (String file : files) { |
| String[] dest = m.mapFileName(file); |
| if (dest != null && dest.length > 0) { |
| convert(file, dest[0]); |
| } |
| } |
| } |
| |
| /** |
| * Convert a single file. |
| * |
| * @param srcName name of the input file. |
| * @param destName name of the input file. |
| */ |
| private void convert(String srcName, String destName) |
| throws BuildException { |
| File srcFile; // File to convert |
| File destFile; // where to put the results |
| |
| // Build the full file names |
| srcFile = new File(srcDir, srcName); |
| destFile = new File(destDir, destName); |
| |
| // Make sure we're not about to clobber something |
| if (srcFile.equals(destFile)) { |
| throw new BuildException("file %s would overwrite itself", srcFile); |
| } |
| |
| // Make intermediate directories if needed |
| // TODO JDK 1.1 doesn't have File.getParentFile, |
| String parentName = destFile.getParent(); |
| if (parentName != null) { |
| File parentFile = new File(parentName); |
| |
| if (!parentFile.exists() |
| && !(parentFile.mkdirs() || parentFile.isDirectory())) { |
| throw new BuildException("cannot create parent directory %s", |
| parentName); |
| } |
| } |
| |
| log("converting " + srcName, Project.MSG_VERBOSE); |
| Native2AsciiAdapter ad = nestedAdapter != null ? nestedAdapter |
| : Native2AsciiAdapterFactory.getAdapter(facade.getImplementation(), this, |
| createImplementationClasspath()); |
| if (!ad.convert(this, srcFile, destFile)) { |
| throw new BuildException("conversion failed"); |
| } |
| } |
| |
| /** |
| * Returns the (implementation specific) settings given as nested |
| * arg elements. |
| * @return the arguments. |
| * @since Ant 1.6.3 |
| */ |
| public String[] getCurrentArgs() { |
| return facade.getArgs(); |
| } |
| |
| private class ExtMapper implements FileNameMapper { |
| |
| @Override |
| public void setFrom(String s) { |
| } |
| |
| @Override |
| public void setTo(String s) { |
| } |
| |
| @Override |
| public String[] mapFileName(String fileName) { |
| int lastDot = fileName.lastIndexOf('.'); |
| if (lastDot >= 0) { |
| return new String[] {fileName.substring(0, lastDot) + extension}; |
| } |
| return new String[] {fileName + extension}; |
| } |
| } |
| } |