HTMLMapConverter.java 11.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.scene7.is.catalog.util.localization.LocaleMap
 *  com.scene7.is.catalog.util.localization.LocalizedText
 *  com.scene7.is.catalog.util.localization.LocalizedTextParser
 *  com.scene7.is.sleng.HotSpot
 *  com.scene7.is.util.ConversionUtil
 *  com.scene7.is.util.Converter
 *  com.scene7.is.util.error.ApplicationException
 *  com.scene7.is.util.error.Scaffold
 *  com.scene7.is.util.text.ParamAccess
 *  com.scene7.is.util.text.ParameterException
 *  com.scene7.is.util.text.Parser
 *  com.scene7.is.util.text.ParserUtil
 *  com.scene7.is.util.text.ParsingException
 *  com.scene7.is.util.text.access.ListParamAccess
 *  com.scene7.is.util.text.parsers.FloatParser
 *  org.apache.commons.beanutils.ConversionException
 *  org.jetbrains.annotations.NotNull
 */
package com.scene7.is.ps.provider.parsers;

import com.scene7.is.catalog.util.localization.LocaleMap;
import com.scene7.is.catalog.util.localization.LocalizedText;
import com.scene7.is.catalog.util.localization.LocalizedTextParser;
import com.scene7.is.ps.provider.HotSpotResponseGenerator;
import com.scene7.is.ps.provider.parsers.MapDTD;
import com.scene7.is.sleng.HotSpot;
import com.scene7.is.util.ConversionUtil;
import com.scene7.is.util.Converter;
import com.scene7.is.util.error.ApplicationException;
import com.scene7.is.util.error.Scaffold;
import com.scene7.is.util.text.ParamAccess;
import com.scene7.is.util.text.ParameterException;
import com.scene7.is.util.text.Parser;
import com.scene7.is.util.text.ParserUtil;
import com.scene7.is.util.text.ParsingException;
import com.scene7.is.util.text.access.ListParamAccess;
import com.scene7.is.util.text.parsers.FloatParser;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.IllegalPathStateException;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.html.parser.DTD;
import javax.swing.text.html.parser.Element;
import javax.swing.text.html.parser.TagElement;
import org.apache.commons.beanutils.ConversionException;
import org.jetbrains.annotations.NotNull;

