summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/util/ClientVersion.java
blob: 7827ac7297db7d77990ddcd166426c53c9915eff (plain) (tree)
1
2
3
4
5
6
7
8
9

                                


                              
                                 
                                         
 
                                       
                                                          

                                                                     

                                           
                              
                                   
                                              
                                
                             
 

                            
                                                                                       


                                                   



                                                     
 

                                   
                                                                                                         
         
 
           
                                                                            



                                                 

                                     
 


                  
                                                   

                                         
 


                                                            
                                                                  

                                                  
                             
                                      
         
 





                                                                       
                             
                                          
         
 
           




                                             
                             



                                 
                                                              


                                                                     
                                          


                                                                                                          
                             
                                                                      

                                                               
         
 



                                                                         
                                                

                                                                
         
 
           
                                                                             


                                                                        
                                            

                                                                       




                                                          

                                                                                                               
                                                                                                   
                                                                                    













                                                                                                        
                         







                                                       
                                                
                                                  
                 


                                              

         



                                      
                               
                                
                                 
         


























                                                                                                                     
 
package org.openslx.dozmod.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openslx.dozmod.App;
import org.openslx.dozmod.Branding;
import org.openslx.sat.thrift.version.Version;
import org.openslx.util.AppUtil;
import org.openslx.util.Json;

public class ClientVersion {

	private static final Logger LOGGER = LogManager.getLogger(ClientVersion.class);

	private static long localRevisionTime = 0;
	private static long remoteRevisionTime = 0;
	private static String localRevision = "???";
	private static String remoteRevision = "???";
	private static String changelog = "???";
	private static Thread remoteThread = null; 

	static  {
		loadLocalVersion();
		loadRemoteVersion(Branding.getUpdateServerAddress() + Version.VERSION + "/version.json");
	}

	/**
	 * Gets the local revision id if loading it worked, "???" otherwise.
	 * 
	 * @return id as String
	 */
	public static String getLocalRevision() {
		return localRevision;
	}

	/**
	 * @return
	 */
	public static long getLocalRevTimestamp() {
		return localRevisionTime;
	}

	/**
	 * Gets the revision id of the latest remote version
	 * 
	 * @return id as String if loading worked, "???" otherwise
	 */
	public static String getRemoteRevision() {
		waitRemote();
		return remoteRevision;
	}

	/**
	 * Gets the timestamp of the latest remote version
	 * 
	 * @return timestamp as Long if loading it worked, 0L otherwise
	 */
	public static long getRemoteRevTimestamp() {
		waitRemote();
		return remoteRevisionTime;
	}

	/**
	 * Gets the changelog
	 * 
	 * @return log as String
	 */
	public static String getChangelog() {
		waitRemote();
		return changelog;
	}

	/**
	 * Checks if we are running latest application version
	 * 
	 * @return true if there is no newer version, false otherwise
	 */
	public static boolean isNewest() {
		// if either local or remote version is unknown, just pretend there's no update
		// as there most likely isn't and we'd just annoy the user
		// TODO: Report "fail" state so at least on manual update check we can tell that it failed
		waitRemote();
		if (localRevisionTime == 0 || remoteRevisionTime == 0)
			return true;
		return localRevisionTime >= remoteRevisionTime;
	}

	/**
	 * Loads the local version information from the jar's MANIFEST.MF
	 * into the fields 'localRevision' and 'localRevisionTime'
	 */
	private static void loadLocalVersion() {
		localRevision = AppUtil.getRevisionVersion();
		localRevisionTime = AppUtil.getBuildTimestamp();
	}

	/**
	 * Loads the given UrlString as JSON and saves the remote information
	 * into fields 'remoteRevision' and 'remoteRevisionTime'
	 * 
	 * The remote JSON should have 'timestamp' and 'revision', like:
	 * { "timestamp": 1, "revision": 2 }
	 */
	private static void loadRemoteVersion(final String urlString) {
		remoteThread = new Thread(new Runnable() {
			@Override
			public void run() {
				App.waitForInit();
				String json = null;
				HttpGet get = new HttpGet(urlString);
				try (CloseableHttpResponse resp = ProxyConfigurator.getClient().execute(get)) {
					ByteArrayOutputStream buffer = new ByteArrayOutputStream();
					buffer.write(resp.getEntity().getContent());
					buffer.close();
					json = new String(buffer.toByteArray(), StandardCharsets.UTF_8);
				} catch (Exception e) {
					if (json == null) {
						LOGGER.error("Could not fetch remote version", e);
						return;
					}
				}

				VersionQuery query = Json.deserialize(json, VersionQuery.class);
				remoteRevision = query.revision;
				// seconds timestamp here...
				remoteRevisionTime = query.timestamp;
				changelog = query.changelog;
			}
		});
		remoteThread.start();
	}
	
	private static synchronized void waitRemote() {
		if (remoteThread == null)
			return;
		try {
			remoteThread.join(5000);
		} catch (InterruptedException e) {
		}
		if (!remoteThread.isAlive()) {
			remoteThread = null;
		}
	}

	/**
	 * Class for GSON json parsing
	 */
	static class VersionQuery {
		long timestamp;
		String revision;
		String changelog;
	}

	public static void createJson(String name) throws IOException {
		loadLocalVersion();
		if (localRevisionTime == 0)
			throw new RuntimeException("Missing manifest/data in jar: No revision time found");
		if (localRevision == null || localRevision.isEmpty())
			throw new RuntimeException("Missing manifest/data in jar: No commit hash found");
		System.out.println("Please enter change log. To finish, put a '.' on a single line");
		StringBuilder sb = new StringBuilder();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		for (String line; (line = br.readLine()) != null;) {
			if (line.equals("."))
				break;
			sb.append(line);
			sb.append('\n');
		}
		VersionQuery vq = new VersionQuery();
		vq.timestamp = localRevisionTime;
		vq.revision = localRevision;
		vq.changelog = sb.toString();
		String data = Json.serialize(vq);
		FileUtils.writeStringToFile(new File(name), data, StandardCharsets.UTF_8);
		System.out.println();
		System.out.println("Created json file at " + name);
		System.out.println("This build is using Thrift RPC interface version >> " + Version.VERSION + " <<");
		System.out.println();
	}
}