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)