<commit_before>package bootstrap.liftweb

import _root_.net.liftweb.common._
import _root_.net.liftweb.util._
import _root_.net.liftweb.http._
import _root_.net.liftweb.sitemap._
import _root_.net.liftweb.sitemap.Loc._
import Helpers._
import de.fuberlin.wiwiss.silk.impl.DefaultImplementations
import js.jquery.JQuery14Artifacts
import java.io.ByteArrayOutputStream
import net.liftweb.json.JsonAST._
import de.fuberlin.wiwiss.silk.linkspec.condition.{Aggregator, Metric}
import de.fuberlin.wiwiss.silk.linkspec.input.Transformer
import xml.PrettyPrinter
import de.fuberlin.wiwiss.silk.instance.Path
import de.fuberlin.wiwiss.silk.util.strategy.{Parameter, Strategy}
import net.liftweb.widgets.autocomplete.AutoComplete
import scala.xml.Text
import de.fuberlin.wiwiss.silk.workbench.lift.util.ConfigBuilder
import de.fuberlin.wiwiss.silk.workbench.workspace.{ProjectExporter, FileUser, User}

/**
  * A class that's instantiated early and run.  It allows the application
  * to modify lift's environment
  */
class Boot
{
  object UserManager extends SessionVar[User](new FileUser)

  def boot
  {
    User.userManager = UserManager.is _

    DefaultImplementations.register()

    LiftRules.jsArtifacts = JQuery14Artifacts

    AutoComplete.init()

    // where to search snippet
    LiftRules.addToPackages("de.fuberlin.wiwiss.silk.workbench.lift")

    // Build SiteMap
    val ifLinkingTaskOpen = If(() => User().linkingTaskOpen, () => RedirectResponse("/index"))
    val ifLinkingTaskClosed = If(() => !User().linkingTaskOpen, () => RedirectResponse("/linkSpec"))

    val workspaceText = LinkText[Unit](_ => Text(if(User().projectOpen) "Workspace: " + User().project.name else "Workspace"))
    val linkSpecText = LinkText[Unit](_ => Text(User().project.name + ": " + User().linkingTask.name))

    val entries =
        Menu(Loc("Workspace", List("index"), workspaceText, ifLinkingTaskClosed)) ::
        Menu(Loc("Link Specification", List("linkSpec"), linkSpecText, ifLinkingTaskOpen)) ::
        Menu(Loc("Evaluate", List("evaluate"), "Evaluate", ifLinkingTaskOpen)) ::
        Menu(Loc("Reference Links", List("alignment"), "Reference Links", ifLinkingTaskOpen)) :: Nil

    LiftRules.setSiteMap(SiteMap(entries:_*))

    LiftRules.dispatch.prepend(dispatch)
  }

  private def dispatch : LiftRules.DispatchPF =
  {
    case req @ Req(List("project"), "xml", GetRequest) =>
    {
      val outputStream = new ByteArrayOutputStream()
      val projectXml = ProjectExporter(User().project)
      val projectStr = new PrettyPrinter(140, 2).format(projectXml)
      () => Full(InMemoryResponse(projectStr.getBytes, ("Content-Type", "application/xml") :: ("Content-Disposition", "attachment") :: Nil, Nil, 200))
    }
    case req @ Req(List("config"), "xml", GetRequest) =>
    {
      val outputStream = new ByteArrayOutputStream()
      val configXml = ConfigBuilder.build().toXML
      val configStr = new PrettyPrinter(140, 2).format(configXml)
      () => Full(InMemoryResponse(configStr.getBytes, ("Content-Type", "application/xml") :: ("Content-Disposition", "attachment") :: Nil, Nil, 200))
    }
    case req @ Req(List("api", "project", "paths"), "", GetRequest) => () => generatePaths(req)
    case req @ Req(List("api", "project", "operators"), "", GetRequest) => () => generateOperators()
  }

