/*
* Copyright 2012
* Ubiquitous Knowledge Processing (UKP) Lab and FG Language Technology
* Technische Universität Darmstadt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.tudarmstadt.ukp.clarin.webanno.ui.curation.page;
import static de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.selectByAddr;
import static org.apache.uima.fit.util.JCasUtil.select;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.uima.UIMAException;
import org.apache.uima.jcas.JCas;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnLoadHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.NumberTextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.security.core.context.SecurityContextHolder;
import org.wicketstuff.annotation.mount.MountPath;
import de.tudarmstadt.ukp.clarin.webanno.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.clarin.webanno.api.CorrectionDocumentService;
import de.tudarmstadt.ukp.clarin.webanno.api.DocumentService;
import de.tudarmstadt.ukp.clarin.webanno.api.ProjectService;
import de.tudarmstadt.ukp.clarin.webanno.api.SecurityUtil;
import de.tudarmstadt.ukp.clarin.webanno.api.SettingsService;
import de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.AnnotationException;
import de.tudarmstadt.ukp.clarin.webanno.api.annotation.model.AnnotatorState;
import de.tudarmstadt.ukp.clarin.webanno.api.annotation.model.AnnotatorStateImpl;
import de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil;
import de.tudarmstadt.ukp.clarin.webanno.constraints.ConstraintsService;
import de.tudarmstadt.ukp.clarin.webanno.curation.storage.CurationDocumentService;
import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocument;
import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationDocumentState;
import de.tudarmstadt.ukp.clarin.webanno.model.Mode;
import de.tudarmstadt.ukp.clarin.webanno.model.Project;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocumentState;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocumentStateTransition;
import de.tudarmstadt.ukp.clarin.webanno.security.UserDao;
import de.tudarmstadt.ukp.clarin.webanno.security.model.User;
import de.tudarmstadt.ukp.clarin.webanno.support.dialog.ConfirmationDialog;
import de.tudarmstadt.ukp.clarin.webanno.support.lambda.LambdaAjaxLink;
import de.tudarmstadt.ukp.clarin.webanno.support.lambda.LambdaAjaxSubmitLink;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.AnnotationPageBase;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.PreferencesUtil;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.component.AnnotationPreferencesModalPanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.component.DocumentNamePanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.component.ExportModalPanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.component.GuidelineModalPanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.dialog.OpenDocumentDialog;
import de.tudarmstadt.ukp.clarin.webanno.ui.core.menu.MenuItem;
import de.tudarmstadt.ukp.clarin.webanno.ui.core.menu.MenuItemCondition;
import de.tudarmstadt.ukp.clarin.webanno.ui.curation.component.CurationPanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.curation.component.model.CurationContainer;
import de.tudarmstadt.ukp.clarin.webanno.ui.curation.component.model.SuggestionBuilder;
import de.tudarmstadt.ukp.clarin.webanno.ui.curation.dialog.ReCreateMergeCASModalPanel;
import de.tudarmstadt.ukp.clarin.webanno.ui.curation.dialog.ReMergeCasModel;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Sentence;
import wicket.contrib.input.events.EventType;
import wicket.contrib.input.events.InputBehavior;
import wicket.contrib.input.events.key.KeyType;
/**
* This is the main class for the curation page. It contains an interface which displays differences
* between user annotations for a specific document. The interface provides a tool for merging these
* annotations and storing them as a new annotation.
*
*/
@MenuItem(icon="images/data_table.png", label="Curation", prio=200)
@MountPath("/curation.html")
public class CurationPage
extends AnnotationPageBase
{
private final static Logger LOG = LoggerFactory.getLogger(CurationPage.class);
private static final long serialVersionUID = 1378872465851908515L;
private @SpringBean DocumentService documentService;
private @SpringBean CorrectionDocumentService correctionDocumentService;
private @SpringBean CurationDocumentService curationDocumentService;
private @SpringBean ProjectService projectService;
private @SpringBean ConstraintsService constraintsService;
private @SpringBean SettingsService settingsService;
private @SpringBean AnnotationSchemaService annotationService;
private @SpringBean UserDao userRepository;
private NumberTextField<Integer> gotoPageTextField;
private DocumentNamePanel documentNamePanel;
private long currentprojectId;
// Open the dialog window on first load
private boolean firstLoad = true;
private ModalWindow openDocumentsModal;
private ReMergeCasModel reMerge;
private CurationContainer curationContainer;
private CurationPanel curationPanel;
private AjaxLink<Void> showreCreateMergeCasModal;
private ModalWindow reCreateMergeCas;
private WebMarkupContainer finishDocumentIcon;
private ConfirmationDialog finishDocumentDialog;
private LambdaAjaxLink finishDocumentLink;
public CurationPage()
{
setModel(Model.of(new AnnotatorStateImpl(Mode.CURATION)));
reMerge = new ReMergeCasModel();
curationContainer = new CurationContainer();
curationContainer.setBratAnnotatorModel(getModelObject());
curationPanel = new CurationPanel("curationPanel", new Model<CurationContainer> (
curationContainer))
{
private static final long serialVersionUID = 2175915644696513166L;
@Override
protected void onChange(AjaxRequestTarget aTarget)
{
try {
actionRefreshDocument(aTarget, getEditorCas());
}
catch (Exception e) {
handleException(aTarget, e);
}
//
// AnnotatorState state = CurationPage.this.getModelObject();
// JCas mergeJCas = null;
// try {
// mergeJCas = repository.readCurationCas(state.getDocument());
// }
// catch (Exception e) {
// aTarget.add(getFeedbackPanel());
// LOG.error("Unable to load data", e);
// error("Unable to load data: " + ExceptionUtils.getRootCauseMessage(e));
// }
// aTarget.add(numberOfPages);
// gotoPageTextField.setModelObject(state.getFirstVisibleSentenceNumber());
// gotoPageAddress = getSentenceAddress(mergeJCas, gotoPageTextField.getModelObject());
// aTarget.add(gotoPageTextField);
// aTarget.add(curationPanel);
}
};
add(curationPanel);
add(documentNamePanel = new DocumentNamePanel("documentNamePanel", getModel()));
documentNamePanel.setOutputMarkupId(true);
add(getOrCreatePositionInfoLabel());
add(openDocumentsModal = new OpenDocumentDialog("openDocumentsModal", getModel(),
getAllowedProjects())
{
private static final long serialVersionUID = 5474030848589262638L;
@Override
public void onDocumentSelected(AjaxRequestTarget aTarget)
{
AnnotatorState state = getModelObject();
String username = SecurityContextHolder.getContext().getAuthentication().getName();
/*
* Changed for #152, getDocument was returning null even after opening a document
* Also, surrounded following code into if block to avoid error.
*/
if (state.getProject() == null) {
setResponsePage(getApplication().getHomePage());
return;
}
if (state.getDocument() != null) {
try {
documentService.createSourceDocument(state.getDocument());
documentService.upgradeCasAndSave(state.getDocument(), state.getMode(), username);
actionLoadDocument(aTarget);
curationPanel.editor.loadFeatureEditorModels(aTarget);
}
catch (Exception e) {
LOG.error("Unable to load data", e);
error("Unable to load data: " + ExceptionUtils.getRootCauseMessage(e));
}
}
}
});
add(new AnnotationPreferencesModalPanel("annotationLayersModalPanel", getModel(),
curationPanel.editor)
{
private static final long serialVersionUID = -4657965743173979437L;
@Override
protected void onChange(AjaxRequestTarget aTarget)
{
actionCompletePreferencesChange(aTarget);
}
});
add(new ExportModalPanel("exportModalPanel", getModel())
{
private static final long serialVersionUID = -468896211970839443L;
{
setOutputMarkupId(true);
setOutputMarkupPlaceholderTag(true);
}
@Override
protected void onConfigure()
{
super.onConfigure();
AnnotatorState state = CurationPage.this.getModelObject();
setVisible(state.getProject() != null
&& (SecurityUtil.isAdmin(state.getProject(), projectService, state.getUser())
|| !state.getProject().isDisableExport()));
}
});
Form<Void> gotoPageTextFieldForm = new Form<Void>("gotoPageTextFieldForm");
gotoPageTextField = new NumberTextField<Integer>("gotoPageText", Model.of(1), Integer.class);
// FIXME minimum and maximum should be obtained from the annotator state
gotoPageTextField.setMinimum(1);
gotoPageTextField.setOutputMarkupId(true);
gotoPageTextFieldForm.add(gotoPageTextField);
gotoPageTextFieldForm.add(new LambdaAjaxSubmitLink("gotoPageLink", gotoPageTextFieldForm,
this::actionGotoPage));
add(gotoPageTextFieldForm);
add(reCreateMergeCas = new ModalWindow("reCreateMergeCasModal"));
reCreateMergeCas.setOutputMarkupId(true);
//Change size if you change text here
reCreateMergeCas.setInitialWidth(580);
reCreateMergeCas.setInitialHeight(40);
reCreateMergeCas.setResizable(true);
reCreateMergeCas.setWidthUnit("px");
reCreateMergeCas.setHeightUnit("px");
reCreateMergeCas
.setTitle("Are you sure? All curation annotations for this document will be lost.");
add(showreCreateMergeCasModal = new AjaxLink<Void>("showreCreateMergeCasModal")
{
private static final long serialVersionUID = 7496156015186497496L;
@Override
protected void onConfigure()
{
AnnotatorState state = CurationPage.this.getModelObject();
setEnabled(state.getDocument() != null
&& !state.getDocument().getState()
.equals(SourceDocumentState.CURATION_FINISHED));
}
@Override
public void onClick(AjaxRequestTarget aTarget)
{
actionRemergeDocument(aTarget);
}
});
showreCreateMergeCasModal.setOutputMarkupId(true);
add(new GuidelineModalPanel("guidelineModalPanel", getModel()));
add(new LambdaAjaxLink("showOpenDocumentModal", this::actionShowOpenDocumentDialog));
add(new LambdaAjaxLink("showPreviousDocument", t -> actionShowPreviousDocument(t))
.add(new InputBehavior(new KeyType[] { KeyType.Shift, KeyType.Page_up },
EventType.click)));
add(new LambdaAjaxLink("showNextDocument", t -> actionShowNextDocument(t))
.add(new InputBehavior(new KeyType[] { KeyType.Shift, KeyType.Page_down },
EventType.click)));
add(new LambdaAjaxLink("showNext", t -> actionShowNextPage(t))
.add(new InputBehavior(new KeyType[] { KeyType.Page_down }, EventType.click)));
add(new LambdaAjaxLink("showPrevious", t -> actionShowPreviousPage(t))
.add(new InputBehavior(new KeyType[] { KeyType.Page_up }, EventType.click)));
add(new LambdaAjaxLink("showFirst", t -> actionShowFirstPage(t))
.add(new InputBehavior(new KeyType[] { KeyType.Home }, EventType.click)));
add(new LambdaAjaxLink("showLast", t -> actionShowLastPage(t))
.add(new InputBehavior(new KeyType[] { KeyType.End }, EventType.click)));
add(new LambdaAjaxLink("toggleScriptDirection", this::actionToggleScriptDirection));
add(finishDocumentDialog = new ConfirmationDialog("finishDocumentDialog",
new StringResourceModel("FinishDocumentDialog.title", this, null),
new StringResourceModel("FinishDocumentDialog.text", this, null)));
add(finishDocumentLink = new LambdaAjaxLink("showFinishDocumentDialog",
this::actionFinishDocument)
{
private static final long serialVersionUID = 874573384012299998L;
@Override
protected void onConfigure()
{
super.onConfigure();
AnnotatorState state = CurationPage.this.getModelObject();
setEnabled(state.getProject() != null && state.getDocument() != null
&& !documentService
.getSourceDocument(state.getDocument().getProject(),
state.getDocument().getName())
.getState().equals(SourceDocumentState.CURATION_FINISHED));
}
});
finishDocumentIcon = new WebMarkupContainer("finishImage");
finishDocumentIcon.setOutputMarkupId(true);
finishDocumentIcon.add(new AttributeModifier("src", new LoadableDetachableModel<String>()
{
private static final long serialVersionUID = 1562727305401900776L;
@Override
protected String load()
{
AnnotatorState state = CurationPage.this.getModelObject();
if (state.getProject() != null && state.getDocument() != null) {
if (documentService
.getSourceDocument(state.getDocument().getProject(),
state.getDocument().getName()).getState()
.equals(SourceDocumentState.CURATION_FINISHED)) {
return "images/accept.png";
}
else {
return "images/inprogress.png";
}
}
else {
return "images/inprogress.png";
}
}
}));
finishDocumentLink.add(finishDocumentIcon);
}
private IModel<List<Pair<Project, String>>> getAllowedProjects()
{
return new LoadableDetachableModel<List<Pair<Project, String>>>()
{
private static final long serialVersionUID = -2518743298741342852L;
@Override
protected List<Pair<Project, String>> load()
{
User user = userRepository.get(
SecurityContextHolder.getContext().getAuthentication().getName());
List<Pair<Project, String>> allowedProject = new ArrayList<>();
List<Project> projectsWithFinishedAnnos = projectService.listProjectsWithFinishedAnnos();
for (Project project : projectService.listProjects()) {
if (SecurityUtil.isCurator(project, projectService, user)) {
if (projectsWithFinishedAnnos.contains(project)) {
allowedProject.add(Pair.of(project, "#008000"));
}
else {
allowedProject.add(Pair.of(project, "#99cc99"));
}
}
}
return allowedProject;
}
};
}
@Override
public void setModel(IModel<AnnotatorState> aModel)
{
setDefaultModel(aModel);
}
@Override
@SuppressWarnings("unchecked")
public IModel<AnnotatorState> getModel()
{
return (IModel<AnnotatorState>) getDefaultModel();
}
@Override
public void setModelObject(AnnotatorState aModel)
{
setDefaultModelObject(aModel);
}
@Override
public AnnotatorState getModelObject()
{
return (AnnotatorState) getDefaultModelObject();
}
@Override
protected List<SourceDocument> getListOfDocs()
{
return curationDocumentService.listCuratableSourceDocuments(getModelObject().getProject());
}
// Update the curation panel.
private void updatePanel(CurationContainer aCurationContainer, AjaxRequestTarget aTarget)
{
AnnotatorState state = getModelObject();
// JCas mergeJCas = null;
// try {
// mergeJCas = repository.readCurationCas(state.getDocument());
// }
// catch (Exception e) {
// aTarget.add(getFeedbackPanel());
// LOG.error("Unable to load data", e);
// error("Unable to load data: " + ExceptionUtils.getRootCauseMessage(e));
// }
gotoPageTextField.setModelObject(state.getFirstVisibleSentenceNumber());
curationPanel.setDefaultModelObject(curationContainer);
aTarget.add(gotoPageTextField);
aTarget.add(curationPanel);
}
/**
* for the first time, open the <b>open document dialog</b>
*/
@Override
public void renderHead(IHeaderResponse response)
{
super.renderHead(response);
String jQueryString = "";
if (firstLoad) {
jQueryString += "jQuery('#showOpenDocumentModal').trigger('click');";
firstLoad = false;
}
response.render(OnLoadHeaderItem.forScript(jQueryString));
}
@Override
protected JCas getEditorCas()
throws IOException
{
AnnotatorState state = getModelObject();
if (state.getDocument() == null) {
throw new IllegalStateException("Please open a document first!");
}
return curationDocumentService.readCurationCas(state.getDocument());
}
private void updateSentenceNumber(JCas aJCas, int aAddress)
{
AnnotatorState state = getModelObject();
Sentence sentence = selectByAddr(aJCas, Sentence.class, aAddress);
state.setFirstVisibleSentence(sentence);
state.setFocusSentenceNumber(WebAnnoCasUtil.getSentenceNumber(aJCas, sentence.getBegin()));
}
private void actionShowOpenDocumentDialog(AjaxRequestTarget aTarget)
{
getModelObject().getSelection().clear();
openDocumentsModal.show(aTarget);
}
private void actionGotoPage(AjaxRequestTarget aTarget, Form<?> aForm)
throws Exception
{
AnnotatorState state = getModelObject();
JCas jcas = getEditorCas();
List<Sentence> sentences = new ArrayList<>(select(jcas, Sentence.class));
int selectedSentence = gotoPageTextField.getModelObject();
selectedSentence = Math.min(selectedSentence, sentences.size());
gotoPageTextField.setModelObject(selectedSentence);
state.setFirstVisibleSentence(sentences.get(selectedSentence - 1));
state.setFocusSentenceNumber(selectedSentence);
actionRefreshDocument(aTarget, jcas);
curationPanel.updatePanel(aTarget, curationContainer);
}
private void actionToggleScriptDirection(AjaxRequestTarget aTarget)
throws UIMAException, ClassNotFoundException, IOException, AnnotationException
{
getModelObject().toggleScriptDirection();
curationPanel.updatePanel(aTarget, curationContainer);
updatePanel(curationContainer, aTarget);
}
private void actionCompletePreferencesChange(AjaxRequestTarget aTarget)
{
AnnotatorState state = CurationPage.this.getModelObject();
// Re-render the whole page because the width of the sidebar may have changed
aTarget.add(CurationPage.this);
aTarget.add(getOrCreatePositionInfoLabel());
JCas mergeCas = null;
try {
aTarget.add(getFeedbackPanel());
mergeCas = curationDocumentService.readCurationCas(state.getDocument());
// The number of visible sentences may have changed - let the state recalculate
// the visible sentences
Sentence sentence = selectByAddr(mergeCas, Sentence.class,
state.getFirstVisibleSentenceAddress());
state.setFirstVisibleSentence(sentence);
curationPanel.updatePanel(aTarget, curationContainer);
updatePanel(curationContainer, aTarget);
updateSentenceNumber(mergeCas, state.getFirstVisibleSentenceAddress());
}
catch (Exception e) {
aTarget.add(getFeedbackPanel());
LOG.error("Unable to load data", e);
error("Unable to load data: " + ExceptionUtils.getRootCauseMessage(e));
}
}
private void actionFinishDocument(AjaxRequestTarget aTarget)
{
finishDocumentDialog.setConfirmAction((aCallbackTarget) -> {
ensureRequiredFeatureValuesSet(aCallbackTarget, getEditorCas());
AnnotatorState state = getModelObject();
SourceDocument sourceDocument = state.getDocument();
if (sourceDocument.getState().equals(SourceDocumentState.CURATION_FINISHED)) {
sourceDocument.setState(SourceDocumentStateTransition.transition(
SourceDocumentStateTransition.CURATION_FINISHED_TO_CURATION_IN_PROGRESS));
}
else {
sourceDocument.setState(SourceDocumentStateTransition.transition(
SourceDocumentStateTransition.CURATION_IN_PROGRESS_TO_CURATION_FINISHED));
sourceDocument.setProcessed(false);
}
documentService.createSourceDocument(sourceDocument);
aCallbackTarget.add(finishDocumentIcon);
aCallbackTarget.add(finishDocumentLink);
aCallbackTarget.add(curationPanel.editor);
aCallbackTarget.add(showreCreateMergeCasModal);
});
finishDocumentDialog.show(aTarget);
}
private void actionRemergeDocument(AjaxRequestTarget aTarget)
{
reCreateMergeCas.setContent(new ReCreateMergeCASModalPanel(reCreateMergeCas.getContentId(),
reCreateMergeCas, reMerge));
reCreateMergeCas.setWindowClosedCallback(new ModalWindow.WindowClosedCallback()
{
private static final long serialVersionUID = 4816615910398625993L;
@Override
public void onClose(AjaxRequestTarget aCallbackTarget)
{
AnnotatorState state = CurationPage.this.getModelObject();
if (reMerge.isReMerege()) {
try {
aCallbackTarget.add(getFeedbackPanel());
curationDocumentService.removeCurationDocumentContent(state.getDocument(),
state.getUser().getUsername());
actionLoadDocument(aCallbackTarget);
aCallbackTarget.appendJavaScript("alert('Re-merge finished!')");
}
catch (Exception e) {
aCallbackTarget.add(getFeedbackPanel());
LOG.error("Unable to load data", e);
error("Unable to load data: " + ExceptionUtils.getRootCauseMessage(e));
}
}
}
});
reCreateMergeCas.show(aTarget);
}
/**
* Open a document or to a different document. This method should be used only the first time
* that a document is accessed. It reset the annotator state and upgrades the CAS.
*/
@Override
protected void actionLoadDocument(AjaxRequestTarget aTarget)
{
LOG.info("BEGIN LOAD_DOCUMENT_ACTION");
AnnotatorState state = getModelObject();
String username = SecurityContextHolder.getContext().getAuthentication().getName();
User user = userRepository.get(username);
state.setUser(user);
try {
// Update source document state to CURRATION_INPROGRESS, if it was not ANNOTATION_FINISHED
if (!state.getDocument().getState().equals(SourceDocumentState.CURATION_FINISHED)) {
state.getDocument().setState(SourceDocumentStateTransition.transition(
SourceDocumentStateTransition.ANNOTATION_IN_PROGRESS_TO_CURATION_IN_PROGRESS));
documentService.createSourceDocument(state.getDocument());
}
// Load user preferences
PreferencesUtil.loadPreferences(username, settingsService, projectService,
annotationService, state, state.getMode());
// Re-render whole page as sidebar size preference may have changed
aTarget.add(CurationPage.this);
List<AnnotationDocument> finishedAnnotationDocuments = new ArrayList<AnnotationDocument>();
for (AnnotationDocument annotationDocument : documentService
.listAnnotationDocuments(state.getDocument())) {
if (annotationDocument.getState().equals(AnnotationDocumentState.FINISHED)) {
finishedAnnotationDocuments.add(annotationDocument);
}
}
SuggestionBuilder cb = new SuggestionBuilder(documentService, correctionDocumentService,
curationDocumentService, annotationService, userRepository);
AnnotationDocument randomAnnotationDocument = null;
if (finishedAnnotationDocuments.size() > 0) {
randomAnnotationDocument = finishedAnnotationDocuments.get(0);
}
// upgrade CASes for each user, what if new type is added once the user finished
// annotation
for (AnnotationDocument ad : finishedAnnotationDocuments) {
documentService.upgradeCasAndSave(ad.getDocument(), state.getMode(), ad.getUser());
}
Map<String, JCas> jCases = cb.listJcasesforCuration(finishedAnnotationDocuments,
randomAnnotationDocument, state.getMode());
JCas mergeJCas = cb.getMergeCas(state, state.getDocument(), jCases,
randomAnnotationDocument);
// (Re)initialize brat model after potential creating / upgrading CAS
state.clearAllSelections();
state.getPreferences().setCurationWindowSize(WebAnnoCasUtil.getSentenceCount(mergeJCas));
// Initialize the visible content
state.setFirstVisibleSentence(WebAnnoCasUtil.getFirstSentence(mergeJCas));
// if project is changed, reset some project specific settings
if (currentprojectId != state.getProject().getId()) {
state.clearRememberedFeatures();
}
currentprojectId = state.getProject().getId();
SuggestionBuilder builder = new SuggestionBuilder(documentService,
correctionDocumentService, curationDocumentService, annotationService,
userRepository);
curationContainer = builder.buildCurationContainer(state);
curationContainer.setBratAnnotatorModel(state);
curationPanel.editor.reset(aTarget);
curationPanel.updatePanel(aTarget, curationContainer);
updatePanel(curationContainer, aTarget);
updateSentenceNumber(mergeJCas, state.getFirstVisibleSentenceAddress());
// Load constraints
state.setConstraints(constraintsService.loadConstraints(state.getProject()));
aTarget.add(getOrCreatePositionInfoLabel());
aTarget.add(documentNamePanel);
aTarget.add(showreCreateMergeCasModal);
aTarget.add(finishDocumentLink);
}
catch (Exception e) {
handleException(aTarget, e);
}
LOG.info("END LOAD_DOCUMENT_ACTION");
}
@Override
protected void actionRefreshDocument(AjaxRequestTarget aTarget, JCas aJCas)
{
try {
aTarget.add(getOrCreatePositionInfoLabel());
curationPanel.updatePanel(aTarget, curationContainer);
updatePanel(curationContainer, aTarget);
}
catch (Exception e) {
handleException(aTarget, e);
}
}
/**
* Only project admins and curators can see this page
*/
@MenuItemCondition
public static boolean menuItemCondition(ProjectService aRepo, UserDao aUserRepo)
{
String username = SecurityContextHolder.getContext().getAuthentication().getName();
User user = aUserRepo.get(username);
return SecurityUtil.curationEnabeled(aRepo, user);
}
}