All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.teamapps.icons.IconLibraryRegistry Maven / Gradle / Ivy

The newest version!
/*-
 * ========================LICENSE_START=================================
 * TeamApps
 * ---
 * Copyright (C) 2014 - 2024 TeamApps.org
 * ---
 * Licensed 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.
 * =========================LICENSE_END==================================
 */
package org.teamapps.icons;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.teamapps.icons.spi.*;

import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class IconLibraryRegistry {

	private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	private final Map>, String> libraryNameByIconClass = new HashMap<>();
	private final Map encodersByLibraryName = new HashMap<>();
	private final Map decodersByLibraryName = new HashMap<>();
	private final Map loadersByLibraryName = new HashMap<>();
	private final Map defaultIconStylesByLibraryName = new HashMap<>();


	public , S> IconEncoder getIconEncoder(Class iconClass) {
		registerIconLibrary(iconClass);
		String libraryName = libraryNameByIconClass.get(iconClass);
		return encodersByLibraryName.get(libraryName);
	}

	public , S> IconDecoder getIconDecoder(String libraryName) {
		return decodersByLibraryName.get(libraryName); // may be null, if no icon of this type has ever been encoded
	}

	public , S> IconLoader getIconLoader(String libraryName) {
		return loadersByLibraryName.get(libraryName);
	}

	public > S getDefaultStyle(Class iconClass) {
		return (S) defaultIconStylesByLibraryName.get(getLibraryName(iconClass));
	}

	public String getLibraryName(Icon icon) {
		return getLibraryName(icon.getClass());
	}

	public , S> String getLibraryName(Class iconClass) {
		registerIconLibrary(iconClass);
		return libraryNameByIconClass.get(iconClass);
	}

	public , S> void registerIconLibrary(Class iconClass) {
		if (!libraryNameByIconClass.containsKey(iconClass)) {
			IconLibrary libraryAnnotation = findAnnotation(iconClass, IconLibrary.class);
			if (libraryAnnotation != null) {
				IconEncoder iconEncoder;
				try {
					iconEncoder = libraryAnnotation.encoder().getDeclaredConstructor().newInstance();
				} catch (Exception e) {
					LOGGER.error("Could not create icon encoder for icon class " + iconClass, e);
					throw new RuntimeException(e);
				}
				IconDecoder iconDecoder;
				try {
					iconDecoder = libraryAnnotation.decoder().getDeclaredConstructor().newInstance();
				} catch (Exception e) {
					LOGGER.error("Could not create icon decoder for icon class " + iconClass, e);
					throw new RuntimeException(e);
				}
				IconLoader iconLoader;
				try {
					iconLoader = libraryAnnotation.loader().getDeclaredConstructor().newInstance();
				} catch (Exception e) {
					LOGGER.error("Could not create icon loader for icon class " + iconClass, e);
					throw new RuntimeException(e);
				}
				DefaultStyleSupplier defaultStyleSupplier;
				try {
					defaultStyleSupplier = libraryAnnotation.defaultStyleSupplier().getDeclaredConstructor().newInstance();
				} catch (Exception e) {
					LOGGER.error("Could not create defaultStyleSupplier for icon class " + iconClass, e);
					throw new RuntimeException(e);
				}
				registerIconLibrary(iconClass, libraryAnnotation.name(), iconEncoder, iconDecoder, iconLoader, defaultStyleSupplier.getDefaultStyle());
			}
		}
	}

	public , S> void registerIconLibrary(Class iconClass, String libraryName, IconEncoder iconEncoder, IconDecoder iconDecoder, IconLoader iconLoader, S defaultStyle) {
		synchronized (this) {
			if (!libraryNameByIconClass.containsKey(iconClass)) {
				libraryNameByIconClass.put(iconClass, libraryName);
				encodersByLibraryName.put(libraryName, iconEncoder);
				decodersByLibraryName.put(libraryName, iconDecoder);
				loadersByLibraryName.put(libraryName, iconLoader);
				defaultIconStylesByLibraryName.put(libraryName, defaultStyle);
			}
		}
	}

	private static  A findAnnotation(Class clazz, Class annotationClass) {
		A annotation = clazz.getAnnotation(annotationClass);
		if (annotation != null) {
			return annotation;
		}
		return Arrays.stream(clazz.getInterfaces())
				.map(i -> findAnnotation(i, annotationClass))
				.filter(Objects::nonNull)
				.findFirst()
				.orElseGet(() -> findAnnotation(clazz.getSuperclass(), annotationClass));
	}
}