  private def generatePaths(req : Req) =
  {
    val maxPathCount = req.param("max").map(_.toInt).getOrElse(Int.MaxValue)

    val linkingTask = User().linkingTask
    val datasets = linkingTask.linkSpec.datasets
    val restrictions = linkingTask.linkSpec.datasets.map(_.restriction)
    val instanceSpecs = linkingTask.cache.instanceSpecs
    val sourcePaths = if(instanceSpecs != null) instanceSpecs.source.paths else List[Path]()
    val targetPaths = if(instanceSpecs != null) instanceSpecs.target.paths else List[Path]()

    val sourceField = JField("source", JObject(JField("id", JString(datasets.source.sourceId)) ::
                                               JField("paths", JArray(generateInstancePaths(sourcePaths, maxPathCount).toList)) ::
                                               JField("availablePaths", JInt(sourcePaths.size)) ::
                                               JField("restrictions", JString(restrictions.source)) :: Nil))
    val targetField = JField("target", JObject(JField("id", JString(datasets.target.sourceId)) ::
                                               JField("paths", JArray(generateInstancePaths(targetPaths, maxPathCount).toList)) ::
                                               JField("availablePaths", JInt(targetPaths.size)) ::
                                               JField("restrictions", JString(restrictions.target)) :: Nil))

    val isLoadingField = JField("isLoading", JBool(instanceSpecs == null))

    var errorMsg : Option[String] = None
    if(linkingTask.cacheLoading != null && linkingTask.cacheLoading.isSet)
    {
      try
      {
        linkingTask.cacheLoading()
      }
      catch
      {
        case ex : Exception => errorMsg = Some(ex.getMessage)
      }
    }

    val json = errorMsg match
    {
      case None => JObject(sourceField :: targetField :: isLoadingField :: Nil)
      case Some(error) => JObject(sourceField :: targetField :: isLoadingField :: JField("error", JString(error)) :: Nil)
    }

    Full(JsonResponse(json))
  }

  private def generateInstancePaths(paths : Traversable[Path], maxPathCount : Int) =
  {
    for(path <- paths.toSeq.take(maxPathCount)) yield
    {
      JObject(JField("path", JString(path.toString)) :: JField("frequency", JDouble(1.0)) :: Nil)
    }
  }

