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

com.github.bloodshura.x.cryptography.util.ApplicationProperties Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013-2018, João Vitor Verona Biazibetti - All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see .
 *
 * https://www.github.com/BloodShura
 */

package com.github.bloodshura.x.cryptography.util;

import com.github.bloodshura.x.cfg.props.Properties;
import com.github.bloodshura.x.charset.Encoding;
import com.github.bloodshura.x.cryptography.Twoway;
import com.github.bloodshura.x.cryptography.exception.CryptoException;
import com.github.bloodshura.x.cryptography.impl.cipher.Aes;
import com.github.bloodshura.x.io.exception.FileException;
import com.github.bloodshura.x.io.file.ApplicationDataDirectory;
import com.github.bloodshura.x.io.file.File;
import com.github.bloodshura.x.io.stream.FastByteArrayOutputStream;
import com.github.bloodshura.x.io.stream.TextReader;
import com.github.bloodshura.x.io.stream.TextWriter;
import com.github.bloodshura.x.resource.LocalResource;
import com.github.bloodshura.x.resource.Resource;
import com.github.bloodshura.x.resource.StringResource;
import com.github.bloodshura.x.security.Password;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.function.Consumer;

public final class ApplicationProperties extends Properties {
	private final Twoway crypter;
	private final File file;
	private final String name;

	private ApplicationProperties(@Nonnull CharSequence name, @Nonnull File file, @Nullable Twoway crypter) {
		this.crypter = crypter;
		this.file = file;
		this.name = name.toString();
	}

	public void enableAutoSave() {
		enableAutoSave(getFile());
	}

	public void enableAutoSave(@Nonnull Consumer exception) {
		enableAutoSave(getFile(), exception);
	}

	@Nullable
	public Twoway getCrypter() {
		return crypter;
	}

	@Nonnull
	public File getFile() {
		return file;
	}

	@Nonnull
	public String getName() {
		return name;
	}

	public boolean hasCrypter() {
		return getCrypter() != null;
	}

	public synchronized void load() throws CryptoException, IOException {
		load(getFile());
	}

	@Override
	public synchronized void load(@Nonnull Resource input) throws CryptoException, IOException {
		byte[] data = input.readData();
		byte[] decrypted = hasCrypter() ? getCrypter().decrypt(data) : data;
		String string = Encoding.UTF_8.build(decrypted);
		StringResource resource = new StringResource(string);

		try (TextReader reader = new TextReader(resource)) {
			load(reader);
		}
	}

	public synchronized void save() throws CryptoException, IOException {
		save(getFile());
	}

	@Override
	public synchronized void save(@Nonnull LocalResource output) throws CryptoException, IOException {
		FastByteArrayOutputStream out = new FastByteArrayOutputStream();

		try (TextWriter writer = new TextWriter(out)) {
			save(writer);
		}

		byte[] data = out.toArray();
		byte[] encrypted = hasCrypter() ? getCrypter().encrypt(data) : data;

		output.write(encrypted);
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, using no {@link Twoway}.
	 *
	 * @param applicationName The application name
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName) throws FileException {
		return forApplication(applicationName, (Twoway) null);
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, with the specified {@link File} as the properties file,
	 * using no {@link Twoway}.
	 *
	 * @param applicationName The application name
	 * @param file            The properties file
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName, @Nonnull File file) {
		return forApplication(applicationName, file, (Twoway) null);
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, with the specified {@link File} as the properties file,
	 * using the specified {@link Twoway} as the file decrypter/encrypter.
	 *
	 * @param applicationName The application name
	 * @param file            The properties file
	 * @param crypter         The file crypter
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName, @Nonnull File file, @Nullable Twoway crypter) {
		return new ApplicationProperties(applicationName.toString(), file, crypter);
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, with the specified {@link File} as the properties file,
	 * using the specified {@link Password} as the salt for a new instance of the {@link Aes} crypter.
	 *
	 * @param applicationName The application name
	 * @param file            The properties file
	 * @param password        The password
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName, @Nonnull File file, @Nonnull Password password) {
		return forApplication(applicationName, file, new Aes(password));
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, using the specified {@link Twoway} as the file decrypter/encrypter.
	 * The crypter can be null.
	 *
	 * @param applicationName The application name
	 * @param crypter         The file crypter
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName, @Nullable Twoway crypter) throws FileException {
		String name = applicationName.toString();
		File file = new File(new ApplicationDataDirectory(name), ".properties");

		return new ApplicationProperties(name, file, crypter);
	}

	/**
	 * Returns an {@link ApplicationProperties} instance for the desired
	 * application name, using the specified {@link Password} as the salt for a
	 * new instance of {@link Aes} crypter.
	 *
	 * @param applicationName The application name
	 * @param password        The password
	 * @return A new instance of ApplicationProperties
	 */
	@Nonnull
	public static ApplicationProperties forApplication(@Nonnull CharSequence applicationName, @Nonnull Password password) throws FileException {
		return forApplication(applicationName, new Aes(password));
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy