Skip to content

Commit

Permalink
#4235 - Direct access-by-URL to sidebar curation mode sometimes does …
Browse files Browse the repository at this point in the history
…not work

- Introduce a new event "PreparingToOpenDocumentEvent" which gives the curation sidebar the opportunity to set the data owner to the curation target before actually starting to load the document.
- Improve debug/trace logging
- Modernizing some terminologies and use var
  • Loading branch information
reckart committed Oct 12, 2023
1 parent e4f5e0d commit 5bfd9de
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.RequestHandlerExecutor.ReplaceHandlerException;
import org.apache.wicket.request.Url;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
Expand Down Expand Up @@ -85,7 +84,7 @@ public abstract class AnnotationPageBase
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

public static final String PAGE_PARAM_DOCUMENT = "d";
public static final String PAGE_PARAM_USER = "u";
public static final String PAGE_PARAM_DATA_OWNER = "u";
public static final String PAGE_PARAM_FOCUS = "f";

private @SpringBean AnnotationSchemaService annotationService;
Expand All @@ -102,30 +101,34 @@ protected AnnotationPageBase(PageParameters aParameters)
super(aParameters);

var params = getPageParameters();
StringValue documentParameter = params.get(PAGE_PARAM_DOCUMENT);
StringValue userParameter = params.get(PAGE_PARAM_USER);
var documentParameter = params.get(PAGE_PARAM_DOCUMENT);
var userParameter = params.get(PAGE_PARAM_DATA_OWNER);

