    001/*
    002 * Copyright 2025 The Apache Software Foundation.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *      http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    013 * See the License for the specific language governing permissions and
    014 * limitations under the License.
    015 */
    016package org.apache.wiki.tags;
    017
    018import java.text.CharacterIterator;
    019import java.text.StringCharacterIterator;
    020import org.apache.logging.log4j.LogManager;
    021import org.apache.logging.log4j.Logger;
    022import org.apache.wiki.util.TextUtil;
    023
    024/**
    025 * Outputs the server's configured maximum file upload size.
    026 *
    027 * @since 3.0.0
    028 */
    029public class MaxUploadTag extends WikiTagBase {
    030
    031    private static final Logger LOG = LogManager.getLogger(MaxUploadTag.class);
    032
    033    @Override
    034    public int doWikiStartTag() throws Exception {
    035        String maxUploadSize = m_wikiContext.getEngine().getWikiProperties().getProperty("jspwiki.attachment.maxsize");
    036        if (maxUploadSize != null) {
    037            try {
    038                long bytes = Long.parseLong(maxUploadSize);
    039                String humanFormat = humanReadableByteCountBin(bytes);
    040                pageContext.getOut().print(TextUtil.replaceEntities(humanFormat));
    041            } catch (NumberFormatException ex) {
    042                LOG.warn("Parse error from configuration setting jspwiki.attachment.maxsize " + ex.getMessage());
    043            }
    044        }
    045        return SKIP_BODY;
    046    }
    047
    048    /*
    049    Binary (1 Ki = 1,024)
    050    from https://stackoverflow.com/a/3758880/1203182
    051     */
    052    public static String humanReadableByteCountBin(long bytes) {
    053        long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
    054        if (absB < 1024) {
    055            return bytes + " B";
    056        }
    057        long value = absB;
    058        CharacterIterator ci = new StringCharacterIterator("KMGTPE");
    059        for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
    060            value >>= 10;
    061            ci.next();
    062        }
    063        value *= Long.signum(bytes);
    064        return String.format("%.1f %ciB", value / 1024.0, ci.current());
    065    }
    066}