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

net.vectorpublish.desktop.vp.DefaultI8nImageFactory Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016, Peter Rader. All rights reserved.
 *  ___ ___               __                 ______         __     __  __         __
 * |   |   |.-----..----.|  |_ .-----..----.|   __ \.--.--.|  |--.|  ||__|.-----.|  |--.
 * |   |   ||  -__||  __||   _||  _  ||   _||    __/|  |  ||  _  ||  ||  ||__ --||     |
 *  \_____/ |_____||____||____||_____||__|  |___|   |_____||_____||__||__||_____||__|__|
 *
 * http://www.gnu.org/licenses/gpl-3.0.html
 */
package net.vectorpublish.desktop.vp;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale.LanguageRange;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.imageio.ImageIO;
import javax.inject.Named;
import javax.swing.ImageIcon;

import org.springframework.beans.factory.annotation.Autowired;

import net.vectorpublish.desktop.vp.api.ContextHolder;
import net.vectorpublish.desktop.vp.i8n.LanguageChangeListener;
import net.vectorpublish.desktop.vp.log.Log;
import net.vectorpublish.desktop.vp.ui.ImageKey;
import net.vectorpublish.desktop.vp.ui.Namespace;
import net.vectorpublish.desktop.vp.ui.i8n.I8nImageFactory;

@Named
public class DefaultI8nImageFactory implements I8nImageFactory, LanguageChangeListener {

	public static ImageIcon HOST_NOT_FOUND_IMG;

	static {
		BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
		Graphics graphics = image.getGraphics();
		graphics.setColor(new Color(0, 0, 0, 0));
		graphics.fillRect(0, 0, 32, 32);
		graphics.setFont(new Font("Helvetica", 0, 10));
		graphics.setColor(Color.BLACK);
		graphics.drawString("Host", 0, 10);
		graphics.drawString("not", 0, 20);
		graphics.drawString("found!", 0, 30);
		HOST_NOT_FOUND_IMG = new ImageIcon(image);
	}

	public static final String NET_VECTORPUBLISH_I8N_PROTOCOL = "net.vectorpublish.i8n.protocol";

	public static final String NET_VECTORPUBLISH_I8N_SERVER = "net.vectorpublish.i8n.server";

	private boolean hasTranslationServer = true;

	protected final HashMap icons = new HashMap<>();

	@Autowired
	protected final Log log = null;

	private LanguageRange lang = LanguageController.FALLBACK_RANGE;

	private String version;

	@Override
	public void changedTo(LanguageRange lr) {
		this.lang = lr;
	}

	@Override
	public ImageIcon get(Namespace namespace, ImageKey key, boolean small) {
		final String name = namespace + "/" + key.getCanonical() + (small ? "/small" : "/large");
		if (icons.containsKey(name)) {
			log.found("Image for key " + name + " in cache!");
			return icons.get(name);
		}
		if (!hasTranslationServer) {
			log.missing("Translation server", "Exit application");
			if (ContextHolder.context == null) {
				System.exit(1);
			} else {
				ContextHolder.context.close();
			}
		}
		URL url = null;
		try {
			final String transApp = getTranslationServer();
			final String location = transApp + "rest/images/" + lang.getRange() + "/" + name;
			log.calculated("Image URL:", location);
			url = new URL(location);
			final URLConnection openConnection = url.openConnection();
			int timeoutMS = 200;
			log.searching("Configuration for request timeout");
			final String configuredTimeout = System.getProperty("net.vectorpublish.i8n.timeout_in_ms");
			if (configuredTimeout != null) {
				log.found("Timeout of " + configuredTimeout);
				timeoutMS = Integer.parseInt(configuredTimeout);
				if (timeoutMS < 1) {
					throw new NumberFormatException("Timeout must be at least 1!");
				}
			} else {
				log.missing("Timeout", "Using default: " + timeoutMS);
			}
			openConnection.setConnectTimeout(timeoutMS);
			openConnection.setReadTimeout(timeoutMS);
			final InputStream inputStream = openConnection.getInputStream();
			log.system("Reading image.");
			final BufferedImage read = ImageIO.read(new URL(location));
			inputStream.close();
			if (read == null) {
				log.missing(location, "Not recieved!");
			} else {
				final ImageIcon imageIcon = new ImageIcon(read);
				log.cache("Image for namespace '" + name + "'.");
				icons.put(name, imageIcon);
				return imageIcon;
			}
		} catch (final UnknownHostException e) {
			log.missing(e.getMessage(), "Host not found, using placeholder image.");
			return HOST_NOT_FOUND_IMG;
		} catch (final SocketTimeoutException e) {
			log.timeout(url, "Too slow to read Image");
		} catch (final MalformedURLException e) {
			e.printStackTrace();
		} catch (final FileNotFoundException e) {
			// the image was not found on server (maybe server down).
			log.missing(url, "Image not found, mark as no internet!");
			hasTranslationServer = false;
		} catch (final IOException e) {
			e.printStackTrace();
		} catch (final NumberFormatException e) {
			e.printStackTrace();
			ContextHolder.context.close();
		}
		return null;
	}

