diff --git a/conf/core/jobs.csv b/conf/core/jobs.csv index 38b273c4f65ce931afd0cf7a4a4a25a3118a0ada..da51e513fdd2581e2fedb856f4cf9fda845ff453 100644 --- a/conf/core/jobs.csv +++ b/conf/core/jobs.csv @@ -31,8 +31,7 @@ 0,0,UPDATE,CheckParValid,ERROR 0,0,UPDATE,CheckParOblPropPresent,ERROR 0,0,UPDATE,CheckValueParsable,ERROR -0,0,DELETE,CheckReferenceDependencyExistent,ERROR -0,0,DELETE,CheckChildDependencyExistent,ERROR +0,0,DELETE,CheckDependenciesBeforeDeletion,ERROR # role specific rules diff --git a/src/main/java/org/caosdb/server/database/BackendTransaction.java b/src/main/java/org/caosdb/server/database/BackendTransaction.java index 270839af40d40668ca3079abcc3e09eb6caaf8ae..7021dfbb0ba8e580b104d5639b9acb1a397064ea 100644 --- a/src/main/java/org/caosdb/server/database/BackendTransaction.java +++ b/src/main/java/org/caosdb/server/database/BackendTransaction.java @@ -29,7 +29,6 @@ import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteRole; import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteSparseEntity; import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteUser; import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetAllNames; -import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetChildren; import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetDependentEntities; import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetFileRecordByPath; import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetIDByName; @@ -87,7 +86,6 @@ import org.caosdb.server.database.backend.interfaces.FileCheckSize; import org.caosdb.server.database.backend.interfaces.FileExists; import org.caosdb.server.database.backend.interfaces.FileWasModifiedAfter; import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl; -import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; import org.caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; import org.caosdb.server.database.backend.interfaces.GetFileIteratorImpl; import org.caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; @@ -155,7 +153,7 @@ public abstract class BackendTransaction implements Undoable { } /** - * Intialiaze the adapters to the database backend. + * Initialize the adapters to the database backend. * * <p>Currently this is hard-coded to the MySQL-Backend but the architecture of this class is * designed to make it easy in the future to choose other implementations (i.e. other back-ends) @@ -165,7 +163,6 @@ public abstract class BackendTransaction implements Undoable { setImpl(GetAllNamesImpl.class, MySQLGetAllNames.class); setImpl(DeleteEntityPropertiesImpl.class, MySQLDeleteEntityProperties.class); setImpl(DeleteSparseEntityImpl.class, MySQLDeleteSparseEntity.class); - setImpl(GetChildrenImpl.class, MySQLGetChildren.class); setImpl(GetDependentEntitiesImpl.class, MySQLGetDependentEntities.class); setImpl(GetIDByNameImpl.class, MySQLGetIDByName.class); setImpl(GetInfoImpl.class, MySQLGetInfo.class); diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java deleted file mode 100644 index 3d3662c6961828436597ee17651adba457ec5fc1..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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.implementation.MySQL; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.LinkedList; -import java.util.List; -import org.caosdb.server.database.access.Access; -import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; -import org.caosdb.server.database.exceptions.TransactionException; -import org.caosdb.server.entity.EntityID; - -public class MySQLGetChildren extends MySQLTransaction implements GetChildrenImpl { - - public MySQLGetChildren(final Access access) { - super(access); - } - - public static final String STMT_GET_CHILDREN = "call retrieveChildren(?)"; - - @Override - public List<EntityID> execute(final EntityID entity) throws TransactionException { - try { - final PreparedStatement stmt = prepareStatement(STMT_GET_CHILDREN); - - stmt.setString(1, entity.toString()); - - ResultSet rs = null; - try { - rs = stmt.executeQuery(); - final List<EntityID> ret = new LinkedList<>(); - while (rs.next()) { - ret.add(new EntityID(rs.getInt(1))); - } - return ret; - } finally { - if (rs != null && !rs.isClosed()) { - rs.close(); - } - } - } catch (final Exception e) { - throw new TransactionException(e); - } - } -} diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java index 459244032cac8128dc6b72679279eb05e8f940c5..5dcd2634f8e8518865021e02c2eb9e3c10ff45d0 100644 --- a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java @@ -39,7 +39,7 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS } public static final String STMT_INSERT_SPARSE_ENTITY = "call insertEntity(?,?,?,?,?)"; - public static final String STMT_INSERT_FILE_PROPERTIES = "call insertFile(?, ?, ?, ?)"; + public static final String STMT_INSERT_FILE_PROPERTIES = "call setFileProperties(?,?,?,?)"; @Override public void execute(final SparseEntity entity) { @@ -63,13 +63,13 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS if (entity.filePath != null) { insertFilePropsStmt.setString(1, entity.id); + insertFilePropsStmt.setString(2, entity.filePath); + insertFilePropsStmt.setLong(3, entity.fileSize); if (entity.fileHash != null) { - insertFilePropsStmt.setString(2, entity.fileHash); + insertFilePropsStmt.setString(4, entity.fileHash); } else { - insertFilePropsStmt.setNull(2, Types.VARCHAR); + insertFilePropsStmt.setNull(4, Types.VARCHAR); } - insertFilePropsStmt.setLong(3, entity.fileSize); - insertFilePropsStmt.setString(4, entity.filePath); insertFilePropsStmt.execute(); } } catch (final SQLIntegrityConstraintViolationException exc) { diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java deleted file mode 100644 index 8b0211a0b56bec22e4823058dfa72c355e59d19d..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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.interfaces; - -import java.util.List; -import org.caosdb.server.database.exceptions.TransactionException; -import org.caosdb.server.entity.EntityID; - -public interface GetChildrenImpl extends BackendTransactionImpl { - - public abstract List<EntityID> execute(EntityID entity) throws TransactionException; -} diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java deleted file mode 100644 index d0e2a809547ad2be4621ccab3f79d793dde70006..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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.List; -import org.caosdb.server.database.BackendTransaction; -import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; -import org.caosdb.server.database.exceptions.TransactionException; -import org.caosdb.server.entity.EntityID; - -public class GetChildren extends BackendTransaction { - - private final EntityID entity; - private List<EntityID> list; - - public GetChildren(final EntityID entity) { - this.entity = entity; - } - - @Override - public void execute() throws TransactionException { - final GetChildrenImpl t = getImplementation(GetChildrenImpl.class); - this.list = t.execute(this.entity); - } - - public List<EntityID> getList() { - return this.list; - } -} diff --git a/src/main/java/org/caosdb/server/jobs/Job.java b/src/main/java/org/caosdb/server/jobs/Job.java index 9da74edd0db86f6d81a8636020afcdaf3faa9e09..9f6103a9bea047fb11b1b25d6ecc9cfa67988ab8 100644 --- a/src/main/java/org/caosdb/server/jobs/Job.java +++ b/src/main/java/org/caosdb/server/jobs/Job.java @@ -22,7 +22,6 @@ package org.caosdb.server.jobs; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -334,7 +333,7 @@ public abstract class Job { private static void scanJobClasspath() { if (allClasses == null || loadAlways == null) { allClasses = new HashMap<>(); - loadAlways = new ArrayList<>(); + loadAlways = new LinkedList<>(); Reflections jobPackage = new Reflections("org.caosdb.server.jobs.core"); Set<Class<? extends Job>> allClassesSet = jobPackage.getSubTypesOf(Job.class); allClassesSet.addAll(jobPackage.getSubTypesOf(FlagJob.class)); @@ -383,7 +382,7 @@ public abstract class Job { final EntityInterface entity, final Transaction<? extends TransactionContainer> transaction) { if (dt == null) { - return new ArrayList<Job>(); + return new LinkedList<Job>(); } if (dt instanceof ReferenceDatatype2) { return jobConfig.getConfiguredJobs( @@ -401,12 +400,15 @@ public abstract class Job { public List<Job> loadStandardJobs( final EntityInterface entity, final Transaction<? extends TransactionContainer> transaction) { - final ArrayList<Job> jobs = new ArrayList<>(); + final List<Job> jobs = new LinkedList<>(); // load permanent jobs - for (final Class<? extends Job> j : loadAlways) { - if (EntityJob.class.isAssignableFrom(j) - && j.getAnnotation(JobAnnotation.class).transaction().isInstance(transaction)) { - jobs.add(getJob(j, JobFailureSeverity.ERROR, entity, transaction)); + for (final Class<? extends Job> jobClass : loadAlways) { + if (EntityJob.class.isAssignableFrom(jobClass) + && jobClass.getAnnotation(JobAnnotation.class).transaction().isInstance(transaction)) { + Job j = getJob(jobClass, JobFailureSeverity.ERROR, entity, transaction); + if (j != null) { + jobs.add(j); + } } } @@ -519,6 +521,7 @@ public abstract class Job { // load jobs for the properties if (entity.hasProperties()) { for (final EntityInterface p : entity.getProperties()) { + // TODO jobs.addAll(loadJobs(p, transaction)); } } @@ -585,7 +588,7 @@ public abstract class Job { * @return A list with the jobs. */ public static List<Job> loadPermanentContainerJobs(final Transaction<?> transaction) { - final ArrayList<Job> jobs = new ArrayList<>(); + final List<Job> jobs = new LinkedList<>(); // load permanent jobs: ContainerJob classes with the correct transaction for (final Class<? extends Job> j : loadAlways) { if (ContainerJob.class.isAssignableFrom(j) diff --git a/src/main/java/org/caosdb/server/jobs/JobConfig.java b/src/main/java/org/caosdb/server/jobs/JobConfig.java index 40917b36714ee95ef491a266580068a06f51703a..ac53b605f5a0d9a5514403a1976b3e42650a75f2 100644 --- a/src/main/java/org/caosdb/server/jobs/JobConfig.java +++ b/src/main/java/org/caosdb/server/jobs/JobConfig.java @@ -158,7 +158,7 @@ public class JobConfig { } /** - * Factory method for the instanciation and configuration of jobs for a specific entity. + * Factory method for the instantiation and configuration of jobs for a specific entity. * * @param domain the domain of the rule * @param entity the entity of the rule (this might be a particular datatype or a role, like @@ -184,9 +184,13 @@ public class JobConfig { final List<Job> result = new LinkedList<>(); jobRules.forEach( config -> { - result.add( - Job.getJob( - (String) config[0], (JobFailureSeverity) config[1], target, transaction)); + Job j = + Job.getJob((String) config[0], (JobFailureSeverity) config[1], target, transaction); + if (j == null) { + throw new NullPointerException("Could not load job: " + config[0]); + } else { + result.add(j); + } }); return result; } diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java b/src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java deleted file mode 100644 index d60db5a3ea2f58caefe240894920318e01efc8a6..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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.jobs.core; - -import java.util.List; -import java.util.Objects; -import org.caosdb.server.database.backend.transaction.GetChildren; -import org.caosdb.server.entity.EntityID; -import org.caosdb.server.entity.EntityInterface; -import org.caosdb.server.jobs.EntityJob; -import org.caosdb.server.utils.EntityStatus; -import org.caosdb.server.utils.ServerMessages; - -/** - * Check whether any children of this entity do exist. There must not be any children left when an - * entity is to be deleted. If all children are to be deleted, too, the test passes. - * - * @author tf - */ -public class CheckChildDependencyExistent extends EntityJob { - - @Override - public final void run() { - if (getEntity().getDomain() == null - || Objects.equals(getEntity().getDomain(), EntityID.DEFAULT_DOMAIN)) { - - final List<EntityID> children = execute(new GetChildren(getEntity().getId())).getList(); - - // loop: - for (final EntityID id : children) { - final EntityInterface foreign = getEntityById(id); - if (foreign == null) { - // if the child is not in the container, the test fails. - getEntity().addError(ServerMessages.REQUIRED_BY_PERSISTENT_ENTITY); - getEntity().addInfo("Required by entity " + id + "."); - getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - } - - // // loop through all entities in the current container - // for (final EntityInterface e : getContainer()) { - // - // // if e is a child - // if (e.getId().equals(id)) { - // if (e.getEntityStatus() == EntityStatus.UNQUALIFIED) { - // getEntity().addError(ServerMessages.REQUIRED_BY_UNQUALIFIED); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - // } else { - // // if the children are among the entities in the - // // container which is to be deleted, the test passes - // e.acceptObserver(new Observer() { - // @Override - // public boolean notifyObserver(final String evt, - // final Observable o) { - // if (evt == Entity.ENTITY_STATUS_CHANGED_EVENT && o == e) { - // if (e.getEntityStatus() == EntityStatus.UNQUALIFIED) { - // getEntity().addError( - // ServerMessages.REQUIRED_BY_UNQUALIFIED); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - // return false; - // } - // } - // return true; - // } - // }); - // } - // continue loop; - // } - // } - - // // if the child is not in the container, the test fails. - // getEntity().addError(ServerMessages.REQUIRED_BY_PERSISTENT_ENTITY); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - } - } - } -} diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java b/src/main/java/org/caosdb/server/jobs/core/CheckDependenciesBeforeDeletion.java similarity index 54% rename from src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckDependenciesBeforeDeletion.java index 2edbc5a270db93312c73b8c960c615a161e8907b..c9f6de7cc1d39cead5998ad680bfe444f38a36ea 100644 --- a/src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckDependenciesBeforeDeletion.java @@ -32,13 +32,13 @@ import org.caosdb.server.utils.EntityStatus; import org.caosdb.server.utils.ServerMessages; /** - * Check whether an entity is referenced by other entities. In the event that someone wants to - * delete this entity, this entity must not be referenced by any other entity which is not deleted - * along with this entity. + * Check whether an entity is referenced by other entities, is being used as a data type by other + * entities or has direct children which are not to be deleted along with this entity and add an + * appropriate error if so. * - * @author tf + * @author Timm Fitschen <t.fitschen@indiscale.com> */ -public class CheckReferenceDependencyExistent extends EntityJob { +public class CheckDependenciesBeforeDeletion extends EntityJob { @Override public final void run() { if (getEntity().getDomain() == null @@ -59,42 +59,6 @@ public class CheckReferenceDependencyExistent extends EntityJob { getEntity().addInfo("Required by entity " + id + "."); getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); } - // for (final EntityInterface e : getContainer()) { - // if (e.getId().equals(id)) { - // // entity is in the container. - // if (e.getEntityStatus() == EntityStatus.UNQUALIFIED) { - // getEntity().addError(ServerMessages.REQUIRED_BY_UNQUALIFIED); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - // } else { - // e.acceptObserver(new Observer() { - // @Override - // public boolean notifyObserver(final String evt, - // final Observable o) { - // if (e == o && evt == Entity.ENTITY_STATUS_CHANGED_EVENT) { - // if (e.getEntityStatus() == EntityStatus.UNQUALIFIED) { - // getEntity().addError( - // ServerMessages.REQUIRED_BY_UNQUALIFIED); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); - // return false; - // } - // } - // return true; - // } - // }); - // } - // - // continue loop; - // } - // } - - // // dependent entity is not in the container. That is, it will - // // not be deleted. Therefore, this entity cannot be deleted - // // either. - // getEntity().addError(ServerMessages.REQUIRED_BY_PERSISTENT_ENTITY); - // getEntity().addInfo("Required by entity " + id + "."); - // getEntity().setEntityStatus(EntityStatus.UNQUALIFIED); } } }