Skip to content
Snippets Groups Projects
Unverified Commit 0b8a1997 authored by Daniel's avatar Daniel
Browse files

DOC: Added (C) notices and some documentation and comments.

parent 74ead0e3
Branches
Tags
3 merge requests!21Release v0.4.0,!7F fsm,!6Draft: F acm permissions2
Showing
with 254 additions and 27 deletions
/*
* ** 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.entity; package org.caosdb.server.entity;
import java.util.HashMap; import java.util.HashMap;
...@@ -12,7 +35,7 @@ import org.jdom2.Element; ...@@ -12,7 +35,7 @@ import org.jdom2.Element;
* *
* <p>If no plug-in handles the client message, it is printed back to the response unaltered. * <p>If no plug-in handles the client message, it is printed back to the response unaltered.
* *
* <p>Client message can have arbitrary key-value tuples {@link #properties}. * <p>Client message can have arbitrary key-value (string-string typed) tuples {@link #properties}.
* *
* @author Timm Fitschen (t.fitschen@indiscale.com) * @author Timm Fitschen (t.fitschen@indiscale.com)
*/ */
...@@ -40,6 +63,7 @@ public class ClientMessage extends Message { ...@@ -40,6 +63,7 @@ public class ClientMessage extends Message {
parent.addContent(e); parent.addContent(e);
} }
/** NB: This is the only place where properties are set in this class. */
public static ClientMessage fromXML(Element pe) { public static ClientMessage fromXML(Element pe) {
ClientMessage result = new ClientMessage(pe.getName(), pe.getText()); ClientMessage result = new ClientMessage(pe.getName(), pe.getText());
for (Attribute a : pe.getAttributes()) { for (Attribute a : pe.getAttributes()) {
......
/*
* ** 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.jobs; package org.caosdb.server.jobs;
/** /**
......
/*
* ** 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.jobs.core; package org.caosdb.server.jobs.core;
import org.caosdb.server.entity.DeleteEntity; import org.caosdb.server.entity.DeleteEntity;
...@@ -11,6 +34,9 @@ import org.caosdb.server.transaction.WriteTransaction; ...@@ -11,6 +34,9 @@ import org.caosdb.server.transaction.WriteTransaction;
/** /**
* Check if the attempted state transition is allowed. * Check if the attempted state transition is allowed.
* *
* <p>This job checks if the attempted state transition is in compliance with the state model. This
* job runs during the CHECK phase and should do all necessary consistency and permission checks.
*
* @author Timm Fitschen (t.fitschen@indiscale.com) * @author Timm Fitschen (t.fitschen@indiscale.com)
*/ */
@JobAnnotation(time = JobExecutionTime.CHECK, transaction = WriteTransaction.class) @JobAnnotation(time = JobExecutionTime.CHECK, transaction = WriteTransaction.class)
...@@ -41,7 +67,7 @@ public class CheckStateTransition extends EntityStateJob { ...@@ -41,7 +67,7 @@ public class CheckStateTransition extends EntityStateJob {
checkStateTransition(oldState, newState); checkStateTransition(oldState, newState);
} else if (getEntity() instanceof DeleteEntity) { } else if (getEntity() instanceof DeleteEntity) {
if (newState != null) checkFinalState(newState); if (newState != null) checkFinalState(newState);
} else { } else { // fresh Entity
if (newState != null) checkInitialState(newState); if (newState != null) checkInitialState(newState);
} }
} catch (Message m) { } catch (Message m) {
...@@ -52,6 +78,8 @@ public class CheckStateTransition extends EntityStateJob { ...@@ -52,6 +78,8 @@ public class CheckStateTransition extends EntityStateJob {
/** /**
* Check if the state belongs to the state model. * Check if the state belongs to the state model.
* *
* <p>In practical terms, throw a Message if the state is invalid.
*
* @param state * @param state
* @throws Message * @throws Message
*/ */
...@@ -65,6 +93,10 @@ public class CheckStateTransition extends EntityStateJob { ...@@ -65,6 +93,10 @@ public class CheckStateTransition extends EntityStateJob {
/** /**
* Check if state is valid and transition is allowed. * Check if state is valid and transition is allowed.
* *
* <p>Especially, transitions between {@code null} states are allowed, non-trivial transitions
* from or to {@code null} must be initial or final states, respectively ({@link
* FORCE_FINAL_STATE} exception applies).
*
* @param oldState * @param oldState
* @param newState * @param newState
* @throws Message if not * @throws Message if not
...@@ -98,6 +130,8 @@ public class CheckStateTransition extends EntityStateJob { ...@@ -98,6 +130,8 @@ public class CheckStateTransition extends EntityStateJob {
} }
/** /**
* Return the two State's common StateModel, or {@code null} if they don't have one in common.
*
* @param oldState * @param oldState
* @param newState * @param newState
* @return the state model which contains both of the states. * @return the state model which contains both of the states.
......
/*
* ** 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.jobs.core; package org.caosdb.server.jobs.core;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -27,24 +50,25 @@ import org.caosdb.server.utils.EntityStatus; ...@@ -27,24 +50,25 @@ import org.caosdb.server.utils.EntityStatus;
import org.jdom2.Element; import org.jdom2.Element;
/** /**
* The EntityStateJob is the abstract base class for four EntityJobs. * The EntityStateJob is the abstract base class for four EntityJobs:
* *
* <p>1. The InitEntityState job reads ClientMessages or StateProperties with tag state and converts * <p>1. The {@link InitEntityState} job reads ClientMessages or StateProperties with tag state and
* them into instances of State. This job runs during WriteTransactions. This job runs during the * converts them into instances of State. This job runs during WriteTransactions. This job runs
* INIT Phase and does not perform any checks other than those necessary for the conversion. * during the INIT Phase and does not perform any checks other than those necessary for the
* conversion.
* *
* <p>2. The CheckStateTransition job checks if the attempted state transition is in compliance with * <p>2. The {@link CheckStateTransition} job checks if the attempted state transition is in
* the state model. This job runs during the CHECK phase and should do all necessary consistency and * compliance with the state model. This job runs during the CHECK phase and should do all necessary
* permission checks. * consistency and permission checks.
* *
* <p>3. The MakeStateProperty job constructs an ordinary Property from the State right before the * <p>3. The {@link MakeStateProperty} job constructs an ordinary Property from the State right
* entity is being written to the back-end and after any checks run. * before the entity is being written to the back-end and after any checks run.
* *
* <p>4. The MakeStateMessage job converts a state property (back) into State messages and appends * <p>4. The {@link MakeStateMessage} job converts a state property (back) into State messages and
* them to the entity. * appends them to the entity.
* *
* <p>Only the 4th job runs during Retrieve transitions. During WriteTransactions all four jobs do * <p>Only the 4th job ({@link MakeStateMessage}) runs during Retrieve transitions. During
* run. * WriteTransactions all four jobs do run.
* *
* @author Timm Fitschen (t.fitschen@indiscale.com) * @author Timm Fitschen (t.fitschen@indiscale.com)
*/ */
...@@ -91,6 +115,10 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -91,6 +115,10 @@ public abstract class EntityStateJob extends EntityJob {
private State toState; private State toState;
private String name; private String name;
/**
* @param transition The transition Entity, from which the Transition is created. Relevant
* Properties are "to" and "from"
*/
public Transition(EntityInterface transition) throws Message { public Transition(EntityInterface transition) throws Message {
this.name = transition.getName(); this.name = transition.getName();
this.fromState = getFromState(transition); this.fromState = getFromState(transition);
...@@ -167,9 +195,9 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -167,9 +195,9 @@ public abstract class EntityStateJob extends EntityJob {
} }
/** /**
* The State instance represents a single entity state. This class is used for concrete state (the * The State instance represents a single entity state. This class is used for concrete states
* state of a stateful entity, say a Record) and abstract states (states which belong to a * (the state of a stateful entity, say a Record) and abstract states (states which are part of a
* StateModel entity). * {@link StateModel}).
* *
* <p>States are identified via their name and the name of the model to which they belong. * <p>States are identified via their name and the name of the model to which they belong.
* *
...@@ -177,8 +205,8 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -177,8 +205,8 @@ public abstract class EntityStateJob extends EntityJob {
* StateModel iff the StateModel RecordType references the State Record. Each State should only * StateModel iff the StateModel RecordType references the State Record. Each State should only
* belong to one StateModel. * belong to one StateModel.
* *
* <p>Furthermore, States are the start or end point of Transitions which belong to the same * <p>Furthermore, States are the start or end point of {@link Transition Transitions} which
* StateModel. Each State can be part of several transitions at the same time. * belong to the same StateModel. Each State can be part of several transitions at the same time.
* *
* <p>Note: The purpose of this should not be confused with {@link EntityStatus} which is purely * <p>Note: The purpose of this should not be confused with {@link EntityStatus} which is purely
* for internal use. * for internal use.
...@@ -194,6 +222,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -194,6 +222,7 @@ public abstract class EntityStateJob extends EntityJob {
private StateModel stateModel; private StateModel stateModel;
public State(String stateName, String stateModelName) throws Message { public State(String stateName, String stateModelName) throws Message {
// TODO Make constructors private or protected and outsource to caching factory methods.
this.stateName = stateName; this.stateName = stateName;
this.stateModelName = stateModelName; this.stateModelName = stateModelName;
} }
...@@ -220,7 +249,12 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -220,7 +249,12 @@ public abstract class EntityStateJob extends EntityJob {
return 21364234 + this.getStateName().hashCode() + this.getStateModelName().hashCode(); return 21364234 + this.getStateName().hashCode() + this.getStateModelName().hashCode();
} }
/** Serialize this State into XML. */ /**
* Serialize this State into XML.
*
* <p>The result looks approximately like this: {@code <State name="My name" model="Model's
* name"/>}
*/
@Override @Override
public void addToElement(Element ret) { public void addToElement(Element ret) {
Element e = new Element(STATE_XML_TAG); Element e = new Element(STATE_XML_TAG);
...@@ -265,7 +299,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -265,7 +299,7 @@ public abstract class EntityStateJob extends EntityJob {
} }
/** /**
* Create a property which represents the current entity state of a stateful entity. * Create a Property which represents the current entity state of a stateful entity.
* *
* @return stateProperty * @return stateProperty
* @throws Message * @throws Message
...@@ -295,7 +329,27 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -295,7 +329,27 @@ public abstract class EntityStateJob extends EntityJob {
@Override @Override
public String toString() { public String toString() {
return "State (name=" + getStateName() + ", model=" + getStateModelName() + ")"; String isInitial = null;
String isFinal = null;
try {
isInitial = String.valueOf(isInitial());
} catch (Message e) {
isInitial = "null";
}
try {
isFinal = String.valueOf(isFinal());
} catch (Message e) {
isFinal = "null";
}
return "State (name="
+ getStateName()
+ ", model="
+ getStateModelName()
+ ", initial="
+ isInitial
+ ", final="
+ isFinal
+ ")";
} }
} }
...@@ -323,6 +377,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -323,6 +377,7 @@ public abstract class EntityStateJob extends EntityJob {
public StateModel(EntityInterface stateModelEntity) throws Message { public StateModel(EntityInterface stateModelEntity) throws Message {
long time1 = System.currentTimeMillis(); long time1 = System.currentTimeMillis();
// TODO Maybe check if a parent is STATE_MODEL_RECORD_TYPE_NAME?
this.name = stateModelEntity.getName(); this.name = stateModelEntity.getName();
this.transitions = getTransitions(stateModelEntity); this.transitions = getTransitions(stateModelEntity);
this.states = getStates(transitions, this); this.states = getStates(transitions, this);
...@@ -335,6 +390,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -335,6 +390,7 @@ public abstract class EntityStateJob extends EntityJob {
} }
private State getInitialState(EntityInterface stateModelEntity) throws Message { private State getInitialState(EntityInterface stateModelEntity) throws Message {
// TODO maybe check if there is more than one "initial" Property?
for (Property p : stateModelEntity.getProperties()) { for (Property p : stateModelEntity.getProperties()) {
if (p.getName().equals(INITIAL_STATE_PROPERTY_NAME)) { if (p.getName().equals(INITIAL_STATE_PROPERTY_NAME)) {
return createState(p); return createState(p);
...@@ -344,6 +400,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -344,6 +400,7 @@ public abstract class EntityStateJob extends EntityJob {
} }
private State getFinalState(EntityInterface stateModelEntity) throws Message { private State getFinalState(EntityInterface stateModelEntity) throws Message {
// TODO maybe check if there is more than one "final" Property?
for (Property p : stateModelEntity.getProperties()) { for (Property p : stateModelEntity.getProperties()) {
if (p.getName().equals(FINAL_STATE_PROPERTY_NAME)) { if (p.getName().equals(FINAL_STATE_PROPERTY_NAME)) {
return createState(p); return createState(p);
...@@ -352,6 +409,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -352,6 +409,7 @@ public abstract class EntityStateJob extends EntityJob {
return null; return null;
} }
/** Transitions are taken from list Property with name="Transition". */
private Set<Transition> getTransitions(EntityInterface stateModelEntity) throws Message { private Set<Transition> getTransitions(EntityInterface stateModelEntity) throws Message {
for (Property p : stateModelEntity.getProperties()) { for (Property p : stateModelEntity.getProperties()) {
if (p.getName().equals(TRANSITION_RECORD_TYPE_NAME)) { if (p.getName().equals(TRANSITION_RECORD_TYPE_NAME)) {
...@@ -372,6 +430,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -372,6 +430,7 @@ public abstract class EntityStateJob extends EntityJob {
Set<Transition> result = new HashSet<>(); Set<Transition> result = new HashSet<>();
try { try {
if (!(p.getDatatype() instanceof AbstractCollectionDatatype)) { if (!(p.getDatatype() instanceof AbstractCollectionDatatype)) {
// FIXME raise an exception instead?
return result; return result;
} }
p.parseValue(); p.parseValue();
...@@ -402,6 +461,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -402,6 +461,7 @@ public abstract class EntityStateJob extends EntityJob {
*/ */
private Set<State> getStates(Set<Transition> transitions, StateModel stateModel) private Set<State> getStates(Set<Transition> transitions, StateModel stateModel)
throws Message { throws Message {
// TODO Move outside of this class
Iterator<Transition> it = transitions.iterator(); Iterator<Transition> it = transitions.iterator();
Set<State> result = new HashSet<>(); Set<State> result = new HashSet<>();
while (it.hasNext()) { while (it.hasNext()) {
...@@ -452,7 +512,9 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -452,7 +512,9 @@ public abstract class EntityStateJob extends EntityJob {
Iterator<Transition> iterator = this.transitions.iterator(); Iterator<Transition> iterator = this.transitions.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
sb.append(iterator.next().name); sb.append(iterator.next().name);
sb.append(" -> ");
sb.append(iterator.next().name); sb.append(iterator.next().name);
sb.append(", ");
} }
sb.append("])"); sb.append("])");
return sb.toString(); return sb.toString();
...@@ -505,6 +567,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -505,6 +567,7 @@ public abstract class EntityStateJob extends EntityJob {
return getState(getEntity(), remove); return getState(getEntity(), remove);
} }
/** Return (and possibly remove) the States Properties of `entity`. */
protected List<Property> getStateProperties(EntityInterface entity, boolean remove) { protected List<Property> getStateProperties(EntityInterface entity, boolean remove) {
Iterator<Property> it = entity.getProperties().iterator(); Iterator<Property> it = entity.getProperties().iterator();
List<Property> result = new ArrayList<>(); List<Property> result = new ArrayList<>();
...@@ -527,6 +590,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -527,6 +590,7 @@ public abstract class EntityStateJob extends EntityJob {
return getStateProperties(getEntity(), remove); return getStateProperties(getEntity(), remove);
} }
/** Get the {@code ClientMessage}s which denote a state. */
protected List<ClientMessage> getStateClientMessages(EntityInterface entity, boolean remove) { protected List<ClientMessage> getStateClientMessages(EntityInterface entity, boolean remove) {
Iterator<Message> stateMessages = entity.getMessages(STATE_XML_TAG).iterator(); Iterator<Message> stateMessages = entity.getMessages(STATE_XML_TAG).iterator();
List<ClientMessage> result = new ArrayList<>(); List<ClientMessage> result = new ArrayList<>();
...@@ -561,13 +625,15 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -561,13 +625,15 @@ public abstract class EntityStateJob extends EntityJob {
/** /**
* Create a State instance from the value of the state property. * Create a State instance from the value of the state property.
* *
* <p>This method also retrieves the state entity from the back-end. * <p>This method also retrieves the state entity from the back-end. The StateModel is deduced
* from finding an appropriately referencing StateModel Record.
* *
* @param p the entity's state property * @param p the entity's state property
* @return The state of the entity * @return The state of the entity
* @throws Message * @throws Message
*/ */
protected State createState(Property p) throws Message { protected State createState(Property p) throws Message {
// TODO this should be cached
try { try {
p.parseValue(); p.parseValue();
ReferenceValue refid = (ReferenceValue) p.getValue(); ReferenceValue refid = (ReferenceValue) p.getValue();
...@@ -584,6 +650,7 @@ public abstract class EntityStateJob extends EntityJob { ...@@ -584,6 +650,7 @@ public abstract class EntityStateJob extends EntityJob {
EntityInterface findStateModel(EntityInterface stateEntity) throws Exception { EntityInterface findStateModel(EntityInterface stateEntity) throws Exception {
// TODO this should be cached // TODO this should be cached
// TODO This should throw a meaningful Exception if no matching StateModel can be found.
TransactionContainer c = new TransactionContainer(); TransactionContainer c = new TransactionContainer();
Query query = Query query =
new Query( new Query(
......
/*
* ** 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.jobs.core; package org.caosdb.server.jobs.core;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -19,8 +42,8 @@ import org.caosdb.server.utils.Observable; ...@@ -19,8 +42,8 @@ import org.caosdb.server.utils.Observable;
import org.caosdb.server.utils.Observer; import org.caosdb.server.utils.Observer;
/** /**
* Initialize the other entity jobs by converting the client message with type "State" into {@link * Initialize the other entity jobs by converting the client message with type "State" or
* State} instances. * StateProperties into {@link State} instances.
* *
* <p>This job also needs to initialize the other jobs even if the current entity version does not * <p>This job also needs to initialize the other jobs even if the current entity version does not
* have a state anymore but the previous version had, because it has to be checked if the stateModel * have a state anymore but the previous version had, because it has to be checked if the stateModel
...@@ -105,7 +128,8 @@ public class InitEntityStateJobs extends EntityStateJob implements Observer { ...@@ -105,7 +128,8 @@ public class InitEntityStateJobs extends EntityStateJob implements Observer {
} }
/** /**
* Returns a list of states as the are represented as properties or client messages in the entity. * Return a list of states from their representations as properties or client messages in the
* entity.
* *
* @param entity * @param entity
* @return list of state instances for the entity. * @return list of state instances for the entity.
......
/*
* ** 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.jobs.core; package org.caosdb.server.jobs.core;
import java.util.List; import java.util.List;
......
/*
* ** 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.jobs.core; package org.caosdb.server.jobs.core;
import org.caosdb.server.entity.Message; import org.caosdb.server.entity.Message;
...@@ -5,6 +28,10 @@ import org.caosdb.server.jobs.JobAnnotation; ...@@ -5,6 +28,10 @@ import org.caosdb.server.jobs.JobAnnotation;
import org.caosdb.server.jobs.JobExecutionTime; import org.caosdb.server.jobs.JobExecutionTime;
import org.caosdb.server.transaction.WriteTransaction; import org.caosdb.server.transaction.WriteTransaction;
/**
* This job constructs an ordinary Property from the State right before the entity is being written
* to the back-end and after any checks run.
*/
@JobAnnotation(transaction = WriteTransaction.class, time = JobExecutionTime.PRE_TRANSACTION) @JobAnnotation(transaction = WriteTransaction.class, time = JobExecutionTime.PRE_TRANSACTION)
public class MakeStateProperty extends EntityStateJob { public class MakeStateProperty extends EntityStateJob {
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
* *
* Copyright (C) 2018 Research Group Biomedical Physics, * Copyright (C) 2018 Research Group Biomedical Physics,
* Max-Planck-Institute for Dynamics and Self-Organization Göttingen * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
* 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 * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
......
...@@ -37,6 +37,7 @@ public abstract class AbstractObservable implements Observable { ...@@ -37,6 +37,7 @@ public abstract class AbstractObservable implements Observable {
return this.observers.add(o); return this.observers.add(o);
} }
/** @param e A String denoting the notification event. */
@Override @Override
public void notifyObservers(final String e) { public void notifyObservers(final String e) {
if (this.observers != null) { if (this.observers != null) {
......
...@@ -25,6 +25,8 @@ package org.caosdb.server.utils; ...@@ -25,6 +25,8 @@ package org.caosdb.server.utils;
public interface Observer { public interface Observer {
/** /**
* Notify this observer that an event {@code e} has happened to the {@code sender}.
*
* @param e * @param e
* @param sender * @param sender
* @return true, iff the Observable has to keep it in the list of observers. * @return true, iff the Observable has to keep it in the list of observers.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment