RequestBuilderUtil.java 17.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.scene7.is.provider.EmbeddedRequest
 *  com.scene7.is.provider.FmtSpec
 *  com.scene7.is.provider.IccProfileSpec
 *  com.scene7.is.provider.ModifierList
 *  com.scene7.is.provider.PSModifierEnum
 *  com.scene7.is.provider.RequestTypeEnum
 *  com.scene7.is.provider.RequestTypeSpec
 *  com.scene7.is.provider.SubstPattern
 *  com.scene7.is.provider.catalog.Catalog
 *  com.scene7.is.provider.catalog.CatalogException
 *  com.scene7.is.provider.catalog.CatalogUtil
 *  com.scene7.is.provider.catalog.ObjectRecord
 *  com.scene7.is.provider.ruleset.RuleAttributeEnum
 *  com.scene7.is.provider.ruleset.RuleSetResults
 *  com.scene7.is.sleng.ColorConvertOptions
 *  com.scene7.is.sleng.ColorProfileSet
 *  com.scene7.is.sleng.ColorSpace
 *  com.scene7.is.sleng.ColorSpaceEnum
 *  com.scene7.is.sleng.DigimarcId
 *  com.scene7.is.sleng.DigimarcInfo
 *  com.scene7.is.sleng.IccProfile
 *  com.scene7.is.sleng.PerspectiveSpec
 *  com.scene7.is.sleng.RenderIntentEnum
 *  com.scene7.is.sleng.Text
 *  com.scene7.is.util.AbstractPath
 *  com.scene7.is.util.Dimension2D
 *  com.scene7.is.util.Dimension2D$Double
 *  com.scene7.is.util.KeyValuePair
 *  com.scene7.is.util.UniversalPath
 *  com.scene7.is.util.text.ParameterException
 *  com.scene7.is.util.text.ParsingException
 *  com.scene7.is.util.text.coders.Base64Coder
 *  org.jetbrains.annotations.NotNull
 *  org.jetbrains.annotations.Nullable
 */
package com.scene7.is.ps.provider;

