FvctxNodeXmlWriter.java 12.5 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.provider.ImageSetColorLabel
 *  com.scene7.is.provider.UserData
 *  com.scene7.is.provider.ZoomTargets
 *  com.scene7.is.sleng.Color
 *  com.scene7.is.sleng.HotSpot
 *  com.scene7.is.util.Factory
 *  com.scene7.is.util.SizeInt
 *  com.scene7.is.util.XMLUtil
 *  com.scene7.is.util.error.ApplicationException
 *  com.scene7.is.util.text.coders.NetPathCoder
 *  org.jetbrains.annotations.NotNull
 *  org.jetbrains.annotations.Nullable
 */
package com.scene7.is.ps.provider.fvctx;

import com.scene7.is.catalog.util.localization.LocaleMap;
import com.scene7.is.catalog.util.localization.LocalizedText;
import com.scene7.is.provider.ImageSetColorLabel;
import com.scene7.is.provider.UserData;
import com.scene7.is.provider.ZoomTargets;
import com.scene7.is.ps.provider.HotSpotResponseGenerator;
import com.scene7.is.ps.provider.IZoomException;
import com.scene7.is.ps.provider.Request;
import com.scene7.is.ps.provider.fvctx.FvctxImageProps;
import com.scene7.is.ps.provider.fvctx.FvctxNode;
import com.scene7.is.ps.provider.fvctx.MediaSetItemType;
import com.scene7.is.ps.provider.fvctx.MediaSetMetaData;
import com.scene7.is.ps.provider.fvctx.MediaSetSetType;
import com.scene7.is.ps.provider.fvctx.MediaSetVideoProps;
import com.scene7.is.sleng.Color;
import com.scene7.is.sleng.HotSpot;
import com.scene7.is.util.Factory;
import com.scene7.is.util.SizeInt;
import com.scene7.is.util.XMLUtil;
import com.scene7.is.util.error.ApplicationException;
import com.scene7.is.util.text.coders.NetPathCoder;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

