Package org.apache.clerezza.platform.language

Source Code of org.apache.clerezza.platform.language.LanguageService

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF 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.  You may obtain a copy of the License at
*
*   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 org.apache.clerezza.platform.language;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import org.apache.clerezza.platform.config.PlatformConfig;
import org.apache.clerezza.platform.config.SystemConfig;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.clerezza.rdf.core.BNode;
import org.apache.clerezza.rdf.core.Graph;
import org.apache.clerezza.rdf.core.Language;
import org.apache.clerezza.rdf.core.MGraph;
import org.osgi.service.component.ComponentContext;
import org.apache.clerezza.rdf.core.NonLiteral;
import org.apache.clerezza.rdf.core.PlainLiteral;
import org.apache.clerezza.rdf.core.Resource;
import org.apache.clerezza.rdf.core.Triple;
import org.apache.clerezza.rdf.core.UriRef;
import org.apache.clerezza.rdf.core.access.LockableMGraph;
import org.apache.clerezza.rdf.core.access.SecuredMGraph;
import org.apache.clerezza.rdf.core.access.TcManager;
import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
import org.apache.clerezza.rdf.core.impl.TripleImpl;
import org.apache.clerezza.rdf.core.serializedform.ParsingProvider;
import org.apache.clerezza.rdf.core.serializedform.SupportedFormat;
import org.apache.clerezza.rdf.ontologies.LINGVOJ;
import org.apache.clerezza.rdf.ontologies.PLATFORM;
import org.apache.clerezza.rdf.ontologies.RDF;
import org.apache.clerezza.rdf.ontologies.RDFS;
import org.apache.clerezza.rdf.utils.GraphNode;
import org.apache.clerezza.rdf.utils.RdfList;

