• R/O
  • SSH
  • HTTPS

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

OmegaT のメニューバーにフォルダーツリー参照用のメニューを追加します。


ファイル情報

Rev. 67
サイズ 15,482 バイト
日時 2015-06-29 23:45:17
作者 yu-tang
ログメッセージ

Change package jp/sourceforge/... to jp/osdn/... and some refactoring

内容

/**************************************************************************
 FolderMenu - easy access to project folders from menu.
 
  Copyright (C) 2000-2006 Keith Godfrey and Maxym Mykhalchuk
               2005-2006 Henry Pijffers
               2006 Martin Wunderlich
               2006-2007 Didier Briel
               2008 Martin Fleurke, Didier Briel
               2009 Didier Briel, Arno Peters, Alex Buloichik
               2010 Alex Buloichik
               2011 Alex Buloichik, Didier Briel
               2012 Guido Leenders, Thomas Cordonnier
               2013 Alex Buloichik
               2014 Yu Tang

               Home page: http://sourceforge.jp/users/yu-tang/
               Support center: http://sourceforge.jp/users/yu-tang/pf/

 This file is part of plugin for OmegaT.
 http://www.omegat.org/

 License: GNU GPL version 3 or (at your option) any later version.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/

package jp.osdn.users.yutang.omegat.plugin.foldermenu;

import gen.core.filters.Files;
import gen.core.filters.Filter;
import gen.core.filters.Filters;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.regex.Pattern;
import org.omegat.core.Core;
import org.omegat.core.data.ProjectProperties;
import org.omegat.filters2.AbstractFilter;
import org.omegat.filters2.FilterContext;
import org.omegat.filters2.IFilter;
import org.omegat.filters2.TranslationException;
import org.omegat.filters2.master.FilterMaster;
import org.omegat.util.Language;

// 

/**
 * Based on org.omegat.filters2.master.FilterMaster#translateFile.
 * 
 * A master class that registers and handles all the filters. Singleton - there can be only one instance of
 * this class.
 * 
 * @author Maxym Mykhalchuk
 * @author Henry Pijffers
 * @author Martin Wunderlich
 * @author Didier Briel
 * @author Martin Fleurke
 * @author Arno Peters
 * @author Alex Buloichik (alex73mail@gmail.com)
 * @author Guido Leenders
 * @author Thomas Cordonnier
 * +
 * @author Yu-Tang
 */
public class FilterHelper {

    /**
     * Get translated file object corresponding to source file.
     * It does not check whether a file exists.
     * 
     * @param filename
     *            Relative source file path to the Source root directory.
     * @return File object, can be null.
     */
    public static File getTargetFile(String filename) {
        try {
            ProjectProperties props = Core.getProject().getProjectProperties();
            String sourcedir = props.getSourceRoot();
            String targetdir = props.getTargetRoot();
            FilterMaster fm = Core.getFilterMaster();
            FilterContext fc = new FilterContext(props);

            LookupInformation lookup = lookupFilter(sourcedir + File.separator + filename, fc, fm.getConfig());
            if (lookup == null) {
                // The file is not supported by any of the filters.
                return null;
            }

            File inFile = new File(sourcedir + File.separator + filename);

            String name = inFile.getName();
            String path = filename.substring(0, filename.length() - name.length());

            File outFile = new File(targetdir
                    + File.separator
                    + path
                    + File.separator
                    + constructTargetFilename(lookup.outFilesInfo.getSourceFilenameMask(), name,
                            lookup.outFilesInfo.getTargetFilenamePattern(), fc.getTargetLang(),
                            lookup.outFilesInfo.getSourceEncoding(), lookup.outFilesInfo.getTargetEncoding(),
                            lookup.filterObject.getFileFormatName()));
            return outFile;
        } catch (Exception ex) {
            return null;
        }
    }

    static class LookupInformation {
        public final Files outFilesInfo;
        public final IFilter filterObject;
        public final Map<String, String> config;

        public LookupInformation(IFilter filterObject, Files outFilesInfo, Map<String, String> config) {
            this.filterObject = filterObject;
            this.outFilesInfo = outFilesInfo;
            this.config = config;
        }
    }