class FvctxNodeXmlWriter
implements FvctxNode,
Factory<Document> {
    private static final String E_FRAME = "f";
    private static final String E_FRAMESET = "fset";
    private static final String E_FVCTX = "fvctx";
    private static final String E_IMAGE = "i";
    private static final String E_SWATCH = "s";
    private static final String ATTR_HEIGHT = "dy";
    private static final String ATTR_IMAGEVERSION = "iv";
    private static final String ATTR_LABEL = "l";
    private static final String ATTR_MAP = "map";
    private static final String ATTR_METAVERSION = "mv";
    private static final String ATTR_NAME = "n";
    private static final String ATTR_PROTOCOLVERSION = "pv";
    private static final String ATTR_WIDTH = "dx";
    private static final String TAG_WARNING = "warning";
    private static final String ATTR_MESSAGE = "message";
    private static final String WARNING_MISSING_IMAGE = "missing-image";
    private final int fvctxVersion;
    @NotNull
    private final LocaleMap localeMap;
    @NotNull
    private final String locale;
    @NotNull
    private final String labelKey;
    @NotNull
    private final List<HotSpot> publicMaps;
    @NotNull
    private final ZoomTargets publicTargets;
    @NotNull
    private final Document document;
    @NotNull
    private final Element root;
    @NotNull
    private Element currentElement;

    FvctxNodeXmlWriter(int fvctxVersion, @NotNull LocaleMap localeMap, @NotNull String locale, @NotNull String labelKey, @NotNull ZoomTargets publicTargets, @NotNull List<HotSpot> publicMaps) {
        this.fvctxVersion = fvctxVersion;
        this.localeMap = localeMap;
        this.locale = locale;
        this.labelKey = labelKey;
        this.publicTargets = publicTargets;
        this.publicMaps = publicMaps;
        this.document = XMLUtil.createDocument();
        this.root = this.document.createElement("fvctx");
        this.document.appendChild(this.root);
        StringBuilder pv = new StringBuilder();
        pv.append(fvctxVersion);
        pv.append(".0");
        this.root.setAttribute("pv", pv.toString());
        this.currentElement = this.root;
    }

    @NotNull
    public Document getProduct() {
        Element t = this.publicTargets.createXmlElement(this.document, this.localeMap, this.locale, false, false);
        this.root.appendChild(t);
        Element h = HotSpotResponseGenerator.createHotspotXmlElement(this.document, this.localeMap, this.locale, this.publicMaps);
        this.root.appendChild(h);
        this.removeDuplicateSizes(this.root);
        return this.document;
    }

    @Override
    public void startItem(MediaSetItemType type) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void endItem(@NotNull String imageVersion) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void startSet(@NotNull String recordName, @NotNull MediaSetSetType setType) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void endSet(@NotNull MediaSetMetaData metaData) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void startFrameset() {
        Element fset = this.document.createElement("fset");
        this.currentElement.appendChild(fset);
        this.currentElement = fset;
    }

    @Override
    public void endFrameset(@NotNull SizeInt size, @NotNull String imageVersion, @NotNull String metaVersion, boolean anonymousFrames) {
        if (!anonymousFrames) {
            this.currentElement.setAttribute("dx", FvctxNodeXmlWriter.stringValueOf(size.width));
            this.currentElement.setAttribute("dy", FvctxNodeXmlWriter.stringValueOf(size.height));
        }
        this.currentElement.setAttribute("iv", imageVersion);
        this.currentElement.setAttribute("mv", metaVersion);
        this.currentElement = (Element)this.currentElement.getParentNode();
    }

    @Override
    public void startFrame(@NotNull String netPath, @NotNull String query, Request parsedRequest, FvctxImageProps imageProps, boolean hasNestedFrame, boolean isMediaSetItem) {
        Element f = this.document.createElement("f");
        this.currentElement.appendChild(f);
        this.currentElement = f;
        Element i = this.createImageElement(netPath, query, imageProps);
        this.currentElement.appendChild(i);
    }

    @Override
    public void startVideoFrame(@NotNull String netPath, @NotNull String query, @NotNull MediaSetVideoProps videoProps) throws ApplicationException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void endFrame(@Nullable SizeInt size, @NotNull String imageVersion, @NotNull MediaSetMetaData metaData, boolean hasNestedFrame) {
        ZoomTargets targets = metaData.getTargets();
        List<HotSpot> maps = metaData.getMaps();
        this.currentElement.setAttribute("map", FvctxNodeXmlWriter.stringValueOf(!maps.isEmpty()));
        this.currentElement.setAttribute("dx", FvctxNodeXmlWriter.stringValueOf(size.width));
        this.currentElement.setAttribute("dy", FvctxNodeXmlWriter.stringValueOf(size.height));
        if (this.includePrivateTargets(this.currentElement) && !targets.isEmpty()) {
            Element t = targets.createXmlElement(this.document, this.localeMap, this.locale, false, false);
            this.currentElement.appendChild(t);
        }
        if (this.includePrivateMaps(this.currentElement) && !maps.isEmpty()) {
            Element h = HotSpotResponseGenerator.createHotspotXmlElement(this.document, this.localeMap, this.locale, maps);
            this.currentElement.appendChild(h);
        }
        this.currentElement = (Element)this.currentElement.getParentNode();
    }

    @Override
    public void endVideoFrame(@NotNull MediaSetMetaData metaData, @NotNull String version, @NotNull String suffix) throws IZoomException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void startAnonymousFrame() {
        Element f = this.document.createElement("f");
        this.currentElement.appendChild(f);
        this.currentElement = f;
    }

    @Override
    public void endAnonymousFrame() {
        this.currentElement = (Element)this.currentElement.getParentNode();
    }

    @Override
    public void image(@NotNull String netPath, @NotNull String query, Request parsedRequest, FvctxImageProps imageProps) {
        Element i = this.createImageElement(netPath, query, imageProps);
        this.currentElement.appendChild(i);
    }

    @Override
    public void swatch(@NotNull String netPath, @NotNull String query, Request parsedRequest, FvctxImageProps imageProps, boolean hasNestedFrame, boolean isMediaItemSwatch) {
        Element s = this.createSwatchImageElement(netPath, query, imageProps);
        this.currentElement.appendChild(s);
    }

    @Override
    public void swatch(@NotNull ImageSetColorLabel data, @NotNull LocaleMap localeMap, @NotNull String locale, boolean hasNestedFrame) {
        Element e = this.document.createElement("s");
        e.setAttribute("c", data.color.toHexStringNoAlpha());
        String swatchLabel = data.label.get(this.localeMap, this.locale);
        if (!swatchLabel.isEmpty()) {
            e.setAttribute("l", swatchLabel);
        }
        this.currentElement.appendChild(e);
    }

    @Override
    public void defaultSwatch() {
    }

    private boolean includePrivateTargets(@NotNull Element frame) {
        assert (frame.getNodeName().equals("f"));
        if (this.fvctxVersion < 4) {
            return false;
        }
        boolean hasNestedFramesets = frame.getElementsByTagName("fset").getLength() > 0;
        return this.publicTargets.isEmpty() || hasNestedFramesets;
    }

    private boolean includePrivateMaps(@NotNull Element frame) {
        assert (frame.getNodeName().equals("f"));
        Element fset = (Element)frame.getParentNode();
        boolean firstFrameInSet = frame.getPreviousSibling() == null;
        boolean firstFrameSet = fset.getPreviousSibling() == null;
        boolean topLevelFrameSet = fset.getParentNode() == this.root;
        return firstFrameInSet && firstFrameSet && topLevelFrameSet;
    }

    @NotNull
    private Element createImageElement(@NotNull String netPath, @NotNull String query, @NotNull FvctxImageProps imageProps) {
        Element i = this.document.createElement("i");
        SizeInt imageSize = imageProps.getSize();
        i.setAttribute("dx", FvctxNodeXmlWriter.stringValueOf(imageSize.width));
        i.setAttribute("dy", FvctxNodeXmlWriter.stringValueOf(imageSize.height));
        this.setCommonImageAttributes(i, netPath, query, imageProps);
        return i;
    }

    @NotNull
    private Element createSwatchImageElement(@NotNull String netPath, String query, @NotNull FvctxImageProps imageProps) {
        Element s = this.document.createElement("s");
        this.setCommonImageAttributes(s, netPath, query, imageProps);
        return s;
    }

    private void setCommonImageAttributes(@NotNull Element e, @NotNull String netPath, @NotNull String query, @NotNull FvctxImageProps imageProps) {
        StringBuilder name = new StringBuilder(NetPathCoder.netPathCoder().encode(netPath));
        if (!query.isEmpty()) {
            name.append('?').append(query);
        }
        e.setAttribute("n", name.toString());
        LocalizedText label = imageProps.getUserData().getFvctxLabel(this.labelKey);
        String l = label.get(this.localeMap, this.locale);
        if (!l.isEmpty()) {
            e.setAttribute("l", l);
        }
        if (imageProps.isDefaultImage()) {
            Element warning = this.document.createElement("warning");
            warning.setAttribute("message", "missing-image");
            e.appendChild(warning);
        }
    }

    @NotNull
    private static String stringValueOf(boolean b) {
        return b ? "1" : "0";
    }

    @NotNull
    private static String stringValueOf(int i) {
        return Integer.toString(i);
    }

    private void removeDuplicateSizes(@NotNull Element root) {
        NodeList images = root.getElementsByTagName("i");
        this.removeSizeAttribute(images);
        NodeList frames = root.getElementsByTagName("f");
        this.removeSizeAttribute(frames);
    }

    private void removeSizeAttribute(@NotNull NodeList elements) {
        for (int i = 0; i < elements.getLength(); ++i) {
            Element element = (Element)elements.item(i);
            Element parent = (Element)element.getParentNode();
            if (!this.hasSameSizeAttributes(parent, element)) continue;
            element.removeAttribute("dx");
            element.removeAttribute("dy");
        }
    }

    private boolean hasSameSizeAttributes(@NotNull Element a, @NotNull Element b) {
        return a.getAttribute("dx").equals(b.getAttribute("dx")) && a.getAttribute("dy").equals(b.getAttribute("dy"));
    }
}