  private def generateOperators() =
  {
    val transformations = JField("transformations", JArray(generateFactoryOperators(Transformer).toList))
    val comparators = JField("comparators", JArray(generateFactoryOperators(Metric).toList))
    val aggregators = JField("aggregators", JArray(generateFactoryOperators(Aggregator).toList))

    val json = JObject(transformations :: comparators :: aggregators :: Nil)

    Full(JsonResponse(json))<commit_msg>Property Paths Json: isLoading set to false if loading fails<commit_after>package bootstrap.liftweb

import _root_.net.liftweb.common._
import _root_.net.liftweb.util._
import _root_.net.liftweb.http._
import _root_.net.liftweb.sitemap._
import _root_.net.liftweb.sitemap.Loc._
import Helpers._
import de.fuberlin.wiwiss.silk.impl.DefaultImplementations
import js.jquery.JQuery14Artifacts
import java.io.ByteArrayOutputStream
import net.liftweb.json.JsonAST._
import de.fuberlin.wiwiss.silk.linkspec.condition.{Aggregator, Metric}
import de.fuberlin.wiwiss.silk.linkspec.input.Transformer
import xml.PrettyPrinter
import de.fuberlin.wiwiss.silk.instance.Path
import de.fuberlin.wiwiss.silk.util.strategy.{Parameter, Strategy}
import net.liftweb.widgets.autocomplete.AutoComplete
import scala.xml.Text
import de.fuberlin.wiwiss.silk.workbench.lift.util.ConfigBuilder
import de.fuberlin.wiwiss.silk.workbench.workspace.{ProjectExporter, FileUser, User}

/**
  * A class that's instantiated early and run.  It allows the application
  * to modify lift's environment
  */
class Boot
{
  object UserManager extends SessionVar[User](new FileUser)

  def boot
  {
    User.userManager = UserManager.is _

    DefaultImplementations.register()

    LiftRules.jsArtifacts = JQuery14Artifacts

    AutoComplete.init()

    // where to search snippet
    LiftRules.addToPackages("de.fuberlin.wiwiss.silk.workbench.lift")

    // Build SiteMap
    val ifLinkingTaskOpen = If(() => User().linkingTaskOpen, () => RedirectResponse("/index"))
    val ifLinkingTaskClosed = If(() => !User().linkingTaskOpen, () => RedirectResponse("/linkSpec"))

    val workspaceText = LinkText[Unit](_ => Text(if(User().projectOpen) "Workspace: " + User().project.name else "Workspace"))
    val linkSpecText = LinkText[Unit](_ => Text(User().project.name + ": " + User().linkingTask.name))

    val entries =
        Menu(Loc("Workspace", List("index"), workspaceText, ifLinkingTaskClosed)) ::
        Menu(Loc("Link Specification", List("linkSpec"), linkSpecText, ifLinkingTaskOpen)) ::
        Menu(Loc("Evaluate", List("evaluate"), "Evaluate", ifLinkingTaskOpen)) ::
        Menu(Loc("Reference Links", List("alignment"), "Reference Links", ifLinkingTaskOpen)) :: Nil

    LiftRules.setSiteMap(SiteMap(entries:_*))

    LiftRules.dispatch.prepend(dispatch)
  }

  private def dispatch : LiftRules.DispatchPF =
  {
    case req @ Req(List("project"), "xml", GetRequest) =>
    {
      val outputStream = new ByteArrayOutputStream()
      val projectXml = ProjectExporter(User().project)
      val projectStr = new PrettyPrinter(140, 2).format(projectXml)
      () => Full(InMemoryResponse(projectStr.getBytes, ("Content-Type", "application/xml") :: ("Content-Disposition", "attachment") :: Nil, Nil, 200))
    }
    case req @ Req(List("config"), "xml", GetRequest) =>
    {
      val outputStream = new ByteArrayOutputStream()
      val configXml = ConfigBuilder.build().toXML
      val configStr = new PrettyPrinter(140, 2).format(configXml)
      () => Full(InMemoryResponse(configStr.getBytes, ("Content-Type", "application/xml") :: ("Content-Disposition", "attachment") :: Nil, Nil, 200))
    }
    case req @ Req(List("api", "project", "paths"), "", GetRequest) => () => generatePaths(req)
    case req @ Req(List("api", "project", "operators"), "", GetRequest) => () => generateOperators()
  }

  private def generatePaths(req : Req) =
  {
    val maxPathCount = req.param("max").map(_.toInt).getOrElse(Int.MaxValue)

    val linkingTask = User().linkingTask
    val datasets = linkingTask.linkSpec.datasets
    val restrictions = linkingTask.linkSpec.datasets.map(_.restriction)
    val instanceSpecs = linkingTask.cache.instanceSpecs
    val sourcePaths = if(instanceSpecs != null) instanceSpecs.source.paths else List[Path]()
    val targetPaths = if(instanceSpecs != null) instanceSpecs.target.paths else List[Path]()

    val sourceField = JField("source", JObject(JField("id", JString(datasets.source.sourceId)) ::
                                               JField("paths", JArray(generateInstancePaths(sourcePaths, maxPathCount).toList)) ::
                                               JField("availablePaths", JInt(sourcePaths.size)) ::
                                               JField("restrictions", JString(restrictions.source)) :: Nil))
    val targetField = JField("target", JObject(JField("id", JString(datasets.target.sourceId)) ::
                                               JField("paths", JArray(generateInstancePaths(targetPaths, maxPathCount).toList)) ::
                                               JField("availablePaths", JInt(targetPaths.size)) ::
                                               JField("restrictions", JString(restrictions.target)) :: Nil))

    var errorMsg : Option[String] = None
    if(linkingTask.cacheLoading != null && linkingTask.cacheLoading.isSet)
    {
      try
      {
        linkingTask.cacheLoading()
      }
      catch
      {
        case ex : Exception => errorMsg = Some(ex.getMessage)
      }
    }

    val isLoadingField = JField("isLoading", JBool(errorMsg.isEmpty && instanceSpecs == null))

    val json = errorMsg match
    {
      case None => JObject(sourceField :: targetField :: isLoadingField :: Nil)
      case Some(error) => JObject(sourceField :: targetField :: isLoadingField :: JField("error", JString(error)) :: Nil)
    }

    Full(JsonResponse(json))
  }

  private def generateInstancePaths(paths : Traversable[Path], maxPathCount : Int) =
  {
    for(path <- paths.toSeq.take(maxPathCount)) yield
    {
      JObject(JField("path", JString(path.toString)) :: JField("frequency", JDouble(1.0)) :: Nil)
    }
  }

  private def generateOperators() =
  {
    val transformations = JField("transformations", JArray(generateFactoryOperators(Transformer).toList))
    val comparators = JField("comparators", JArray(generateFactoryOperators(Metric).toList))
    val aggregators = JField("aggregators", JArray(generateFactoryOperators(Aggregator).toList))

    val json = JObject(transformations :: comparators :: aggregators :: Nil)

    Full(JsonResponse(json))
{'fraction_non_alphanumeric': 0.13331147003361482, 'fraction_numerical': 0.0032794949577765026, 'mean_word_length': 3.5978137957029777, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '837104', 'n_tokens_mistral': 3674, 'n_tokens_neox': 3511, 'n_words': 669}