org.phenotips.xliff12.XLIFFResourceBundleControl.java Source code

Java tutorial

Introduction

Here is the source code for org.phenotips.xliff12.XLIFFResourceBundleControl.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/
 */
package org.phenotips.xliff12;

import org.phenotips.xliff12.model.Bpt;
import org.phenotips.xliff12.model.Ept;
import org.phenotips.xliff12.model.File;
import org.phenotips.xliff12.model.G;
import org.phenotips.xliff12.model.It;
import org.phenotips.xliff12.model.Mrk;
import org.phenotips.xliff12.model.Ph;
import org.phenotips.xliff12.model.Sub;
import org.phenotips.xliff12.model.TransUnit;
import org.phenotips.xliff12.model.Xliff;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A wrapper around the auto-generated {@link Xliff} class, offering a nicer API for accessing translations.
 *
 * @version $Id: b191efdf6a4d6f011742ea74d844df3743adeaa2 $
 * @since 1.3
 */
public final class XLIFFResourceBundleControl extends ResourceBundle.Control {
    /** The singleton instance for this resource bundle loading controller. */
    public static final XLIFFResourceBundleControl INSTANCE = new XLIFFResourceBundleControl();

    /** Logging helper object. */
    private static final Logger LOGGER = LoggerFactory.getLogger(XLIFFResourceBundleControl.class);

    private static final List<String> SUPPORTED_EXTENSIONS = Arrays.asList("xlf", "xliff");

    private JAXBContext jaxbContext;

    /**
     * Hidden default constructor, to prevent initialization. Use {@link #INSTANCE} to access an instance of this
     * resouce bundle loading controller.
     */
    private XLIFFResourceBundleControl() {
        try {
            this.jaxbContext = JAXBContext.newInstance(Xliff.class);
        } catch (JAXBException ex) {
            LOGGER.error("Failed to initialize JAXB: {}", ex.getMessage(), ex);
        }
    }

    @Override
    public List<String> getFormats(String baseName) {
        if (baseName == null) {
            throw new NullPointerException();
        }
        return SUPPORTED_EXTENSIONS;
    }

    @Override
    public Locale getFallbackLocale(String baseName, Locale locale) {
        return null;
    }

    @Override
    public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader,
            boolean reload) throws IllegalAccessException, InstantiationException, IOException {
        if (baseName == null || locale == null || format == null || loader == null) {
            throw new NullPointerException();
        }
        ResourceBundle bundle = null;
        if (SUPPORTED_EXTENSIONS.contains(format.toLowerCase(Locale.ROOT))) {
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, format);
            try (InputStream stream = loader.getResourceAsStream(resourceName)) {
                if (stream != null) {
                    try {
                        Unmarshaller jaxbUnmarshaller = this.jaxbContext.createUnmarshaller();
                        Xliff xliff = (Xliff) jaxbUnmarshaller.unmarshal(stream);
                        bundle = new XLIFFResourceBundle(xliff);
                    } catch (JAXBException e) {
                        LOGGER.error("Invalid XLIFF file: {}", resourceName);
                    }
                }
            }
        }
        return bundle;
    }

    private static class XLIFFResourceBundle extends ListResourceBundle {
        /**
         * The file node.
         */
        private final Xliff file;

        /**
         * Simple constructor for wrapping an {@link Xliff} object.
         *
         * @param file the Xliff object to wrap
         */
        XLIFFResourceBundle(Xliff file) {
            this.file = file;
        }

        @Override
        protected Object[][] getContents() {
            Map<String, String> data = new HashMap<>();

            for (File f : this.file.getFiles()) {
                for (Object possibleTransUnit : f.getBody().getGroupsAndTransUnitsAndBinUnits()) {
                    if (possibleTransUnit instanceof TransUnit) {
                        TransUnit transUnit = (TransUnit) possibleTransUnit;
                        if (transUnit.getTarget() == null) {
                            continue;
                        }
                        String key = StringUtils.defaultString(transUnit.getResname(), transUnit.getId());
                        StringBuilder result = new StringBuilder();
                        getContent(transUnit.getTarget().getContent(), result);
                        if (result.length() > 0) {
                            data.put(key, result.toString());
                        }
                    }
                }
            }
            Object[][] result = new Object[data.size()][];
            int i = 0;
            for (Map.Entry<String, String> item : data.entrySet()) {
                result[i] = new Object[2];
                result[i][0] = item.getKey();
                result[i][1] = item.getValue();
                ++i;
            }
            return result;
        }
    }

    private static void getContent(List<Object> objects, StringBuilder result) {
        for (Object element : objects) {
            if (element instanceof String) {
                result.append(String.valueOf(element));
            } else if (element instanceof Mrk) {
                getContent(((Mrk) element).getContent(), result);
            } else if (element instanceof G) {
                getContent(((G) element).getContent(), result);
            } else if (element instanceof Ph) {
                getContent(((Ph) element).getContent(), result);
            } else if (element instanceof Bpt) {
                getContent(((Bpt) element).getContent(), result);
            } else if (element instanceof Ept) {
                getContent(((Ept) element).getContent(), result);
            } else if (element instanceof It) {
                getContent(((It) element).getContent(), result);
            } else if (element instanceof Sub) {
                getContent(((Sub) element).getContent(), result);
            }
        }
    }
}