-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; version 2
-
-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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import java.io.UnsupportedEncodingException;
-import java.util.UUID;
-
-
-/**
- * Structure containing information about one entry.
- *
- *
- * One entry: [FIELDTYPE(FT)][FIELDSIZE(FS)][FIELDDATA(FD)]
- * [FT+FS+(FD)][FT+FS+(FD)][FT+FS+(FD)][FT+FS+(FD)][FT+FS+(FD)]...
- *
- * [ 2 bytes] FIELDTYPE
- * [ 4 bytes] FIELDSIZE, size of FIELDDATA in bytes
- * [ n bytes] FIELDDATA, n = FIELDSIZE
- *
- * Notes:
- * - Strings are stored in UTF-8 encoded form and are null-terminated.
- * - FIELDTYPE can be one of the FT_ constants.
- *
- *
- * @author Naomaru Itoi
- * @author Bill Zwicky
- * @author Dominik Reichl
- * @author Jeremy Jamet
- */
-public class PwEntryV3 extends PwEntry {
-
- /** Size of byte buffer needed to hold this struct. */
- private static final String PMS_ID_BINDESC = "bin-stream";
- private static final String PMS_ID_TITLE = "Meta-Info";
- private static final String PMS_ID_USER = "SYSTEM";
- private static final String PMS_ID_URL = "$";
-
- private String title;
- private String username;
- private byte[] password;
- private String url;
- private String additional;
- /** A string describing what is in pBinaryData */
- private String binaryDesc;
- private byte[] binaryData;
-
- public PwEntryV3() {
- super();
- }
-
- public PwEntryV3(PwGroupV3 p) {
- construct(p);
- }
-
- public PwEntryV3(Parcel in) {
- super(in);
- title = in.readString();
- username = in.readString();
- in.readByteArray(password);
- url = in.readString();
- additional = in.readString();
- binaryDesc = in.readString();
- in.readByteArray(binaryData);
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeString(title);
- dest.writeString(username);
- dest.writeByteArray(password);
- dest.writeString(url);
- dest.writeString(additional);
- dest.writeString(binaryDesc);
- dest.writeByteArray(binaryData);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwEntryV3 createFromParcel(Parcel in) {
- return new PwEntryV3(in);
- }
-
- @Override
- public PwEntryV3[] newArray(int size) {
- return new PwEntryV3[size];
- }
- };
-
- protected void updateWith(PwEntryV3 source) {
- super.assign(source);
-
- title = source.title;
- username = source.username;
- int passLen = source.password.length;
- password = new byte[passLen];
- System.arraycopy(source.password, 0, password, 0, passLen);
- url = source.url;
- additional = source.additional;
-
- binaryDesc = source.binaryDesc;
- if ( source.binaryData != null ) {
- int descLen = source.binaryData.length;
- binaryData = new byte[descLen];
- System.arraycopy(source.binaryData, 0, binaryData, 0, descLen);
- }
- }
-
- @Override
- public PwEntryV3 clone() {
- // Attributes in parent
- PwEntryV3 newEntry = (PwEntryV3) super.clone();
-
- // Attributes here
- // newEntry.parent stay the same in copy
- // newEntry.groupId stay the same in copy
- // newEntry.title stay the same in copy
- // newEntry.username stay the same in copy
- if (password != null) {
- int passLen = password.length;
- password = new byte[passLen];
- System.arraycopy(password, 0, newEntry.password, 0, passLen);
- }
- // newEntry.url stay the same in copy
- // newEntry.additional stay the same in copy
-
- // newEntry.binaryDesc stay the same in copy
- if ( binaryData != null ) {
- int descLen = binaryData.length;
- newEntry.binaryData = new byte[descLen];
- System.arraycopy(binaryData, 0, newEntry.binaryData, 0, descLen);
- }
-
- return newEntry;
- }
-
- public void setGroupId(int groupId) {
- this.parent = new PwGroupV3();
- this.parent.setGroupId(groupId);
- }
-
- @Override
- public String getUsername() {
- if (username == null) {
- return "";
- }
- return username;
- }
-
- @Override
- public void setUsername(String user) {
- username = user;
- }
-
- @Override
- public String getTitle() {
- return title;
- }
-
- @Override
- public void setTitle(String title) {
- this.title = title;
- }
-
- @Override
- public String getNotes() {
- return additional;
- }
-
- @Override
- public void setNotes(String notes) {
- additional = notes;
- }
-
- @Override
- public String getUrl() {
- return url;
- }
-
- @Override
- public void setUrl(String url) {
- this.url = url;
- }
-
- public void populateBlankFields(PwDatabaseV3 db) {
- // TODO verify and remove
- if (icon == null) {
- icon = db.getIconFactory().getKeyIcon();
- }
-
- if (username == null) {
- username = "";
- }
-
- if (password == null) {
- password = new byte[0];
- }
-
- if (uuid == null) {
- uuid = UUID.randomUUID();
- }
-
- if (title == null) {
- title = "";
- }
-
- if (url == null) {
- url = "";
- }
-
- if (additional == null) {
- additional = "";
- }
-
- if (binaryDesc == null) {
- binaryDesc = "";
- }
-
- if (binaryData == null) {
- binaryData = new byte[0];
- }
- }
-
- /**
- * @return the actual password byte array.
- */
- @Override
- public String getPassword() {
- if (password == null) {
- return "";
- }
- return new String(password);
- }
-
- public byte[] getPasswordBytes() {
- return password;
- }
-
- /**
- * fill byte array
- */
- private static void fill(byte[] array, byte value) {
- for (int i=0; i.
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import com.kunzisoft.keepass.database.security.ProtectedBinary;
-import com.kunzisoft.keepass.database.security.ProtectedString;
-import com.kunzisoft.keepass.utils.MemUtil;
-import com.kunzisoft.keepass.utils.SprEngineV4;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class PwEntryV4 extends PwEntry implements ITimeLogger {
-
- public static final String STR_TITLE = "Title";
- public static final String STR_USERNAME = "UserName";
- public static final String STR_PASSWORD = "Password";
- public static final String STR_URL = "URL";
- public static final String STR_NOTES = "Notes";
-
- // To decode each field not parcelable
- private transient PwDatabaseV4 mDatabase = null;
- private transient boolean mDecodeRef = false;
-
- private PwIconCustom customIcon = PwIconCustom.ZERO;
- private long usageCount = 0;
- private PwDate parentGroupLastMod = new PwDate();
- private Map customData = new HashMap<>();
- private ExtraFields fields = new ExtraFields();
- private HashMap binaries = new HashMap<>();
- private String foregroundColor = "";
- private String backgroupColor = "";
- private String overrideURL = "";
- private AutoType autoType = new AutoType();
- private ArrayList history = new ArrayList<>();
- private String url = "";
- private String additional = "";
- private String tags = "";
-
- public PwEntryV4() {
- super();
- }
-
- public PwEntryV4(PwGroupV4 p) {
- construct(p);
- }
-
- public void updateWith(PwEntryV4 source) {
- super.assign(source);
- customIcon = source.customIcon;
- usageCount = source.usageCount;
- parentGroupLastMod = source.parentGroupLastMod;
- customData.clear();
- customData.putAll(source.customData); // Add all custom elements in map
- fields = source.fields;
- binaries = source.binaries;
- foregroundColor = source.foregroundColor;
- backgroupColor = source.backgroupColor;
- overrideURL = source.overrideURL;
- autoType = source.autoType;
- history = source.history;
- url = source.url;
- additional = source.additional;
- tags = source.tags;
- }
-
- public PwEntryV4(Parcel in) {
- super(in);
- customIcon = in.readParcelable(PwIconCustom.class.getClassLoader());
- usageCount = in.readLong();
- parentGroupLastMod = in.readParcelable(PwDate.class.getClassLoader());
- customData = MemUtil.readStringParcelableMap(in);
- fields = in.readParcelable(ExtraFields.class.getClassLoader());
- binaries = MemUtil.readStringParcelableMap(in, ProtectedBinary.class);
- foregroundColor = in.readString();
- backgroupColor = in.readString();
- overrideURL = in.readString();
- autoType = in.readParcelable(AutoType.class.getClassLoader());
- history = in.readArrayList(PwEntryV4.class.getClassLoader()); // TODO verify
- url = in.readString();
- additional = in.readString();
- tags = in.readString();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeParcelable(customIcon, flags);
- dest.writeLong(usageCount);
- dest.writeParcelable(parentGroupLastMod, flags);
- MemUtil.writeStringParcelableMap(dest, customData);
- dest.writeParcelable(fields, flags);
- // TODO MemUtil.writeStringParcelableMap(dest, flags, binaries);
- dest.writeString(foregroundColor);
- dest.writeString(backgroupColor);
- dest.writeString(overrideURL);
- dest.writeParcelable(autoType, flags);
- dest.writeList(history);
- dest.writeString(url);
- dest.writeString(additional);
- dest.writeString(tags);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwEntryV4 createFromParcel(Parcel in) {
- return new PwEntryV4(in);
- }
-
- @Override
- public PwEntryV4[] newArray(int size) {
- return new PwEntryV4[size];
- }
- };
-
- @SuppressWarnings("unchecked")
- @Override
- public PwEntryV4 clone() {
- // Attributes in parent
- PwEntryV4 newEntry = (PwEntryV4) super.clone();
-
- // Attributes here
- newEntry.customIcon = new PwIconCustom(this.customIcon);
- // newEntry.usageCount stay the same in copy
- newEntry.parentGroupLastMod = this.parentGroupLastMod.clone();
-
- newEntry.fields = this.fields.clone();
- // TODO customData make copy from hashmap
- newEntry.binaries = (HashMap) this.binaries.clone();
- // newEntry.foregroundColor stay the same in copy
- // newEntry.backgroupColor stay the same in copy
- // newEntry.overrideURL stay the same in copy
- newEntry.autoType = autoType.clone();
- newEntry.history = (ArrayList) this.history.clone();
-
- // newEntry.url stay the same in copy
- // newEntry.additional stay the same in copy
- // newEntry.tags stay the same in copy
-
- return newEntry;
- }
-
- @Override
- public void startToManageFieldReferences(PwDatabase db) {
- this.mDatabase = (PwDatabaseV4) db;
- this.mDecodeRef = true;
- }
-
- @Override
- public void stopToManageFieldReferences() {
- this.mDatabase = null;
- this.mDecodeRef = false;
- }
-
- private String decodeRefKey(boolean decodeRef, String key) {
- String text = getProtectedStringValue(key);
- if (decodeRef) {
- text = decodeRef(text, mDatabase);
- }
- return text;
- }
-
- private String decodeRef(String text, PwDatabase db) {
- if (db == null) { return text; }
- SprEngineV4 spr = new SprEngineV4();
- return spr.compile(text, this, db);
- }
-
- @Override
- public String getUsername() {
- return decodeRefKey(mDecodeRef, STR_USERNAME);
- }
-
- @Override
- public String getTitle() {
- return decodeRefKey(mDecodeRef, STR_TITLE);
- }
-
- @Override
- public String getPassword() {
- return decodeRefKey(mDecodeRef, STR_PASSWORD);
- }
-
- @Override
- public void setTitle(String title) {
- boolean protect = (mDatabase != null) && mDatabase.getMemoryProtection().protectTitle;
- setProtectedString(STR_TITLE, title, protect);
- }
-
- @Override
- public void setUsername(String user) {
- boolean protect = (mDatabase != null) && mDatabase.getMemoryProtection().protectUserName;
- setProtectedString(STR_USERNAME, user, protect);
- }
-
- @Override
- public void setPassword(String pass) {
- boolean protect = (mDatabase != null) && mDatabase.getMemoryProtection().protectPassword;
- setProtectedString(STR_PASSWORD, pass, protect);
- }
-
- @Override
- public void setUrl(String url) {
- boolean protect = (mDatabase != null) && mDatabase.getMemoryProtection().protectUrl;
- setProtectedString(STR_URL, url, protect);
- }
-
- @Override
- public void setNotes(String notes) {
- boolean protect = (mDatabase != null) && mDatabase.getMemoryProtection().protectNotes;
- setProtectedString(STR_NOTES, notes, protect);
- }
-
- public String getProtectedStringValue(String key) {
- return fields.getProtectedStringValue(key);
- }
-
- public void setProtectedString(String key, String value, boolean protect) {
- fields.putProtectedString(key, value, protect);
- }
-
- public PwDate getLocationChanged() {
- return parentGroupLastMod;
- }
-
- public long getUsageCount() {
- return usageCount;
- }
-
- public void setLocationChanged(PwDate date) {
- parentGroupLastMod = date;
- }
-
- public void setUsageCount(long count) {
- usageCount = count;
- }
-
- @Override
- public String getNotes() {
- return decodeRefKey(mDecodeRef, STR_NOTES);
- }
-
- @Override
- public String getUrl() {
- return decodeRefKey(mDecodeRef, STR_URL);
- }
-
- @Override
- public PwIcon getIcon() {
- if (customIcon == null || customIcon.isUnknown()) {
- return super.getIcon();
- } else {
- return customIcon;
- }
- }
-
- public void setIconCustom(PwIconCustom icon) {
- this.customIcon = icon;
- }
-
- public PwIconCustom getIconCustom() {
- return customIcon;
- }
-
- public void setIconStandard(PwIconStandard icon) {
- this.icon = icon;
- this.customIcon = PwIconCustom.ZERO;
- }
-
- @Override
- public boolean allowExtraFields() {
- return true;
- }
-
- public ExtraFields getFields() {
- return fields;
- }
-
- public void addExtraField(String label, ProtectedString value) {
- fields.putProtectedString(label, value);
- }
-
- @Override
- public void removeAllCustomFields() {
- fields.removeAllCustomFields();
- }
-
- public HashMap getBinaries() {
- return binaries;
- }
-
- public void putProtectedBinary(String key, ProtectedBinary value) {
- binaries.put(key, value);
- }
-
- public String getForegroundColor() {
- return foregroundColor;
- }
-
- public void setForegroundColor(String color) {
- this.foregroundColor = color;
- }
-
- public String getBackgroupColor() {
- return backgroupColor;
- }
-
- public void setBackgroupColor(String color) {
- this.backgroupColor = color;
- }
-
- public String getOverrideURL() {
- return overrideURL;
- }
-
- public void setOverrideURL(String overrideURL) {
- this.overrideURL = overrideURL;
- }
-
- public AutoType getAutoType() {
- return autoType;
- }
-
- public void setAutoType(AutoType autoType) {
- this.autoType = autoType;
- }
-
- public ArrayList getHistory() {
- return history;
- }
-
- public void setHistory(ArrayList history) {
- this.history = history;
- }
-
- public void addToHistory(PwEntryV4 entry) {
- history.add(entry);
- }
-
- public int sizeOfHistory() {
- return history.size();
- }
-
- public String getAdditional() {
- return additional;
- }
-
- public void setAdditional(String additional) {
- this.additional = additional;
- }
-
- public String getTags() {
- return tags;
- }
-
- public void setTags(String tags) {
- this.tags = tags;
- }
-
- public void putCustomData(String key, String value) {
- customData.put(key, value);
- }
-
- public boolean containsCustomData() {
- return customData.size() > 0;
- }
-
- private static final long FIXED_LENGTH_SIZE = 128; // Approximate fixed length size
- public long getSize() {
- long size = FIXED_LENGTH_SIZE;
-
- for (Entry pair : fields.getListOfAllFields().entrySet()) {
- size += pair.getKey().length();
- size += pair.getValue().length();
- }
-
- for (Entry pair : binaries.entrySet()) {
- size += pair.getKey().length();
- size += pair.getValue().length();
- }
-
- size += autoType.defaultSequence.length();
- for (Entry pair : autoType.entrySet()) {
- size += pair.getKey().length();
- size += pair.getValue().length();
- }
-
- for (PwEntryV4 entry : history) {
- size += entry.getSize();
- }
-
- size += overrideURL.length();
- size += tags.length();
-
- return size;
- }
-
- @Override
- public void createBackup(PwDatabase db) {
- super.createBackup(db);
-
- PwEntryV4 copy = clone();
- copy.history = new ArrayList<>();
- history.add(copy);
-
- if (db != null)
- if (db instanceof PwDatabaseV4)
- maintainBackups((PwDatabaseV4) db);
- }
-
- private boolean maintainBackups(PwDatabaseV4 db) {
- boolean deleted = false;
-
- int maxItems = db.getHistoryMaxItems();
- if (maxItems >= 0) {
- while (history.size() > maxItems) {
- removeOldestBackup();
- deleted = true;
- }
- }
-
- long maxSize = db.getHistoryMaxSize();
- if (maxSize >= 0) {
- while(true) {
- long histSize = 0;
- for (PwEntryV4 entry : history) {
- histSize += entry.getSize();
- }
-
- if (histSize > maxSize) {
- removeOldestBackup();
- deleted = true;
- } else {
- break;
- }
- }
- }
-
- return deleted;
- }
-
- private void removeOldestBackup() {
- Date min = null;
- int index = -1;
-
- for (int i = 0; i < history.size(); i++) {
- PwEntry entry = history.get(i);
- Date lastMod = entry.getLastModificationTime().getDate();
- if ((min == null) || lastMod.before(min)) {
- index = i;
- min = lastMod;
- }
- }
-
- if (index != -1) {
- history.remove(index);
- }
- }
-
- @Override
- public void touch(boolean modified, boolean touchParents) {
- super.touch(modified, touchParents);
- ++usageCount;
- }
-
- @Override
- public void touchLocation() {
- parentGroupLastMod = new PwDate();
- }
-
- public boolean isSearchingEnabled() {
- if (parent != null) {
- return parent.isSearchingEnabled();
- }
- return PwGroupV4.DEFAULT_SEARCHING_ENABLED;
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java
deleted file mode 100644
index 6f97bd489..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class PwGroup
- extends PwNode {
-
- protected String name = "";
-
- // TODO verify children not needed
- transient protected List childGroups = new ArrayList<>();
- transient protected List childEntries = new ArrayList<>();
-
- protected PwGroup() {
- super();
- }
-
- protected PwGroup(Parcel in) {
- super(in);
- name = in.readString();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeString(name);
- }
-
- @Override
- public PwGroup clone() {
- // name is clone automatically (IMMUTABLE)
- return (PwGroup) super.clone();
- }
-
- protected void assign(PwGroup source) {
- super.assign(source);
- name = source.name;
- }
-
- public List getChildGroups() {
- return childGroups;
- }
-
- public List getChildEntries() {
- return childEntries;
- }
-
- public void setGroups(List groups) {
- childGroups = groups;
- }
-
- public void setEntries(List entries) {
- childEntries = entries;
- }
-
- public void addChildGroup(GroupG group) {
- this.childGroups.add(group);
- }
-
- public void addChildEntry(EntryE entry) {
- this.childEntries.add(entry);
- }
-
- public GroupG getChildGroupAt(int number) {
- return this.childGroups.get(number);
- }
-
- public EntryE getChildEntryAt(int number) {
- return this.childEntries.get(number);
- }
-
- public void removeChildGroup(GroupG group) {
- this.childGroups.remove(group);
- }
-
- public void removeChildEntry(EntryE entry) {
- this.childEntries.remove(entry);
- }
-
- public int numbersOfChildGroups() {
- return childGroups.size();
- }
-
- public int numbersOfChildEntries() {
- return childEntries.size();
- }
-
- @Override
- public Type getType() {
- return Type.GROUP;
- }
-
- /**
- * Filter MetaStream entries and return children
- * @return List of direct children (one level below) as PwNode
- */
- public List getDirectChildren() {
- List children = new ArrayList<>();
- children.addAll(childGroups);
- for(EntryE child : childEntries) {
- if (!child.isMetaStream())
- children.add(child);
- }
- return children;
- }
-
- public abstract PwGroupId getId();
- public abstract void setId(PwGroupId id);
-
- @Override
- protected String getVisualTitle() {
- return getTitle();
- }
-
- @Override
- public String getTitle() {
- return getName();
- }
-
- /**
- * The same thing as {@link #getTitle()}
- */
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public boolean allowAddEntryIfIsRoot() {
- return false;
- }
-
- public boolean preOrderTraverseTree(GroupHandler groupHandler,
- EntryHandler entryHandler) {
- if (entryHandler != null) {
- for (EntryE entry : childEntries) {
- if (!entryHandler.operate(entry)) return false;
- }
- }
-
- for (GroupG group : childGroups) {
- if ((groupHandler != null) && !groupHandler.operate(group)) return false;
- group.preOrderTraverseTree(groupHandler, entryHandler);
- }
-
- return true;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- PwGroup pwGroup = (PwGroup) o;
- return isSameType(pwGroup)
- && (getId() != null ? getId().equals(pwGroup.getId()) : pwGroup.getId() == null);
- }
-
- @Override
- public int hashCode() {
- PwGroupId groupId = getId();
- return groupId != null ? groupId.hashCode() : 0;
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java
deleted file mode 100644
index 24cb9126f..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-public class PwGroupIdV3 extends PwGroupId {
-
- private int id;
-
- public PwGroupIdV3(int groupId) {
- super();
- this.id = groupId;
- }
-
- public PwGroupIdV3(Parcel in) {
- super(in);
- id = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeInt(id);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwGroupIdV3 createFromParcel(Parcel in) {
- return new PwGroupIdV3(in);
- }
-
- @Override
- public PwGroupIdV3[] newArray(int size) {
- return new PwGroupIdV3[size];
- }
- };
-
- @Override
- public boolean equals(Object compare) {
- if ( ! (compare instanceof PwGroupIdV3) ) {
- return false;
- }
- PwGroupIdV3 cmp = (PwGroupIdV3) compare;
- return id == cmp.id;
- }
-
- @Override
- public int hashCode() {
- Integer i = id;
- return i.hashCode();
- }
-
- public int getId() {
- return id;
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java
deleted file mode 100644
index 0617e5dd8..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2018 Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import java.util.UUID;
-
-public class PwGroupIdV4 extends PwGroupId {
-
- private UUID uuid;
-
- public PwGroupIdV4(UUID uuid) {
- super();
- this.uuid = uuid;
- }
-
- public PwGroupIdV4(Parcel in) {
- super(in);
- uuid = (UUID) in.readSerializable();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeSerializable(uuid);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwGroupIdV4 createFromParcel(Parcel in) {
- return new PwGroupIdV4(in);
- }
-
- @Override
- public PwGroupIdV4[] newArray(int size) {
- return new PwGroupIdV4[size];
- }
- };
-
- @Override
- public boolean equals(Object id) {
- if ( ! (id instanceof PwGroupIdV4) ) {
- return false;
- }
- PwGroupIdV4 v4 = (PwGroupIdV4) id;
- return uuid.equals(v4.uuid);
- }
-
- @Override
- public int hashCode() {
- return uuid.hashCode();
- }
-
- public UUID getId() {
- return uuid;
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java
deleted file mode 100644
index 2da96b601..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
-*/
-
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-public class PwGroupV3 extends PwGroup {
-
- // for tree traversing
- private int groupId;
- private int level = 0; // short
- /** Used by KeePass internally, don't use */
- private int flags;
-
- public PwGroupV3() {
- super();
- }
-
- public PwGroupV3(Parcel in) {
- super(in);
- groupId = in.readInt();
- level = in.readInt();
- flags = in.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeInt(groupId);
- dest.writeInt(level);
- dest.writeInt(flags);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwGroupV3 createFromParcel(Parcel in) {
- return new PwGroupV3(in);
- }
-
- @Override
- public PwGroupV3[] newArray(int size) {
- return new PwGroupV3[size];
- }
- };
-
- public PwGroupV3(PwGroupV3 p) {
- construct(p);
- }
-
- protected void updateWith(PwGroupV3 source) {
- super.assign(source);
- groupId = source.groupId;
- level = source.level;
- flags = source.flags;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public PwGroupV3 clone() {
- // newGroup.groupId stay the same in copy
- // newGroup.level stay the same in copy
- // newGroup.flags stay the same in copy
- return (PwGroupV3) super.clone();
- }
-
- @Override
- public void setParent(PwGroupV3 parent) {
- super.setParent(parent);
- level = this.parent.getLevel() + 1;
- }
-
- public int getGroupId() {
- return groupId;
- }
-
- public void setGroupId(int groupId) {
- this.groupId = groupId;
- }
-
- public int getLevel() {
- return level;
- }
-
- public void setLevel(int level) {
- this.level = level;
- }
-
- @Override
- public PwGroupId getId() {
- return new PwGroupIdV3(groupId);
- }
-
- @Override
- public void setId(PwGroupId id) {
- PwGroupIdV3 id3 = (PwGroupIdV3) id;
- groupId = id3.getId();
- }
-
- public int getFlags() {
- return flags;
- }
-
- public void setFlags(int flags) {
- this.flags = flags;
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- public void populateBlankFields(PwDatabaseV3 db) {
- // TODO populate blanck field
- if (icon == null) {
- icon = db.getIconFactory().getFolderIcon();
- }
-
- if (name == null) {
- name = "";
- }
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java
deleted file mode 100644
index e1055c3ce..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import com.kunzisoft.keepass.utils.MemUtil;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-public class PwGroupV4 extends PwGroup implements ITimeLogger {
-
- public static final boolean DEFAULT_SEARCHING_ENABLED = true;
-
- private UUID uuid = PwDatabase.UUID_ZERO;
- private PwIconCustom customIcon = PwIconCustom.ZERO;
- private long usageCount = 0;
- private PwDate parentGroupLastMod = new PwDate();
- private Map customData = new HashMap<>();
- private boolean expires = false;
- private String notes = "";
- private boolean isExpanded = true;
- private String defaultAutoTypeSequence = "";
- private Boolean enableAutoType = null;
- private Boolean enableSearching = null;
- private UUID lastTopVisibleEntry = PwDatabase.UUID_ZERO;
-
- public PwGroupV4() {
- super();
- }
-
- public PwGroupV4(PwGroupV4 p) {
- construct(p);
- parentGroupLastMod = new PwDate();
- }
-
- public PwGroupV4(String name, PwIconStandard icon) {
- this.uuid = UUID.randomUUID();
- this.name = name;
- this.icon = icon;
- }
-
- public PwGroupV4(Parcel in) {
- super(in);
- uuid = (UUID) in.readSerializable();
- customIcon = in.readParcelable(PwIconCustom.class.getClassLoader());
- usageCount = in.readLong();
- parentGroupLastMod = in.readParcelable(PwDate.class.getClassLoader());
- // TODO customData = MemUtil.readStringParcelableMap(in);
- expires = in.readByte() != 0;
- notes = in.readString();
- isExpanded = in.readByte() != 0;
- defaultAutoTypeSequence = in.readString();
- byte autoTypeByte = in.readByte();
- enableAutoType = (autoTypeByte == -1) ? null : autoTypeByte != 0;
- byte enableSearchingByte = in.readByte();
- enableSearching = (enableSearchingByte == -1) ? null : enableSearchingByte != 0;
- lastTopVisibleEntry = (UUID) in.readSerializable();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeSerializable(uuid);
- dest.writeParcelable(customIcon, flags);
- dest.writeLong(usageCount);
- dest.writeParcelable(parentGroupLastMod, flags);
- // TODO MemUtil.writeStringParcelableMap(dest, customData);
- dest.writeByte((byte) (expires ? 1 : 0));
- dest.writeString(notes);
- dest.writeByte((byte) (isExpanded ? 1 : 0));
- dest.writeString(defaultAutoTypeSequence);
- dest.writeByte((byte) (enableAutoType == null ? -1 : (enableAutoType ? 1 : 0)));
- dest.writeByte((byte) (enableAutoType == null ? -1 : (enableAutoType ? 1 : 0)));
- dest.writeSerializable(lastTopVisibleEntry);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwGroupV4 createFromParcel(Parcel in) {
- return new PwGroupV4(in);
- }
-
- @Override
- public PwGroupV4[] newArray(int size) {
- return new PwGroupV4[size];
- }
- };
-
- protected void updateWith(PwGroupV4 source) {
- super.assign(source);
- uuid = source.uuid;
- customIcon = source.customIcon;
- usageCount = source.usageCount;
- parentGroupLastMod = source.parentGroupLastMod;
- customData = source.customData;
-
- expires = source.expires;
-
- notes = source.notes;
- isExpanded = source.isExpanded;
- defaultAutoTypeSequence = source.defaultAutoTypeSequence;
- enableAutoType = source.enableAutoType;
- enableSearching = source.enableSearching;
- lastTopVisibleEntry = source.lastTopVisibleEntry;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public PwGroupV4 clone() {
- // Attributes in parent
- PwGroupV4 newGroup = (PwGroupV4) super.clone();
-
- // Attributes here
- // newGroup.uuid stay the same in copy
- newGroup.customIcon = new PwIconCustom(this.customIcon);
- // newGroup.usageCount stay the same in copy
- newGroup.parentGroupLastMod = this.parentGroupLastMod.clone();
- // TODO customData make copy from hashmap newGroup.customData = (HashMap) this.customData.clone();
-
- // newGroup.expires stay the same in copy
-
- // newGroup.notes stay the same in copy
- // newGroup.isExpanded stay the same in copy
- // newGroup.defaultAutoTypeSequence stay the same in copy
- // newGroup.enableAutoType stay the same in copy
- // newGroup.enableSearching stay the same in copy
- // newGroup.lastTopVisibleEntry stay the same in copy
-
- return newGroup;
- }
-
- public void addGroup(PwGroupV4 subGroup) {
- if ( subGroup == null ) throw new RuntimeException("subGroup");
- childGroups.add(subGroup);
- subGroup.parent = this;
- }
-
- public void addEntry(PwEntryV4 pe) {
- assert(pe != null);
- addChildEntry(pe);
- pe.setParent(this);
- }
-
- public UUID getUUID() {
- return uuid;
- }
-
- public void setUUID(UUID uuid) {
- this.uuid = uuid;
- }
-
- @Override
- public PwGroupId getId() {
- return new PwGroupIdV4(uuid);
- }
-
- @Override
- public void setId(PwGroupId id) {
- PwGroupIdV4 id4 = (PwGroupIdV4) id;
- uuid = id4.getId();
- }
-
- @Override
- public PwDate getLocationChanged() {
- return parentGroupLastMod;
- }
-
- @Override
- public void setLocationChanged(PwDate date) {
- parentGroupLastMod = date;
- }
-
- @Override
- public long getUsageCount() {
- return usageCount;
- }
-
- @Override
- public void setUsageCount(long count) {
- usageCount = count;
- }
-
- @Override
- public boolean isExpires() {
- return expires;
- }
-
- @Override
- public void setExpires(boolean exp) {
- expires = exp;
- }
-
- @Override
- public boolean allowAddEntryIfIsRoot() {
- return true;
- }
-
- @Override
- public PwIcon getIcon() {
- if (customIcon == null || customIcon.getUUID().equals(PwDatabase.UUID_ZERO)) {
- return super.getIcon();
- } else {
- return customIcon;
- }
- }
-
- public PwIconCustom getIconCustom() {
- return customIcon;
- }
-
- public void setIconCustom(PwIconCustom icon) {
- this.customIcon = icon;
- }
-
- public void setIconStandard(PwIconStandard icon) { // TODO Encapsulate with PwEntryV4
- this.icon = icon;
- this.customIcon = PwIconCustom.ZERO;
- }
-
- public void putCustomData(String key, String value) {
- customData.put(key, value);
- }
-
- public boolean containsCustomData() {
- return customData.size() > 0;
- }
-
- public String getNotes() {
- return notes;
- }
-
- public void setNotes(String notes) {
- this.notes = notes;
- }
-
- public boolean isExpanded() {
- return isExpanded;
- }
-
- public void setExpanded(boolean expanded) {
- isExpanded = expanded;
- }
-
- public String getDefaultAutoTypeSequence() {
- return defaultAutoTypeSequence;
- }
-
- public void setDefaultAutoTypeSequence(String defaultAutoTypeSequence) {
- this.defaultAutoTypeSequence = defaultAutoTypeSequence;
- }
-
- public Boolean getEnableAutoType() {
- return enableAutoType;
- }
-
- public void setEnableAutoType(Boolean enableAutoType) {
- this.enableAutoType = enableAutoType;
- }
-
- public Boolean getEnableSearching() {
- return enableSearching;
- }
-
- public void setEnableSearching(Boolean enableSearching) {
- this.enableSearching = enableSearching;
- }
-
- public UUID getLastTopVisibleEntry() {
- return lastTopVisibleEntry;
- }
-
- public void setLastTopVisibleEntry(UUID lastTopVisibleEntry) {
- this.lastTopVisibleEntry = lastTopVisibleEntry;
- }
-
- public boolean isSearchingEnabled() {
- PwGroupV4 group = this;
- while (group != null) {
- Boolean search = group.enableSearching;
- if (search != null) {
- return search;
- }
- group = group.parent;
- }
-
- // If we get to the root tree and its null, default to true
- return true;
- }
-
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java
deleted file mode 100644
index a92d9cdad..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-import java.util.UUID;
-
-public class PwIconCustom extends PwIcon {
- public static final PwIconCustom ZERO = new PwIconCustom(PwDatabase.UUID_ZERO, new byte[0]);
-
- private final UUID uuid;
- transient private byte[] imageData;
-
- public PwIconCustom(UUID uuid, byte[] data) {
- super();
- this.uuid = uuid;
- this.imageData = data;
- }
-
- public PwIconCustom(PwIconCustom icon) {
- super();
- uuid = icon.uuid;
- imageData = icon.imageData;
- }
-
- protected PwIconCustom(Parcel in) {
- super(in);
- uuid = (UUID) in.readSerializable();
- // TODO Take too much memories
- // in.readByteArray(imageData);
- }
-
- @Override
- public boolean isUnknown() {
- return uuid == null || this.equals(ZERO);
- }
-
- public UUID getUUID() {
- return uuid;
- }
-
- public byte[] getImageData() {
- return imageData;
- }
-
- public void setImageData(byte[] imageData) {
- this.imageData = imageData;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeSerializable(uuid);
- // Too big for a parcelable dest.writeByteArray(imageData);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwIconCustom createFromParcel(Parcel in) {
- return new PwIconCustom(in);
- }
-
- @Override
- public PwIconCustom[] newArray(int size) {
- return new PwIconCustom[size];
- }
- };
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- PwIconCustom other = (PwIconCustom) obj;
- if (uuid == null) {
- return other.uuid == null;
- } else return uuid.equals(other.uuid);
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIconFactory.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIconFactory.java
deleted file mode 100644
index 843e1bb71..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwIconFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import org.apache.commons.collections.map.AbstractReferenceMap;
-import org.apache.commons.collections.map.ReferenceMap;
-
-import java.util.UUID;
-
-public class PwIconFactory {
- /** customIconMap
- * Cache for icon drawable.
- * Keys: Integer, Values: PwIconStandard
- */
- private ReferenceMap cache = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK);
-
- /** standardIconMap
- * Cache for icon drawable.
- * Keys: UUID, Values: PwIconCustom
- */
- private ReferenceMap customCache = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK);
-
- public PwIconStandard getUnknownIcon() {
- return getIcon(PwIconStandard.UNKNOWN);
- }
-
- public PwIconStandard getKeyIcon() {
- return getIcon(PwIconStandard.KEY);
- }
-
- public PwIconStandard getTrashIcon() {
- return getIcon(PwIconStandard.TRASH);
- }
-
- public PwIconStandard getFolderIcon() {
- return getIcon(PwIconStandard.FOLDER);
- }
-
- public PwIconStandard getIcon(int iconId) {
- PwIconStandard icon = (PwIconStandard) cache.get(iconId);
-
- if (icon == null) {
- icon = new PwIconStandard(iconId);
- cache.put(iconId, icon);
- }
-
- return icon;
- }
-
- public PwIconCustom getIcon(UUID iconUuid) {
- PwIconCustom icon = (PwIconCustom) customCache.get(iconUuid);
-
- if (icon == null) {
- icon = new PwIconCustom(iconUuid, null);
- customCache.put(iconUuid, icon);
- }
-
- return icon;
- }
-
- public void put(PwIconCustom icon) {
- customCache.put(icon.getUUID(), icon);
- }
-
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java
deleted file mode 100644
index f0c73e0f9..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-
-public class PwIconStandard extends PwIcon {
- private final int iconId;
-
- public static final int UNKNOWN = -1;
- public static final int KEY = 0;
- public static final int TRASH = 43;
- public static final int FOLDER = 48;
-
- public PwIconStandard() {
- this.iconId = KEY;
- }
-
- public PwIconStandard(int iconId) {
- this.iconId = iconId;
- }
-
- public PwIconStandard(PwIconStandard icon) {
- this.iconId = icon.iconId;
- }
-
- protected PwIconStandard(Parcel in) {
- super(in);
- iconId = in.readInt();
- }
-
- @Override
- public boolean isUnknown() {
- return iconId == UNKNOWN;
- }
-
- public int getIconId() {
- return iconId;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(iconId);
- }
-
- public static final Creator CREATOR = new Creator() {
- @Override
- public PwIconStandard createFromParcel(Parcel in) {
- return new PwIconStandard(in);
- }
-
- @Override
- public PwIconStandard[] newArray(int size) {
- return new PwIconStandard[size];
- }
- };
-
- @Override
- public boolean isMetaStreamIcon() {
- return iconId == 0;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + iconId;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- PwIconStandard other = (PwIconStandard) obj;
- if (iconId != other.iconId)
- return false;
- return true;
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java b/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java
deleted file mode 100644
index 97d69e80b..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2018 Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- *
- */
-package com.kunzisoft.keepass.database;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.kunzisoft.keepass.app.App;
-
-import org.joda.time.LocalDate;
-
-/**
- * Abstract class who manage Groups and Entries
- */
-public abstract class PwNode implements ISmallTimeLogger, Parcelable, Cloneable {
-
- protected Parent parent = null;
- protected PwIconStandard icon = new PwIconStandard();
- protected PwDate creation = new PwDate();
- protected PwDate lastMod = new PwDate();
- protected PwDate lastAccess = new PwDate();
- protected PwDate expireDate = PwDate.PW_NEVER_EXPIRE;
-
- protected PwNode() {}
-
- protected PwNode(Parcel in) {
- // TODO better technique ?
- try {
- PwGroupId pwGroupId = in.readParcelable(PwGroupId.class.getClassLoader());
- parent = (Parent) App.getDB().getPwDatabase().getGroupByGroupId(pwGroupId);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- icon = in.readParcelable(PwIconStandard.class.getClassLoader());
- creation = in.readParcelable(PwDate.class.getClassLoader());
- lastMod = in.readParcelable(PwDate.class.getClassLoader());
- lastAccess = in.readParcelable(PwDate.class.getClassLoader());
- expireDate = in.readParcelable(PwDate.class.getClassLoader());
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- PwGroupId parentId = null;
- if (parent != null)
- parentId = parent.getId();
- dest.writeParcelable(parentId, flags);
-
- dest.writeParcelable(icon, flags);
- dest.writeParcelable(creation, flags);
- dest.writeParcelable(lastMod, flags);
- dest.writeParcelable(lastAccess, flags);
- dest.writeParcelable(expireDate, flags);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- protected void construct(Parent parent) {
- this.parent = parent;
- }
-
- protected void assign(PwNode source) {
- this.parent = source.parent;
- this.icon = source.icon;
- this.creation = source.creation;
- this.lastMod = source.lastMod;
- this.lastAccess = source.lastAccess;
- this.expireDate = source.expireDate;
- }
-
- @Override
- public PwNode clone() {
- PwNode newNode;
- try {
- newNode = (PwNode) super.clone();
- // newNode.parent stay the same in copy
- newNode.icon = new PwIconStandard(this.icon);
- newNode.creation = creation.clone();
- newNode.lastMod = lastMod.clone();
- newNode.lastAccess = lastAccess.clone();
- newNode.expireDate = expireDate.clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException("Clone should be supported");
- }
- return newNode;
- }
-
- /**
- * Type of available Nodes
- */
- public enum Type {
- GROUP, ENTRY
- }
-
- /**
- * @return Type of Node
- */
- public abstract Type getType();
-
- /**
- * @return Title
- */
- public abstract String getTitle();
-
- /**
- * @return Title to display, typically return alternative title if {@link #getTitle()} is empty
- */
- protected abstract String getVisualTitle();
-
- /**
- * @return Visual icon
- */
- public PwIcon getIcon() {
- return getIconStandard();
- }
-
- public PwIconStandard getIconStandard() {
- return icon;
- }
-
- public void setIconStandard(PwIconStandard icon) {
- this.icon = icon;
- }
-
- /**
- * Retrieve the parent node
- * @return PwGroup parent as group
- */
- public Parent getParent() {
- return parent;
- }
-
- /**
- * Assign a parent to this node
- */
- public void setParent(Parent prt) {
- parent = prt;
- }
-
- /**
- * @return true if parent is present (can be a root or a detach element)
- */
- public boolean containsParent() {
- return getParent() != null;
- }
-
- public PwDate getCreationTime() {
- return creation;
- }
-
- public void setCreationTime(PwDate date) {
- creation = date;
- }
-
- public PwDate getLastModificationTime() {
- return lastMod;
- }
-
- public void setLastModificationTime(PwDate date) {
- lastMod = date;
- }
-
- public PwDate getLastAccessTime() {
- return lastAccess;
- }
-
- public void setLastAccessTime(PwDate date) {
- lastAccess = date;
- }
-
- public PwDate getExpiryTime() {
- return expireDate;
- }
-
- public void setExpiryTime(PwDate date) {
- expireDate = date;
- }
-
- public void setExpires(boolean expires) {
- if (!expires) {
- expireDate = PwDate.PW_NEVER_EXPIRE;
- }
- }
-
- public boolean isExpires() {
- // If expireDate is before NEVER_EXPIRE date less 1 month (to be sure)
- return expireDate.getDate().before(LocalDate.fromDateFields(PwDate.NEVER_EXPIRE).minusMonths(1).toDate());
- }
-
- /**
- * If the content (type, title, icon) is visually the same
- * @param o Node to compare
- * @return True if visually as o
- */
- public boolean isContentVisuallyTheSame(PwNode o) {
- return getType().equals(o.getType())
- && getVisualTitle().equals(o.getVisualTitle())
- && getIcon().equals(o.getIcon());
- }
-
- /**
- * Define if it's the same type of another node
- * @param otherNode The other node to test
- * @return true if both have the same type
- */
- boolean isSameType(PwNode otherNode) {
- return getType() != null ? getType().equals(otherNode.getType()) : otherNode.getType() == null;
- }
-
- public boolean isContainedIn(PwGroup container) {
- PwGroup cur = this.getParent();
- while (cur != null) {
- if (cur.equals(container)) {
- return true;
- }
- cur = cur.getParent();
- }
- return false;
- }
-
- public void touch(boolean modified, boolean touchParents) {
- PwDate now = new PwDate();
- setLastAccessTime(now);
-
- if (modified) {
- setLastModificationTime(now);
- }
-
- Parent parent = getParent();
- if (touchParents && parent != null) {
- parent.touch(modified, true);
- }
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.java b/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.java
deleted file mode 100644
index b921c24a1..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright 2018 Jeremy Jamet / Kunzisoft.
- *
- * This file is part of KeePass DX.
- *
- * KeePass DX is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeePass DX 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeePass DX. If not, see .
- *
- */
-
-package com.kunzisoft.keepass.database;
-
-import java.util.Comparator;
-
-public enum SortNodeEnum {
- DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME;
-
- public Comparator getNodeComparator(boolean ascending, boolean groupsBefore) {
- switch (this) {
- case DB:
- return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
- default:
- case TITLE:
- return new NodeTitleComparator(ascending, groupsBefore);
- case USERNAME:
- return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
- case CREATION_TIME:
- return new NodeCreationComparator(ascending, groupsBefore);
- case LAST_MODIFY_TIME:
- return new NodeLastModificationComparator(ascending, groupsBefore);
- case LAST_ACCESS_TIME:
- return new NodeLastAccessComparator(ascending, groupsBefore);
- }
- }
-
- private static abstract class NodeComparator implements Comparator {
- boolean ascending;
- boolean groupsBefore;
-
- NodeComparator(boolean ascending, boolean groupsBefore) {
- this.ascending = ascending;
- this.groupsBefore = groupsBefore;
- }
-
- int compareWith(Comparator comparatorGroup,
- Comparator comparatorEntry,
- PwNode object1,
- PwNode object2,
- int resultOfNodeMethodCompare) {
- if (object1.equals(object2))
- return 0;
-
- if (object1 instanceof PwGroup) {
- if (object2 instanceof PwGroup) {
- return comparatorGroup
- .compare((PwGroup) object1, (PwGroup) object2);
- } else if (object2 instanceof PwEntry) {
- if(groupsBefore)
- return -1;
- else
- return 1;
- } else {
- return -1;
- }
- } else if (object1 instanceof PwEntry) {
- if(object2 instanceof PwEntry) {
- return comparatorEntry
- .compare((PwEntry) object1, (PwEntry) object2);
- } else if (object2 instanceof PwGroup) {
- if(groupsBefore)
- return 1;
- else
- return -1;
- } else {
- return -1;
- }
- }
-
- // If same name, can be different
- if (resultOfNodeMethodCompare == 0)
- return object1.hashCode() - object2.hashCode();
- return resultOfNodeMethodCompare;
- }
- }
-
- /**
- * Comparator of Node by Title, Groups first, Entries second
- */
- public static class NodeTitleComparator extends NodeComparator {
-
- NodeTitleComparator(boolean ascending, boolean groupsBefore) {
- super(ascending, groupsBefore);
- }
-
- public int compare(PwNode object1, PwNode object2) {
-
- return compareWith(
- new GroupNameComparator(ascending),
- new EntryNameComparator(ascending),
- object1,
- object2,
- object1.getTitle()
- .compareToIgnoreCase(object2.getTitle()));
- }
- }
-
- /**
- * Comparator of node by creation, Groups first, Entries second
- */
- public static class NodeCreationComparator extends NodeComparator {
-
-
- NodeCreationComparator(boolean ascending, boolean groupsBefore) {
- super(ascending, groupsBefore);
- }
-
- @Override
- public int compare(PwNode object1, PwNode object2) {
-
- return compareWith(
- new GroupCreationComparator(ascending),
- new EntryCreationComparator(ascending),
- object1,
- object2,
- object1.getCreationTime().getDate()
- .compareTo(object2.getCreationTime().getDate()));
- }
- }
-
- /**
- * Comparator of node by last modification, Groups first, Entries second
- */
- public static class NodeLastModificationComparator extends NodeComparator {
-
- NodeLastModificationComparator(boolean ascending, boolean groupsBefore) {
- super(ascending, groupsBefore);
- }
-
- @Override
- public int compare(PwNode object1, PwNode object2) {
-
- return compareWith(
- new GroupLastModificationComparator(ascending),
- new EntryLastModificationComparator(ascending),
- object1,
- object2,
- object1.getLastModificationTime().getDate()
- .compareTo(object2.getLastModificationTime().getDate()));
- }
- }
-
- /**
- * Comparator of node by last access, Groups first, Entries second
- */
- public static class NodeLastAccessComparator extends NodeComparator {
-
- NodeLastAccessComparator(boolean ascending, boolean groupsBefore) {
- super(ascending, groupsBefore);
- }
-
- @Override
- public int compare(PwNode object1, PwNode object2) {
-
- return compareWith(
- new GroupLastAccessComparator(ascending),
- new EntryLastAccessComparator(ascending),
- object1,
- object2,
- object1.getLastAccessTime().getDate()
- .compareTo(object2.getLastAccessTime().getDate()));
- }
- }
-
- private static abstract class AscendingComparator implements Comparator {
-
- private boolean ascending;
-
- AscendingComparator(boolean ascending) {
- this.ascending = ascending;
- }
-
- int compareWithAscending(int basicCompareResult) {
- // If descending, revert
- if (!ascending)
- return -basicCompareResult;
-
- return basicCompareResult;
- }
- }
-
- /**
- * Group comparator by name
- */
- public static class GroupNameComparator extends AscendingComparator {
-
- GroupNameComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwGroup object1, PwGroup object2) {
- if (object1.equals(object2))
- return 0;
-
- int groupNameComp = object1.getName().compareToIgnoreCase(object2.getName());
- // If same name, can be different
- if (groupNameComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(groupNameComp);
- }
- }
-
- /**
- * Group comparator by name
- */
- public static class GroupCreationComparator extends AscendingComparator {
-
- GroupCreationComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwGroup object1, PwGroup object2) {
- if (object1.equals(object2))
- return 0;
-
- int groupCreationComp = object1.getCreationTime().getDate()
- .compareTo(object2.getCreationTime().getDate());
- // If same creation, can be different
- if (groupCreationComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(groupCreationComp);
- }
- }
-
- /**
- * Group comparator by last modification
- */
- public static class GroupLastModificationComparator extends AscendingComparator {
-
- GroupLastModificationComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwGroup object1, PwGroup object2) {
- if (object1.equals(object2))
- return 0;
-
- int groupLastModificationComp = object1.getLastModificationTime().getDate()
- .compareTo(object2.getLastModificationTime().getDate());
- // If same creation, can be different
- if (groupLastModificationComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(groupLastModificationComp);
- }
- }
-
- /**
- * Group comparator by last access
- */
- public static class GroupLastAccessComparator extends AscendingComparator {
-
- GroupLastAccessComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwGroup object1, PwGroup object2) {
- if (object1.equals(object2))
- return 0;
-
- int groupLastAccessComp = object1.getLastAccessTime().getDate()
- .compareTo(object2.getLastAccessTime().getDate());
- // If same creation, can be different
- if (groupLastAccessComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(groupLastAccessComp);
- }
- }
-
- /**
- * Comparator of Entry by Name
- */
- public static class EntryNameComparator extends AscendingComparator {
-
- EntryNameComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwEntry object1, PwEntry object2) {
- if (object1.equals(object2))
- return 0;
-
- int entryTitleComp = object1.getTitle().compareToIgnoreCase(object2.getTitle());
- // If same title, can be different
- if (entryTitleComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(entryTitleComp);
- }
- }
-
- /**
- * Comparator of Entry by Creation
- */
- public static class EntryCreationComparator extends AscendingComparator {
-
- EntryCreationComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwEntry object1, PwEntry object2) {
- if (object1.equals(object2))
- return 0;
-
- int entryCreationComp = object1.getCreationTime().getDate()
- .compareTo(object2.getCreationTime().getDate());
- // If same creation, can be different
- if (entryCreationComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(entryCreationComp);
- }
- }
-
- /**
- * Comparator of Entry by Last Modification
- */
- public static class EntryLastModificationComparator extends AscendingComparator {
-
- EntryLastModificationComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwEntry object1, PwEntry object2) {
- if (object1.equals(object2))
- return 0;
-
- int entryLastModificationComp = object1.getLastModificationTime().getDate()
- .compareTo(object2.getLastModificationTime().getDate());
- // If same creation, can be different
- if (entryLastModificationComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(entryLastModificationComp);
- }
- }
-
- /**
- * Comparator of Entry by Last Access
- */
- public static class EntryLastAccessComparator extends AscendingComparator {
-
- EntryLastAccessComparator(boolean ascending) {
- super(ascending);
- }
-
- public int compare(PwEntry object1, PwEntry object2) {
- if (object1.equals(object2))
- return 0;
-
- int entryLastAccessComp = object1.getLastAccessTime().getDate()
- .compareTo(object2.getLastAccessTime().getDate());
- // If same creation, can be different
- if (entryLastAccessComp == 0) {
- return object1.hashCode() - object2.hashCode();
- }
-
- return compareWithAscending(entryLastAccessComp);
- }
- }
-}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.kt b/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.kt
new file mode 100644
index 000000000..22a6b2415
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/database/SortNodeEnum.kt
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2018 Jeremy Jamet / Kunzisoft.
+ *
+ * This file is part of KeePass DX.
+ *
+ * KeePass DX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePass DX 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePass DX. If not, see .
+ *
+ */
+
+package com.kunzisoft.keepass.database
+
+import com.kunzisoft.keepass.database.element.EntryVersioned
+import com.kunzisoft.keepass.database.element.GroupVersioned
+import com.kunzisoft.keepass.database.element.NodeVersioned
+
+import java.util.Comparator
+
+enum class SortNodeEnum {
+ DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME;
+
+ fun getNodeComparator(ascending: Boolean, groupsBefore: Boolean): Comparator {
+ return when (this) {
+ DB -> NodeCreationComparator(ascending, groupsBefore) // TODO Sort
+ TITLE -> NodeTitleComparator(ascending, groupsBefore)
+ USERNAME -> NodeCreationComparator(ascending, groupsBefore) // TODO Sort
+ CREATION_TIME -> NodeCreationComparator(ascending, groupsBefore)
+ LAST_MODIFY_TIME -> NodeLastModificationComparator(ascending, groupsBefore)
+ LAST_ACCESS_TIME -> NodeLastAccessComparator(ascending, groupsBefore)
+ }
+ }
+
+ abstract class NodeComparator internal constructor(internal var ascending: Boolean, private var groupsBefore: Boolean) : Comparator {
+
+ internal fun compareWith(comparatorGroup: Comparator,
+ comparatorEntry: Comparator,
+ object1: NodeVersioned,
+ object2: NodeVersioned,
+ resultOfNodeMethodCompare: Int): Int {
+ if (object1 == object2)
+ return 0
+
+ if (object1 is GroupVersioned) {
+ return if (object2 is GroupVersioned) {
+ comparatorGroup
+ .compare(object1, object2)
+ } else if (object2 is EntryVersioned) {
+ if (groupsBefore)
+ -1
+ else
+ 1
+ } else {
+ -1
+ }
+ } else if (object1 is EntryVersioned) {
+ return if (object2 is EntryVersioned) {
+ comparatorEntry
+ .compare(object1, object2)
+ } else if (object2 is GroupVersioned) {
+ if (groupsBefore)
+ 1
+ else
+ -1
+ } else {
+ -1
+ }
+ }
+
+ // If same name, can be different
+ return if (resultOfNodeMethodCompare == 0) object1.hashCode() - object2.hashCode() else resultOfNodeMethodCompare
+ }
+ }
+
+ /**
+ * Comparator of Node by Title, Groups first, Entries second
+ */
+ class NodeTitleComparator internal constructor(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
+
+ override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int {
+
+ return compareWith(
+ GroupNameComparator(ascending),
+ EntryNameComparator(ascending),
+ object1,
+ object2,
+ object1.title
+ .compareTo(object2.title, ignoreCase = true))
+ }
+ }
+
+ /**
+ * Comparator of node by creation, Groups first, Entries second
+ */
+ class NodeCreationComparator internal constructor(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
+
+ override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int {
+
+ return compareWith(
+ GroupCreationComparator(ascending),
+ EntryCreationComparator(ascending),
+ object1,
+ object2,
+ object1.creationTime.date
+ ?.compareTo(object2.creationTime.date) ?: 0)
+ }
+ }
+
+ /**
+ * Comparator of node by last modification, Groups first, Entries second
+ */
+ class NodeLastModificationComparator internal constructor(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
+
+ override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int {
+
+ return compareWith(
+ GroupLastModificationComparator(ascending),
+ EntryLastModificationComparator(ascending),
+ object1,
+ object2,
+ object1.lastModificationTime.date
+ ?.compareTo(object2.lastModificationTime.date) ?: 0)
+ }
+ }
+
+ /**
+ * Comparator of node by last access, Groups first, Entries second
+ */
+ class NodeLastAccessComparator internal constructor(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
+
+ override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int {
+
+ return compareWith(
+ GroupLastAccessComparator(ascending),
+ EntryLastAccessComparator(ascending),
+ object1,
+ object2,
+ object1.lastAccessTime.date
+ ?.compareTo(object2.lastAccessTime.date) ?: 0)
+ }
+ }
+
+ abstract class AscendingComparator internal constructor(private val ascending: Boolean) : Comparator {
+
+ internal fun compareWithAscending(basicCompareResult: Int): Int {
+ // If descending, revert
+ return if (!ascending) -basicCompareResult else basicCompareResult
+
+ }
+ }
+
+ /**
+ * Group comparator by name
+ */
+ class GroupNameComparator internal constructor(ascending: Boolean) : AscendingComparator(ascending) {
+
+ override fun compare(object1: GroupVersioned, object2: GroupVersioned): Int {
+ if (object1 == object2)
+ return 0
+
+ val groupNameComp = object1.title.compareTo(object2.title, ignoreCase = true)
+ // If same name, can be different
+ return if (groupNameComp == 0) {
+ object1.hashCode() - object2.hashCode()
+ } else compareWithAscending(groupNameComp)
+
+ }
+ }
+
+ /**
+ * Group comparator by name
+ */
+ class GroupCreationComparator internal constructor(ascending: Boolean) : AscendingComparator(ascending) {
+
+ override fun compare(object1: GroupVersioned, object2: GroupVersioned): Int {
+ if (object1 == object2)
+ return 0
+
+ val groupCreationComp = object1.creationTime.date
+ ?.compareTo(object2.creationTime.date) ?: 0
+ // If same creation, can be different
+ return if (groupCreationComp == 0) {
+ object1.hashCode() - object2.hashCode()
+ } else compareWithAscending(groupCreationComp)
+
+ }
+ }
+
+ /**
+ * Group comparator by last modification
+ */
+ class GroupLastModificationComparator internal constructor(ascending: Boolean) : AscendingComparator(ascending) {
+
+ override fun compare(object1: GroupVersioned, object2: GroupVersioned): Int {
+ if (object1 == object2)
+ return 0
+
+ val groupLastModificationComp = object1.lastModificationTime.date
+ ?.compareTo(object2.lastModificationTime.date) ?: 0
+ // If same creation, can be different
+ return if (groupLastModificationComp == 0) {
+ object1.hashCode() - object2.hashCode()
+ } else compareWithAscending(groupLastModificationComp)
+
+ }
+ }
+
+ /**
+ * Group comparator by last access
+ */
+ class GroupLastAccessComparator internal constructor(ascending: Boolean) : AscendingComparator