ilscipio/scipio-erp

View on GitHub
applications/product/servicedef/services_image.xml

Summary

Maintainability
Test Coverage
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
  -->

<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd">
    <description>SCIPIO: New Image Services</description>
    <!-- NOTE: old image services are in services.xml -->
    <vendor>Ilscipio GmbH</vendor>

    <!-- SCIPIO: WARN: some of these services contain security-sensitive parameters
        and should not be called directly as controller events (assume all except where otherwise noted) -->

    <!--
        IMAGE COMMON INTERFACES
    -->
    <service name="imageFileScaleCommon" engine="interface">
        <!-- INPUT IMAGE -->
        <attribute name="imageOrigPath" mode="IN" type="String" optional="true">
            <description>Full path of original image in filesystem as input (alternative to imageOrigUrl; if neither specified, auto-determines an original filename under imageServerPath); also supports component:// and file:// prefixes</description>
        </attribute>
        <attribute name="imageOrigUrl" mode="IN" type="String" optional="true">
            <description>URL of image relative to server root of original image in filesystem as input; WARN: 2017-07-04: MUST start with imageUrlPrefix else error; no other mount-points supported (alternative to imageOrigPath; if neither specified, auto-determines an original filename under imageServerPath)</description>
        </attribute>
        <attribute name="imageOrigFn" mode="IN" type="String" optional="true">
            <description>Original filename (no directories) of the image - required only if neither imageOrigPath nor imageOrigUrl specified</description>
        </attribute>
        <attribute name="imageOrigFnFmt" mode="IN" type="String" optional="true">
            <description>Image filename format string for original only, relative to imageServerPath/imageUrlPrefix, no extension; only useful if copyOrig==true or if imageOrigPath/imageOrigUrl are omitted (default: same as imageFnFmt)</description>
        </attribute>
        <!-- TODO: support this alternate input
        <attribute name="imageOrigContentId" mode="IN" type="String" optional="true">
            <description>Original image contentId as input (alternative to imageOrigPath)</description>
        </attribute>-->

        <!-- BASE PATHS -->
        <attribute name="imageServerPath" mode="IN" type="String" optional="true">
            <description>Full filesystem path of base server image, parameterized with ${tenantId} (default: uses image.server.path / catalog.properties); also supports component:// and file:// prefixes</description>
        </attribute>
        <attribute name="imageUrlPrefix" mode="IN" type="String" optional="true">
            <description>URL prefix for generated images, parameterized with ${tenantId} (default: uses image.url.prefix / catalog.properties)</description>
        </attribute>

        <!-- GENERATED FILES PARAMETERS -->
        <attribute name="imageFnFmt" mode="IN" type="String" optional="true">
            <description>Image filename format string, relative to imageServerPath/imageUrlPrefix, no extension, parameterized with ${sizetype} (or ${type}) and product fields (default: uses image.filename.format OR image.filename.additionalviewsize.format / catalog.properties)</description>
        </attribute>
        <attribute name="imagePathArgs" mode="IN" type="Map" optional="true">
            <description>Additional args for parameterized paths</description>
        </attribute>
        <attribute name="imageProfile" mode="IN" type="Object" optional="true">
            <description>Image profile, now generally required (name or org.ofbiz.common.image.ImageProfile)</description>
        </attribute>
        <attribute name="imagePropXmlPath" mode="IN" type="String" optional="true">
            <description>Path to ImageProperties.xml file containing size types, from ofbiz home root</description>
        </attribute>
        <attribute name="sizeTypeList" mode="IN" type="Collection" optional="true">
            <description>List of size types to generate and return (default: all types in file)</description>
        </attribute>
        <attribute name="copyOrig" mode="IN" type="Boolean" optional="true">
            <description>If true, also creates copy of the original under the size type "original" (default: false)</description>
        </attribute>
        <attribute name="deleteOld" mode="IN" type="Boolean" optional="true">
            <description>[TODO: NOT IMPLEMENTED] If true, also deletes old files in target directory (default: false)</description>
        </attribute>
        <attribute mode="IN" name="imageWriteOptions" type="Map" optional="true"/>

        <!-- SCALING OPTIONS -->
        <attribute name="scalingOptions" mode="IN" type="Map" optional="true">
            <description>Scaling options, notably the entry: scalerName (algorithm or library name)</description>
        </attribute>

        <!-- OUTPUT -->
        <attribute name="imageUrlMap" mode="OUT" type="Map" optional="true">
            <description>Map of size types to URLs (relative to server root, with imageUrlPrefix); if copyOrig==true, also contains "original" (UNLESS found to already exist / same as input)
                NOTE: Unlike stock ofbiz functions, this returns ALL generated. Use productSizeTypeList to iterate the common size types.</description>
        </attribute>
        <attribute name="imageInfoMap" mode="OUT" type="Map" optional="true">
            <description>Map of maps describing url, width, height and variantInfo for each sizeType; also contains "original" which contains copyOrig boolean</description>
        </attribute>
        <attribute name="bufferedImage" mode="OUT" type="java.awt.image.BufferedImage" optional="true">
            <description>Original image contents, for reuse</description>
        </attribute>
        <attribute name="successCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="skipCount" mode="OUT" type="Integer" optional="true"/><!-- FIXME: currently always zero for this service -->
    </service>

    <!--
        PRODUCT IMAGE SERVICES
    -->
    <service name="productImageFileScaleInAllSize" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageFileScaleInAllSize" auth="false">
        <description>Scales a product image file according to size types in product config ImageProperties.xml and using filename formats from catalog.properties</description>

        <!-- COMMON -->
        <implements service="imageFileScaleCommon"/>

        <!-- PRODUCT-SPECIFIC -->
        <attribute name="productId" mode="IN" type="String" optional="false">
            <description>productId</description>
        </attribute>
        <attribute name="imageViewType" mode="IN" type="com.ilscipio.scipio.product.image.ProductImageViewType" optional="true">
            <description>Full instance alternative to viewType/viewNumber parameters (NOTE: imageViewType should be "original" viewSize only)</description>
        </attribute>
        <attribute name="viewType" mode="IN" type="String" optional="true">
            <description>main|additional</description>
        </attribute>
        <attribute name="viewNumber" mode="IN" type="Object" optional="true">
            <description>For additional (String or Integer), a number between 1-4 for stock records; 0 for main viewType</description>
        </attribute>

        <!-- IMAGE VARIANT CONFIG
             SCIPIO (18/12/2018): Passing custom image variant config, for custom image sizes
        -->
        <attribute mode="IN" name="imageVariantConfig" type="org.ofbiz.common.image.ImageVariantConfig" optional="true"/>

        <!-- OUTPUT -->
        <attribute name="productSizeTypeList" mode="OUT" type="List" optional="true">
            <description>The list of typical product size types: [small, medium, large, detail]</description>
        </attribute>
    </service>
    
    <!-- TODO? Products don't currently support this?
    <service name="productImageDbScaleInAllSize" engine="java"
            location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageDbScaleInAllSize" auth="false">
        <description>(TODO) Scales a content/generic database image according to size types in ImageProperties.xml - core implementation (caller specifies all locations/filenames)</description>
        <implements service="contentImageDbScaleInAllSizeCore"/>  
    </service>
    -->

    <service name="productImageAutoRescale" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageAutoRescale" auth="false" transaction-timeout="1800">
        <description>Automatically rescales one or more product images for a product (does NOT consult parent/virtual products)</description>
        <attribute name="productId" mode="IN" type="String" optional="true"/>
        <attribute name="product" mode="IN" type="GenericValue" optional="true"/>
        <attribute name="allImages" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, automatically tries to apply to all the known associated images or all productContentTypeId</description>
        </attribute>
        <attribute name="productContentTypeId" mode="IN" type="String" optional="true">
            <description>productContentTypeId of the ProductContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="productContentTypeIdList" mode="IN" type="List" optional="true">
            <description>List of productContentTypeId of the ProductContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="contentId" mode="IN" type="String" optional="true">
            <description>contentId of the ProductContent for the image [either contentId or productContentTypeId must be set]</description>
        </attribute>
        <attribute name="contentIdList" mode="IN" type="List" optional="true">
            <description>List of contentId of the ProductContent for the image [either contentId or productContentTypeId must be set]</description>
        </attribute>
        <attribute name="sizeTypeList" mode="IN" type="Collection" optional="true">
            <description>Optional list of size dimension names to restrict resizing to (e.g.: 320x240, small); unlisted are left unchanged</description>
        </attribute>
        <attribute name="createSizeTypeContent" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>If true (default), ProductContent/DataResource records are added to products for size types not previously defined</description>
        </attribute>
        <attribute name="recreateExisting" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If false (default), existing files for the size types are ignored and not regenerated; if true, all or give size types are always regenerated (slow)</description>
        </attribute>
        <attribute name="nonFatal" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, runs in separate transaction and returns failure on image resize fail;
                if false, runs in current transaction and returns error on on image resize fail</description>
        </attribute>
        <attribute name="logDetail" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <attribute name="clearCaches" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <attribute name="imageOrigUrlMap" mode="IN" type="Map" optional="true">
            <description>Maps productContentTypeId to original image URLs, intended for initial call; only needed if not already present on the product</description>
        </attribute>
        <attribute name="imageOrigUrl" mode="IN" type="String" optional="true">
            <description>imageOrigUrl for single productContentTypeId, same as imageOrigUrlMap[productContentTypeId]</description>
        </attribute>
        <attribute name="copyOrig" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>Whether to make a copy of passed origImageUrl (if passed)</description>
        </attribute>
        <!-- per-image counts -->
        <attribute name="successCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="skipCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="errorCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failCount" mode="OUT" type="Integer" optional="true"/>
        <!-- per-variant counts -->
        <attribute name="variantSuccessCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="variantFailCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="reason" mode="OUT" type="String" optional="true"/>
    </service>

    <service name="productImageAutoRescaleProducts" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageAutoRescaleProducts" auth="false" transaction-timeout="144000">
        <description>Automatically rescales one or more product images for multiple or all products (does NOT consult parent/virtual products)</description>
        <attribute name="products" mode="IN" type="Object" optional="true">
            <description>List of product values or IDs or EntityListIterator</description>
        </attribute>
        <attribute name="productIdList" mode="IN" type="List" optional="true">
            <description>List of product IDs (alias for "products", same functionality, for easier use with runService UI)</description>
        </attribute>
        <attribute name="allProducts" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, queries all products in the system instead of passing by list</description>
        </attribute>
        <attribute name="allImages" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>(For each image) If true, automatically tries to apply to the known associated image types</description>
        </attribute>
        <attribute name="productContentTypeId" mode="IN" type="String" optional="true">
            <description>(For each image) productContentTypeId of the ProductContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="productContentTypeIdList" mode="IN" type="List" optional="true">
            <description>(For each image) List of productContentTypeId of the ProductContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="sizeTypeList" mode="IN" type="Collection" optional="true">
            <description>(For each image) Optional list of size dimension names to restrict resizing to (e.g.: 320x240, small); unlisted are left unchanged</description>
        </attribute>
        <attribute name="createSizeTypeContent" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>If true (default), ProductContent/DataResource records are added to products for size types not previously defined</description>
        </attribute>
        <attribute name="recreateExisting" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If false (default), existing files for the size types are ignored and not regenerated; if true, all or give size types are always regenerated (slow)</description>
        </attribute>
        <attribute name="maxProducts" mode="IN" type="Integer" optional="true"/>
        <attribute name="maxErrorCount" mode="IN" type="Integer" optional="true"/>
        <attribute name="sepProductTrans" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>NOTE: For safety this is left true by default, but in addition each image may also get a separate transaction through nonFatal (TODO: clarify)</description>
        </attribute>
        <attribute name="allCond" mode="IN" type="org.ofbiz.entity.condition.EntityCondition" optional="true"/>
        <attribute name="allOrderBy" mode="IN" type="List" optional="true"/>
        <attribute name="allResumeId" mode="IN" type="String" optional="true"/>
        <attribute name="logBatch" mode="IN" type="Integer" optional="true"/>
        <attribute name="logDetail" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <!-- per-image counts -->
        <attribute name="successCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="skipCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="errorCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failCount" mode="OUT" type="Integer" optional="true"/>
        <!-- per-variant counts -->
        <attribute name="variantSuccessCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="variantFailCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failProductIdList" mode="OUT" type="List" optional="true"/>
    </service>

    <service name="productImageAutoRescaleAll" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageAutoRescaleAll" auth="false" transaction-timeout="172800" semaphore="fail">
        <description>Automatically rescales one or more product images for multiple or all products (does NOT consult parent/virtual products)</description>
        <implements service="productImageAutoRescaleProducts"/>
        <override name="allProducts" default-value="true"/>
        <override name="allOrderBy" default-value="[productId]"/>
        <override name="logBatch" default-value="100"/>
        <override name="logDetail" default-value="true"/>
    </service>

    <service name="abortProductImageAutoRescaleAll" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="abortProductImageAutoRescaleAll" use-transaction="false">
        <description>Aborts productImageAutoRescaleAll if possible</description>
    </service>

    <service name="productImageVariantsDistributedClearCaches" engine="jms" location="serviceMessenger" invoke="productImageVariantsClearCaches"
             auth="true" use-transaction="false" log-eca="quiet" log="quiet" hideResultInLog="true">
        <description>Clear ProductImageVariants caches (SCIPIO)</description>
        <attribute name="productId" type="String" mode="IN" optional="true"/>
        <attribute name="productContentTypeId" type="String" mode="IN" optional="true"/>
    </service>
    <service name="productImageVariantsClearCaches" engine="java" export="true"
             location="com.ilscipio.scipio.product.image.ProductImageVariants" invoke="clearCaches" auth="true" use-transaction="false">
        <description>Clear ProductImageVariants caches (SCIPIO)</description>
        <!--<permission-service service-name="cmsGenericPermission" main-action="UPDATE"/>-->
        <attribute name="productId" type="String" mode="IN" optional="true"/>
        <attribute name="productContentTypeId" type="String" mode="IN" optional="true"/>
        <attribute name="distribute" type="Boolean" mode="IN" optional="true" default-value="false"/>
    </service>

    <service name="productImageMigrateImageUrlProductContentTypeData" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageMigrateImageUrlProductContentTypeData" auth="true">
        <description>Migrates IMAGE_URL ProductContentType data for 2021-02 enhancements (SCIPIO)</description>
        <required-permissions join-type="OR">
            <check-permission permission="CATALOG_ADMIN"/>
        </required-permissions>
        <attribute name="force" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If false, only runs if the ORIGINAL_IMAGE_URL record looks incomplete</description>
        </attribute>
        <attribute name="forceAll" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If true, recreates all - implies force</description>
        </attribute>
        <attribute name="preview" type="Boolean" mode="IN" optional="true" default-value="true">
            <description>If true, aborts transaction at end</description>
        </attribute>
    </service>

    <service name="productImageOpRequest" engine="java"
             location="com.ilscipio.scipio.product.image.ProductImageServices" invoke="productImageOpRequest" auth="false" transaction-timeout="144000">
        <description>Run a ProductImageOpRequest from ECA (SCIPIO)</description>
        <attribute name="opReq" type="GenericValue" mode="IN" optional="false">
            <description>ProductImageOpRequest instance</description>
        </attribute>
        <attribute name="deleteReq" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If false, only runs if the ORIGINAL_IMAGE_URL record looks incomplete</description>
        </attribute>
    </service>

    <!--
        PRODUCT CATEGORY IMAGE SERVICES
    -->
    <service name="categoryImageFileScaleInAllSize" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageFileScaleInAllSize" auth="false">
        <description>Scales a product image file according to size types in product config ImageProperties.xml and using filename formats from catalog.properties</description>

        <!-- COMMON -->
        <implements service="imageFileScaleCommon"/>

        <!-- CATEGORY-SPECIFIC -->
        <attribute name="productCategoryId" mode="IN" type="String" optional="false">
            <description>productCategoryId</description>
        </attribute>
        <attribute name="imageViewType" mode="IN" type="com.ilscipio.scipio.category.image.CategoryImageViewType" optional="true">
            <description>Full instance alternative to viewType/viewNumber parameters (NOTE: imageViewType should be "original" viewSize only)</description>
        </attribute>
        <attribute name="viewType" mode="IN" type="String" optional="true">
            <description>main|additional</description>
        </attribute>
        <attribute name="viewNumber" mode="IN" type="Object" optional="true">
            <description>For additional (String or Integer), a number between 1-4 for stock records; 0 for main viewType</description>
        </attribute>

        <!-- OUTPUT -->
        <attribute name="categorySizeTypeList" mode="OUT" type="List" optional="true">
            <description>The list of typical product size types: [small, medium, large, detail]</description>
        </attribute>
    </service>

    <service name="categoryImageAutoRescale" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageAutoRescale" auth="false" transaction-timeout="1800">
        <description>Automatically rescales one or more category images for a category</description>
        <attribute name="productCategoryId" mode="IN" type="String" optional="true"/>
        <attribute name="productCategory" mode="IN" type="GenericValue" optional="true"/>
        <attribute name="allImages" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, automatically tries to apply to all the known associated images or all prodCatContentTypeId</description>
        </attribute>
        <attribute name="prodCatContentTypeId" mode="IN" type="String" optional="true">
            <description>productContentTypeId of the ProductContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for categories with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="prodCatContentTypeIdList" mode="IN" type="List" optional="true">
            <description>List of prodCatContentTypeId of the ProductCategoryContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for categories with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="contentId" mode="IN" type="String" optional="true">
            <description>contentId of the ProductCategoryContent for the image [either contentId or prodCatContentTypeId must be set]</description>
        </attribute>
        <attribute name="contentIdList" mode="IN" type="List" optional="true">
            <description>List of contentId of the ProductCategoryContent for the image [either contentId or prodCatContentTypeId must be set]</description>
        </attribute>
        <attribute name="sizeTypeList" mode="IN" type="Collection" optional="true">
            <description>Optional list of size dimension names to restrict resizing to (e.g.: 320x240, small); unlisted are left unchanged</description>
        </attribute>
        <attribute name="createSizeTypeContent" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>If true (default), ProductCategoryContent/DataResource records are added to categories for size types not previously defined</description>
        </attribute>
        <attribute name="recreateExisting" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If false (default), existing files for the size types are ignored and not regenerated; if true, all or give size types are always regenerated (slow)</description>
        </attribute>
        <attribute name="nonFatal" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, runs in separate transaction and returns failure on image resize fail;
                if false, runs in current transaction and returns error on on image resize fail</description>
        </attribute>
        <attribute name="logDetail" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <attribute name="clearCaches" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <attribute name="imageOrigUrlMap" mode="IN" type="Map" optional="true">
            <description>Maps prodCatContentTypeId to original image URLs, intended for initial call; only needed if not already present on the category</description>
        </attribute>
        <attribute name="imageOrigUrl" mode="IN" type="String" optional="true">
            <description>imageOrigUrl for single prodCatContentTypeId, same as imageOrigUrlMap[prodCatContentTypeId]</description>
        </attribute>
        <attribute name="copyOrig" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>Whether to make a copy of passed origImageUrl (if passed)</description>
        </attribute>
        <!-- per-image counts -->
        <attribute name="successCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="skipCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="errorCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failCount" mode="OUT" type="Integer" optional="true"/>
        <!-- per-variant counts -->
        <attribute name="variantSuccessCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="variantFailCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="reason" mode="OUT" type="String" optional="true"/>
    </service>

    <service name="categoryImageAutoRescaleCategories" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageAutoRescaleCategories" auth="false" transaction-timeout="144000">
        <description>Automatically rescales one or more category images for multiple or all categories</description>
        <attribute name="productCategories" mode="IN" type="Object" optional="true">
            <description>List of product categories values or IDs or EntityListIterator</description>
        </attribute>
        <attribute name="productCategoryIdList" mode="IN" type="List" optional="true">
            <description>List of category product IDs (alias for "categories", same functionality, for easier use with runService UI)</description>
        </attribute>
        <attribute name="allProductCategories" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If true, queries all categories in the system instead of passing by list</description>
        </attribute>
        <attribute name="allImages" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>(For each image) If true, automatically tries to apply to the known associated image types</description>
        </attribute>
        <attribute name="prodCatContentTypeIdList" mode="IN" type="String" optional="true">
            <description>(For each image) prodCatContentTypeIdList of the ProductCategoryContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="prodCatContentTypeIdList" mode="IN" type="List" optional="true">
            <description>(For each image) List of prodCatContentTypeId of the ProductCategoryContent for the image - for main product image use ORIGINAL_IMAGE_URL,
                otherwise ADDITIONAL_IMAGE_x - NOTE: for products with no ORIGINAL_IMAGE_URL, DETAIL_IMAGE_URL is consulted instead</description>
        </attribute>
        <attribute name="sizeTypeList" mode="IN" type="Collection" optional="true">
            <description>(For each image) Optional list of size dimension names to restrict resizing to (e.g.: 320x240, small); unlisted are left unchanged</description>
        </attribute>
        <attribute name="createSizeTypeContent" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>If true (default), ProductCategoryContent/DataResource records are added to products for size types not previously defined</description>
        </attribute>
        <attribute name="recreateExisting" mode="IN" type="Boolean" optional="true" default-value="false">
            <description>If false (default), existing files for the size types are ignored and not regenerated; if true, all or give size types are always regenerated (slow)</description>
        </attribute>
        <attribute name="maxProductCategories" mode="IN" type="Integer" optional="true"/>
        <attribute name="maxErrorCount" mode="IN" type="Integer" optional="true"/>
        <attribute name="sepProductCategoryTrans" mode="IN" type="Boolean" optional="true" default-value="true">
            <description>NOTE: For safety this is left true by default, but in addition each image may also get a separate transaction through nonFatal (TODO: clarify)</description>
        </attribute>
        <attribute name="allCond" mode="IN" type="org.ofbiz.entity.condition.EntityCondition" optional="true"/>
        <attribute name="allOrderBy" mode="IN" type="List" optional="true"/>
        <attribute name="allResumeId" mode="IN" type="String" optional="true"/>
        <attribute name="logBatch" mode="IN" type="Integer" optional="true"/>
        <attribute name="logDetail" mode="IN" type="Boolean" optional="true" default-value="false"/>
        <!-- per-image counts -->
        <attribute name="successCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="skipCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="errorCount" mode="OUT" type="Integer" optional="true"/>
        <attribute name="failCount" mode="OUT" type="Integer" optional="true"/>

        <attribute name="failCategoryIdList" mode="OUT" type="List" optional="true"/>
    </service>

    <service name="categoryImageAutoRescaleAll" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageAutoRescaleAll" auth="false" transaction-timeout="172800" semaphore="fail">
        <description>Automatically rescales one or more category images for multiple or all categories</description>
        <implements service="categoryImageAutoRescaleCategories"/>
        <override name="allCategories" default-value="true"/>
        <override name="allOrderBy" default-value="[productCategoryId]"/>
        <override name="logBatch" default-value="100"/>
        <override name="logDetail" default-value="true"/>
    </service>

    <service name="abortCategoryImageAutoRescaleAll" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="abortCategoryImageAutoRescaleAll" use-transaction="false">
        <description>Aborts categoryImageAutoRescaleAll if possible</description>
    </service>

    <service name="categoryImageMigrateImageUrlCategoryContentTypeData" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageMigrateImageUrlCategoryContentTypeData" auth="true">
        <description>Migrates CATEGORY_IMAGE_URL ProdCatContentType data for 2022-09 enhancements (SCIPIO)</description>
        <required-permissions join-type="OR">
            <check-permission permission="CATALOG_ADMIN"/>
        </required-permissions>
        <attribute name="force" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If false, only runs if the ORIGINAL_IMAGE_URL record looks incomplete</description>
        </attribute>
        <attribute name="forceAll" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If true, recreates all - implies force</description>
        </attribute>
        <attribute name="preview" type="Boolean" mode="IN" optional="true" default-value="true">
            <description>If true, aborts transaction at end</description>
        </attribute>
    </service>

    <service name="categoryImageOpRequest" engine="java"
             location="com.ilscipio.scipio.category.image.CategoryImageServices" invoke="categoryImageOpRequest" auth="false" transaction-timeout="144000">
        <description>Run a CategoryImageOpRequest from ECA (SCIPIO)</description>
        <attribute name="opReq" type="GenericValue" mode="IN" optional="false">
            <description>CategoryImageOpRequest instance</description>
        </attribute>
        <attribute name="deleteReq" type="Boolean" mode="IN" optional="true" default-value="false">
            <description>If false, only runs if the CATEGORY_IMAGE_URL record looks incomplete</description>
        </attribute>
    </service>

    <service name="categoryImageVariantsDistributedClearCaches" engine="jms" location="serviceMessenger" invoke="categoryImageVariantsClearCaches"
             auth="true" use-transaction="false" log-eca="quiet" log="quiet" hideResultInLog="true">
        <description>Clear CategoryImageVariants caches (SCIPIO)</description>
        <attribute name="productCategoryId" type="String" mode="IN" optional="true"/>
        <attribute name="prodCatContentTypeId" type="String" mode="IN" optional="true"/>
    </service>
    <service name="categoryImageVariantsClearCaches" engine="java" export="true"
             location="com.ilscipio.scipio.category.image.CategoryImageVariants" invoke="clearCaches" auth="true" use-transaction="false">
        <description>Clear CategoryImageVariants caches (SCIPIO)</description>
        <!--<permission-service service-name="cmsGenericPermission" main-action="UPDATE"/>-->
        <attribute name="productCategoryId" type="String" mode="IN" optional="true"/>
        <attribute name="prodCatContentTypeId" type="String" mode="IN" optional="true"/>
        <attribute name="distribute" type="Boolean" mode="IN" optional="true" default-value="false"/>
    </service>

</services>