package com.intellij.flex.compiler; import flex2.compiler.config.ConfigurationException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class FlexCompilerUtil { private static final String LOCALE = "{locale}"; public static void ensureFileCanBeCreated(final File file) throws ConfigurationException { if (file.isDirectory()) { throw new ConfigurationException(file + " is a directory"); } if (!file.exists()) { final File parent = file.getParentFile(); if (parent != null && !parent.exists()) { final boolean ok = parent.mkdirs(); if (!ok && !parent.exists()) { // check exists() once more because it could be created in another thread throw new ConfigurationException("Can't create directory '" + parent + "'"); } } try { new FileOutputStream(file).close(); file.delete(); } catch (IOException e) { throw new ConfigurationException("Can't create file '" + file.getPath() + "': " + e.getMessage()); } } } /* We can't pass unexpanded paths to oemConfig.setSourcePath() because paths relative to config file won't be resolved (IDEA-61189) Also we can't pass expanded paths because we'll loose i18n - source path chain will be the same for all locales (IDEA-71381) So we must prepare absolute (i.e. expanded) paths with locale specific part substituted back to {locale} token. */ public static File[] getPathsWithLocaleToken(final File[] unexpandedPaths, final File[] expandedPaths, final String[] locales) { final File[] result = new File[unexpandedPaths.length]; for (int i = 0, j = 0; i < unexpandedPaths.length; i++) { final String unexpandedPath = unexpandedPaths[i].getPath(); if (unexpandedPath.contains(LOCALE)) { final String resultPath = getExpandedPathWithLocaleToken(unexpandedPath, expandedPaths, j, locales); if (resultPath == null) { error(unexpandedPaths, expandedPaths, locales); } result[i] = new File(resultPath); // just some extra check that we do everything correctly final int numberOfMatches = getNumberOfMatches(unexpandedPath, LOCALE); for (final String locale : locales) { final String expandedPath = expandedPaths[j].getPath(); if (numberOfMatches == getNumberOfMatches(expandedPath, locale) && !resultPath.equals(expandedPath.replace(locale, LOCALE))) { return error(unexpandedPaths, expandedPaths, locales); } j++; } } else { result[i] = expandedPaths[j]; j++; } } return result; } private static String getExpandedPathWithLocaleToken(final String unexpandedPath, final File[] expandedPaths, final int index, final String[] locales) { final int numberOfMatches = getNumberOfMatches(unexpandedPath, LOCALE); for (int i = 0; i < locales.length; i++) { final String expandedPath = expandedPaths[index + i].getPath(); if (numberOfMatches == getNumberOfMatches(expandedPath, locales[i])) { return expandedPath.replace(locales[i], LOCALE); } } if (locales.length == 1) { return expandedPaths[index].getPath().replace(locales[0], LOCALE); } return null; // no idea which parts of absolute must be substituted by {locale} token } private static int getNumberOfMatches(final String s, final String substring) { int num = 0; int lastIndex = 0; while ((lastIndex = s.indexOf(substring, lastIndex == 0 ? 0 : lastIndex + 1)) > 0) { num++; } return num; } private static File[] error(final File[] unexpandedPaths, final File[] expandedPaths, final String[] locales) { final StringBuilder message = new StringBuilder(); message.append("Unexpected paths.\nUnexpanded=["); for (final File file : unexpandedPaths) { message.append(file.getPath()).append(","); } message.append("]\nExpanded=["); for (final File file : expandedPaths) { message.append(file.getPath()).append(","); } message.append("]\nLocales=["); for (final String loc : locales) { message.append(loc).append(","); } message.append("]"); throw new RuntimeException(message.toString()); } }