public class HTMLMapConverter
extends Converter<String, List<HotSpot>> {
    private static final Logger LOGGER = Logger.getLogger(HTMLMapConverter.class.getName());
    private static final Parser<Float> COORD_PARSER = FloatParser.floatParser();
    private static final Converter<String, List<HotSpot>> CONVERTER_INSTANCE = new HTMLMapConverter();
    private static final Parser<List<HotSpot>> PARSER_INSTANCE = ParserUtil.parser(CONVERTER_INSTANCE);
    private static final int MESSAGE_SIZE_LIMIT = 1000;
    private static final int ERROR_COUNT_LIMIT = 10;

    @NotNull
    public static Converter<String, List<HotSpot>> htmlMapConverter() {
        return CONVERTER_INSTANCE;
    }

    @NotNull
    public static Parser<List<HotSpot>> htmlMapParser() {
        return PARSER_INSTANCE;
    }

    @NotNull
    public List<HotSpot> convert(@NotNull String src) {
        Handler handler;
        block3 : {
            StringReader in = new StringReader(src);
            handler = new Handler(src);
            try {
                handler.parse(in);
            }
            catch (IOException e) {
                throw Scaffold.error((Throwable)e);
            }
            catch (HTMLParsingError ex) {
                ApplicationException e = ex.cause;
                String message = e != null ? e.getMessage() : "";
                LOGGER.warning(ex.getMessage() + ": " + HTMLMapConverter.limitSize(src) + ": " + message);
                if (e == null) break block3;
                LOGGER.log(Level.FINER, "Reason", (Throwable)e);
            }
        }
        return handler.spotList;
    }

    @NotNull
    public String revert(@NotNull List<HotSpot> src) {
        return HotSpotResponseGenerator.toHtml(LocaleMap.EMPTY_LOCALE_MAP, "", src);
    }

    private HTMLMapConverter() {
        super(String.class, (Class)ConversionUtil.unsafeCast(List.class));
    }

    private static String limitSize(String value) {
        if (value.length() > 1000) {
            return value.substring(0, 1000);
        }
        return value;
    }

    private static class Handler
    extends javax.swing.text.html.parser.Parser {
        private int errorCount;
        private final String value;
        private final List<HotSpot> spotList = new ArrayList<HotSpot>();
        private static final MapDTD DTD = new MapDTD();

        Handler(String value) {
            super(DTD);
            this.value = value;
        }

        @Override
        protected void handleEmptyTag(TagElement tag) {
            block12 : {
                try {
                    Element element = tag.getElement();
                    if (element == Handler.DTD.AREA) {
                        Area area;
                        HotSpot hotSpot = new HotSpot();
                        SimpleAttributeSet attSet = this.getAttributes();
                        Enumeration e = attSet.getAttributeNames();
                        String shape = "rect";
                        String coords = null;
                        while (e.hasMoreElements()) {
                            Object key = e.nextElement();
                            String name = String.valueOf(key).toLowerCase();
                            String value = (String)attSet.getAttribute(key);
                            if ("shape".equals(name)) {
                                shape = value;
                                continue;
                            }
                            if ("coords".equals(name)) {
                                coords = value;
                                continue;
                            }
                            LocalizedText text = (LocalizedText)LocalizedTextParser.localizedTextParser().parse(value);
                            hotSpot.setProperty(name, text);
                        }
                        if (coords != null) {
                            this.initHotSpot(hotSpot, shape, coords);
                        }
                        if ((area = hotSpot.getArea()) == null || !area.isEmpty()) {
                            this.spotList.add(hotSpot);
                        }
                        break block12;
                    }
                    this.error("tag.unrecognized ", element.getName());
                }
                catch (ParameterException x) {
                    throw new HTMLParsingError(null, (ApplicationException)x);
                }
                catch (ParsingException x) {
                    throw new HTMLParsingError(null, (ApplicationException)x);
                }
                finally {
                    this.flushAttributes();
                }
            }
        }

        @Override
        protected void handleError(int ln, String msg) {
            if (this.errorCount < 10) {
                ++this.errorCount;
                if ("attvalerr".equals(msg)) {
                    msg = "Invalid attribute value";
                }
            } else {
                throw new HTMLParsingError("Error count exceeds maximum", null);
            }
            String message = "Error parsing image map. " + msg + " at " + this.getCurrentLine() + ':' + this.getCurrentPos() + ": '" + HTMLMapConverter.limitSize(this.value) + '\'';
            LOGGER.warning(message);
        }

        @Override
        protected void error(String err, String arg1, String arg2, String arg3) {
            this.handleError(1, err + ' ' + arg1 + ' ' + arg2 + ' ' + arg3);
        }

        @Override
        protected void error(String err, String arg1, String arg2) {
            if ("invalid.tagatt".equals(err)) {
                if ("area".equals(arg2)) {
                    return;
                }
                if ("name".equals(arg1) && "map".equals(arg2)) {
                    return;
                }
            }
            this.error(err, arg1, arg2, "");
        }

        @Override
        protected void error(String err, String arg1) {
            if ("end.missing".equals(err) && "html".equals(arg1)) {
                return;
            }
            if ("tag.unrecognized ".equals(err) && "map".equals(arg1)) {
                return;
            }
            if ("end.unrecognized".equals(err) && "map".equals(arg1)) {
                return;
            }
            if ("end.extra.tag".equals(err) && "map".equals(arg1)) {
                return;
            }
            this.error(err, arg1, "", "");
        }

        @Override
        protected void error(String err) {
            this.handleError(this.getCurrentLine(), err);
        }

        private void initHotSpot(HotSpot hotSpot, String shape, String coords) throws ParameterException, ParsingException {
            try {
                ListParamAccess params = new ListParamAccess(coords);
                if ("rect".equals(shape) || "rectangle".equals(shape)) {
                    hotSpot.setArea(Handler.parseRect((ParamAccess)params));
                } else if ("circ".equals(shape) || "circle".equals(shape)) {
                    hotSpot.setArea(Handler.parseCircle((ParamAccess)params));
                } else if ("poly".equals(shape) || "polygon".equals(shape)) {
                    hotSpot.setArea(Handler.parsePolygon((ParamAccess)params));
                }
            }
            catch (IllegalPathStateException e) {
                this.error(e.getMessage(), this.value);
            }
        }

        private static Area parseRect(ParamAccess coords) throws ParameterException {
            float x1 = ((Float)coords.getCustom("x1", COORD_PARSER)).floatValue();
            float y1 = ((Float)coords.getCustom("y1", COORD_PARSER)).floatValue();
            float x2 = ((Float)coords.getCustom("x2", COORD_PARSER)).floatValue();
            float y2 = ((Float)coords.getCustom("y2", COORD_PARSER)).floatValue();
            float x = Math.min(x1, x2);
            float y = Math.min(y1, y2);
            float width = Math.abs(x1 - x2);
            float height = Math.abs(y1 - y2);
            Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width, height);
            return new Area(rect);
        }

        private static Area parseCircle(ParamAccess coords) throws ParameterException {
            float x = ((Float)coords.getCustom("x", COORD_PARSER)).floatValue();
            float y = ((Float)coords.getCustom("y", COORD_PARSER)).floatValue();
            float radius = ((Float)coords.getCustom("radius", COORD_PARSER)).floatValue();
            Ellipse2D.Float circle = new Ellipse2D.Float(x - radius, y - radius, radius * 2.0f, radius * 2.0f);
            return new Area(circle);
        }

        private static Area parsePolygon(ParamAccess coords) throws ParameterException {
            GeneralPath path = new GeneralPath();
            if (coords.contains("next")) {
                path.moveTo(((Float)coords.getCustom("x0", COORD_PARSER)).floatValue(), ((Float)coords.getCustom("y0", COORD_PARSER)).floatValue());
            }
            int i = 1;
            while (coords.contains("next")) {
                path.lineTo(((Float)coords.getCustom("x" + i, COORD_PARSER)).floatValue(), ((Float)coords.getCustom("y" + i, COORD_PARSER)).floatValue());
                ++i;
            }
            path.closePath();
            return new Area(path);
        }
    }

    private static class HTMLParsingError
    extends Error {
        final ApplicationException cause;

        HTMLParsingError(String message, ApplicationException cause) {
            super(message);
            this.cause = cause;
        }
    }

}