    /**
     * Gets the filter according to the source filename provided. In case of failing to find a filter to
     * handle the file returns <code>null</code>.
     * 
     * In case of finding an appropriate filter it
     * <ul>
     * <li>Creates the filter (use <code>OneFilter.getFilter()</code> to get it)
     * <li>Creates a reader (use <code>OneFilter.getReader()</code> to get it)
     * <li>Checks whether the filter supports the file.
     * </ul>
     * It <b>does not</b> check whether the filter supports the inFile, i.e. it doesn't call
     * <code>isFileSupported</code>
     * 
     * 
     * @param filename
     *            The source filename.
     * @return The filter to handle the inFile.
     */
    private static LookupInformation lookupFilter(String filename, FilterContext fc, Filters filters) throws TranslationException,
            IOException {
        File inFile = new File(filename);
        String name = inFile.getName();
        String path = inFile.getParent();
        if (path == null)
            path = "";

        for (Filter f : filters.getFilters()) {
            if (!f.isEnabled()) {
                continue;
            }
            for (Files ff : f.getFiles()) {
                if (matchesMask(name, ff.getSourceFilenameMask())) {
                    IFilter filterObject;
                    filterObject = FilterMaster.getFilterInstance(f.getClassName());

                    if (filterObject != null) {
                        fc.setInEncoding(ff.getSourceEncoding());
                        fc.setOutEncoding(ff.getTargetEncoding());
                        // only for exist filters
                        Map<String, String> config = FilterMaster.forFilter(f.getOption());
                        if (!filterObject.isFileSupported(inFile, config, fc)) {
                            break;
                        }

                        return new LookupInformation(filterObject, ff, config);
                    }
                }
            }
        }
        return null;
    }