/**
* This class provides a OSGi service for managing languages in the Clerezza
* platform.
*
* @author mir
*/
@Component(immediate=true, enabled= true)
@Service(LanguageService.class)
public class LanguageService

  @Reference
  private TcManager tcManager;

  /**
   * this is linked to the system-graph, accessing requires respective
   * permission
   */
  private List<Resource> languageList;
  /**
   * no permission on the system graph required to access this
   */
  private List<Resource> languageListCache;

  private static final String PARSER_FILTER =
      "(supportedFormat=" + SupportedFormat.RDF_XML +")";

  @Reference(target=PARSER_FILTER)
  private ParsingProvider parser;

  @Reference(target = SystemConfig.SYSTEM_GRAPH_FILTER)
  private MGraph securedSystemGraph;

  @Reference(target = PlatformConfig.CONFIG_GRAPH_FILTER)
  private MGraph securedConfigGraph;
 
  private SoftReference<Graph> softLingvojGraph = new SoftReference<Graph>(null);


  private LockableMGraph getSystemGraph() {
    return ((SecuredMGraph) securedSystemGraph).getUnsecuredMGraph();
  }

  private LockableMGraph getConfigGraph() {
    return ((SecuredMGraph) securedConfigGraph).getUnsecuredMGraph();
  }

  /**
   * Returns a <code>List</code> of <code>LanguageDescription</code>s which
   * describe the languages which are supported by the platform. The first
   * entry describes the default language of the platform.
   * @return a list containing all language descriptions.
   */
  public List<LanguageDescription> getLanguages() {
    List<LanguageDescription> langList = new ArrayList<LanguageDescription>();
    Iterator<Resource> languages = languageListCache.iterator();
    while (languages.hasNext()) {
      UriRef language = (UriRef) languages.next();
      langList.add(new LanguageDescription(new GraphNode(language, getConfigGraph())));
    }
    return langList;
  }

  /**
   * Returns the <code>LanguageDescription</code> of the default language
   * of the platform.
   * @return the language description of the default language.
   */
  public LanguageDescription getDefaultLanguage() {
    return new LanguageDescription(
        new GraphNode(languageListCache.get(0), getConfigGraph()));
  }

  /**
   * Returns a set containg all language uris which are in the
   * <http://www.lingvoj.org/lingvoj> graph which is included in this bundle.
   * @return a set containing all language uris. This uris can be used to
   * add the language to Clerezza over the addLanguage()-method in this class.
   */
  public Set<UriRef> getAllLanguages() {
    Set<UriRef> result = new HashSet<UriRef>();
    Graph lingvojGraph = getLingvojGraph();
    Iterator<Triple> languages = lingvojGraph.filter(null, RDFS.isDefinedBy,
        null);
    while (languages.hasNext()) {
      UriRef languageUri = (UriRef) languages.next().getSubject();
      result.add(languageUri);
    }
    return result;
  }

  /**
   * Returns a language uri of a language which has a label containing the
   * specified languageName. The label itself is in the language specified through
   * inLanguage. If inLanguage is null, then all labels of a language of searched.
   * If no language was found in the <http://www.lingvoj.org/lingvoj>
   * graph, then null is returned. The returned uri can be used to
   * add the language to Clerezza over the addLanguage()-method in this class.
   * @return a language uris
   */
  public UriRef getLanguage(String languageName, Language inLanguage) {
    Graph lingvojGraph = getLingvojGraph();
    Iterator<Triple> languages = lingvojGraph.filter(null, RDFS.isDefinedBy, null);
    while (languages.hasNext()) {
      GraphNode languageNode = new GraphNode((UriRef) languages.next().getSubject(), lingvojGraph);
      Iterator<Resource> labels = languageNode.getObjects(RDFS.label);
      while (labels.hasNext()) {
        PlainLiteral label = (PlainLiteral) labels.next();
        if (label.getLanguage().equals(inLanguage) || inLanguage == null) {
          if (label.getLexicalForm().contains(languageName)) {
            return (UriRef) languageNode.getNode();
          }
        }
      }
    }
    return null;
  }
 
  /**
   * Get the language as <code>GraphNode</code> specified through languageUri.
   * The languageUri has to be a <http://www.lingvoj.org/ontology#Lingvo>
   * according to the graph <http://www.lingvoj.org/lingvoj> included in this
   * bundle., e.g. "http://www.lingvoj.org/lang/de".
   *
   * @param languageUri The language uri which specifies the language
   */
  public GraphNode getLanguageNode(NonLiteral langUri) {
    Graph lingvojRdf = getLingvojGraph();
    return new GraphNode(langUri, lingvojRdf);
  }

  /**
   * Adds the language specified through languageUri to the Clerezza
   * platform. The languageUri has to be a <http://www.lingvoj.org/ontology#Lingvo>
   * according to the graph <http://www.lingvoj.org/lingvoj> included in this
   * bundle., e.g. "http://www.lingvoj.org/lang/de" adds German.
   * The uri is added to the system graph and its context to the config graph.
   * The context added is the context provided by lingvoj.rdf.
   * @param languageUri The language uri which specifies the language to be
   *    added to the platform.
   */
  public void addLanguage(UriRef languageUri) {
    if (!languageListCache.contains(languageUri)) {
      LockableMGraph systemGraph = getSystemGraph();
      Lock writeLock = systemGraph.getLock().writeLock();
      writeLock.lock();
      try {
        if (languageList.add(languageUri)) {
          addToLanguageConfigGraph(languageUri);
        }
      } finally {
        writeLock.unlock();
      }
      languageListCache.add(languageUri);
    }
  }

  private void synchronizeContentGraph() {
    for (Resource resource : languageListCache) {
      addToLanguageConfigGraph((UriRef)resource);
    }
  }
  /**
   * Adds the language information of the language specified through
   * languageUri to the config graph. The languageUri has to be of type
   * <http://www.lingvoj.org/ontology#Lingvo> according to the graph
   * <http://www.lingvoj.org/lingvoj> included in this
   * bundle., e.g. "http://www.lingvoj.org/lang/de" adds German.
   *
   * The added language will not be a platform language.
   *
   * @param languageUri
   */
  public void addToLanguageConfigGraph(NonLiteral languageUri) {
    LockableMGraph configGraph = getConfigGraph();
    Lock writeLock = configGraph.getLock().writeLock();
    writeLock.lock();
    try {
      if (!configGraph.filter(languageUri, LINGVOJ.iso1, null).hasNext()) {
        configGraph.addAll(getLanguageContext(languageUri));
      }
    } finally {
      writeLock.unlock();
    }
  }

  private Graph getLanguageContext(NonLiteral langUri) {
    Graph lingvojRdf = getLingvojGraph();
    GraphNode languageNode = new GraphNode(langUri, lingvojRdf);
    return languageNode.getNodeContext();
  }
 
  private Graph getLingvojGraph() {
    Graph lingvojGraph = softLingvojGraph.get();
    if (lingvojGraph != null) {
      return lingvojGraph;
    }
    URL config = getClass().getResource("lingvoj.rdf");
    if (config == null) {
      throw new RuntimeException("no file found");
    }
    try {
      MGraph lingvojMGraph = new SimpleMGraph();
      parser.parse(lingvojMGraph, config.openStream(), SupportedFormat.RDF_XML, null);
      lingvojGraph = lingvojMGraph.getGraph();
      softLingvojGraph = new SoftReference<Graph>(lingvojGraph);
      return lingvojGraph;
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    }
  }

  /**
   * The activate method is called when SCR activates the component configuration.
   *
   * @param componentContext
   */
  protected void activate(ComponentContext componentContext) {
    LockableMGraph systemGraph = getSystemGraph();
    NonLiteral listNode = getListNode(systemGraph);

    Lock writeLock = systemGraph.getLock().writeLock();
    writeLock.lock();
    try {
      // the constructor of RdfList might write to the graph! => requires a write lock
      final RdfList rdfList = new RdfList(listNode, systemGraph);
      languageList = Collections.synchronizedList(rdfList);
      //access to languages should not require access to system graph,
      //so copying the resources to an ArrayList
      languageListCache = Collections.synchronizedList(
          new ArrayList<Resource>(rdfList));
      if (languageListCache.size() == 0) {
        addLanguage(new UriRef("http://www.lingvoj.org/lang/en"));
      }
      //this is to make sure the content graph contains the relevant data
      synchronizeContentGraph();
    } finally {
      writeLock.unlock();
    }
  }

  private NonLiteral getListNode(LockableMGraph systemGraph) {
    NonLiteral instance = null;
    Lock readLock = systemGraph.getLock().readLock();
    readLock.lock();
    try {
      Iterator<Triple> instances = systemGraph.filter(null, RDF.type, PLATFORM.Instance);
      if (!instances.hasNext()) {
        throw new RuntimeException("No Platform:Instance in system graph.");
      }
      instance = instances.next().getSubject();
      Iterator<Triple> langListIter = systemGraph.filter(instance,
          PLATFORM.languages, null);
      if (langListIter.hasNext()) {
        return (NonLiteral) langListIter.next().getObject();
      }
    } finally {
      readLock.unlock();
    }
    BNode listNode = new BNode();
    Lock writeLock = systemGraph.getLock().writeLock();
    writeLock.lock();
    try {
      systemGraph.add(new TripleImpl(instance, PLATFORM.languages, listNode));
    } finally {
      writeLock.unlock();
    }
    return listNode;
  }
}
TOP

Related Classes of org.apache.clerezza.platform.language.LanguageService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.