Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Version specific store of app data, and preferences #396

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
023d86a
Application data, User Library and Preferences are now stored specifi…
Oliver-Loeffler Dec 22, 2021
34bd44f
Implemented a process to conditionally import previous SceneBuilder v…
Oliver-Loeffler Dec 22, 2021
ae2be0e
Replaced sysout with logging.
Oliver-Loeffler Jan 5, 2022
5c956a0
Added a draft implementation of a UserLibraryImport process.
Oliver-Loeffler Jan 5, 2022
b131c63
Moved OS depending behavior in separate class. Also introduced an
Oliver-Loeffler Jan 5, 2022
ef870f1
Complemented Javadoc and renamed the application directory interface.
Oliver-Loeffler Jan 11, 2022
d537ca3
Adjusted lambda formatting following Scene Builder convention.
Oliver-Loeffler Jan 11, 2022
e8ab957
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 11, 2022
dad37c2
Spelling correction.
Oliver-Loeffler Jan 11, 2022
ad07a68
Added unsupported operation exceptions for cases where the OS is
Oliver-Loeffler Jan 11, 2022
97d8d21
Javadoc update
Oliver-Loeffler Jan 11, 2022
d35f78f
Added test for OS detection.
Oliver-Loeffler Jan 11, 2022
9681d4e
Formatting
Oliver-Loeffler Jan 11, 2022
13e2025
TODO added
Oliver-Loeffler Jan 11, 2022
7fc222a
Merge branch 'master' into issue-346
Oliver-Loeffler Jan 12, 2022
0d7f7ff
Merge branch 'issue-346' of [email protected]:Oliver-Loeffler/scenebuild…
Oliver-Loeffler Jan 12, 2022
71032ca
Formatting adjusted to match master
Oliver-Loeffler Jan 12, 2022
e781830
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 13, 2022
b12356b
Rework
Oliver-Loeffler Jan 14, 2022
e867fb2
Refactor
Oliver-Loeffler Jan 14, 2022
e3ae783
LibraryFolder refactored
Oliver-Loeffler Jan 14, 2022
359c066
Logfolder refactored out
Oliver-Loeffler Jan 14, 2022
9472f05
Refactoring
Oliver-Loeffler Jan 14, 2022
d3e6dfa
Refactored so that Paths are used rather then strings everywhere
Oliver-Loeffler Jan 14, 2022
2809ae8
Javadoc update
Oliver-Loeffler Jan 14, 2022
b377675
Refactored handling of OS specifics. Eliminated
Oliver-Loeffler Jan 14, 2022
f2ae1c8
Merge branch 'issue-346' of [email protected]:Oliver-Loeffler/scenebuild…
Oliver-Loeffler Jan 14, 2022
fda949b
Reverted formatting changes.
Oliver-Loeffler Jan 14, 2022
e8e447e
Header cleanup. Formatting. Test naming. Javadoc. Minimal refactoring.
Oliver-Loeffler Jan 15, 2022
71d06d9
Added proper prepartion for one PrefsImporter test.
Oliver-Loeffler Jan 15, 2022
a828260
Added support for SNAPSHOT versions.
Oliver-Loeffler Jan 16, 2022
e535b41
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 17, 2022
b254f26
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 19, 2022
f5fa41b
Removed JCenter repository incl. related search.
Oliver-Loeffler Jan 21, 2022
289c176
merged with master
Oliver-Loeffler Jan 21, 2022
1c04087
Revert "Removed JCenter repository incl. related search."
Oliver-Loeffler Jan 21, 2022
7c8ac26
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 22, 2022
e14bde0
KIT continues to work with Java-11
Oliver-Loeffler Jan 22, 2022
ee82283
APP runs with Java-17
Oliver-Loeffler Jan 22, 2022
b5c5cbe
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 22, 2022
f8d616e
Merge branch 'issue-346' of [email protected]:Oliver-Loeffler/scenebuild…
Oliver-Loeffler Jan 22, 2022
9ec2526
Introduced background library import using a JavaFX task.
Oliver-Loeffler Jan 22, 2022
bca0745
Merge branch 'issue-346' of [email protected]:Oliver-Loeffler/scenebuild…
Oliver-Loeffler Jan 22, 2022
0c98a20
Working draft for preferences and user library import.
Oliver-Loeffler Jan 23, 2022
89bcc3d
Reduced method visibility.
Oliver-Loeffler Jan 23, 2022
8e1593d
Icon added to dialog.
Oliver-Loeffler Jan 23, 2022
8736830
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Jan 23, 2022
425abd0
KIT and APP now use Java-17 again. Eclipse does not like different
Oliver-Loeffler Jan 23, 2022
765d60b
Renamed method according to feedback.
Oliver-Loeffler Jan 23, 2022
7060a38
State model for return codes corrected.
Oliver-Loeffler Jan 23, 2022
e3e2d84
Cleanup
Oliver-Loeffler Jan 23, 2022
35065c6
Logging improved. Removed the need for the boolean variable in app.
Oliver-Loeffler Jan 23, 2022
936cd7f
Naming update
Oliver-Loeffler Jan 24, 2022
dc11ea8
Further reduced visibility of class elements.
Oliver-Loeffler Jan 24, 2022
4ff39ef
Merge branch 'master' into issue-346
Oliver-Loeffler Feb 5, 2022
a6f92c2
Merge branch 'gluonhq:master' into issue-346
Oliver-Loeffler Feb 6, 2022
e5a522c
Merge branch 'master' into issue-346
Oliver-Loeffler Feb 9, 2022
5844f3f
Replaced JUnit4 with JUnit5
Oliver-Loeffler Feb 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<useIncrementalCompilation>false</useIncrementalCompilation>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down
106 changes: 36 additions & 70 deletions app/src/main/java/com/oracle/javafx/scenebuilder/app/AppPlatform.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Gluon and/or its affiliates.
* Copyright (c) 2017, 2022, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -32,15 +32,13 @@
*/
package com.oracle.javafx.scenebuilder.app;

