Util.java 14.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.scene7.is.provider.CacheSpec
 *  com.scene7.is.provider.FmtSpec
 *  com.scene7.is.provider.RequestContext
 *  com.scene7.is.provider.RequestTypeEnum
 *  com.scene7.is.provider.RequestTypeSpec
 *  com.scene7.is.provider.Response
 *  com.scene7.is.provider.catalog.ObjectRecordTracker
 *  com.scene7.is.sleng.CacheEnum
 *  com.scene7.is.sleng.ExpirationBuilder
 *  com.scene7.is.sleng.FXGServer
 *  com.scene7.is.sleng.ImageAccessException
 *  com.scene7.is.sleng.ImageServer
 *  com.scene7.is.sleng.ResponseFormatEnum
 *  com.scene7.is.sleng.ScaleModeEnum
 *  com.scene7.is.sleng.ScaleModeSpec
 *  com.scene7.is.sleng.VersionKeyBuilder
 *  com.scene7.is.sleng.ipp.IppAccessException
 *  com.scene7.is.sleng.ipp.IppBadImageAnchorException
 *  com.scene7.is.util.MimeTypeEnum
 *  com.scene7.is.util.RectInt
 *  com.scene7.is.util.Size
 *  com.scene7.is.util.callbacks.Option
 *  com.scene7.is.util.error.Scaffold
 *  com.scene7.is.util.text.ParameterException
 *  org.jetbrains.annotations.NotNull
 *  org.jetbrains.annotations.Nullable
 */
package com.scene7.is.ps.provider;