    /**
     * Construct a target filename according to pattern from a file's name. Filename should be "name.ext",
     * without path.
     * <p>
     * Output filename pattern is pretty complex. <br>
     * It may consist of normal characters and some substituted variables. They have the format
     * <code>${variableName}</code> and are case insensitive. <br>
     * There're such variables:
     * <ul>
     * <li><code>${filename}</code> - full filename of the input file, both name and extension (default)
     * <li><code>${nameOnly}</code> - only the name of the input file without extension part
     * <li><code>${extension}</code> - the extension of the input file
     * <li><code>${nameOnly-1}</code> - only the name of the input file with first extension
     * <li><code>${extension-1}</code> - the extensions, without the first one
     * <li><code>${targetLocale}</code> - target locale code (of a form "xx_YY")
     * <li><code>${targetLanguage}</code> - the target language and country code together (of a form "XX-YY")
     * <li><code>${targetLanguageCode}</code> - the target language only ("XX")
     * <li><code>${targetCountryCode}</code> - the target country only ("YY")
     * <li><code>${1}, ${2}, ...</code> - variables captured by jokers (* or ?)
     * </ul>
     * <p>
     * Most file filters will use default "<code>${filename}</code>, that leads to the name of translated file
     * being the same as the name of source file. But for example the Java(TM) Resource Bundles file filter
     * will have the pattern equal to "<code>${nameonly}_${targetlanguage}.${extension}</code> ".
     * <p>
     * E.g. if you have
     * <ul>
     * <li>a source filename mask "*.ext1.ext2"
     * <li>file name "thisisfile.ext1.ext2"
     * </ul>
     * Then
     * <ul>
     * <li><code>${nameOnly}</code> will be equal to "thisisfile"
     * <li>and <code>${extension}</code> - "ext1.ext2"
     * <li><code>${nameOnly-1}</code> will be equal to "thisisfile.ext1"
     * <li>and <code>${extension-1}</code> - "ext2"
     * </ul>
     * 
     * @param filename
     *            Filename to change
     * @param pattern
     *            Pattern, according to which we change the filename
     * @return The changed filename
     */
    private static String constructTargetFilename(String sourceMask, String filename, String pattern,
            Language targetLang, String sourceEncoding, String targetEncoding, String filterFormatName) {
        int lastStarPos = sourceMask.lastIndexOf('*');
        int dot = 0;
        if (lastStarPos >= 0) {
            // bugfix #1204740
            // so where's the dot next to the star
            int lastDotPos = sourceMask.indexOf('.', lastStarPos);
            // counting chars after the dot
            int extlength = sourceMask.length() - lastDotPos;
            // going forward this many chars
            // and finding the dot we looked for
            dot = filename.length() - extlength;
        } else {
            dot = filename.lastIndexOf('.');
        }

        String nameOnly = filename;
        String extension = "";
        if (dot >= 0) {
            nameOnly = filename.substring(0, dot);
            extension = filename.substring(dot + 1);
        }

        String res = pattern;
        res = res.replace(AbstractFilter.TFP_FILENAME, filename);
        res = res.replace(AbstractFilter.TFP_NAMEONLY, nameOnly);
        res = res.replace(AbstractFilter.TFP_EXTENSION, extension);

        res = res.replace(AbstractFilter.TFP_TARGET_LOCALE, targetLang.getLocaleCode());
        res = res.replace(AbstractFilter.TFP_TARGET_LANGUAGE, targetLang.getLanguage());
        res = res.replace(AbstractFilter.TFP_TARGET_LANG_CODE, targetLang.getLanguageCode());
        res = res.replace(AbstractFilter.TFP_TARGET_COUNTRY_CODE, targetLang.getCountryCode());
        // Replace also old variable spelling
        res = res.replace(AbstractFilter.TFP_TARGET_COUTRY_CODE, targetLang.getCountryCode());
        res = res.replace(AbstractFilter.TFP_TARGET_LOCALE_LCID, targetLang.getLocaleLCID());
        //
        // System generation time
        //
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LA, FilterMaster.now("a"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LD, FilterMaster.now("d"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LDD, FilterMaster.now("dd"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LH, FilterMaster.now("h"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LHH, FilterMaster.now("hh"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LM, FilterMaster.now("m"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LMM, FilterMaster.now("mm"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LS, FilterMaster.now("s"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LSS, FilterMaster.now("ss"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_LYYYY, FilterMaster.now("yyyy"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UD, FilterMaster.now("D"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UEEE, FilterMaster.now("EEE"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UEEEE, FilterMaster.now("EEEE"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UH, FilterMaster.now("H"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UHH, FilterMaster.now("HH"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UM, FilterMaster.now("M"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UMM, FilterMaster.now("MM"));
        res = res.replace(AbstractFilter.TFP_TIMESTAMP_UMMM, FilterMaster.now("MMM"));
        //
        // Workstation properties
        //
        res = res.replace(AbstractFilter.TFP_SYSTEM_OS_NAME, System.getProperty("os.name"));
        res = res.replace(AbstractFilter.TFP_SYSTEM_OS_VERSION, System.getProperty("os.arch"));
        res = res.replace(AbstractFilter.TFP_SYSTEM_OS_ARCH, System.getProperty("os.version"));
        res = res.replace(AbstractFilter.TFP_SYSTEM_USER_NAME, System.getProperty("user.name"));
        String hostName = null;
        try {
            hostName = java.net.InetAddress.getLocalHost().getHostName();
        } catch (java.net.UnknownHostException uhe) {
            hostName = "";
        }
        res = res.replace(AbstractFilter.TFP_SYSTEM_HOST_NAME, hostName);
        //
        // File properties.
        //
        String sourceEncodingText = "auto";
        if (sourceEncoding != null) {
            sourceEncodingText = sourceEncoding;
        }
        res = res.replace(AbstractFilter.TFP_FILE_SOURCE_ENCODING, sourceEncodingText);
        //
        String targetEncodingText = "auto";
        if (targetEncoding != null) {
            targetEncodingText = targetEncoding;
        }
        res = res.replace(AbstractFilter.TFP_FILE_TARGET_ENCODING, targetEncodingText);
        //
        res = res.replace(AbstractFilter.TFP_FILE_FILTER_NAME, filterFormatName);
        //
        
        String sourceMaskPattern = sourceMask.replaceAll("\\?","(.)").replaceAll("\\*","(.*?)");
        java.util.regex.Matcher sourceMatcher = Pattern.compile(sourceMaskPattern).matcher(filename);
        if (sourceMatcher.find()) {
            for (int i = 1; i <= sourceMatcher.groupCount(); i++) {
                res = res.replaceAll("\\$\\{" + i + "\\}", sourceMatcher.group(i));
            }
        }
        
        String[] splitName = filename.split("\\.");
        StringBuffer nameOnlyBuf = new StringBuffer (splitName[0]);
        StringBuffer extensionBuf = new StringBuffer (splitName[splitName.length - 1]);
        for (int i = 0; i < splitName.length; i++) {
            res = res.replaceAll ("\\$\\{nameOnly-" + i + "\\}", nameOnlyBuf.toString());
            res = res.replaceAll ("\\$\\{extension-" + i + "\\}", extensionBuf.toString());
            if (i + 1 < splitName.length) {
                nameOnlyBuf.append (".").append(splitName[i + 1]);
                extensionBuf.insert(0, splitName[splitName.length - i - 2] + '.');
            }
        }

        return res;
    }

    /**
     * Whether the mask matches the filename. Filename should be "name.ext", without path.
     * 
     * @param filename
     *            The filename to check
     * @param mask
     *            The mask, against which the filename is tested
     * @return Whether the mask matches the filename.
     */
    private static boolean matchesMask(String filename, String mask) {
        mask = mask.replaceAll("\\.", "\\\\.");
        mask = mask.replaceAll("\\*", ".*");
        mask = mask.replaceAll("\\?", ".");
        return filename.matches("(?iu)" + mask);
    }

}