import com.scene7.is.provider.EmbeddedRequest;
import com.scene7.is.provider.FmtSpec;
import com.scene7.is.provider.IccProfileSpec;
import com.scene7.is.provider.ModifierList;
import com.scene7.is.provider.PSModifierEnum;
import com.scene7.is.provider.RequestTypeEnum;
import com.scene7.is.provider.RequestTypeSpec;
import com.scene7.is.provider.SubstPattern;
import com.scene7.is.provider.catalog.Catalog;
import com.scene7.is.provider.catalog.CatalogException;
import com.scene7.is.provider.catalog.CatalogUtil;
import com.scene7.is.provider.catalog.ObjectRecord;
import com.scene7.is.provider.ruleset.RuleAttributeEnum;
import com.scene7.is.provider.ruleset.RuleSetResults;
import com.scene7.is.ps.provider.EmbeddedImageSource;
import com.scene7.is.ps.provider.EmbeddedLayerSource;
import com.scene7.is.ps.provider.IZoomException;
import com.scene7.is.ps.provider.LayerSource;
import com.scene7.is.ps.provider.ModifierSet;
import com.scene7.is.ps.provider.Request;
import com.scene7.is.ps.provider.Util;
import com.scene7.is.ps.provider.defs.LayerSpec;
import com.scene7.is.ps.provider.defs.ModifierEnum;
import com.scene7.is.ps.provider.parsers.query.PSModifierListConverter;
import com.scene7.is.sleng.ColorConvertOptions;
import com.scene7.is.sleng.ColorProfileSet;
import com.scene7.is.sleng.ColorSpace;
import com.scene7.is.sleng.ColorSpaceEnum;
import com.scene7.is.sleng.DigimarcId;
import com.scene7.is.sleng.DigimarcInfo;
import com.scene7.is.sleng.IccProfile;
import com.scene7.is.sleng.PerspectiveSpec;
import com.scene7.is.sleng.RenderIntentEnum;
import com.scene7.is.sleng.Text;
import com.scene7.is.util.AbstractPath;
import com.scene7.is.util.Dimension2D;
import com.scene7.is.util.KeyValuePair;
import com.scene7.is.util.UniversalPath;
import com.scene7.is.util.text.ParameterException;
import com.scene7.is.util.text.ParsingException;
import com.scene7.is.util.text.coders.Base64Coder;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class RequestBuilderUtil {
    public static final String DEFAULT_QUERY = "REQ=SERVERPROPS";
    public static final ModifierList<PSModifierEnum> EMPTY_MODIFIER_LIST = PSModifierListConverter.psModifierList();

    @NotNull
    public static String buildNetPath(@NotNull Catalog catalog, @NotNull String imageId) {
        if (catalog.getRootId().isEmpty()) {
            return "/" + imageId;
        }
        return "/" + catalog.getRootId() + '/' + imageId;
    }

    @NotNull
    public static String parseImageId(@NotNull Catalog catalog, @NotNull ObjectRecord imageRecord) throws IZoomException {
        String netPath = CatalogUtil.getRecordPath((ObjectRecord)imageRecord);
        return RequestBuilderUtil.parseImageId(catalog, netPath);
    }

    public static String parseImageId(@NotNull Catalog catalog, @NotNull String netPath) throws IZoomException {
        String imageId = RequestBuilderUtil.trimRootPath(netPath, catalog.getRootId());
        RequestBuilderUtil.validateNetPath(imageId);
        return imageId;
    }

    @NotNull
    public static String trimRootPath(@NotNull String path, @NotNull String rootPath) {
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        if (path.equals(rootPath)) {
            return "";
        }
        if (!path.startsWith(rootPath)) {
            return path;
        }
        if (rootPath.length() > path.length()) {
            return path;
        }
        String child = path.substring(rootPath.length());
        if (child.length() > 0 && child.charAt(0) == '/') {
            return child.substring(1);
        }
        return path;
    }

    public static void validateNetPath(String path) throws IZoomException {
        try {
            if (!new AbstractPath(path).isSubPath()) {
                throw new IZoomException(IZoomException.ILLEGAL_PATH, path, null);
            }
        }
        catch (ParsingException e) {
            throw new IZoomException(IZoomException.ILLEGAL_PATH, path, (Throwable)e);
        }
    }

    public static void processDigimarc(@NotNull Request request, @NotNull RuleSetResults ruleSetResults) throws ParameterException, ParsingException {
        ModifierSet globalAttributes = request.getGlobalAttributes();
        RequestBuilderUtil.processDigimarcModifier(globalAttributes, ModifierEnum.DIGIMARC_ID, ModifierEnum.I_DIGIMARC_ID, (Boolean)ruleSetResults.getAttribute(RuleAttributeEnum.EXTRACTDIGIMARCID, (Object)false));
        RequestBuilderUtil.processDigimarcModifier(globalAttributes, ModifierEnum.DIGIMARC_INFO, ModifierEnum.I_DIGIMARC_INFO, (Boolean)ruleSetResults.getAttribute(RuleAttributeEnum.EXTRACTDIGIMARCINFO, (Object)false));
    }

    private static <T> void processDigimarcModifier(ModifierSet globalAttributes, ModifierEnum<T> urlModifier, ModifierEnum<T> catalogAttribute, boolean extractFromUrl) throws ParameterException, ParsingException {
        if (!globalAttributes.contains(urlModifier)) {
            return;
        }
        if (!extractFromUrl) {
            throw new ParsingException(4, "Digimarc attribute is not allowed in url", null);
        }
        globalAttributes.set(catalogAttribute, globalAttributes.get(urlModifier));
    }

    public static void copySrcProfiles(ModifierSet layer, ObjectRecord record) throws CatalogException {
        ColorProfileSet profiles = record.getDefaultSourceProfiles();
        layer.set(ModifierEnum.I_ICC_SOURCE_PROFILE_MAP, profiles);
        if (layer.contains(ModifierEnum.EFFECT)) {
            Map<Object, ModifierSet> effects = layer.getOrDie(ModifierEnum.EFFECT);
            for (ModifierSet effect : effects.values()) {
                effect.set(ModifierEnum.I_ICC_SOURCE_PROFILE_MAP, profiles);
            }
        }
    }

    public static void copyDstProfiles(ModifierSet atts, ObjectRecord record, boolean doEmbedded) throws CatalogException {
        if (!doEmbedded) {
            ColorProfileSet profiles = record.getDefaultProfiles();
            atts.set(ModifierEnum.I_ICC_PROFILE_MAP, profiles);
        }
    }

    public static void processOutputColorSpace(Request request) throws CatalogException, ParameterException {
        ModifierSet atts = request.getGlobalAttributes();
        RequestTypeEnum requestType = atts.getOrDie(ModifierEnum.REQ).type;
        ColorSpaceEnum colorSpace = atts.get(ModifierEnum.FMT).colorSpace;
        if (colorSpace == null && requestType == RequestTypeEnum.MASK) {
            colorSpace = ColorSpaceEnum.GRAY;
        }
        if (atts.contains(ModifierEnum.ICC)) {
            IccProfileSpec profileSpec = atts.getOrDie(ModifierEnum.ICC);
            IccProfile profile = request.getProfile(profileSpec.getProfileName());
            atts.set(ModifierEnum.I_ICC_OUT_COLORSPACE, new ColorSpace(colorSpace, profile.path()));
        } else if (colorSpace != null) {
            atts.set(ModifierEnum.I_ICC_OUT_COLORSPACE, new ColorSpace(colorSpace, null));
        }
    }

    private static <T> T resolveColorConvertOption(@Nullable T value, @NotNull T def) {
        return value != null ? value : def;
    }

    public static void processColorConvertOptions(ModifierSet atts, boolean doEmbedded) {
        if (atts.contains(ModifierEnum.ICC)) {
            IccProfileSpec profileSpec = atts.getOrDie(ModifierEnum.ICC);
            ColorConvertOptions convertOpts = atts.getOrDie(ModifierEnum.I_ICC_OPTIONS);
            RenderIntentEnum renderIntent = RequestBuilderUtil.resolveColorConvertOption(profileSpec.getRenderIntent(), convertOpts.getRenderIntent());
            boolean bpc = RequestBuilderUtil.resolveColorConvertOption(profileSpec.getBlackPointCompensation(), convertOpts.getBlackPointCompensation());
            boolean dither = RequestBuilderUtil.resolveColorConvertOption(profileSpec.getDither(), convertOpts.getDither());
            atts.set(ModifierEnum.I_ICC_OPTIONS, new ColorConvertOptions(renderIntent, bpc, dither));
        } else if (doEmbedded) {
            atts.set(ModifierEnum.I_ICC_OPTIONS, null);
        }
    }

    public static void processPerspective(Request request) {
        for (ModifierSet layer : request.getLayers()) {
            RequestBuilderUtil.processPerspective(layer);
        }
        RequestBuilderUtil.processPerspective(request.getLayerComp());
    }

    private static void processPerspective(ModifierSet layer) {
        if (layer.contains(ModifierEnum.PERSPECTIVE) || layer.contains(ModifierEnum.PERSPECTIVEN)) {
            layer.set(ModifierEnum.DST_RES, null);
            if (layer.getScore(ModifierEnum.SRC) > layer.getScore(ModifierEnum.TEXT)) {
                layer.set(ModifierEnum.SIZE, null);
                layer.set(ModifierEnum.SIZEN, null);
            }
            layer.set(ModifierEnum.ORIGIN, null);
            layer.set(ModifierEnum.ORIGINN, null);
        }
    }

    public static void validateViewSource(Request source) throws IZoomException {
        ModifierSet globals = source.getGlobalAttributes();
        if (globals.contains(ModifierEnum.VIEW)) {
            IZoomException e = new IZoomException(IZoomException.ILLEGAL_VIEW_SOURCE, "Recursion detected", null);
            e.setProperty("view.modifier", String.valueOf(globals.getOrDie(ModifierEnum.I_MODIFIER)));
            throw e;
        }
        if (!source.hasSubstPairs()) {
            throw new IZoomException(IZoomException.ILLEGAL_VIEW_SOURCE, "Substitution in the view modifier", null);
        }
    }

    public static boolean isEmbeddedRequest(@NotNull LayerSource source) {
        return source instanceof EmbeddedLayerSource;
    }

    public static void validateLayerSource(@NotNull Integer layerId, @NotNull Request source) throws IZoomException {
        ModifierSet layer0;
        ModifierEnum<Text> illegalModifier = null;
        if (source.getLayerCount() > 1) {
            illegalModifier = ModifierEnum.LAYER;
        }
        if ((layer0 = source.findCreateLayer(LayerSpec.LAYER_0)).contains(ModifierEnum.SRC)) {
            illegalModifier = ModifierEnum.SRC;
        }
        if (layer0.contains(ModifierEnum.MASK)) {
            illegalModifier = ModifierEnum.MASK;
        }
        if (layer0.contains(ModifierEnum.LAYER)) {
            illegalModifier = ModifierEnum.LAYER;
        }
        if (layer0.contains(ModifierEnum.TEXT)) {
            illegalModifier = ModifierEnum.TEXT;
        }
        if (illegalModifier != null) {
            IZoomException e = new IZoomException(IZoomException.ILLEGAL_LAYER_SOURCE, "", null);
            e.setProperty("modifier", String.valueOf(illegalModifier));
            e.setProperty("layer", String.valueOf(layerId));
            throw e;
        }
    }

    public static void applyURLSourceTimeStamps(ModifierSet layer, Object source) {
        if (source instanceof Request) {
            Request embeddedRequest = (Request)source;
            long ttl = Util.computeTimeToLive(embeddedRequest);
            boolean useLastModified = Util.computeLastModified(embeddedRequest) != -1;
            long catalogTimeStamp = Util.computeCatalogTimeStamp(embeddedRequest);
            layer.set(ModifierEnum.I_EXPIRATION, ttl);
            layer.set(ModifierEnum.I_USE_LAST_MODIFIED, useLastModified);
            layer.set(ModifierEnum.I_LAST_MODIFIED, catalogTimeStamp);
        } else if (source instanceof EmbeddedRequest) {
            EmbeddedRequest embeddedRequest = (EmbeddedRequest)source;
            layer.set(ModifierEnum.I_EXPIRATION, embeddedRequest.getTimeToLive());
            layer.set(ModifierEnum.I_USE_LAST_MODIFIED, embeddedRequest.getUseLastModified());
            layer.set(ModifierEnum.I_LAST_MODIFIED, embeddedRequest.getLastModified());
        } else if (source instanceof EmbeddedImageSource) {
            EmbeddedImageSource embeddedSource = (EmbeddedImageSource)source;
            Request embeddedRequest = embeddedSource.getRequest();
            long ttl = Util.computeTimeToLive(embeddedRequest);
            boolean useLastModified = Util.computeLastModified(embeddedRequest) != -1;
            long catalogTimeStamp = Util.computeCatalogTimeStamp(embeddedRequest);
            layer.set(ModifierEnum.I_EXPIRATION, ttl);
            layer.set(ModifierEnum.I_USE_LAST_MODIFIED, useLastModified);
            layer.set(ModifierEnum.I_LAST_MODIFIED, catalogTimeStamp);
        }
    }

    public static String variableSubstitutionIsSource(String sourcePath, Request request) {
        StringBuilder buffer = new StringBuilder(sourcePath);
        int nameValueSeparator = buffer.indexOf("?") == -1 ? 63 : 38;
        for (Map.Entry<String, String> entry : request.getSubstPairs().entrySet()) {
            String name = entry.getKey();
            if ("OBJECT".equals(name)) continue;
            String value = entry.getValue();
            buffer.append((char)nameValueSeparator).append('$').append(name);
            buffer.append('=').append(value);
            nameValueSeparator = 38;
        }
        return buffer.toString();
    }

    @NotNull
    public static String variableSubstitutionURLSource(@NotNull String sourcePath, @NotNull Request request) {
        String result = sourcePath;
        for (Map.Entry<String, String> entry : request.getSubstPairs().entrySet()) {
            String regex = "(?i)\\$" + entry.getKey() + "\\$";
            String replacement = entry.getValue();
            result = result.replaceAll(regex, replacement);
        }
        return result;
    }

    public static String canonicalizeQuery(String netPath, String query, boolean obfuscated, boolean locked) throws IZoomException, ParsingException {
        String query1 = query;
        if (query1 == null) {
            query1 = "";
        }
        if (obfuscated) {
            query1 = Base64Coder.getInstance().decode(query1);
        }
        if (locked) {
            query1 = RequestBuilderUtil.unlock(query1);
        }
        if ("".equals(netPath) && "".equals(query1)) {
            query1 = "REQ=SERVERPROPS";
        }
        return query1;
    }

    public static String unlock(String value) throws IZoomException {
        if (value.length() >= 5) {
            String lockStr = value.substring(value.length() - 4);
            try {
                long lock = Long.decode("0x" + lockStr);
                String result = value.substring(0, value.length() - 5);
                long sum = 0;
                for (int i = 0; i < result.length(); ++i) {
                    sum = sum * 131 + (long)result.charAt(i) & 65535;
                }
                if (lock == sum) {
                    return result;
                }
                throw new IZoomException(IZoomException.INVALID_LOCK, lockStr, null);
            }
            catch (NumberFormatException e) {
                throw new IZoomException(IZoomException.INVALID_LOCK, lockStr, e);
            }
        }
        throw new IZoomException(IZoomException.INVALID_LOCK, "", null);
    }

    @NotNull
    public static String getAbsolutePath(@NotNull Catalog catalog, @NotNull String path) {
        String rootId;
        if ((path = UniversalPath.removeLeadingSlashes((CharSequence)path)).startsWith((rootId = catalog.getRootId()) + "/") || rootId.isEmpty()) {
            return path;
        }
        return rootId + '/' + path;
    }

    public static void validateRequest(Request request) {
        RequestBuilderUtil.validateModifierSet(request.getGlobalAttributes());
        RequestBuilderUtil.validateModifierSet(request.getLayerComp());
        for (ModifierSet layer : request.getLayers()) {
            RequestBuilderUtil.validateModifierSet(layer);
        }
    }

    public static void validateModifierSet(ModifierSet modifiers) {
        for (KeyValuePair modifier : modifiers) {
            if (modifier.value instanceof SubstPattern) {
                throw new AssertionError((Object)(modifier.key + ": " + modifier.value));
            }
        }
        if (modifiers.contains(ModifierEnum.EFFECT) && modifiers.getOrDie(ModifierEnum.EFFECT) instanceof Map) {
            Map<Object, ModifierSet> effects = modifiers.getOrDie(ModifierEnum.EFFECT);
            for (ModifierSet effect : effects.values()) {
                RequestBuilderUtil.validateModifierSet(effect);
            }
        }
    }

    private RequestBuilderUtil() {
    }
}