| package org.unicode.cldr.util; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.unicode.cldr.util.CLDRFile.DraftStatus; |
| import org.unicode.cldr.util.CLDRLocale.SublocaleProvider; |
| import org.unicode.cldr.util.XMLSource.ResolvingSource; |
| |
| /** |
| * A factory is the normal method to produce a set of CLDRFiles from a directory of XML files. |
| * See SimpleFactory for a concrete subclass. |
| */ |
| public abstract class Factory implements SublocaleProvider { |
| |
| /** |
| * Flag to set more verbose output in makeServolingSource |
| */ |
| private static final boolean DEBUG_FACTORY = false; |
| |
| private File supplementalDirectory = null; |
| |
| /** |
| * Note, the source director(ies) may be a list (seed/common). Therefore, this function is deprecated |
| * |
| * @deprecated |
| * @return the first directory |
| */ |
| public String getSourceDirectory() { |
| return getSourceDirectories()[0].getAbsolutePath(); |
| } |
| |
| /** |
| * Note, the source director(ies) may be a list (seed/common). |
| * |
| * @return the first directory |
| */ |
| public abstract File[] getSourceDirectories(); |
| |
| /** |
| * Which source directory does this particular localeID belong to? |
| * |
| * @param localeID |
| * @return |
| */ |
| @Deprecated |
| public final File getSourceDirectoryForLocale(String localeID) { |
| List<File> temp = getSourceDirectoriesForLocale(localeID); |
| return temp == null ? null : temp.get(0); |
| } |
| |
| /** |
| * Classify the tree according to type (maturity) |
| * |
| * @author srl |
| * |
| */ |
| public enum SourceTreeType { |
| common, seed, other |
| }; |
| |
| /** |
| * Returns the source tree type of either an XML file or its parent directory. |
| * |
| * @param fileOrDir |
| * @return |
| */ |
| public static final SourceTreeType getSourceTreeType(File fileOrDir) { |
| if (fileOrDir == null) return null; |
| File parentDir = fileOrDir.isFile() ? fileOrDir.getParentFile() : fileOrDir; |
| File grandparentDir = parentDir.getParentFile(); |
| |
| try { |
| return SourceTreeType.valueOf(grandparentDir.getName()); |
| } catch (IllegalArgumentException iae) { |
| try { |
| return SourceTreeType.valueOf(parentDir.getName()); |
| } catch (IllegalArgumentException iae2) { |
| return SourceTreeType.other; |
| } |
| } |
| } |
| |
| public enum DirectoryType { |
| main, supplemental, bcp47, casing, collation, dtd, rbnf, segments, transforms, other |
| }; |
| |
| public static final DirectoryType getDirectoryType(File fileOrDir) { |
| if (fileOrDir == null) return null; |
| File parentDir = fileOrDir.isFile() ? fileOrDir.getParentFile() : fileOrDir; |
| |
| try { |
| return DirectoryType.valueOf(parentDir.getName()); |
| } catch (IllegalArgumentException iae2) { |
| return DirectoryType.other; |
| } |
| } |
| |
| protected abstract CLDRFile handleMake(String localeID, boolean resolved, DraftStatus madeWithMinimalDraftStatus); |
| |
| public CLDRFile make(String localeID, boolean resolved, DraftStatus madeWithMinimalDraftStatus) { |
| return handleMake(localeID, resolved, madeWithMinimalDraftStatus) |
| .setSupplementalDirectory(getSupplementalDirectory()); |
| } |
| |
| public CLDRFile make(String localeID, boolean resolved, boolean includeDraft) { |
| return make(localeID, resolved, includeDraft ? DraftStatus.unconfirmed : DraftStatus.approved); |
| } |
| |
| public CLDRFile make(String localeID, boolean resolved) { |
| return make(localeID, resolved, getMinimalDraftStatus()); |
| } |
| |
| public CLDRFile makeWithFallback(String localeID) { |
| return makeWithFallback(localeID, getMinimalDraftStatus()); |
| } |
| |
| public CLDRFile makeWithFallback(String localeID, DraftStatus madeWithMinimalDraftStatus) { |
| String currentLocaleID = localeID; |
| Set<String> availableLocales = this.getAvailable(); |
| while (!availableLocales.contains(currentLocaleID) && currentLocaleID != "root") { |
| currentLocaleID = LocaleIDParser.getParent(currentLocaleID); |
| } |
| return make(currentLocaleID, true, madeWithMinimalDraftStatus); |
| } |
| |
| public static XMLSource makeResolvingSource(List<XMLSource> sources) { |
| return new ResolvingSource(sources); |
| } |
| |
| /** |
| * Temporary wrapper for creating an XMLSource. This is a hack and should |
| * only be used in the Survey Tool for now. |
| * |
| * @param localeID |
| * @return |
| */ |
| public final XMLSource makeSource(String localeID) { |
| return make(localeID, false).dataSource; |
| } |
| |
| /** |
| * Creates a resolving source for the given locale ID. |
| * |
| * @param localeID |
| * @param madeWithMinimalDraftStatus |
| * @return |
| */ |
| protected ResolvingSource makeResolvingSource(String localeID, DraftStatus madeWithMinimalDraftStatus) { |
| List<XMLSource> sourceList = new ArrayList<XMLSource>(); |
| String curLocale = localeID; |
| while (curLocale != null) { |
| if (DEBUG_FACTORY) { |
| System.out.println("Factory.makeResolvingSource: calling handleMake for locale " + |
| curLocale + " and MimimalDraftStatus " + madeWithMinimalDraftStatus); |
| } |
| CLDRFile file = handleMake(curLocale, false, madeWithMinimalDraftStatus); |
| if (file == null) { |
| throw new NullPointerException(this + ".handleMake returned a null CLDRFile for " + curLocale); |
| } |
| XMLSource source = file.dataSource; |
| sourceList.add(source); |
| curLocale = LocaleIDParser.getParent(curLocale); |
| } |
| return new ResolvingSource(sourceList); |
| } |
| |
| public abstract DraftStatus getMinimalDraftStatus(); |
| |
| /** |
| * Convenience static |
| * |
| * @param path |
| * @param string |
| * @return |
| */ |
| public static Factory make(String path, String string) { |
| try { |
| return SimpleFactory.make(path, string); |
| } catch (Exception e) { |
| throw new IllegalArgumentException("path: " + path + "; string: " + string, e); |
| } |
| } |
| |
| /** |
| * Convenience static |
| * |
| * @param mainDirectory |
| * @param string |
| * @param approved |
| * @return |
| */ |
| public static Factory make(String mainDirectory, String string, DraftStatus approved) { |
| return SimpleFactory.make(mainDirectory, string, approved); |
| } |
| |
| /** |
| * Get a set of the available locales for the factory. |
| */ |
| public Set<String> getAvailable() { |
| return Collections.unmodifiableSet(handleGetAvailable()); |
| } |
| |
| protected abstract Set<String> handleGetAvailable(); |
| |
| /** |
| * Get a set of the available language locales (according to isLanguage). |
| */ |
| public Set<String> getAvailableLanguages() { |
| Set<String> result = new TreeSet<String>(); |
| for (Iterator<String> it = handleGetAvailable().iterator(); it.hasNext();) { |
| String s = it.next(); |
| if (XPathParts.isLanguage(s)) result.add(s); |
| } |
| return result; |
| } |
| |
| /** |
| * Get a set of the locales that have the given parent (according to isSubLocale()) |
| * |
| * @param isProper |
| * if false, then parent itself will match |
| */ |
| public Set<String> getAvailableWithParent(String parent, boolean isProper) { |
| Set<String> result = new TreeSet<String>(); |
| |
| for (Iterator<String> it = handleGetAvailable().iterator(); it.hasNext();) { |
| String s = it.next(); |
| int relation = XPathParts.isSubLocale(parent, s); |
| if (relation >= 0 && !(isProper && relation == 0)) result.add(s); |
| } |
| return result; |
| } |
| |
| public File getSupplementalDirectory() { |
| return supplementalDirectory; |
| } |
| |
| /** |
| * Sets the supplemental directory to be used by this Factory and CLDRFiles |
| * created by this Factory. |
| * |
| * @param supplementalDirectory |
| * @return |
| */ |
| public Factory setSupplementalDirectory(File supplementalDirectory) { |
| this.supplementalDirectory = supplementalDirectory; |
| return this; |
| } |
| |
| // TODO(jchye): Clean this up. |
| public CLDRFile getSupplementalData() { |
| try { |
| return make("supplementalData", false); |
| } catch (RuntimeException e) { |
| return Factory.make(getSupplementalDirectory().getPath(), ".*").make("supplementalData", false); |
| } |
| } |
| |
| public CLDRFile getSupplementalMetadata() { |
| try { |
| return make("supplementalMetadata", false); |
| } catch (RuntimeException e) { |
| return Factory.make(getSupplementalDirectory().getPath(), ".*").make("supplementalMetadata", false); |
| } |
| } |
| |
| /** |
| * These factory implementations don't do any caching. |
| */ |
| public Set<CLDRLocale> subLocalesOf(CLDRLocale forLocale) { |
| return calculateSubLocalesOf(forLocale, getAvailableCLDRLocales()); |
| } |
| |
| /** |
| * Helper function. |
| * |
| * @return |
| */ |
| public Set<CLDRLocale> getAvailableCLDRLocales() { |
| return CLDRLocale.getInstance(getAvailable()); |
| } |
| |
| /** |
| * Helper function. Does not cache. |
| * |
| * @param locale |
| * @param available |
| * @return |
| */ |
| public Set<CLDRLocale> calculateSubLocalesOf(CLDRLocale locale, Set<CLDRLocale> available) { |
| Set<CLDRLocale> sub = new TreeSet<CLDRLocale>(); |
| for (CLDRLocale l : available) { |
| if (l.getParent() == locale) { |
| sub.add(l); |
| } |
| } |
| return sub; |
| } |
| |
| /** |
| * Get all of the files in the source directories that match localeName (which is really xml file name). |
| * @param localeName |
| * @return |
| */ |
| public abstract List<File> getSourceDirectoriesForLocale(String localeName); |
| } |