import com.oracle.javafx.scenebuilder.app.util.AppSettings;
import com.oracle.javafx.scenebuilder.app.util.MessageBox;
import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;
import static com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform.IS_LINUX;
import static com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform.IS_MAC;
import static com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform.IS_WINDOWS;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
Expand All @@ -50,61 +48,37 @@
*
*/
public class AppPlatform {

private static String applicationDataFolder;
private static String userLibraryFolder;
private static String messageBoxFolder;
private static String logsFolder;
private static MessageBox<MessageBoxMessage> messageBox;

public static synchronized String getApplicationDataFolder() {

if (applicationDataFolder == null) {
final String appName = "Scene Builder"; //NOI18N

if (IS_WINDOWS) {
applicationDataFolder
= System.getenv("APPDATA") + "\\" + appName; //NOI18N
} else if (IS_MAC) {
applicationDataFolder
= System.getProperty("user.home") //NOI18N
+ "/Library/Application Support/" //NOI18N
+ appName;
} else if (IS_LINUX) {
applicationDataFolder
= System.getProperty("user.home") + "/.scenebuilder"; //NOI18N
}
}

assert applicationDataFolder != null;

return applicationDataFolder;
}


public static synchronized String getUserLibraryFolder() {

if (userLibraryFolder == null) {
userLibraryFolder = getApplicationDataFolder() + "/Library"; //NOI18N
private static PlatformSpecificDirectories platformSpecificDirectories;

public static synchronized AppPlatformDirectories getAppDirectories() {
final String appVersion = getApplicationVersion();
if (platformSpecificDirectories == null) {
OperatingSystem os = OperatingSystem.get();
platformSpecificDirectories = new PlatformSpecificDirectories(os, appVersion);
}

return userLibraryFolder;
assert platformSpecificDirectories != null;
return platformSpecificDirectories;
}

/**
* Returns the directory path for logs. Default path is "${user.home}/.scenebuilder/logs/".
* @return Directory path for Scene Builder logs
/*
* TODO:
* How to deal with snapshot versions?
* Shall the suffix "-SNAPSHOT" be ignored?
*
* For testing it would be helpful to have
* the snapshot suffix as with that one could run
* released vs. non-released SB versions.
*/
public static synchronized String getLogFolder() {
if (logsFolder == null) {
logsFolder = Paths.get(System.getProperty("user.home"), ".scenebuilder", "logs").toString(); //NOI18N
}
return logsFolder;
}
private static String getApplicationVersion() {
String version = AppSettings.getSceneBuilderVersion();
assert version != null;
assert !version.isBlank();
return version;
}

public static boolean requestStart(
AppNotificationHandler notificationHandler, Application.Parameters parameters)
throws IOException {
public static boolean requestStart(AppNotificationHandler notificationHandler,
Application.Parameters parameters) throws IOException {
if (EditorPlatform.isAssertionEnabled()) {
// Development mode : we do not delegate to the existing instance
notificationHandler.handleLaunch(parameters.getUnnamed());
Expand All @@ -126,25 +100,25 @@ public interface AppNotificationHandler {
* Private (requestStartGeneric)
*/

private static synchronized boolean requestStartGeneric(
AppNotificationHandler notificationHandler, Application.Parameters parameters)
throws IOException {
private static synchronized boolean requestStartGeneric(AppNotificationHandler notificationHandler,
Application.Parameters parameters) throws IOException {
assert notificationHandler != null;
assert parameters != null;
assert messageBox == null;


Path mboxDir = ((PlatformSpecificDirectories)getAppDirectories()).getMessageBoxFolder();
try {
Files.createDirectories(Paths.get(getMessageBoxFolder()));
Files.createDirectories(Paths.get(getLogFolder()));
Files.createDirectories(mboxDir);
Files.createDirectories(getAppDirectories().getLogFolder());
} catch(FileAlreadyExistsException x) {
// Fine
}

final boolean result;
messageBox = new MessageBox<>(getMessageBoxFolder(), MessageBoxMessage.class, 1000 /* ms */);
messageBox = new MessageBox<>(mboxDir.toAbsolutePath().toString(), MessageBoxMessage.class, 1000 /* ms */);
// Fix Start: Github Issue #301
final List<String> parametersUnnamed = new ArrayList<>(parameters.getUnnamed());
if (IS_MAC) {
if (OperatingSystem.get().equals(OperatingSystem.MACOS)) {
parametersUnnamed.removeIf(p -> p.startsWith("-psn"));
}
// Fix End
Expand All @@ -165,14 +139,6 @@ private static synchronized boolean requestStartGeneric(
return result;
}

private static String getMessageBoxFolder() {
if (messageBoxFolder == null) {
messageBoxFolder = getApplicationDataFolder() + "/MB"; //NOI18N
}

return messageBoxFolder;
}

private static class MessageBoxMessage extends ArrayList<String> {
static final long serialVersionUID = 10;
public MessageBoxMessage(List<String> strings) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2022, Gluon and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation and Gluon nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.javafx.scenebuilder.app;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;

public interface AppPlatformDirectories {

/**
* @return the root location where application data shall be stored on the
* corresponding platform.
*/
Path getApplicationDataRoot();

/**
* Scene Builder provides the option to hold custom JAR files in a user library.
* This method provides the full path to the location of the user library
* directory. Typically, the user library directory (Library) is placed inside
* the application data folder.
*/
Path getUserLibraryFolder();

/**
* @return Provides the name of the by default version specific application data
* sub directory. This folder is will be located inside the application
* data root folder.
*/
String getApplicationDataSubFolder();

/**
* In previous versions, Scene Builder stored its files in a directory without
* version number. Hence, in some cases it might be helpful to control when the
* version number is used or not. To obtain this folder without version number
* can be beneficial in cases, where one wants to search the application data root
* folder for other existing settings of Scene Builder.
*
* @param includeVersion If true, the version number might be a part of the sub
* folder name.
* @return Provides the name of the application data sub directory with or
* without version information.
*/
String getApplicationDataSubFolder(boolean includeVersion);

/**
* The application data folder is usually a child folder inside the application
* data root.
*
* @return the exact location, specifically for this version of Scene Builder,
* where settings and arbitrary files can be placed.
*/
Path getApplicationDataFolder();

/**
* Logfile location
* @return The directory containing the application log file.
*/
Path getLogFolder();

/**
* Creates the user library folder when needed.
* If the directory cannot be created, the error is logged.
*/
public default void createUserLibraryFolder() {
Path libDir = getUserLibraryFolder();
if (Files.notExists(libDir)) {
try {
Files.createDirectories(libDir);
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to create user library directory!", e);
}
}
}

/* MessageBox folder is not provided by this as MessageBox folder previously
* was package private, here all previously public directories are accessible.
*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2022, Gluon and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation and Gluon nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.javafx.scenebuilder.app;

import java.util.Locale;

/**
* Detects the used operating system and provides an enum item for it.
*/
public enum OperatingSystem {

MACOS("mac"),
WINDOWS("windows"),
LINUX("linux"),
OTHER("other-os");

private final String osName;

OperatingSystem(String osName) {
this.osName = osName;
}

/**
* Obtains the operating system type from system property os.name.
* For unknown operating systems OTHER will be returned.
* @return {@link OperatingSystem}
*/
public static OperatingSystem get() {
return get(System.getProperty("os.name"));
}

static OperatingSystem get(String osNameSytemProperty) {
String osNameProperty = osNameSytemProperty.toLowerCase(Locale.ROOT);
for (OperatingSystem os : OperatingSystem.values()) {
if (osNameProperty.contains(os.osName)) {
return os;
}
}
return OTHER;
}
}
Loading