import com.scene7.is.provider.CacheSpec;
import com.scene7.is.provider.FmtSpec;
import com.scene7.is.provider.RequestContext;
import com.scene7.is.provider.RequestTypeEnum;
import com.scene7.is.provider.RequestTypeSpec;
import com.scene7.is.provider.Response;
import com.scene7.is.provider.catalog.ObjectRecordTracker;
import com.scene7.is.ps.provider.CacheEntry;
import com.scene7.is.ps.provider.CatalogRecordException;
import com.scene7.is.ps.provider.IZoomException;
import com.scene7.is.ps.provider.ModifierSet;
import com.scene7.is.ps.provider.Request;
import com.scene7.is.ps.provider.SlengCompiler;
import com.scene7.is.ps.provider.defs.ModifierEnum;
import com.scene7.is.ps.provider.defs.TileRect;
import com.scene7.is.ps.provider.util.CachingPolicy;
import com.scene7.is.ps.provider.util.CatalogCachingPolicy;
import com.scene7.is.ps.provider.util.ExpirationPolicy;
import com.scene7.is.ps.provider.util.ImageRequester;
import com.scene7.is.ps.provider.util.Requester;
import com.scene7.is.ps.provider.util.TileRequester;
import com.scene7.is.sleng.CacheEnum;
import com.scene7.is.sleng.ExpirationBuilder;
import com.scene7.is.sleng.FXGServer;
import com.scene7.is.sleng.ImageAccessException;
import com.scene7.is.sleng.ImageServer;
import com.scene7.is.sleng.ResponseFormatEnum;
import com.scene7.is.sleng.ScaleModeEnum;
import com.scene7.is.sleng.ScaleModeSpec;
import com.scene7.is.sleng.VersionKeyBuilder;
import com.scene7.is.sleng.ipp.IppAccessException;
import com.scene7.is.sleng.ipp.IppBadImageAnchorException;
import com.scene7.is.util.MimeTypeEnum;
import com.scene7.is.util.RectInt;
import com.scene7.is.util.Size;
import com.scene7.is.util.callbacks.Option;
import com.scene7.is.util.error.Scaffold;
import com.scene7.is.util.text.ParameterException;
import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class Util {
    private static final Logger LOGGER = Logger.getLogger(Util.class.getName());
    private static final MimeTypeEnum[] MIME_TYPES = new MimeTypeEnum[ResponseFormatEnum.class.getEnumConstants().length];
    public static String LOCALIZATION_DUMMY_IMAGE_PATH_PREFIX = "TRANSLATED_IDS_NOT_FOUND";

    private Util() {
    }

    public static CachingPolicy getCachingPolicy(Request request) {
        ModifierSet attributes = request.getGlobalAttributes();
        boolean useCatalogValidation = attributes.getOrDie(ModifierEnum.I_CACHE_VALIDATION_POLICY);
        CacheEnum cacheUse = attributes.get(ModifierEnum.CACHE, CacheSpec.ON).getServer();
        if (useCatalogValidation) {
            long timeStamp = Util.computeCatalogTimeStamp(request);
            return new CatalogCachingPolicy(cacheUse, timeStamp);
        }
        long timeToLive = Util.computeCacheTimeToLive(request);
        return new ExpirationPolicy(cacheUse, timeToLive);
    }

    public static Requester getRequester(@NotNull byte[] code, @NotNull Request request, @Nullable SlengCompiler compiler, @NotNull ImageServer imageServer, @NotNull FXGServer fxgServer) throws IZoomException, ParameterException {
        ModifierSet attributes = request.getGlobalAttributes();
        RequestTypeSpec requestType = attributes.getOrDie(ModifierEnum.REQ);
        Size sizeLimit = request.getMaxPix();
        boolean optimize = Util.doOptimize(request);
        MimeTypeEnum mimeType = Util.getMimeType(request);
        if (requestType.type == RequestTypeEnum.TILE) {
            RectInt rect = attributes.get(ModifierEnum.RECT).rect;
            double scale = 1.0 / attributes.get(ModifierEnum.SCL, 1.0);
            TileRect tileRect = TileRect.tileRect(rect, scale);
            String version = attributes.get(ModifierEnum.ID, "undefined");
            return new TileRequester(code, mimeType, tileRect, sizeLimit, version, compiler, optimize, imageServer, fxgServer);
        }
        if (attributes.contains(ModifierEnum.RECT)) {
            TileRect tileRect = attributes.get(ModifierEnum.RECT);
            String version = attributes.get(ModifierEnum.ID, "undefined");
            return new TileRequester(code, mimeType, tileRect, sizeLimit, version, compiler, optimize, imageServer, fxgServer);
        }
        return new ImageRequester(code, mimeType, sizeLimit, compiler, optimize, imageServer, fxgServer);
    }

    static long computeTimeToLive(Request request) {
        ModifierSet attributes = request.getGlobalAttributes();
        long timeToLive = attributes.getOrDie(ModifierEnum.I_EXPIRATION);
        for (ModifierSet layer : request.getLayers()) {
            if (!layer.contains(ModifierEnum.I_EXPIRATION)) continue;
            long layerTimeToLive = layer.getOrDie(ModifierEnum.I_EXPIRATION);
            if (timeToLive == -1) {
                timeToLive = layerTimeToLive;
                continue;
            }
            if (layerTimeToLive == -1) continue;
            timeToLive = Math.min(timeToLive, layerTimeToLive);
        }
        return timeToLive;
    }

    static long computeDefaultTimeToLive(Request request) {
        ModifierSet attributes = request.getGlobalAttributes();
        return attributes.getOrDie(ModifierEnum.I_DEFAULT_EXPIRATION);
    }

    static long computeNonImgTimeToLive(Request request) {
        ModifierSet attributes = request.getGlobalAttributes();
        return attributes.getOrDie(ModifierEnum.I_NON_IMG_EXPIRATION);
    }

    static long computeExpiration(Request request, ImageServer server) throws IZoomException {
        long timeToLive = Util.computeTimeToLive(request);
        long expiration = Response.ttl2Expiration((long)timeToLive);
        try {
            SlengCompiler compiler = new SlengCompiler(server, false, false, false);
            byte[] code = compiler.compileRequest(request);
            expiration = ExpirationBuilder.getExpiration((ImageServer)server, (byte[])code, (long)expiration);
        }
        catch (ImageAccessException e) {
            throw new IZoomException(IZoomException.COULD_NOT_COMPUTE_EXPIRATION, "computeExpiration failed", (Throwable)e);
        }
        catch (ParameterException e) {
            throw new IZoomException(IZoomException.COULD_NOT_COMPUTE_EXPIRATION, "computeExpiration failed", (Throwable)e);
        }
        return expiration;
    }

    static long computeDefaultExpiration(Request request) {
        return Response.ttl2Expiration((long)Util.computeDefaultTimeToLive(request));
    }

    static long computeNonImgExpiration(Request request) {
        return Response.ttl2Expiration((long)Util.computeNonImgTimeToLive(request));
    }

    public static long computeCatalogTimeStamp(Request request) {
        ModifierSet attr = request.getGlobalAttributes();
        long lastModified = attr.getOrDie(ModifierEnum.I_LAST_MODIFIED);
        for (ModifierSet layer : request.getLayers()) {
            lastModified = Math.max(lastModified, layer.getOrDie(ModifierEnum.I_LAST_MODIFIED));
        }
        return lastModified;
    }

    static long computeLastModified(Request request) {
        ModifierSet attr = request.getGlobalAttributes();
        if (!Boolean.TRUE.equals(attr.getOrDie(ModifierEnum.I_USE_LAST_MODIFIED))) {
            return -1;
        }
        long lastModified = attr.getOrDie(ModifierEnum.I_LAST_MODIFIED);
        for (ModifierSet layer : request.getLayers()) {
            if (!Boolean.TRUE.equals(layer.get(ModifierEnum.I_USE_LAST_MODIFIED, Boolean.FALSE))) {
                LOGGER.log(Level.WARNING, "UseLastModified is inconsistent in cross catalog reference");
                return -1;
            }
            lastModified = Math.max(lastModified, layer.getOrDie(ModifierEnum.I_LAST_MODIFIED));
        }
        return lastModified;
    }

    static long computeCacheTimeToLive(Request request) {
        long timeToLive = Util.getCacheExpiration(request.getGlobalAttributes());
        for (ModifierSet layer : request.getLayers()) {
            if (!Util.containsCacheExpiration(layer)) continue;
            long layerTimeToLive = Util.getCacheExpiration(layer);
            timeToLive = Math.min(timeToLive, layerTimeToLive);
        }
        return timeToLive;
    }

    public static boolean isModified(@NotNull ImageServer server, @NotNull FXGServer fxgServer, @NotNull CacheEntry entry, @NotNull byte[] code) throws ImageAccessException {
        byte[] cachedVersionKey;
        byte[] versionKey = VersionKeyBuilder.buildVersionKey((ImageServer)server, (FXGServer)fxgServer, (byte[])code).getBytes();
        return !Arrays.equals(versionKey, cachedVersionKey = entry.versionKey);
    }

    static MimeTypeEnum getMimeType(Request request) {
        ModifierSet attributes = request.getGlobalAttributes();
        FmtSpec format = attributes.getOrDie(ModifierEnum.FMT);
        return Util.getMimeType(format.format);
    }

    public static boolean doOptimize(Request request) throws ParameterException {
        ScaleModeSpec scaleModeSpec = request.getGlobalAttributes().get(ModifierEnum.SCALE_MODE);
        ScaleModeEnum scaleMode = scaleModeSpec.scaleMode;
        return scaleMode != ScaleModeEnum.COMPATIBLE;
    }

    public static MimeTypeEnum getMimeType(ResponseFormatEnum responseFormat) {
        return MIME_TYPES[responseFormat.ordinal()];
    }

    private static boolean containsCacheExpiration(ModifierSet modifiers) {
        if (modifiers.contains(ModifierEnum.I_CACHE_EXPIRATION)) {
            return true;
        }
        return modifiers.contains(ModifierEnum.I_EXPIRATION);
    }

    private static long getCacheExpiration(ModifierSet modifiers) {
        if (modifiers.contains(ModifierEnum.I_CACHE_EXPIRATION)) {
            return modifiers.getOrDie(ModifierEnum.I_CACHE_EXPIRATION);
        }
        return modifiers.getOrDie(ModifierEnum.I_EXPIRATION);
    }

    public static String findFailingImageId(@NotNull Option<? extends Throwable> exception, RequestContext context) {
        String failingImageId = "";
        for (Throwable except : exception) {
            if (except instanceof IppBadImageAnchorException || except.getCause() instanceof IppBadImageAnchorException) {
                String originalPath = except instanceof IppBadImageAnchorException ? ((IppBadImageAnchorException)except).getOriginalPath() : ((IppBadImageAnchorException)except.getCause()).getOriginalPath();
                failingImageId = context.getObjectRecordTracker().findImageId(originalPath);
                continue;
            }
            if (!(except instanceof CatalogRecordException)) continue;
            failingImageId = ((CatalogRecordException)except).failingRecordId;
        }
        return failingImageId;
    }

    public static boolean isInPSCatalog(@NotNull String imageId, @NotNull RequestContext context) {
        return context.getObjectRecordTracker().isInCatalog(imageId);
    }

    public static boolean missingImageHasCatalogEntry(@NotNull Option<? extends Throwable> ex, @NotNull RequestContext context) {
        for (Throwable e : ex) {
            if (e instanceof IppAccessException) continue;
            ex = Option.some((Object)e.getCause());
        }
        String failingImageId = Util.findFailingImageId(ex, context);
        if (failingImageId.isEmpty()) {
            return false;
        }
        return Util.isInPSCatalog(failingImageId, context);
    }

    public static boolean isInvalidPath(@NotNull String s) {
        if (s.startsWith("\\")) {
            return true;
        }
        if (s.startsWith("%5C")) {
            return true;
        }
        if (s.startsWith("%5c")) {
            return true;
        }
        if (s.startsWith("//")) {
            return true;
        }
        return false;
    }

    static {
        Util.MIME_TYPES[ResponseFormatEnum.GIF.ordinal()] = MimeTypeEnum.IMAGE_GIF;
        Util.MIME_TYPES[ResponseFormatEnum.JPEG.ordinal()] = MimeTypeEnum.IMAGE_JPEG;
        Util.MIME_TYPES[ResponseFormatEnum.PJPEG.ordinal()] = MimeTypeEnum.IMAGE_JPEG;
        Util.MIME_TYPES[ResponseFormatEnum.PNG.ordinal()] = MimeTypeEnum.IMAGE_PNG;
        Util.MIME_TYPES[ResponseFormatEnum.PNG8.ordinal()] = MimeTypeEnum.IMAGE_PNG;
        Util.MIME_TYPES[ResponseFormatEnum.TIF.ordinal()] = MimeTypeEnum.IMAGE_TIFF;
        Util.MIME_TYPES[ResponseFormatEnum.EPS.ordinal()] = MimeTypeEnum.IMAGE_EPS;
        Util.MIME_TYPES[ResponseFormatEnum.PTIF.ordinal()] = MimeTypeEnum.IMAGE_TIFF;
        Util.MIME_TYPES[ResponseFormatEnum.SWF.ordinal()] = MimeTypeEnum.APPLICATION_X_SHOCKWAVE_FLASH;
        Util.MIME_TYPES[ResponseFormatEnum.SWF3.ordinal()] = MimeTypeEnum.APPLICATION_X_SHOCKWAVE_FLASH;
        Util.MIME_TYPES[ResponseFormatEnum.XML.ordinal()] = MimeTypeEnum.TEXT_XML;
        Util.MIME_TYPES[ResponseFormatEnum.PCX.ordinal()] = MimeTypeEnum.IMAGE_X_PCX;
        Util.MIME_TYPES[ResponseFormatEnum.DEFLATE.ordinal()] = MimeTypeEnum.APPLICATION_OCTET_STREAM;
        Util.MIME_TYPES[ResponseFormatEnum.PROPS.ordinal()] = MimeTypeEnum.TEXT_PLAIN;
        Util.MIME_TYPES[ResponseFormatEnum.HTML.ordinal()] = MimeTypeEnum.TEXT_HTML;
        Util.MIME_TYPES[ResponseFormatEnum.JAVA_SCRIPT.ordinal()] = MimeTypeEnum.TEXT_JAVASCRIPT;
        Util.MIME_TYPES[ResponseFormatEnum.PDF.ordinal()] = MimeTypeEnum.APPLICATION_PDF;
        Util.MIME_TYPES[ResponseFormatEnum.SIMPLE.ordinal()] = MimeTypeEnum.APPLICATION_OCTET_STREAM;
        Util.MIME_TYPES[ResponseFormatEnum.F4M.ordinal()] = MimeTypeEnum.TEXT_XML;
        Util.MIME_TYPES[ResponseFormatEnum.M3U8.ordinal()] = MimeTypeEnum.TEXT_PLAIN;
        Util.MIME_TYPES[ResponseFormatEnum.PSD.ordinal()] = MimeTypeEnum.APPLICATION_PHOTOSHOP;
        Util.MIME_TYPES[ResponseFormatEnum.WEBP.ordinal()] = MimeTypeEnum.IMAGE_WEBP;
        Scaffold.validateMapping(ResponseFormatEnum.class, (Object[])MIME_TYPES);
    }
}