Skip to content

Commit

Permalink
#5325 - Simpler way of adding pre-defined knowledge bases
Browse files Browse the repository at this point in the history
- Added KnowledgeBaseInitializer interface
- Added "Add" button to the knowledge base list
  • Loading branch information
reckart committed Mar 2, 2025
1 parent 3ee308e commit 2ff35ba
Show file tree
Hide file tree
Showing 11 changed files with 1,723 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,20 @@
import static java.util.Collections.emptyList;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Optional;

import org.eclipse.rdf4j.repository.config.RepositoryImplConfig;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.request.resource.ResourceReference;

import de.tudarmstadt.ukp.clarin.webanno.model.Project;
import de.tudarmstadt.ukp.clarin.webanno.project.initializers.KnowledgeBaseInitializer;
import de.tudarmstadt.ukp.inception.kb.KnowledgeBaseService;
import de.tudarmstadt.ukp.inception.kb.config.KnowledgeBaseProperties;
import de.tudarmstadt.ukp.inception.kb.model.KnowledgeBase;
import de.tudarmstadt.ukp.inception.kb.yaml.KnowledgeBaseProfile;
import de.tudarmstadt.ukp.inception.project.api.ProjectInitializationRequest;
import de.tudarmstadt.ukp.inception.project.api.ProjectInitializer;
import de.tudarmstadt.ukp.inception.project.initializers.wikidatalinking.config.WikiDataLinkingProjectInitializersAutoConfiguration;

Expand All @@ -39,10 +44,13 @@
* </p>
*/
public class WikiDataKnowledgeBaseInitializer
implements ProjectInitializer
implements KnowledgeBaseInitializer
{
private static final String WIKIDATA_PROFILE = "wikidata";

private static final PackageResourceReference THUMBNAIL = new PackageResourceReference(
MethodHandles.lookup().lookupClass(), "WikiDataKnowledgeBaseInitializer.svg");

private final KnowledgeBaseService kbService;
private final KnowledgeBaseProfile wikidataProfile;
private final KnowledgeBaseProperties kbProperties;
Expand All @@ -68,6 +76,18 @@ public String getName()
return "Wikidata knowledge base";
}

@Override
public Optional<String> getDescription()
{
return Optional.ofNullable(wikidataProfile.getInfo().getDescription());
}

@Override
public Optional<ResourceReference> getThumbnail()
{
return Optional.of(THUMBNAIL);
}

@Override
public boolean applyByDefault()
{
Expand All @@ -87,16 +107,15 @@ public List<Class<? extends ProjectInitializer>> getDependencies()
}

