XliffDictHelper.java 10.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.util.TraversingItemVisitor
 *  javax.jcr.util.TraversingItemVisitor$Default
 *  org.apache.commons.collections.iterators.IteratorEnumeration
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.jackrabbit.commons.json.JsonHandler
 *  org.apache.jackrabbit.commons.json.JsonParser
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceMetadata
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.osgi.framework.Bundle
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.i18n.impl.dict;

import com.adobe.granite.i18n.impl.bundle.XliffExporter;
import com.adobe.granite.i18n.impl.dict.XliffDictImporter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.util.TraversingItemVisitor;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.commons.collections.iterators.IteratorEnumeration;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.commons.json.JsonHandler;
import org.apache.jackrabbit.commons.json.JsonParser;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class XliffDictHelper {
    private final Logger log;
    private final String DISALLOW_DTD_FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    private final XliffExporter exporter;

    public XliffDictHelper(Bundle bundle) {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.DISALLOW_DTD_FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
        this.exporter = new XliffExporter(bundle);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void exportDict(String path, SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        Session session = (Session)request.getResourceResolver().adaptTo(Session.class);
        String jsonNodePath = this.getPathforJsonNode(path);
        try {
            if (session.nodeExists(path)) {
                Node node = session.getNode(path);
                if (node.isNodeType("mix:language") && node.hasProperty("{http://www.jcp.org/jcr/1.0}language")) {
                    Locale locale = new Locale(node.getProperty("{http://www.jcp.org/jcr/1.0}language").getString());
                    final HashMap<String, String> translations = new HashMap<String, String>();
                    TraversingItemVisitor.Default v = new TraversingItemVisitor.Default(){

                        protected void entering(Node node, int level) throws RepositoryException {
                            if (node.isNodeType("sling:Message") && node.hasProperty("sling:message")) {
                                String value = node.getProperty("sling:message").getString();
                                String key = node.hasProperty("sling:key") ? node.getProperty("sling:key").getString() : node.getName();
                                translations.put(key, value);
                            }
                        }
                    };
                    v.visit(node);
                    this.exporter.export(this.getResourceBundle(locale, translations), response);
                    return;
                }
            } else if (session.nodeExists(jsonNodePath)) {
                Resource jsonFileResource = request.getResourceResolver().getResource(jsonNodePath);
                ValueMap properties = (ValueMap)jsonFileResource.adaptTo(ValueMap.class);
                final HashMap<String, String> translations = new HashMap<String, String>();
                if (((String)properties.get("jcr:mixinTypes", String.class)).equalsIgnoreCase("mix:language") && properties.containsKey((Object)"jcr:language")) {
                    JsonParser parser = new JsonParser(new JsonHandler(){
                        private String key;

                        public void key(String key) throws IOException {
                            this.key = key;
                        }

                        public void value(String value) throws IOException {
                            translations.put(this.key, value);
                        }

                        public void object() throws IOException {
                        }

                        public void endObject() throws IOException {
                        }

                        public void array() throws IOException {
                        }

                        public void endArray() throws IOException {
                        }

                        public void value(boolean value) throws IOException {
                        }

                        public void value(long value) throws IOException {
                        }

                        public void value(double value) throws IOException {
                        }
                    });
                    Locale locale = new Locale((String)properties.get("jcr:language", String.class));
                    InputStream stream = (InputStream)jsonFileResource.adaptTo(InputStream.class);
                    if (stream != null) {
                        String encoding = "utf-8";
                        ResourceMetadata metadata = jsonFileResource.getResourceMetadata();
                        if (metadata != null && metadata.getCharacterEncoding() != null) {
                            encoding = metadata.getCharacterEncoding();
                        }
                        try {
                            parser.parse(stream, encoding);
                        }
                        finally {
                            stream.close();
                        }
                    }
                    this.log.error("Not a json file :" + jsonFileResource.getPath());
                    IOException ioe = new IOException("Not a json file :" + jsonFileResource.getPath());
                    throw ioe;
                    this.exporter.export(this.getResourceBundle(locale, translations), response);
                    return;
                }
            }
            response.sendError(404);
        }
        catch (RepositoryException e) {
            this.log.error("export xliff failed", (Throwable)e);
            IOException ioe = new IOException("export xliff failed");
            ioe.initCause((Throwable)e);
            throw ioe;
        }
    }

    public void importDict(String path, SlingHttpServletRequest request, SlingHttpServletResponse response, InputStream inputStream) throws IOException {
        String[] selectors;
        String depthParam;
        String overwriteParam;
        Session session = (Session)request.getResourceResolver().adaptTo(Session.class);
        int treeDepth = 0;
        for (String selector : selectors = request.getRequestPathInfo().getSelectors()) {
            if (selector == null) continue;
            try {
                treeDepth = Integer.parseInt(selector);
                break;
            }
            catch (NumberFormatException e) {
                treeDepth = 0;
            }
        }
        if ((depthParam = request.getParameter("depth")) != null) {
            try {
                treeDepth = Integer.parseInt(depthParam);
            }
            catch (NumberFormatException e) {
                this.log.error("error in calculating depth", (Throwable)e);
            }
        }
        boolean overwrite = (overwriteParam = request.getParameter("overwrite")) != null && ("true".equals(overwriteParam) || "on".equals(overwriteParam));
        SAXParserFactory spf = SAXParserFactory.newInstance();
        try {
            spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            SAXParser sp = spf.newSAXParser();
            sp.parse(inputStream, (DefaultHandler)new XliffDictImporter(session, path, treeDepth, overwrite, request.getResourceResolver()));
            response.setStatus(200);
            response.setContentType("text/html");
            response.getWriter().println("{ \"success\": true }");
        }
        catch (SAXException e) {
            this.log.error("import xliff failed", (Throwable)e);
            IOException ioe = new IOException("import xliff failed");
            ioe.initCause(e);
            throw ioe;
        }
        catch (ParserConfigurationException e) {
            this.log.error("import xliff failed", (Throwable)e);
            IOException ioe = new IOException("import xliff failed");
            ioe.initCause(e);
            throw ioe;
        }
    }

    public String getPathforJsonNode(String path) {
        Object[] pathArray = path.split("/");
        pathArray[pathArray.length - 1] = pathArray[pathArray.length - 1].split("\\.")[0] + ".json";
        return StringUtils.join((Object[])pathArray, (String)"/");
    }

    public ResourceBundle getResourceBundle(final Locale locale, final Map<String, String> translations) {
        ResourceBundle bundle = new ResourceBundle(){

            @Override
            public Locale getLocale() {
                return locale;
            }

            @Override
            protected Object handleGetObject(String key) {
                return translations.get(key);
            }

            @Override
            public Enumeration<String> getKeys() {
                return new IteratorEnumeration(translations.keySet().iterator());
            }
        };
        return bundle;
    }

}