Java tutorial
/* * Copyright (C) 2016 Giancarlo Frison <giancarlo@gfrison.com> * * Licensed under the UbiCrypt License, Version 1.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://github.com/gfrison/ubicrypt/LICENSE.md * 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. */ package ubicrypt; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.openpgp.PGPKeyPair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Lazy; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.jar.Manifest; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.stage.Stage; import rx.schedulers.Schedulers; import rx.subjects.Subject; import ubicrypt.core.FixPassPhraseInitializer; import ubicrypt.core.PathConf; import ubicrypt.core.UbiConf; import ubicrypt.core.Utils; import ubicrypt.core.events.ShutdownOK; import ubicrypt.core.events.ShutdownRequest; import ubicrypt.ui.ControllerFactory; import ubicrypt.ui.OSUtil; import ubicrypt.ui.StackNavigator; import ubicrypt.ui.UIConf; import static java.util.concurrent.TimeUnit.SECONDS; import static ubicrypt.core.Utils.securityFile; import static ubicrypt.core.Utils.ubiqFolder; import static ubicrypt.core.crypto.PGPEC.encrypt; import static ubicrypt.core.crypto.PGPEC.encryptionKey; import static ubicrypt.ui.Anchor.anchor; @Lazy public class UbiCrypt extends Application { private static final Logger log = LoggerFactory.getLogger(UbiCrypt.class); private static final AtomicBoolean stopped = new AtomicBoolean(false); private ConfigurableApplicationContext ctx; private Runnable shutdown = () -> { if (stopped.compareAndSet(false, true)) { if (ctx != null) { Platform.runLater(() -> anchor().browse("wait", "Shutting down UbiCrypt...")); Subject appEvents = ctx.getBeanFactory().getBean("appEvents", Subject.class); log.info("shutdown request, waiting for all components acks..."); CountDownLatch cd = new CountDownLatch(1); appEvents.filter(event -> event instanceof ShutdownOK).subscribe(next -> cd.countDown()); appEvents.onNext(new ShutdownRequest()); try { if (cd.await(10, SECONDS)) { log.info("shutting gracefully down"); } else { log.info("shutting process timed out"); } } catch (InterruptedException e) { e.printStackTrace(); } ctx.close(); } Platform.exit(); } }; public static void main(final String[] args) throws IOException, InterruptedException { Utils.setProperties(args); ubiqFolder().toFile().mkdirs(); if (Utils.isAppInUse(ubiqFolder())) { log.error("UbiCrypt already running. Quit"); return; } Application.launch(args); } public static String getVersion() { String version = null; // try to load from maven properties first try { try (final InputStream is = UbiCrypt.class.getResourceAsStream("META-INF/MANIFEST.MF")) { if (is != null) { Manifest manifest = new Manifest(is); version = manifest.getMainAttributes().getValue("Implementation-Version"); } } } catch (final Exception e) { // ignore } // fallback to using Java API if (version == null) { final Package aPackage = UbiCrypt.class.getPackage(); if (aPackage != null) { version = aPackage.getImplementationVersion(); if (version == null) { version = aPackage.getSpecificationVersion(); } } } if (version == null) { // we could not compute the version so use a blank version = ""; } return version; } @Override public void init() throws Exception { super.init(); } @Override public void stop() throws Exception { shutdown.run(); super.stop(); } @Override public void start(final Stage stage) throws Exception { setUserAgentStylesheet(STYLESHEET_MODENA); stage.setTitle("UbiCrypt"); anchor().setStage(stage); try { final PGPKeyPair kp = encryptionKey(); encrypt(Collections.singletonList(kp.getPublicKey()), new ByteArrayInputStream(StringUtils.repeat("ciao", 1).getBytes())); } catch (Exception e) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Strong Encryption Required"); alert.setHeaderText("Install JCE Unlimited Strength Jurisdiction policy files"); alert.setContentText( "You can install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files, which are required to use strong encryption.\n" + "Download the files and instructions for Java 8.\n" + "Locate the jre\\lib\\security directory for the Java instance that the UbiCrypt is using.\n" + "For example, this location might be: C:\\Program Files\\Java\\jre8\\lib\\security.\n" + "Replace these two files with the .jar files included in the JCE Unlimited Strength Jurisdiction Policy Files download.\n" + "Stop and restart the UbiCrypt.\n\n\n\n\n\n"); ButtonType icePage = new ButtonType("Go to JCE download Page"); alert.getButtonTypes().addAll(icePage); Optional<ButtonType> result = alert.showAndWait(); if (result.get() == icePage) { getHostServices().showDocument( "http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html"); } Platform.exit(); } final File secFile = securityFile().toFile(); stage.setScene(anchor().show(secFile.exists() ? "login" : "createKey", getHostServices())); stage.show(); final UbiCrypt ubiCrypt = this; anchor().getPasswordStream().subscribeOn(Schedulers.io()).subscribe(pwd -> { final SpringApplication app = new SpringApplication(UbiConf.class, PathConf.class, UIConf.class); app.setRegisterShutdownHook(false); app.addInitializers(new FixPassPhraseInitializer(pwd)); app.setLogStartupInfo(true); ctx = app.run(); ctx.getAutowireCapableBeanFactory().autowireBean(ubiCrypt); ctx.getBeanFactory().registerSingleton("stage", stage); ctx.getBeanFactory().registerSingleton("hostService", getHostServices()); ctx.getBeanFactory().registerSingleton("osUtil", new OSUtil(getHostServices())); ControllerFactory cfactory = new ControllerFactory(ctx); StackNavigator navigator = new StackNavigator(null, "main", cfactory); stage.setScene(new Scene(navigator.open())); }); stage.setOnCloseRequest(windowEvent -> shutdown.run()); Runtime.getRuntime().addShutdownHook(new Thread(shutdown)); } }