Commit 17c8db92 authored by Carsten  Rose's avatar Carsten Rose
Browse files

plantuml: sequence diagrams for record locking

parent 1a4781f5
......@@ -30,7 +30,7 @@ qfq.zip:
cd extension; zip -r ../$@ $(EXTENSION_CONTENT)
clean:
rm -f qfq_$(PKG_VERSION).zip
cd doc/diagram ; $(MAKE) $@
update-qfq-doc:
rsync -av --delete --exclude=_make --exclude=_static extension/Documentation/ ../qfq-doc/Documentation/
......@@ -68,17 +68,14 @@ release: bootstrap build-dist
t3sphinx: .virtual_env
. .python_virtualenv/bin/activate ; cd extension/Documentation/_make; make html
plantuml: uml/javascript/classdiagram.pu .support_plantuml
java -jar support/plantuml/plantuml.jar -tpng -o ../../doc/plantuml/javascript uml/javascript/classdiagram.pu
plantuml:
cd doc/diagram ; $(MAKE)
bootstrap: .phpdocinstall .npmpackages .bowerpackages .plantuml_install .virtual_env
npm update
bower update
grunt default
update-jslib:
jsdoc: .npmpackages
$(JSDOC) -c JSDocConf.json
......@@ -93,7 +90,7 @@ phpdoc: .phpdocinstall
pear -c "`pwd`/support/pear.config" install phpdoc/phpDocumentor
touch $@
.plantuml_install: .doc_plantuml .support_plantuml
.plantuml_install: .support_plantuml
wget --no-check-certificate -O support/plantuml/plantuml.jar 'https://downloads.sourceforge.net/project/plantuml/plantuml.jar'
touch $@
......@@ -116,11 +113,6 @@ phpdoc: .phpdocinstall
mkdir -p support/plantuml
touch $@
.doc_plantuml:
mkdir -p doc/plantuml/javascript
mkdir -p doc/plantuml/php
touch $@
.virtual_env: pip-temp-directory
virtualenv .python_virtualenv
. .python_virtualenv/bin/activate ; TMPDIR="$(PIP_TMP)" pip install --upgrade sphinx==1.5.5
......@@ -129,4 +121,4 @@ phpdoc: .phpdocinstall
pip-temp-directory:
test -d "$(PIP_TMP)" || mkdir -p "$(PIP_TMP)"
.PHONY: nightly maintainer-clean snapshot release git-revision t3sphinx build-dist make-dist-dir dist-move-doc dist-copy-extension pip-temp-directory
.PHONY: nightly maintainer-clean snapshot release git-revision t3sphinx build-dist make-dist-dir dist-move-doc dist-copy-extension pip-temp-directory plantuml
PLANTUML ?= ../../support/plantuml/plantuml.jar
TARGETS = $(subst .pu,.png,$(wildcard *.pu))
all: $(TARGETS)
clean:
rm -f *.png
.pu.png:
java -jar $(PLANTUML) -tpng -o . $<
.SUFFIXES: .pu .png
@startuml
actor Alice #FFBBBB
actor Bob #BBBBFF
== Advisory Lock: single user ==
Alice -> form: open page
form -> Alice: form
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
dirty -> Alice: status=success, lock_timeout=<secs>
activate dirty #FFBBBB
...
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: yes
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Alice: status=succes,redirect=client
== Advisory Lock: multi user ==
Alice -> form: open page
form -> Alice: form
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
activate dirty #FFBBBB
dirty -> Alice: status=success, lock_timeout=<secs>
...
Bob -> form: open page
form -> Bob: form
...
Bob -> Bob: edit (first change)
Bob -> dirty: action=lock
dirty -> Bob: status=**conflict_allow_force**,\nlock_timeout=<secs>,\nmessage=Record locked by user Alice
note right: User Bob can edit and save
Bob -> save: Post form
save -> dirty: lock valid?
dirty -> save: no
save -> save: save form
save -> dirty: action=release
dirty->dirty: lock for Alice can't be released by Bob
save -> Bob: status=succes,redirect=client
...
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: yes
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Alice: status=succes,redirect=client
@enduml
\ No newline at end of file
@startuml
actor Alice #FFBBBB
== Exclusive Lock: single user, lock in time ==
Alice -> form: open page
form -> Alice: form
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
dirty -> Alice: status=success, lock_timeout=<secs>
activate dirty #FFBBBB
...
alt press 'save' or press 'save and close'
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: yes
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Alice: status=succes,redirect=client
|||
else press 'form close' or press 'back'
Alice -> dirty: action=release
dirty -> Alice: status=success
end
== Exclusive Lock: single user, lock expired ==
Alice -> form: open page
form -> Alice: form
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
activate dirty #FFBBBB
dirty -> Alice: status=success, lock_timeout=<secs>
...
dirty -> dirty: lock expired
deactivate dirty
alt any user change in form
Alice -> dirty: action=lock
activate dirty
dirty -> Alice: status=success, lock_timeout=<secs>
deactivate dirty
|||
else press 'save' or press 'save and close'
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: no
save -> dirty: extend lock
activate dirty
dirty -> save: ok
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Alice: status=succes,redirect=client
|||
else press 'form close' or press 'back'
Alice -> dirty: action=release
dirty -> Alice: status=success
end
@enduml
\ No newline at end of file
@startuml
actor Alice #FFBBBB
actor Bob #BBBBFF
== Exclusive Lock: multi user, lock in time ==
Alice -> form: open page
form -> Alice: form
Bob -> form: open page
form -> Bob: form
...
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
activate dirty #FFBBBB
dirty -> Alice: status=**success**, lock_timeout=<secs>
...
Bob -> Bob: edit (first change)
Bob -> dirty: action=lock
dirty -> Bob: status=**conflict**, message=Record locked by user ...
note left: Save Button becomes disabled
...
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: yes
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Alice: status=**succes**,redirect=client
== Exclusive Lock: multi user, lock expired & lost ==
Alice -> form: open page
form -> Alice: form
Alice -> Alice: edit (first change)
Alice -> dirty: action=lock
activate dirty #FFBBBB
dirty -> Alice: status=**success**, lock_timeout=<secs>
Bob -> form: open page
form -> Bob: form
...
dirty -> dirty: lock expired
deactivate dirty
|||
Bob -> Bob: edit (first change)
Bob -> dirty: action=lock
activate dirty #DDDDFF
dirty -> Bob: status=**success**, lock_timeout=<secs>
...
Alice -> save: POST form
save -> dirty: lock valid?
dirty -> save: no
save -> Alice: status=**conflict**,redirect=no
note left: Save Button becomes disabled
...
Bob -> save: POST form
save -> dirty: lock valid?
dirty -> save: yes
save -> save: save form
save -> dirty: action=release
deactivate dirty
save -> Bob: status=**succes**,redirect=client
@enduml
\ No newline at end of file
@startuml
scale max 2100*2970
skinparam classAttributeIconSize 0
package "QfqNS" {
class Alert {
+isShown()
+show()
-afterFadeIn()
-cancelButtonHandler()
-countAlertsInAlertContainer()
-getAlertClassbasedOnMessageTyp()
-getButtons()
-makeAlertContainerSingleton()
-buttonHandler()
}
class EventEmitter
class QfqEvents <<mixin>> {
+makePayload()
+onMixin()
}
class BSTabs {
+activateTab()
+getActiveTab()
+getContainingTabIdForFormControl()
+getCurrentTab()
+getTabAnchors()
+getTabIds()
+getTabName()
-fillTabInformation()
-installTabHandlers()
-tabShowHandler()
-getActiveTabFromDOM()
}
class FileDelete {
-setupOnClickHandler()
-buttonClicked()
-performFileDelete()
-prepareData()
-ajaxSuccessHandler()
-ajaxErrorHandler()
}
class FileUpload {
-setupOnChangeHandler()
-performFileUpload()
-prepareData()
-ajaxSuccessHandler()
-ajaxErrorHandler()
}
class Form {
+getFormChanged()
+resetFormChanged()
+submitTo()
+validate()
-ajaxSuccessHandler()
-changeHandler()
-serialize()
-submitFailureHandler()
}
class PageState {
-popStateHandler()
+getPageState()
+getPageData()
+setPageState()
+newPageState()
}
class PageTitle <<static>> {
+set()
+get()
+setSubTitle()
}
class QfqForm {
+getSip()
+isFormChanged()
+submit()
-ajaxDeleteSuccessDispatcher()
-applyElementConfiguration()
-changeHandler()
-clearAllValidationStates()
-destroyFormAndSetText()
-endUploadHandler()
-fileDeleteSuccessHandler()
-fileUploadSuccessHandler()
-formUpdateHandler()
-getCloseButton()
-getDeleteButton()
-getFormGroupByControlName()
-getNewButton()
-getNewButtonTarget()
-getSaveButton()
-handleCloseClick()
-handleDeleteClick()
-handleDeleteSuccess()
-handleFormUpdate()
-handleLogicDeleteError()
-handleLogicSubmitError()
-handleNewClick()
-handleSaveClick()
-handleSubmitSuccess()
-readElementConfigurationData()
-resetHandler()
-resetValidationState()
-setBsTabs()
-setButtonEnabled()
-setHelpBlockValidationMessage()
-setValidationState()
-setupFormUpdateHandler()
-startUploadHandler()
-submitSuccessDispatcher()
}
class QfqPage {
-destroyFormHandler()
-tabShowHandler()
-popStateHandler()
}
class QfqRecordList {
-connectClickHandler()
-handleDeleteButtonClick()
-ajaxDeleteSuccessDispatcher()
-handleDeleteSuccess()
-getRecordElement()
-handleLogicDeleteError()
}
class Log <<static>> {
+message()
+debug()
+warning()
+error()
}
Alert .. FileDelete
Alert .. QfqForm
Alert .. QfqRecordList
Log .. QfqForm
Log .. QfqPage
BSTabs "1" <--* "1" QfqPage
PageState "1" <--* "1" QfqPage
QfqForm "1" <--* "1" QfqPage
PageTitle .. QfqPage
BSTabs "1" <--* "1" QfqForm
Form "1" <--* "1" QfqForm
QfqEvents "1" <--* "1" QfqForm
FileUpload "1" <--* "1" QfqForm
FileDelete "1" <--* "1" QfqForm
QfqEvents <-- Alert
QfqEvents "1" <--* "1" PageState
Log .. PageState
QfqEvents "1" <--* "1" FileUpload
QfqEvents "1" <--* "1" FileDelete
QfqEvents "1" <--* "1" BSTabs
EventEmitter <-- QfqEvents
}
package "QfqNS.Element" {
class Checkbox {
+setValue()
+getValue()
}
class FormGroup {
+hasHelpBlock()
+hasLabel()
+isType()
+setEnabled()
+setHidden()
+setReadOnly()
+setRequired()
-$findFormGroup()
-readOnlyHandler()
}
class Radio {
+setValue()
+getValue()
}
class Select {
+getValue()
+setValue()
-clearSelection()
-setSelection()
}
class Textual {
+setValue()
+getValue()
}
FormGroup <-- Checkbox
FormGroup <-- Radio
FormGroup <-- Select
FormGroup <-- Textual
}
QfqForm .. FormGroup
@enduml
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment