diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java deleted file mode 100644 index 28ffbf8a408afb8c10c9e1acdeb37e2eebaf07e4..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ** header v3.0 This file is a part of the CaosDB Project. - * - * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> - * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> - * - * This program is free software: you can redistribute it and/or modify it under the terms of the - * GNU Affero General Public License as published by the Free Software Foundation, either version 3 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License along with this program. - * If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.database.backend.transaction; - -import java.util.HashMap; -import org.caosdb.datetime.UTCDateTime; -import org.caosdb.server.database.exceptions.TransactionException; -import org.caosdb.server.database.proto.VersionHistoryItem; -import org.caosdb.server.entity.EntityInterface; -import org.caosdb.server.entity.Version; - -public class RetrieveTransactionHistory extends RetrieveVersionHistory { - - public RetrieveTransactionHistory(EntityInterface e) { - super(e); - } - - @Override - protected void process(HashMap<String, VersionHistoryItem> map) throws TransactionException { - super.process(map); - if (!map.isEmpty()) getEntity().setVersion(getHistory()); - } - - @Override - protected Version getVersion(String id) { - Version v = new Version(id); - VersionHistoryItem i = getHistoryItems().get(v.getId()); - if (i != null) { - v.setDate(UTCDateTime.UTCSeconds(i.seconds, i.nanos)); - v.setUsername(i.username); - v.setRealm(i.realm); - } - return v; - } - - private Version getHistory() { - Version v = getVersion(getEntity().getVersion().getId()); - v.setSuccessors(getSuccessors(v.getId(), true)); - v.setPredecessors(getPredecessors(v.getId(), true)); - v.setHead(v.getSuccessors().isEmpty()); - v.setCompleteHistory(true); - return v; - } -} diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java index 53ff3a0858616a0915639cf1dd29a707d55e5eca..3d1cf0a9adc58e5db5721047192e2fb7fb147924 100644 --- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java @@ -1,117 +1,61 @@ /* - * ** header v3.0 - * This file is a part of the CaosDB Project. + * ** header v3.0 This file is a part of the CaosDB Project. * * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under the terms of the + * GNU Affero General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Affero General Public License along with this program. + * If not, see <https://www.gnu.org/licenses/>. * * ** end header */ package org.caosdb.server.database.backend.transaction; import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import org.apache.commons.jcs.access.behavior.ICacheAccess; -import org.caosdb.server.caching.Cache; -import org.caosdb.server.database.CacheableBackendTransaction; -import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl; +import org.caosdb.datetime.UTCDateTime; import org.caosdb.server.database.exceptions.TransactionException; import org.caosdb.server.database.proto.VersionHistoryItem; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.Version; -public abstract class RetrieveVersionHistory - extends CacheableBackendTransaction<Integer, HashMap<String, VersionHistoryItem>> { - - private static final ICacheAccess<Integer, HashMap<String, VersionHistoryItem>> cache = - Cache.getCache("BACKEND_RetrieveVersionHistory"); - private EntityInterface entity; - - /** A map of all history items which belong to this entity. The keys are the version ids. */ - private HashMap<String, VersionHistoryItem> historyItems; - - public static void removeCached(Integer entityId) { - cache.remove(entityId); - } +public class RetrieveVersionHistory extends VersionTransaction { public RetrieveVersionHistory(EntityInterface e) { - super(cache); - this.entity = e; + super(e); } - @Override - public HashMap<String, VersionHistoryItem> executeNoCache() throws TransactionException { - RetrieveVersionHistoryImpl impl = getImplementation(RetrieveVersionHistoryImpl.class); - return impl.execute(getKey()); - } - - /** After this method call, the version map is available to the object. */ @Override protected void process(HashMap<String, VersionHistoryItem> map) throws TransactionException { - this.historyItems = map; + super.process(map); + if (!map.isEmpty()) getEntity().setVersion(getHistory()); } @Override - protected Integer getKey() { - return entity.getId(); - } - - public HashMap<String, VersionHistoryItem> getHistoryItems() { - return this.historyItems; - } - - public EntityInterface getEntity() { - return this.entity; - } - - /** Return a list of direct predecessors which have their direct predecessors attached */ - protected List<Version> getPredecessors(String id, boolean transitive) { - LinkedList<Version> result = new LinkedList<>(); - if (getHistoryItems().containsKey(id) && getHistoryItems().get(id).parents != null) - for (String p : getHistoryItems().get(id).parents) { - Version predecessor = getVersion(p); - if (transitive) { - predecessor.setPredecessors(getPredecessors(p, transitive)); - } - result.add(predecessor); - } - return result; + protected Version getVersion(String id) { + Version v = new Version(id); + VersionHistoryItem i = getHistoryItems().get(v.getId()); + if (i != null) { + v.setDate(UTCDateTime.UTCSeconds(i.seconds, i.nanos)); + v.setUsername(i.username); + v.setRealm(i.realm); + } + return v; } - protected abstract Version getVersion(String version); - - /** Return a list of direct successors which have their direct successors attached */ - protected List<Version> getSuccessors(String id, boolean transitive) { - LinkedList<Version> result = new LinkedList<>(); - - outer: - for (VersionHistoryItem i : getHistoryItems().values()) { - if (i.parents != null) - for (String p : i.parents) { - if (id.equals(p)) { - Version successor = getVersion(i.id); - result.add(successor); - if (transitive) { - successor.setSuccessors(getSuccessors(i.id, transitive)); - } - continue outer; - } - } - } - return result; + private Version getHistory() { + Version v = getVersion(getEntity().getVersion().getId()); + v.setSuccessors(getSuccessors(v.getId(), true)); + v.setPredecessors(getPredecessors(v.getId(), true)); + v.setHead(v.getSuccessors().isEmpty()); + v.setCompleteHistory(true); + return v; } } diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java index 26f3f396210eec58144b55d0f7e9d0c469cb7b30..8d0e54c95d17d0eb83af541b9fee2fb605b17ec9 100644 --- a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java @@ -28,7 +28,7 @@ import org.caosdb.server.database.proto.VersionHistoryItem; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.Version; -public class RetrieveVersionInfo extends RetrieveVersionHistory { +public class RetrieveVersionInfo extends VersionTransaction { public RetrieveVersionInfo(EntityInterface e) { super(e); diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java index 60fd34c77f1e70184dfc50c1a5644f3503ac9630..2bf965575884f29640a80ec3d3ab284b7779c8f2 100644 --- a/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java @@ -54,7 +54,7 @@ public class UpdateEntity extends BackendTransaction { execute(new InsertEntityProperties(e)); - RetrieveVersionHistory.removeCached(e.getId()); + VersionTransaction.removeCached(e.getId()); execute(new RetrieveVersionInfo(e)); } } diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..95b2ba0fd8159aac1ccee1612ca0d6d247a46c6e --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java @@ -0,0 +1,117 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VersionHistoryItem; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; + +public abstract class VersionTransaction + extends CacheableBackendTransaction<Integer, HashMap<String, VersionHistoryItem>> { + + private static final ICacheAccess<Integer, HashMap<String, VersionHistoryItem>> cache = + Cache.getCache("BACKEND_RetrieveVersionHistory"); + private EntityInterface entity; + + /** A map of all history items which belong to this entity. The keys are the version ids. */ + private HashMap<String, VersionHistoryItem> historyItems; + + public static void removeCached(Integer entityId) { + cache.remove(entityId); + } + + public VersionTransaction(EntityInterface e) { + super(cache); + this.entity = e; + } + + @Override + public HashMap<String, VersionHistoryItem> executeNoCache() throws TransactionException { + RetrieveVersionHistoryImpl impl = getImplementation(RetrieveVersionHistoryImpl.class); + return impl.execute(getKey()); + } + + /** After this method call, the version map is available to the object. */ + @Override + protected void process(HashMap<String, VersionHistoryItem> map) throws TransactionException { + this.historyItems = map; + } + + @Override + protected Integer getKey() { + return entity.getId(); + } + + public HashMap<String, VersionHistoryItem> getHistoryItems() { + return this.historyItems; + } + + public EntityInterface getEntity() { + return this.entity; + } + + /** Return a list of direct predecessors which have their direct predecessors attached */ + protected List<Version> getPredecessors(String id, boolean transitive) { + LinkedList<Version> result = new LinkedList<>(); + if (getHistoryItems().containsKey(id) && getHistoryItems().get(id).parents != null) + for (String p : getHistoryItems().get(id).parents) { + Version predecessor = getVersion(p); + if (transitive) { + predecessor.setPredecessors(getPredecessors(p, transitive)); + } + result.add(predecessor); + } + return result; + } + + protected abstract Version getVersion(String version); + + /** Return a list of direct successors which have their direct successors attached */ + protected List<Version> getSuccessors(String id, boolean transitive) { + LinkedList<Version> result = new LinkedList<>(); + + outer: + for (VersionHistoryItem i : getHistoryItems().values()) { + if (i.parents != null) + for (String p : i.parents) { + if (id.equals(p)) { + Version successor = getVersion(i.id); + result.add(successor); + if (transitive) { + successor.setSuccessors(getSuccessors(i.id, transitive)); + } + continue outer; + } + } + } + return result; + } +} diff --git a/src/main/java/org/caosdb/server/jobs/core/History.java b/src/main/java/org/caosdb/server/jobs/core/History.java index 87e9f69d0de18779268b8fc43b228d604dfe5133..e9d81ad40adeef1e3fa6d1498dabfe3a58c6fa29 100644 --- a/src/main/java/org/caosdb/server/jobs/core/History.java +++ b/src/main/java/org/caosdb/server/jobs/core/History.java @@ -23,7 +23,6 @@ package org.caosdb.server.jobs.core; import org.apache.shiro.authz.AuthorizationException; -import org.caosdb.server.database.backend.transaction.RetrieveTransactionHistory; import org.caosdb.server.database.backend.transaction.RetrieveVersionHistory; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.jobs.FlagJob; @@ -33,6 +32,12 @@ import org.caosdb.server.permissions.EntityPermission; import org.caosdb.server.utils.EntityStatus; import org.caosdb.server.utils.ServerMessages; +/** + * Retrieves the complete version history of each entity and appends it to the + * entity. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ @JobAnnotation(time = JobExecutionTime.POST_TRANSACTION, flag = "H") public class History extends FlagJob { @@ -43,7 +48,7 @@ public class History extends FlagJob { if (entity.getId() != null && entity.getId() > 0) { try { entity.checkPermission(EntityPermission.RETRIEVE_HISTORY); - final RetrieveVersionHistory t = new RetrieveTransactionHistory(entity); + final RetrieveVersionHistory t = new RetrieveVersionHistory(entity); execute(t); } catch (final AuthorizationException e) { entity.setEntityStatus(EntityStatus.UNQUALIFIED);