From 34042e54627af8c407558d336db9678e8c576b62 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sat, 13 Oct 2018 18:07:24 -0400 Subject: [PATCH] Extract user preferences into a separate class. --- .../gui/view/UserContentPanel.java | 21 ++++---- .../lyndir/masterpassword/model/MPUser.java | 8 ++-- .../model/MPUserPreferences.java | 19 ++++++++ .../model/impl/MPBasicSite.java | 3 +- .../model/impl/MPBasicUser.java | 6 +++ .../model/impl/MPBasicUserPreferences.java | 46 ++++++++++++++++++ .../masterpassword/model/impl/MPFileUser.java | 48 +++++-------------- .../model/impl/MPFileUserPreferences.java | 37 ++++++++++++++ .../model/impl/MPFlatMarshaller.java | 2 +- .../masterpassword/model/impl/MPJSONFile.java | 4 +- 10 files changed, 140 insertions(+), 54 deletions(-) create mode 100644 platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUserPreferences.java create mode 100644 platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUserPreferences.java create mode 100644 platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUserPreferences.java diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java index 222c4967..7ef280c7 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/view/UserContentPanel.java @@ -584,10 +584,13 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener, if (fileUser != null) { components.add( Components.label( "Default Password Type:" ), Components.comboBox( MPResultType.values(), MPResultType::getLongName, - fileUser.getDefaultType(), fileUser::setDefaultType ), + fileUser.getPreferences().getDefaultType(), + fileUser.getPreferences()::setDefaultType ), Components.strut() ); - components.add( Components.checkBox( "Hide Passwords", fileUser.isHidePasswords(), fileUser::setHidePasswords ) ); + components.add( Components.checkBox( "Hide Passwords", + fileUser.getPreferences().isHidePasswords(), + fileUser.getPreferences()::setHidePasswords ) ); } Components.showDialog( this, user.getFullName(), new JOptionPane( Components.panel( @@ -615,14 +618,14 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener, Components.strut() ); components.add( Components.label( "Password Type:" ), - Components.comboBox( MPResultType.values(), type -> getTypeDescription( - type, user.getDefaultType(), user.getAlgorithm().mpw_default_result_type() ), + Components.comboBox( MPResultType.values(), type -> + getTypeDescription( type, user.getPreferences().getDefaultType() ), site.getResultType(), site::setResultType ), Components.strut() ); components.add( Components.label( "Login Type:" ), - Components.comboBox( MPResultType.values(), type -> getTypeDescription( - type, user.getAlgorithm().mpw_default_login_type() ), + Components.comboBox( MPResultType.values(), type -> + getTypeDescription( type, user.getAlgorithm().mpw_default_login_type() ), site.getLoginType(), site::setLoginType ), Components.strut() ); @@ -890,7 +893,7 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener, if ((result == null) || result.isEmpty()) resultField.setText( " " ); - else if (!showLogin && (user instanceof MPFileUser) && ((MPFileUser) user).isHidePasswords()) + else if (!showLogin && user.getPreferences().isHidePasswords()) resultField.setText( EACH_CHARACTER.matcher( result ).replaceAll( "•" ) ); else resultField.setText( result ); @@ -1033,8 +1036,8 @@ public class UserContentPanel extends JPanel implements MasterPassword.Listener, if (!Strings.isNullOrEmpty( queryText )) if (siteItems.stream().noneMatch( MPQuery.Result::isExact )) { MPQuery.Result> selectedItem = sitesModel.getSelectedItem(); - if ((selectedItem != null) && user.equals( selectedItem.getOption().getUser() ) && - queryText.equals( selectedItem.getOption().getSiteName() )) + if ((selectedItem != null) && user.equals( selectedItem.getValue().getUser() ) && + queryText.equals( selectedItem.getValue().getSiteName() )) siteItems.add( selectedItem ); else siteItems.add( MPQuery.Result.allOf( new MPNewSite( user, query.getQuery() ), query.getQuery() ) ); diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUser.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUser.java index 808eb811..7f707f8c 100644 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUser.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUser.java @@ -38,6 +38,9 @@ public interface MPUser> extends Comparable> { @Nonnull String getFullName(); + @Nonnull + MPUserPreferences getPreferences(); + // - Algorithm @Nonnull @@ -45,11 +48,6 @@ public interface MPUser> extends Comparable> { void setAlgorithm(MPAlgorithm algorithm); - @Nullable - default MPResultType getDefaultType() { - return null; - } - @Nullable byte[] getKeyID(); diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUserPreferences.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUserPreferences.java new file mode 100644 index 00000000..d7bab23f --- /dev/null +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/MPUserPreferences.java @@ -0,0 +1,19 @@ +package com.lyndir.masterpassword.model; + +import com.lyndir.masterpassword.MPResultType; +import javax.annotation.Nullable; + + +/** + * @author lhunath, 2018-10-13 + */ +public interface MPUserPreferences { + + MPResultType getDefaultType(); + + void setDefaultType(@Nullable MPResultType defaultType); + + boolean isHidePasswords(); + + void setHidePasswords(boolean hidePasswords); +} diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicSite.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicSite.java index 5abb44c4..3fbf823d 100644 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicSite.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicSite.java @@ -55,8 +55,7 @@ public abstract class MPBasicSite, Q extends MPQuestion> ext this.siteName = siteName; this.algorithm = (algorithm != null)? algorithm: this.user.getAlgorithm(); this.counter = (counter != null)? counter: this.algorithm.mpw_default_counter(); - this.resultType = (resultType != null)? resultType: - ifNotNullElse( this.user.getDefaultType(), this.algorithm.mpw_default_result_type() ); + this.resultType = (resultType != null)? resultType: this.user.getPreferences().getDefaultType(); this.loginType = (loginType != null)? loginType: this.algorithm.mpw_default_login_type(); } diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUser.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUser.java index 80c90d89..86f181ab 100755 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUser.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUser.java @@ -77,6 +77,12 @@ public abstract class MPBasicUser> extends Changeabl return fullName; } + @Nonnull + @Override + public MPUserPreferences getPreferences() { + return new MPBasicUserPreferences>( this ); + } + @Nonnull @Override public MPAlgorithm getAlgorithm() { diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUserPreferences.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUserPreferences.java new file mode 100644 index 00000000..a32363f7 --- /dev/null +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPBasicUserPreferences.java @@ -0,0 +1,46 @@ +package com.lyndir.masterpassword.model.impl; + +import com.lyndir.masterpassword.MPResultType; +import com.lyndir.masterpassword.model.MPUserPreferences; +import javax.annotation.Nullable; + + +/** + * @author lhunath, 2018-10-13 + */ +public class MPBasicUserPreferences> implements MPUserPreferences { + + private final U user; + + @Nullable + private MPResultType defaultType; + private boolean hidePasswords; + + public MPBasicUserPreferences(final U user) { + this.user = user; + } + + protected U getUser() { + return user; + } + + @Override + public MPResultType getDefaultType() { + return (defaultType != null)? defaultType: user.getAlgorithm().mpw_default_result_type(); + } + + @Override + public void setDefaultType(@Nullable final MPResultType defaultType) { + this.defaultType = defaultType; + } + + @Override + public boolean isHidePasswords() { + return hidePasswords; + } + + @Override + public void setHidePasswords(final boolean hidePasswords) { + this.hidePasswords = hidePasswords; + } +} diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUser.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUser.java index c7d8a990..d05ece6d 100755 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUser.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUser.java @@ -20,8 +20,7 @@ package com.lyndir.masterpassword.model.impl; import com.lyndir.lhunath.opal.system.logging.Logger; import com.lyndir.masterpassword.*; -import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException; -import com.lyndir.masterpassword.model.MPUser; +import com.lyndir.masterpassword.model.*; import java.io.File; import java.io.IOException; import javax.annotation.Nonnull; @@ -43,17 +42,16 @@ public class MPFileUser extends MPBasicUser { private File file; private MPMarshalFormat format; private MPMarshaller.ContentMode contentMode; + private ReadableInstant lastUsed; + private boolean complete; - private MPResultType defaultType; - private ReadableInstant lastUsed; - private boolean hidePasswords; - private boolean complete; + private final MPFileUserPreferences preferences; @Nullable public static MPFileUser load(final File file) throws IOException, MPMarshalException { for (final MPMarshalFormat format : MPMarshalFormat.values()) - if (format.matches(file)) + if (format.matches( file )) return format.unmarshaller().readUser( file ); return null; @@ -74,9 +72,8 @@ public class MPFileUser extends MPBasicUser { super( avatar, fullName, algorithm ); this.keyID = (keyID != null)? keyID.clone(): null; - this.defaultType = (defaultType != null)? defaultType: algorithm.mpw_default_result_type(); this.lastUsed = lastUsed; - this.hidePasswords = hidePasswords; + this.preferences = new MPFileUserPreferences( this, defaultType, hidePasswords ); this.format = format; this.contentMode = contentMode; @@ -92,6 +89,12 @@ public class MPFileUser extends MPBasicUser { return (keyID == null)? null: keyID.clone(); } + @Nonnull + @Override + public MPUserPreferences getPreferences() { + return preferences; + } + @Override public void setAlgorithm(final MPAlgorithm algorithm) { if (!algorithm.equals( getAlgorithm() ) && (keyID != null)) { @@ -128,19 +131,6 @@ public class MPFileUser extends MPBasicUser { setChanged(); } - @Override - public MPResultType getDefaultType() { - return defaultType; - } - - public void setDefaultType(final MPResultType defaultType) { - if (this.defaultType == defaultType) - return; - - this.defaultType = defaultType; - setChanged(); - } - public ReadableInstant getLastUsed() { return lastUsed; } @@ -150,18 +140,6 @@ public class MPFileUser extends MPBasicUser { setChanged(); } - public boolean isHidePasswords() { - return hidePasswords; - } - - public void setHidePasswords(final boolean hidePasswords) { - if (Objects.equals( this.hidePasswords, hidePasswords )) - return; - - this.hidePasswords = hidePasswords; - setChanged(); - } - protected boolean isComplete() { return complete; } @@ -193,7 +171,7 @@ public class MPFileUser extends MPBasicUser { */ public void migrateTo(final File path, final MPMarshalFormat newFormat) { MPMarshalFormat oldFormat = format; - File oldFile = file, newFile = new File( path, getFullName() + newFormat.fileSuffix() ); + File oldFile = file, newFile = new File( path, getFullName() + newFormat.fileSuffix() ); // If the format hasn't changed, migrate by moving the file: the contents doesn't need to change. if ((oldFormat == newFormat) && !oldFile.equals( newFile ) && oldFile.exists()) diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUserPreferences.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUserPreferences.java new file mode 100644 index 00000000..b800f0c6 --- /dev/null +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFileUserPreferences.java @@ -0,0 +1,37 @@ +package com.lyndir.masterpassword.model.impl; + +import com.lyndir.masterpassword.MPResultType; +import java.util.Objects; +import javax.annotation.Nullable; + + +/** + * @author lhunath, 2018-10-13 + */ +public class MPFileUserPreferences extends MPBasicUserPreferences { + + public MPFileUserPreferences(final MPFileUser user, @Nullable final MPResultType defaultType, final boolean hidePasswords) { + super( user ); + + setDefaultType( defaultType ); + setHidePasswords( hidePasswords ); + } + + @Override + public void setDefaultType(@Nullable final MPResultType defaultType) { + if (getDefaultType() == defaultType) + return; + + super.setDefaultType( defaultType ); + getUser().setChanged(); + } + + @Override + public void setHidePasswords(final boolean hidePasswords) { + if (Objects.equals( isHidePasswords(), hidePasswords )) + return; + + super.setHidePasswords( hidePasswords ); + getUser().setChanged(); + } +} diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFlatMarshaller.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFlatMarshaller.java index e96c50c9..b3cca47c 100644 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFlatMarshaller.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPFlatMarshaller.java @@ -56,7 +56,7 @@ public class MPFlatMarshaller implements MPMarshaller { content.append( "# Avatar: " ).append( user.getAvatar() ).append( '\n' ); content.append( "# Key ID: " ).append( user.exportKeyID() ).append( '\n' ); content.append( "# Algorithm: " ).append( user.getAlgorithm().version().toInt() ).append( '\n' ); - content.append( "# Default Type: " ).append( user.getDefaultType().getType() ).append( '\n' ); + content.append( "# Default Type: " ).append( user.getPreferences().getDefaultType().getType() ).append( '\n' ); content.append( "# Passwords: " ).append( user.getContentMode().name() ).append( '\n' ); content.append( "##\n" ); content.append( "#\n" ); diff --git a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPJSONFile.java b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPJSONFile.java index 65582d51..5b64350e 100644 --- a/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPJSONFile.java +++ b/platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/impl/MPJSONFile.java @@ -77,10 +77,10 @@ public class MPJSONFile extends MPJSONAnyObject { user.avatar = modelUser.getAvatar(); user.full_name = modelUser.getFullName(); user.last_used = MPModelConstants.dateTimeFormatter.print( modelUser.getLastUsed() ); - user.hide_passwords = modelUser.isHidePasswords(); user.key_id = modelUser.exportKeyID(); user.algorithm = modelUser.getAlgorithm().version(); - user.default_type = modelUser.getDefaultType(); + user.default_type = modelUser.getPreferences().getDefaultType(); + user.hide_passwords = modelUser.getPreferences().isHidePasswords(); // Section "sites" sites = new LinkedHashMap<>();