001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.openwire;
018
019import java.io.IOException;
020import org.apache.activemq.util.IOExceptionSupport;
021
022public class OpenWireUtil {
023
024    static final String jmsPackageToReplace = "jakarta.jms";
025    static final String jmsPackageToUse = "javax.jms";
026
027    /**
028     * Verify that the provided class extends {@link Throwable} and throw an
029     * {@link IllegalArgumentException} if it does not.
030     *
031     * @param clazz
032     */
033    public static void validateIsThrowable(Class<?> clazz) {
034        if (!Throwable.class.isAssignableFrom(clazz)) {
035            throw new IllegalArgumentException("Class " + clazz + " is not assignable to Throwable");
036        }
037    }
038
039    /**
040     * Verify that the buffer size that will be allocated will not push the total allocated
041     * size of this frame above the expected frame size. This is an estimate as the current
042     * size is only tracked when calls to this method are made and is primarily intended
043     * to prevent large arrays from being created due to an invalid size.
044     *
045     * Also verify the size against configured max frame size.
046     * This check is a sanity check in case of corrupt packets contain invalid size values.
047     *
048     * @param wireFormat configured OpenWireFormat
049     * @param size buffer size to verify
050     * @throws IOException If size is larger than currentFrameSize or maxFrameSize
051     */
052    public static void validateBufferSize(OpenWireFormat wireFormat, int size) throws IOException {
053        validateLessThanFrameSize(wireFormat, size);
054
055        // if currentFrameSize is set and was checked above then this check should not be needed,
056        // but it doesn't hurt to verify again in case the max frame size check was missed
057        // somehow
058        if (wireFormat.isMaxFrameSizeEnabled() && size > wireFormat.getMaxFrameSize()) {
059            throw IOExceptionSupport.createFrameSizeException(size,  wireFormat.getMaxFrameSize());
060        }
061    }
062
063    // Verify total tracked sizes will not exceed the overall size of the frame
064    private static void validateLessThanFrameSize(OpenWireFormat wireFormat, int size)
065        throws IOException {
066        final OpenWireFormat.MarshallingContext context = wireFormat.getMarshallingContext();
067        // No information on current frame size so just return
068        if (context == null || context.getFrameSize() < 0) {
069            return;
070        }
071
072        // Increment existing estimated buffer size with new size
073        context.increment(size);
074
075        // We should never be trying to allocate a buffer that is going to push the total
076        // size greater than the entire frame itself
077        if (context.getEstimatedAllocated() > context.getFrameSize()) {
078            throw IOExceptionSupport.createFrameSizeBufferException(
079                context.getEstimatedAllocated(), context.getFrameSize());
080        }
081    }
082
083    /**
084     * This method can be used to convert from javax -> jakarta or
085     * vice versa depending on the version used by the client
086     *
087     * @param className
088     * @return
089     */
090    public static String convertJmsPackage(String className) {
091        if (className != null && className.startsWith(jmsPackageToReplace)) {
092            return className.replace(jmsPackageToReplace, jmsPackageToUse);
093        }
094        return className;
095    }
096
097}