	/**
	 * Returns the translation application for the current release.
	 *
	 * @return The base-url of the translation application including a pending
	 *         "/".
	 * @throws IOException
	 *             If the current release could not be determined.
	 */
	public String getTranslationServer() throws IOException {
		final String protocol = loadProtocol();
		final String server = loadServer();
		final String transApp = protocol + "://" + server + "/I8n-Server-" + version + "/";
		return transApp;
	}

	@PostConstruct
	public void load() throws IOException, ClassNotFoundException {
		log.searching("Package of vectorpublish to read version-info.");
		final Package pack = DefaultI8nImageFactory.class.getPackage();
		log.found("Package: " + pack);
		log.searching("Version");
		String ver = pack.getImplementationVersion();
		if (ver == null) {
			log.missing("Version", "In package");
			log.searching("Version in manifest");
			final Enumeration resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
			while (resources.hasMoreElements()) {
				final URL manifestURL = resources.nextElement();
				log.checkThat(manifestURL, "contains manifest.");
				final InputStream openStream = manifestURL.openStream();
				final Manifest mf = new Manifest(openStream);
				openStream.close();
				final Attributes mainAttributes = mf.getMainAttributes();
				log.found("Manifest-Main-Attributes:" + mainAttributes.size());
				for (final Entry s : mainAttributes.entrySet()) {
					log.found("Attribute " + s.getKey() + " = " + s.getValue());
				}
				final String vendor = mainAttributes.getValue("Implementation-Vendor-Id");
				if (vendor != null && vendor.equals("net.vectorpublish")) {
					ver = mainAttributes.getValue("Implementation-Version");
					log.found("Version " + ver + " in manifest (" + manifestURL + ").");
					break;
				}
			}
			if (ver == null) {
				log.missing("Version", "In manifests.");
			}
		} else {
			log.found("Version " + ver + " from package.");
		}
		version = ver;

		final File f = new File("icons" + version + ".cache");
		if (f.exists()) {
			final ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
			final Map hm = (Map) ois.readObject();
			icons.clear();
			icons.putAll(hm);
			ois.close();
		}

	}

	/**
	 * Returns the protocol the server should have.
	 *
	 * @return The Protocol without ://.
	 */
	private String loadProtocol() {
		String protocol = "http";
		log.searching("Looking for different protocol than " + protocol);
		final String overrideProtocol = System.getProperty(NET_VECTORPUBLISH_I8N_PROTOCOL);
		if (overrideProtocol != null) {
			log.found("Override protocol (" + NET_VECTORPUBLISH_I8N_PROTOCOL + ")");
			log.override("Protocol", protocol, protocol);
			protocol = overrideProtocol;
		} else {
			log.missing("Override protocol (" + NET_VECTORPUBLISH_I8N_PROTOCOL + ")", "Keep " + protocol);
		}
		return protocol;
	}

	/**
	 * Returns the socket of the server.
	 *
	 * @return The socket of the server, 127.0.0.1:8080 in example.
	 */
	private String loadServer() {
		String server = "www.vectorpublish.net";
		log.searching("Looking for different server than " + server);
		final String overrideServer = System.getProperty(NET_VECTORPUBLISH_I8N_SERVER);
		if (overrideServer != null) {
			log.found("Override server (" + NET_VECTORPUBLISH_I8N_SERVER + ")");
			log.override("Server", server, server);
			server = overrideServer;
		} else {
			log.missing("Override server (" + NET_VECTORPUBLISH_I8N_SERVER + ")", "Keep " + server);
		}
		return server;
	}

	@PreDestroy
	public void persist() throws IOException {
		final File f = new File("icons" + version + ".cache");
		final ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f));
		os.writeObject(icons);
		os.close();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy