ResourceBundleExportServlet.java 5.94 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.Servlet
 *  javax.servlet.http.HttpServletRequest
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Deactivate
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingException
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 *  org.osgi.framework.Bundle
 *  org.osgi.framework.BundleContext
 */
package com.adobe.granite.i18n.impl;

import com.adobe.granite.i18n.LocaleUtil;
import com.adobe.granite.i18n.impl.ETagHelper;
import com.adobe.granite.i18n.impl.bundle.JsonExporter;
import com.adobe.granite.i18n.impl.bundle.ResourceBundleExporter;
import com.adobe.granite.i18n.impl.bundle.TextExporter;
import com.adobe.granite.i18n.impl.bundle.XliffExporter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.WeakHashMap;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

@Component
@Service(value={Servlet.class})
@Properties(value={@Property(name="service.description", value={"ResourceBundle Renderer Servlet"}), @Property(name="sling.servlet.paths", value={"/libs/cq/i18n/dict"})})
public class ResourceBundleExportServlet
extends SlingSafeMethodsServlet {
    private static final long serialVersionUID = -7329439205765482666L;
    private Map<String, ResourceBundleExporter> exporters = new HashMap<String, ResourceBundleExporter>();
    private ResourceBundleExporter defaultExporter;
    private WeakHashMap<ResourceBundle, String> bundleChecksumCache = new WeakHashMap();

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        String format = request.getRequestPathInfo().getExtension();
        ResourceBundleExporter helper = format == null ? this.defaultExporter : this.exporters.get(format);
        if (helper != null) {
            ResourceBundle bundle = this.getResourceBundle(request);
            response.setHeader("Cache-Control", "public");
            if (ETagHelper.handleETag((HttpServletRequest)request, (HttpServletResponse)response, this.getChecksum(bundle))) {
                return;
            }
            helper.export(bundle, response);
        } else {
            response.sendError(501, "Format " + format + " not supported");
        }
    }

    private ResourceBundle getResourceBundle(SlingHttpServletRequest request) {
        String localeString = request.getRequestPathInfo().getSelectorString();
        Locale locale = localeString != null ? LocaleUtil.parseLocale(localeString) : null;
        return request.getResourceBundle(locale);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private String getChecksum(ResourceBundle bundle) {
        Object checksum;
        WeakHashMap<ResourceBundle, String> weakHashMap = this.bundleChecksumCache;
        synchronized (weakHashMap) {
            checksum = this.bundleChecksumCache.get(bundle);
            if (checksum != null) {
                return checksum;
            }
        }
        String checksum2 = this.calculateChecksum(bundle);
        if (checksum2 != null) {
            checksum = this.bundleChecksumCache;
            synchronized (checksum) {
                this.bundleChecksumCache.put(bundle, checksum2);
            }
        }
        return checksum2;
    }

    private String calculateChecksum(ResourceBundle bundle) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            Enumeration<String> keys = bundle.getKeys();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();
                md5.update(key.getBytes("utf-8"));
                md5.update(bundle.getObject(key).toString().getBytes("utf-8"));
            }
            return new BigInteger(1, md5.digest()).toString(16);
        }
        catch (NoSuchAlgorithmException e) {
            throw new SlingException("MessageDigest does not support MD5 algorithm", (Throwable)e);
        }
        catch (UnsupportedEncodingException e) {
            throw new SlingException("String.getBytes() does not support utf-8 charset", (Throwable)e);
        }
    }

    @Activate
    protected void activate(BundleContext context) {
        this.defaultExporter = new TextExporter();
        this.exporters.put("txt", this.defaultExporter);
        this.exporters.put("json", new JsonExporter());
        if (context != null) {
            XliffExporter exporter = new XliffExporter(context.getBundle());
            this.exporters.put("xliff", exporter);
            this.exporters.put("xlf", exporter);
        }
    }

    @Deactivate
    protected void deactivate() {
        this.exporters.clear();
    }
}