diff --git a/silk-plugins/silk-plugins-csv/src/main/scala/org/silkframework/plugins/dataset/csv/CsvDatasetTrait.scala b/silk-plugins/silk-plugins-csv/src/main/scala/org/silkframework/plugins/dataset/csv/CsvDatasetTrait.scala index a1cbfd6b6a..6b86fd6d8b 100644 --- a/silk-plugins/silk-plugins-csv/src/main/scala/org/silkframework/plugins/dataset/csv/CsvDatasetTrait.scala +++ b/silk-plugins/silk-plugins-csv/src/main/scala/org/silkframework/plugins/dataset/csv/CsvDatasetTrait.scala @@ -32,6 +32,7 @@ trait CsvDatasetTrait { val separatorChar: Char = if (separator == "\\t") { '\t' } else if (separator.length == 1) { separator.head } + else if(separator.isEmpty) { ',' } else { throw new IllegalArgumentException(s"Invalid separator: '$separator'. Must be a single character.") } val arraySeparatorChar: Option[Char] = diff --git a/silk-react-components/src/HierarchicalMapping/elements/RuleTitle.jsx b/silk-react-components/src/HierarchicalMapping/elements/RuleTitle.jsx index 7d3aa8ce39..8ca8d42dd7 100644 --- a/silk-react-components/src/HierarchicalMapping/elements/RuleTitle.jsx +++ b/silk-react-components/src/HierarchicalMapping/elements/RuleTitle.jsx @@ -4,7 +4,8 @@ import { NotAvailable } from '@eccenca/gui-elements'; import { ThingName } from '../components/ThingName'; import { - MAPPING_RULE_TYPE_ROOT, + MAPPING_RULE_TYPE_COMPLEX_URI, + MAPPING_RULE_TYPE_ROOT, MAPPING_RULE_TYPE_URI, } from '../utils/constants'; import { MAPPING_RULE_TYPE_COMPLEX, MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from '../utils/constants'; @@ -35,7 +36,12 @@ const RuleTitle = ({ rule, ...otherProps }) => { ) : ( ); + case MAPPING_RULE_TYPE_URI: + case MAPPING_RULE_TYPE_COMPLEX_URI: + return uri } + + return ; }; export default RuleTitle; diff --git a/silk-workbench/silk-workbench-workspace/app/controllers/workspaceApi/search/ItemTypeFacetCollector.scala b/silk-workbench/silk-workbench-workspace/app/controllers/workspaceApi/search/ItemTypeFacetCollector.scala index 5782f8b18f..a77127e7f0 100644 --- a/silk-workbench/silk-workbench-workspace/app/controllers/workspaceApi/search/ItemTypeFacetCollector.scala +++ b/silk-workbench/silk-workbench-workspace/app/controllers/workspaceApi/search/ItemTypeFacetCollector.scala @@ -8,6 +8,8 @@ import org.silkframework.rule.{LinkSpec, TransformSpec} import org.silkframework.workspace.activity.workflow.Workflow import org.silkframework.workspace.{Project, ProjectTask} +import java.util.concurrent.ConcurrentHashMap +import java.util.logging.Logger import scala.collection.immutable.ListMap import scala.collection.mutable import scala.reflect.ClassTag @@ -42,6 +44,9 @@ trait ItemTypeFacetCollector[T <: TaskSpec] { } object ItemTypeFacetCollector { + private val logger: Logger = Logger.getLogger(this.getClass.getName) + private val facetErrorsLogged = new ConcurrentHashMap[String, Long]() + /** Returns true if the project task should be in the result set according to the facet setting. * It collects facet values after filtering. * Values are collected for each facet, when no other facet filters out a project task. */ @@ -64,7 +69,14 @@ object ItemTypeFacetCollector { matchingFacets.add(facetSetting.facetId) } case None => - throw new IllegalArgumentException(s"Facet ID '${facetSetting.facetId}' is not available for facet collector '${this.getClass.getSimpleName}'.") + // Unknown facet always matches + matchingFacets.add(facetSetting.facetId) + val facetKey = this.getClass.getSimpleName + "_" + facetSetting.facetId + if(Option(facetErrorsLogged.get(facetKey)).isEmpty || facetErrorsLogged.get(facetKey) < (System.currentTimeMillis() - 1000)) { + logger.warning(s"Wrong facet configuration in search request. Facet ID '${facetSetting.facetId}' is " + + s"not available for facet collector '${this.getClass.getSimpleName}'.") + facetErrorsLogged.put(facetKey, System.currentTimeMillis()) + } } } val allMatch = facetSettings.size == matchingFacets.size // Only when all requested facet settings match, it's an overall match diff --git a/silk-workspace/src/main/scala/org/silkframework/workspace/PluginBasedWorkspaceFactory.scala b/silk-workspace/src/main/scala/org/silkframework/workspace/PluginBasedWorkspaceFactory.scala index 66d039412d..2f78138826 100644 --- a/silk-workspace/src/main/scala/org/silkframework/workspace/PluginBasedWorkspaceFactory.scala +++ b/silk-workspace/src/main/scala/org/silkframework/workspace/PluginBasedWorkspaceFactory.scala @@ -14,14 +14,15 @@ package org.silkframework.workspace -import java.util.logging.{Level, Logger} - -import javax.inject.Inject import org.silkframework.config.{Config, DefaultConfig} import org.silkframework.runtime.activity.UserContext import org.silkframework.runtime.plugin.PluginRegistry import org.silkframework.workspace.resources.ResourceRepository +import java.time.Instant +import java.util.logging.{Level, Logger} +import javax.inject.Inject + class PluginBasedWorkspaceFactory extends WorkspaceFactory { override def workspace(implicit userContext: UserContext): Workspace = PluginBasedWorkspaceFactory.workspace @@ -29,16 +30,25 @@ class PluginBasedWorkspaceFactory extends WorkspaceFactory { } object PluginBasedWorkspaceFactory { + private val log: Logger = Logger.getLogger(this.getClass.getName.stripSuffix("$")) + @Inject private var configMgr: Config = DefaultConfig.instance + @volatile + private var timestamp: Instant = Instant.MIN + private var _workspace: Option[Workspace] = None def workspace(implicit userContext: UserContext): Workspace = this.synchronized { _workspace match { - case Some(w) => w - case None => + case Some(w) if !timestamp.isBefore(configMgr.timestamp) => w + case _ => + if(_workspace.nonEmpty) { + log.info("Reloading workspace because the configuration has been updated.") + } + timestamp = configMgr.timestamp try { val w = initWorkspace _workspace = Some(w)