// If the page was accessed using an URL form ending in a document ID, let's move
// the document ID into the fragment and redirect to the form without the document ID.
// This ensures that any links on the page do not carry the document ID, so that we can
// happily switch between documents using AJAX without having to worry about links with
// a document ID potentially sending us back to a specific document.
if (!documentParameter.isEmpty()) {
RequestCycle requestCycle = getRequestCycle();
Url clientUrl = requestCycle.getRequest().getClientUrl();
var requestCycle = getRequestCycle();
var clientUrl = requestCycle.getRequest().getClientUrl();
clientUrl.resolveRelative(Url.parse("./"));
List<String> fragmentParams = new ArrayList<>();
var fragmentParams = new ArrayList<String>();
fragmentParams.add(format("%s=%s", PAGE_PARAM_DOCUMENT, documentParameter.toString()));
params.remove(PAGE_PARAM_DOCUMENT);
if (!userParameter.isEmpty()) {
fragmentParams.add(format("%s=%s", PAGE_PARAM_USER, userParameter.toString()));
params.remove(PAGE_PARAM_USER);
fragmentParams
.add(format("%s=%s", PAGE_PARAM_DATA_OWNER, userParameter.toString()));
params.remove(PAGE_PARAM_DATA_OWNER);
}
for (var namedParam : params.getAllNamed()) {
clientUrl.setQueryParameter(namedParam.getKey(), namedParam.getValue());
}
clientUrl.setFragment("!" + fragmentParams.stream().collect(joining("&")));
String url = requestCycle.getUrlRenderer().renderRelativeUrl(clientUrl);
var url = requestCycle.getUrlRenderer().renderRelativeUrl(clientUrl);
LOG.trace(
"Pushing parameter for document [{}] and user [{}] into fragment: {} (URL redirect)",
documentParameter, userParameter, url);
throw new RedirectToUrlException(url.toString());
}
}
Expand Down Expand Up @@ -198,18 +201,18 @@ protected UrlParametersReceivingBehavior createUrlFragmentBehavior()
protected void onParameterArrival(IRequestParameters aRequestParameters,
AjaxRequestTarget aTarget)
{
StringValue document = aRequestParameters.getParameterValue(PAGE_PARAM_DOCUMENT);
StringValue focus = aRequestParameters.getParameterValue(PAGE_PARAM_FOCUS);
StringValue user = aRequestParameters.getParameterValue(PAGE_PARAM_USER);
var document = aRequestParameters.getParameterValue(PAGE_PARAM_DOCUMENT);
var focus = aRequestParameters.getParameterValue(PAGE_PARAM_FOCUS);
var user = aRequestParameters.getParameterValue(PAGE_PARAM_DATA_OWNER);

// nothing changed, do not check for project, because inception always opens
// on a project
if (document.isEmpty() && focus.isEmpty()) {
return;
}

SourceDocument previousDoc = getModelObject().getDocument();
User aPreviousUser = getModelObject().getUser();
LOG.trace("URL fragment update: {}@{} focus {}", user, document, focus);

var previousDoc = getModelObject().getDocument();
var aPreviousUser = getModelObject().getUser();
handleParameters(document, focus, user);

updateDocumentView(aTarget, previousDoc, aPreviousUser, focus);
Expand All @@ -220,6 +223,20 @@ protected void onParameterArrival(IRequestParameters aRequestParameters,
protected abstract void handleParameters(StringValue aDocumentParameter,
StringValue aFocusParameter, StringValue aUser);

/**
* Switch between documents. Note that the document and data owner to switch to are obtained
* from the {@link AnnotatorState}. The parameters indicate the the old document and data owner
* before the switch!
*
* @param aTarget
* a request target.
* @param aPreviousDocument
* the document before the switch.
* @param aPreviousUser
* the data owner before the switch.
* @param aFocusParameter
* the focus before the switch.
*/
protected abstract void updateDocumentView(AjaxRequestTarget aTarget,
SourceDocument aPreviousDocument, User aPreviousUser, StringValue aFocusParameter);

Expand Down Expand Up @@ -512,14 +529,14 @@ private class UrlFragmentUpdateListener
@Override
public void onTargetRespond(AjaxRequestTarget aTarget)
{
AnnotatorState state = getModelObject();
var state = getModelObject();

if (state.getDocument() == null) {
return;
}

Long currentDocumentId = state.getDocument().getId();
int currentFocusUnitIndex = state.getFocusUnitIndex();
var currentDocumentId = state.getDocument().getId();
var currentFocusUnitIndex = state.getFocusUnitIndex();

// Check if the relevant parameters have actually changed since the URL parameters were
// last set - if this is not the case, then let's not set the parameters because that
Expand All @@ -533,7 +550,7 @@ public void onTargetRespond(AjaxRequestTarget aTarget)
urlFragmentLastDocumentId = currentDocumentId;
urlFragmentLastFocusUnitIndex = currentFocusUnitIndex;

UrlFragment fragment = new UrlFragment(aTarget);
var fragment = new UrlFragment(aTarget);

fragment.putParameter(PAGE_PARAM_DOCUMENT, currentDocumentId);

Expand All @@ -549,10 +566,10 @@ public void onTargetRespond(AjaxRequestTarget aTarget)
// the CURATION_USER here.
if (Set.of(userRepository.getCurrentUsername(), CURATION_USER)
.contains(state.getUser().getUsername())) {
fragment.removeParameter(PAGE_PARAM_USER);
fragment.removeParameter(PAGE_PARAM_DATA_OWNER);
}
else {
fragment.putParameter(PAGE_PARAM_USER, state.getUser().getUsername());
fragment.putParameter(PAGE_PARAM_DATA_OWNER, state.getUser().getUsername());
}

// If we do not manually set editedFragment to false, then changing the URL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Licensed to the Technische Universität Darmstadt under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The Technische Universität Darmstadt
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.
*
* 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.inception.annotation.events;

import org.springframework.context.ApplicationEvent;

import de.tudarmstadt.ukp.clarin.webanno.api.annotation.page.AnnotationPageBase;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.clarin.webanno.support.wicket.event.HybridApplicationUIEvent;
import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState;

/**
* Fire this event to give listeners a chance to look at or even modify the {@link AnnotatorState}
* before actually loading the data.
*/
public class PreparingToOpenDocumentEvent
extends ApplicationEvent
implements HybridApplicationUIEvent
{
private static final long serialVersionUID = -5971290341142438144L;

private final SourceDocument document;
// user who owns/annotates the opened document
private final String documentOwner;
// user who opened the document
private final String sessionOwner;

public PreparingToOpenDocumentEvent(AnnotationPageBase aSource, SourceDocument aDocument,
String aDocumentOwner, String aSessionOwner)
{
super(aSource);
document = aDocument;
documentOwner = aDocumentOwner;
sessionOwner = aSessionOwner;
}

public SourceDocument getDocument()
{
return document;
}

public String getSessionOwner()
{
return sessionOwner;
}

public String getDocumentOwner()
{
return documentOwner;
}

@Override
public AnnotationPageBase getSource()
{
return (AnnotationPageBase) super.getSource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import de.tudarmstadt.ukp.clarin.webanno.api.event.AfterCasWrittenEvent;
import de.tudarmstadt.ukp.inception.annotation.events.BeforeDocumentOpenedEvent;
import de.tudarmstadt.ukp.inception.annotation.events.PreparingToOpenDocumentEvent;

@ConfigurationProperties("event-logging")
public class EventLoggingPropertiesImpl
Expand All @@ -37,6 +38,7 @@ public class EventLoggingPropertiesImpl
AvailabilityChangeEvent.class.getSimpleName(), //
"RecommenderTaskNotificationEvent", //
BeforeDocumentOpenedEvent.class.getSimpleName(), //
PreparingToOpenDocumentEvent.class.getSimpleName(), //
"BrokerAvailabilityEvent", //
"ShutdownDialogAvailableEvent");

Expand Down
Loading

0 comments on commit 5bfd9de

Please sign in to comment.