@Override
public void configure(Project aProject) throws IOException
public void configure(ProjectInitializationRequest aRequest) throws IOException
{
// set all the fields according to the chosen profile
RepositoryImplConfig cfg = kbService
.getRemoteConfig(wikidataProfile.getAccess().getAccessUrl());
var cfg = kbService.getRemoteConfig(wikidataProfile.getAccess().getAccessUrl());

// sets root concepts list - if null then an empty list otherwise change the
// values to IRI and populate the list
KnowledgeBase kb = new KnowledgeBase();
kb.setProject(aProject);
var kb = new KnowledgeBase();
kb.setProject(aRequest.getProject());
kb.setReadOnly(true);
kb.setMaxResults(kbProperties.getDefaultMaxResults());
kb.setType(wikidataProfile.getType());
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.clarin.webanno.project.initializers;

import java.util.Optional;

import org.apache.wicket.request.resource.ResourceReference;

import de.tudarmstadt.ukp.inception.project.api.ProjectInitializer;

public interface KnowledgeBaseInitializer
extends ProjectInitializer
{
default Optional<String> getDescription()
{
return Optional.empty();
}

default Optional<ResourceReference> getThumbnail()
{
return Optional.empty();
}
}
4 changes: 4 additions & 0 deletions inception/inception-ui-kb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
<groupId>de.tudarmstadt.ukp.inception.app</groupId>
<artifactId>inception-support-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>de.tudarmstadt.ukp.inception.app</groupId>
<artifactId>inception-ui-project</artifactId>
</dependency>

<dependency>
<groupId>org.dkpro.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@
<wicket:panel>
<div class="flex-content card">
<div class="card-header">
<div wicket:id="dialog"/>
<wicket:message key="kb.knowledgebases"/>
<div class="actions">
<button wicket:id="new" class="btn btn-primary">
<i class="fas fa-plus-square"></i>
<div class="btn-action-label"><wicket:message key="create"/></div>
</button>
<button wicket:id="add" class="btn btn-primary btn-action">
<i class="fas fa-list"></i>&nbsp;
<wicket:message key="add"/>
</button>
</div>
</div>
<div class="card-body fit-child-snug">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,60 @@
*/
package de.tudarmstadt.ukp.inception.ui.kb.project;

import static de.tudarmstadt.ukp.inception.support.lambda.LambdaBehavior.visibleWhenNot;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

import java.lang.invoke.MethodHandles;
import java.util.List;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.feedback.IFeedback;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wicketstuff.event.annotation.OnEvent;

import de.tudarmstadt.ukp.clarin.webanno.model.Project;
import de.tudarmstadt.ukp.clarin.webanno.project.initializers.KnowledgeBaseInitializer;
import de.tudarmstadt.ukp.clarin.webanno.ui.project.layers.LayerTemplateSelectedEvent;
import de.tudarmstadt.ukp.inception.bootstrap.BootstrapModalDialog;
import de.tudarmstadt.ukp.inception.kb.KnowledgeBaseService;
import de.tudarmstadt.ukp.inception.kb.model.KnowledgeBase;
import de.tudarmstadt.ukp.inception.project.api.ProjectInitializationRequest;
import de.tudarmstadt.ukp.inception.project.api.ProjectService;
import de.tudarmstadt.ukp.inception.schema.api.event.LayerConfigurationChangedEvent;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaAjaxFormComponentUpdatingBehavior;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaAjaxLink;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaBehavior;
import de.tudarmstadt.ukp.inception.support.spring.ApplicationEventPublisherHolder;
import de.tudarmstadt.ukp.inception.support.wicket.ListPanel_ImplBase;
import de.tudarmstadt.ukp.inception.support.wicket.OverviewListChoice;
import de.tudarmstadt.ukp.inception.ui.kb.project.wizard.KnowledgeBaseCreationDialog;

public class KnowledgeBaseListPanel
extends ListPanel_ImplBase
{
static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final long serialVersionUID = 8414963964131106164L;

private @SpringBean KnowledgeBaseService kbService;
private @SpringBean ProjectService projectService;
private @SpringBean ApplicationEventPublisherHolder applicationEventPublisherHolder;

private IModel<Project> projectModel;
private IModel<KnowledgeBase> kbModel;
private OverviewListChoice<KnowledgeBase> overviewList;
private final BootstrapModalDialog dialog;
private final LambdaAjaxLink addButton;

private KnowledgeBaseCreationDialog modal;
private final IModel<List<KnowledgeBaseInitializer>> knowledgeBaseInitializers;

public KnowledgeBaseListPanel(String id, IModel<Project> aProjectModel,
IModel<KnowledgeBase> aKbModel)
Expand All @@ -54,6 +81,18 @@ public KnowledgeBaseListPanel(String id, IModel<Project> aProjectModel,

kbModel = aKbModel;

knowledgeBaseInitializers = LoadableDetachableModel.of(this::listKnowledgeBaseInitializers);
add(LambdaBehavior.onDetach(knowledgeBaseInitializers::detach));

dialog = new BootstrapModalDialog("dialog");
dialog.trapFocus();
queue(dialog);

addButton = new LambdaAjaxLink("add", this::actionAddKnowledgeBase);
addButton.setOutputMarkupPlaceholderTag(true);
addButton.add(visibleWhenNot(knowledgeBaseInitializers.map(List::isEmpty)));
add(addButton);

projectModel = aProjectModel;
overviewList = new OverviewListChoice<>("knowledgebases");
overviewList.setChoiceRenderer(new ChoiceRenderer<>("name"));
Expand All @@ -68,9 +107,65 @@ public KnowledgeBaseListPanel(String id, IModel<Project> aProjectModel,
add(new LambdaAjaxLink("new", this::actionCreate));
}

public Project getModelObject()
{
return (Project) getDefaultModelObject();
}

@SuppressWarnings("unchecked")
public IModel<Project> getModel()
{
return (IModel<Project>) getDefaultModel();
}

@Override
protected void actionCreate(AjaxRequestTarget aTarget) throws Exception
{
modal.show(aTarget);
}

private List<KnowledgeBaseInitializer> listKnowledgeBaseInitializers()
{
if (getModelObject() == null) {
return emptyList();
}

return projectService.listProjectInitializers().stream()
.filter(initializer -> initializer instanceof KnowledgeBaseInitializer)
.map(KnowledgeBaseInitializer.class::cast)
.filter(initializer -> !initializer.alreadyApplied(getModelObject())).toList();
}

private void actionAddKnowledgeBase(AjaxRequestTarget aTarget)
{
var dialogContent = new KnowledgeBaseTemplateSelectionDialogPanel(
BootstrapModalDialog.CONTENT_ID, getModel(), knowledgeBaseInitializers);
dialog.open(dialogContent, aTarget);
}

@OnEvent
public void onLayerTemplateSelected(LayerTemplateSelectedEvent aEvent)
{
var target = aEvent.getTarget();
var initializer = aEvent.getLayerInitializer();
try {
// target.add(initializersContainer);
target.add(overviewList);
target.add(addButton);
target.addChildren(getPage(), IFeedback.class);
var request = ProjectInitializationRequest.builder() //
.withProject(getModelObject()) //
.build();
projectService.initializeProject(request, asList(initializer));
success("Applyed knowledge base initializer [" + initializer.getName() + "]");
}
catch (Exception e) {
error("Error applying knowledge base initializer [" + initializer.getName() + "]: "
+ ExceptionUtils.getRootCauseMessage(e));
LOG.error("Error applying knowledge base initializer {}", initializer, e);
}

applicationEventPublisherHolder.get()
.publishEvent(new LayerConfigurationChangedEvent(this, getModelObject()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.ui.kb.project;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.wicketstuff.event.annotation.AbstractAjaxAwareEvent;

import de.tudarmstadt.ukp.clarin.webanno.project.initializers.KnowledgeBaseInitializer;

public class KnowledgeBaseTemplateSelectedEvent
extends AbstractAjaxAwareEvent
{
private final KnowledgeBaseInitializer kbInitializer;

public KnowledgeBaseTemplateSelectedEvent(AjaxRequestTarget aTarget,
KnowledgeBaseInitializer aKBInitializer)
{
super(aTarget);

kbInitializer = aKBInitializer;
}

public KnowledgeBaseInitializer getKnowledgeBaseInitializer()
{
return kbInitializer;
}
}
Loading

0 comments on commit 2ff35ba

Please sign in to comment.