001/**
002 *
003 * Copyright 2019-2020 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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.jivesoftware.smack.provider;
018
019import java.lang.reflect.ParameterizedType;
020import java.lang.reflect.Type;
021
022import org.jivesoftware.smack.packet.Element;
023
024public class AbstractProvider<E extends Element> {
025
026    private final Class<E> elementClass;
027
028    @SuppressWarnings("unchecked")
029    protected AbstractProvider() {
030        Type currentType = getClass().getGenericSuperclass();
031        while (!(currentType instanceof ParameterizedType)) {
032            Class<?> currentClass = (Class<?>) currentType;
033            currentType = currentClass.getGenericSuperclass();
034        }
035        ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType;
036        Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments();
037        Type elementType = actualTypeArguments[0];
038
039
040        if (elementType instanceof Class) {
041            elementClass = (Class<E>) elementType;
042        } else if (elementType instanceof ParameterizedType) {
043            ParameterizedType parameteriezedElementType = (ParameterizedType) elementType;
044            elementClass = (Class<E>) parameteriezedElementType.getRawType();
045        } else {
046            throw new AssertionError(
047                            "Element type '" + elementType + "' is neither of type Class or ParameterizedType");
048        }
049    }
050
051    public final Class<E> getElementClass() {
052        return elementClass;
053    }
054}