Package org.ontoware.rdf2go.impl.jena

Source Code of org.ontoware.rdf2go.impl.jena.ModelSetImplJena$ContextIterator

package org.ontoware.rdf2go.impl.jena;

import static org.ontoware.rdf2go.impl.jena.ModelImplJena.getJenaLang;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.io.output.WriterOutputStream;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RiotException;
import org.apache.jena.riot.RiotWriter;
import org.ontoware.aifbcommons.collection.ClosableIterable;
import org.ontoware.aifbcommons.collection.ClosableIterator;
import org.ontoware.rdf2go.Reasoning;
import org.ontoware.rdf2go.exception.LockException;
import org.ontoware.rdf2go.exception.MalformedQueryException;
import org.ontoware.rdf2go.exception.ModelRuntimeException;
import org.ontoware.rdf2go.exception.QueryLanguageNotSupportedException;
import org.ontoware.rdf2go.exception.SyntaxNotSupportedException;
import org.ontoware.rdf2go.model.Model;
import org.ontoware.rdf2go.model.ModelSet;
import org.ontoware.rdf2go.model.QuadPattern;
import org.ontoware.rdf2go.model.QueryResultTable;
import org.ontoware.rdf2go.model.Statement;
import org.ontoware.rdf2go.model.Syntax;
import org.ontoware.rdf2go.model.impl.AbstractModelSetImpl;
import org.ontoware.rdf2go.model.node.Node;
import org.ontoware.rdf2go.model.node.NodeOrVariable;
import org.ontoware.rdf2go.model.node.Resource;
import org.ontoware.rdf2go.model.node.ResourceOrVariable;
import org.ontoware.rdf2go.model.node.URI;
import org.ontoware.rdf2go.model.node.UriOrVariable;
import org.ontoware.rdf2go.model.node.Variable;
import org.ontoware.rdf2go.model.node.impl.URIImpl;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;


/**
* A ModelSet implementation for Jena. It relies on the Jena
* {@linkplain com.hp.hpl.jena.query.Dataset}.
*
* @since 4.8.1
*
* @author Roland Stühmer
*
* @version $Revision: 1950 $
*
*/
public class ModelSetImplJena extends AbstractModelSetImpl {

  private static final long serialVersionUID = 9211877052180956697L;
 
  private final com.hp.hpl.jena.query.Dataset dataset;
  private final com.hp.hpl.jena.shared.Lock lock;
  private Query countStatementsQuery;
  private boolean open = true;
 
  private static class ContextIterator implements ClosableIterator<URI> {

    private final Iterator<String> underlying;

    public ContextIterator(Iterator<String> idIterator) {
      this.underlying = idIterator;
    }

    @Override
    public void close() {
    }

    @Override
    public boolean hasNext() {
      return this.underlying.hasNext();
    }

    @Override
    public URI next() {
      return new URIImpl(this.underlying.next());
    }

    @Override
    public void remove() {
      throw new UnsupportedOperationException();
    }
  }

  private class ModelIterator implements ClosableIterator<Model> {

    private final ClosableIterator<URI> underlying;

    private URI lastURI;

    public ModelIterator(ClosableIterator<URI> contextIterator) {
      this.underlying = contextIterator;
    }

    @Override
    public void close() {
      this.underlying.close();
    }

    @Override
    public boolean hasNext() {
      return this.underlying.hasNext();
    }

    @Override
    public Model next() {
      URI uri = this.underlying.next();

      Model model = getModel(uri);

      this.lastURI = uri;
      return model;
    }

    @Override
    public void remove() {
      // only possible when next() has been invoked at least once
      if (this.lastURI == null) {
        throw new IllegalStateException();
      }

      removeModel(lastURI);

      this.lastURI = null;
    }

  }

  private class JenaQuadPattern implements QuadPattern {

    private static final long serialVersionUID = -2397218722246644188L;

    private final UriOrVariable context;

    private final NodeOrVariable object;

    private final UriOrVariable predicate;

    private final ResourceOrVariable subject;

    public JenaQuadPattern(UriOrVariable context,
        ResourceOrVariable subject, UriOrVariable predicate,
        NodeOrVariable object) {
      this.checkNonNull(context);
      this.checkNonNull(subject);
      this.checkNonNull(predicate);
      this.checkNonNull(object);

      this.context = context;
      this.subject = subject;
      this.predicate = predicate;
      this.object = object;
    }

    @Override
    public UriOrVariable getContext() {
      return this.context;
    }

    @Override
    public NodeOrVariable getObject() {
      return this.object;
    }

    @Override
    public UriOrVariable getPredicate() {
      return this.predicate;
    }

    @Override
    public ResourceOrVariable getSubject() {
      return this.subject;
    }

    @Override
    public boolean matches(Statement statement) {
      return this.matches(statement.getContext(), this.context)
          && this.matches(statement.getSubject(), this.subject)
          && this.matches(statement.getPredicate(), this.predicate)
          && this.matches(statement.getObject(), this.object);
    }

    private void checkNonNull(NodeOrVariable value) {
      if (value == null) {
        throw new NullPointerException();
      }
    }

    private boolean matches(Node node, NodeOrVariable variable) {
      return variable.equals(Variable.ANY) || variable.equals(node);
    }
  }

  private static class StatementIterator implements ClosableIterator<Statement> {
   
    private final Iterator<com.hp.hpl.jena.sparql.core.Quad> underlying;
   
    public StatementIterator(
        Iterator<com.hp.hpl.jena.sparql.core.Quad> jenaQuadIterator) {
      this.underlying = jenaQuadIterator;
    }

    @Override
    public void close() {
    }

    @Override
    public boolean hasNext() {
      return this.underlying.hasNext();
    }

    @Override
    public Statement next() {
      com.hp.hpl.jena.sparql.core.Quad quad = this.underlying
          .next();
      return new StatementJena29Impl(quad.getGraph(), quad.getSubject(),
          quad.getPredicate(), quad.getObject());
    }

    @Override
    public void remove() {
      this.underlying.remove();
    }
  }

  public ModelSetImplJena(com.hp.hpl.jena.query.Dataset dataset) {
    this.dataset = dataset;
    this.lock = this.dataset.getLock();
    org.apache.jena.riot.RIOT.init(); //wires RIOT readers/writers into Jena
  }

  @Override
  public ModelSet open() {
    return this;
  }

  @Override
  public boolean isOpen() {
    return this.open;
  }

  @Override
  public void close() {
    this.open = false;
  }

  @Override
  public long size() throws ModelRuntimeException {

    // Start with the size of the default graph
    long size = this.dataset.getDefaultModel().size();

    // Loop and add the sizes of all contained graphs
    Iterator<String> it = this.dataset.listNames();
    while (it.hasNext()) {
      size += this.dataset.getNamedModel(it.next()).size();
    }

    return size;
  }

  @Override
  public Model getModel(URI contextURI) {
    com.hp.hpl.jena.rdf.model.Model jenaModel = dataset
        .getNamedModel(contextURI.toString());

    if (jenaModel == null) {
      jenaModel = com.hp.hpl.jena.rdf.model.ModelFactory
          .createDefaultModel();
    }
   
    // return opened model
    return new ModelImplJena(contextURI, jenaModel).open();
  }

  @Override
  public boolean removeModel(URI contextURI) {
    this.dataset.removeNamedModel(contextURI.toString());
    return true;
  }

  @Override
  public boolean containsModel(URI contextURI) {
    return this.dataset.containsNamedModel(contextURI.toString());
  }

  @Override
  public Model getDefaultModel() {
    com.hp.hpl.jena.rdf.model.Model jenaModel = this.dataset
        .getDefaultModel();
    // return opened model
    return new ModelImplJena(jenaModel).open();
  }

  /**
   * Return all <i>named</i> models. This does not currently return the
   * default model because there is no usable iterator in Jena for this. Also
   * the default Model in Jena has no usable context URI which causes problems
   * later when iterating over the models e.g., using
   * {@linkplain ClosableIterator#remove()}
   */
  @Override
  public ClosableIterator<Model> getModels() {
    return new ModelIterator(this.getModelURIs());
  }

  @Override
  public ClosableIterator<URI> getModelURIs() {
    return new ContextIterator(this.dataset.listNames());
  }

  @Override
  public Object getUnderlyingModelSetImplementation() {
    return this.dataset;
  }

  @Override
  public ClosableIterable<Statement> queryConstruct(String query,
      String querylanguage) throws QueryLanguageNotSupportedException,
      MalformedQueryException, ModelRuntimeException {

    Query jenaQuery = QueryFactory.create(query);
    QueryExecution qexec = QueryExecutionFactory.create(jenaQuery,
        this.dataset);

    if (jenaQuery.isConstructType()) {
      com.hp.hpl.jena.rdf.model.Model m = qexec.execConstruct();
      Model resultModel = new ModelImplJena(null, m, Reasoning.none);
      resultModel.open();
      return resultModel;
    } else {
      throw new RuntimeException(
          "Cannot handle this type of query! Please use CONSTRUCT.");
    }
  }

  @Override
  public QueryResultTable querySelect(String query, String querylanguage)
      throws QueryLanguageNotSupportedException, MalformedQueryException,
      ModelRuntimeException {
    com.hp.hpl.jena.query.Syntax syntax = com.hp.hpl.jena.query.Syntax
        .lookup(querylanguage);
    if (syntax == null) {
      // delegate to super
      throw new QueryLanguageNotSupportedException(
          "Unsupported query language: " + querylanguage);
    }
    Query jenaQuery = QueryFactory.create(query, syntax);
    return new QueryResultTableImpl(jenaQuery,
        this.dataset);
  }

  @Override
  public ClosableIterable<Statement> sparqlConstruct(String query)
      throws ModelRuntimeException, MalformedQueryException {
    Query jenaQuery = QueryFactory.create(query);
    QueryExecution qexec = QueryExecutionFactory.create(jenaQuery,
        this.dataset);

    if (jenaQuery.isConstructType()) {
      com.hp.hpl.jena.rdf.model.Model m = qexec.execConstruct();
      Model resultModel = new ModelImplJena(null, m, Reasoning.none);
      resultModel.open();
      return resultModel;
    } else {
      throw new RuntimeException(
          "Cannot handle this type of query! Please use CONSTRUCT.");
    }

  }

  @Override
  public ClosableIterable<Statement> sparqlDescribe(String query)
      throws ModelRuntimeException {
    Query jenaQuery = QueryFactory.create(query);
    QueryExecution qexec = QueryExecutionFactory.create(jenaQuery,
        this.dataset);

    if (jenaQuery.isDescribeType()) {
      com.hp.hpl.jena.rdf.model.Model m = qexec.execDescribe();
      Model resultModel = new ModelImplJena(null, m, Reasoning.none);
      resultModel.open();
      return resultModel;
    } else {
      throw new RuntimeException(
          "Cannot handle this type of query! Please use DESCRIBE.");
    }
  }

  @Override
  public QueryResultTable sparqlSelect(String queryString)
      throws MalformedQueryException, ModelRuntimeException {
    Query jenaQuery = QueryFactory.create(queryString);
    return new QueryResultTableImpl(jenaQuery,
        this.dataset);
  }

  @Override
  public boolean sparqlAsk(String query) throws ModelRuntimeException,
      MalformedQueryException {
    Query jenaQuery = QueryFactory.create(query);
    QueryExecution qexec = QueryExecutionFactory.create(jenaQuery,
        this.dataset);

    if (jenaQuery.isAskType()) {
      return qexec.execAsk();
    } else {
      throw new RuntimeException(
          "Cannot handle this type of query! Please use ASK.");
    }
  }

  /**
   * Read data from an {@linkplain Reader} with RDF syntax {@link Syntax#Trix}.
   */
  @Override
  public void readFrom(Reader in) throws IOException, ModelRuntimeException {
    readFrom(in, Syntax.Trix, null);
  }

  @Override
  public void readFrom(Reader in, Syntax syntax) throws IOException,
      ModelRuntimeException, SyntaxNotSupportedException {
    readFrom(in, syntax, null);
  }

  @Override
  public void readFrom(Reader in, Syntax syntax, String baseURI)
      throws IOException, ModelRuntimeException,
      SyntaxNotSupportedException {
    ReaderInputStream is = new ReaderInputStream(in, StandardCharsets.UTF_8);
    readFrom(is, syntax, baseURI);
  }

  /**
   * Read data from an {@linkplain InputStream} with RDF syntax
   * {@link Syntax#Trix}.
   *
   * <br />
   * <b>Please note:</b><br />
   * In this Jena implementation this will fail until a matching
   * {@linkplain RiotReader} is available. Please use
   * {@linkplain ModelSetImplJena#readFrom(Reader, Syntax)} with an available
   * syntax such as {@link Syntax#Nquads} or {@link Syntax#Trig}.
   */
  @Override
  public void readFrom(InputStream in) throws IOException,
      ModelRuntimeException {
    readFrom(in, Syntax.Trix, null);
  }

  @Override
    public void readFrom(InputStream in, Syntax syntax) throws IOException,
      ModelRuntimeException, SyntaxNotSupportedException {
    readFrom(in, syntax, null);
    }
   
  @Override
  public void readFrom(InputStream in, Syntax syntax, String baseURI)
      throws IOException, ModelRuntimeException,
      SyntaxNotSupportedException {

    RDFDataMgr.read(this.dataset.asDatasetGraph(), in, baseURI, getJenaLang(syntax));
  }

  /**
   * Write data to a {@linkplain Writer} with RDF syntax
   * {@link Syntax#Trix}.
   *
   * <br />
   * <b>Please note:</b><br />
   * In this Jena implementation this will fail until a matching
   * {@linkplain RiotWriter} is available. Please use
   * {@linkplain ModelSetImplJena#writeTo(Writer, Syntax)} with an available
   * syntax such as {@link Syntax#Nquads}.
   */
  @Override
  public void writeTo(Writer out) throws IOException, ModelRuntimeException {
    writeTo(out, Syntax.Trix);
  }

  /**
   * Write data to an {@linkplain OutputStream} with RDF syntax
   * {@link Syntax#Trix}.
   *
   * <br />
   * <b>Please note:</b><br />
   * In this Jena implementation this will fail until a matching
   * {@linkplain RiotWriter} is available. Please use
   * {@linkplain ModelSetImplJena#writeTo(OutputStream, Syntax)} with an available
   * syntax such as {@link Syntax#Nquads}.
   */
  @Override
  public void writeTo(OutputStream out) throws IOException,
      ModelRuntimeException {
    writeTo(out, Syntax.Trix);
  }

  @Override
    public void writeTo(Writer writer, Syntax syntax) throws IOException,
      ModelRuntimeException, SyntaxNotSupportedException {
    WriterOutputStream stream = new WriterOutputStream(writer, StandardCharsets.UTF_8);
    writeTo(stream, syntax);
  }

  @Override
  public void writeTo(OutputStream out, Syntax syntax) throws IOException,
      ModelRuntimeException, SyntaxNotSupportedException {
   
    if (syntax == null) {
      throw new NullPointerException("syntax may not be null");
    }
   
    Lang jenaLang = getJenaLang(syntax);

//    if (RDFLanguages.isTriples(jenaLang)) {
//      /*
//       * NB: Writing a ModelSet to a triple serialization loses the
//       * context of any quads if present.
//       */
//      Iterator<Model> it = this.getModels();
//      while (it.hasNext()) {
//        Model model = it.next();
//        model.writeTo(out, syntax);
//      }
//      this.getDefaultModel().writeTo(out, syntax);
//    }
// FIXME stuehmer: write unit test to see if this can be removed
//    else {
    try {
      RDFDataMgr.write(out, this.dataset, jenaLang);
    }
    catch (RiotException e) {
      throw new SyntaxNotSupportedException(
          "error writing syntax " + syntax + ": " + e.getMessage());
    }
  }

  @Override
  public QuadPattern createQuadPattern(UriOrVariable context,
      ResourceOrVariable subject, UriOrVariable predicate,
      NodeOrVariable object) {
    return new JenaQuadPattern(context, subject, predicate, object);
  }

  @Override
  public void addStatement(Statement statement) throws ModelRuntimeException {
    addStatement(statement.getContext(), statement.getSubject(),
        statement.getPredicate(), statement.getObject());
  }

  @Override
  public void addStatement(URI context, Resource subject, URI predicate,
      Node object) throws ModelRuntimeException {
    com.hp.hpl.jena.rdf.model.Model jenaModel;
   
    if (context != null) {
      jenaModel = this.dataset.getNamedModel(context.toString());
    } else {
      jenaModel = this.dataset.getDefaultModel();
    }
    jenaModel.getGraph().add(
        new com.hp.hpl.jena.graph.Triple(TypeConversion.toJenaNode(
            subject, jenaModel), TypeConversion.toJenaNode(
            predicate, jenaModel), TypeConversion.toJenaNode(
            object, jenaModel)));
  }

  @Override
  public void removeAll() throws ModelRuntimeException {
    // Empty the default graph
    this.dataset.getDefaultModel().removeAll();
    // Remove all named graphs
    Iterator<String> it = this.dataset.listNames();
    while (it.hasNext()) {
      it.next();
      it.remove();
    }
  }

  @Override
    public void removeStatements(QuadPattern quadPattern)
      throws ModelRuntimeException {
    removeStatements(quadPattern.getContext(), quadPattern.getSubject(),
        quadPattern.getPredicate(), quadPattern.getObject());
  }

  @Override
    public void removeStatements(UriOrVariable context,
      ResourceOrVariable subject, UriOrVariable predicate,
      NodeOrVariable object) throws ModelRuntimeException {
    this.dataset.asDatasetGraph().deleteAny(
        (context != null) ? TypeConversion.toJenaNode(context)
            : com.hp.hpl.jena.graph.Node.ANY,
        TypeConversion.toJenaNode(subject),
        TypeConversion.toJenaNode(predicate),
        TypeConversion.toJenaNode(object));
  }
 
  @Override
  public void removeStatement(Statement statement)
      throws ModelRuntimeException {
    removeStatement(statement.getContext(), statement.getSubject(),
        statement.getPredicate(), statement.getObject());
  }

  @Override
  public void removeStatement(URI context, Resource subject, URI predicate,
      Node object) throws ModelRuntimeException {
   
    if (context == null) {
      this.dataset
          .getDefaultModel()
          .getGraph()
          .delete(new com.hp.hpl.jena.graph.Triple(TypeConversion
              .toJenaNode(subject), TypeConversion
              .toJenaNode(predicate), TypeConversion
              .toJenaNode(object)));
    } else {
      this.dataset.asDatasetGraph().delete(
          TypeConversion.toJenaNode(context),
          TypeConversion.toJenaNode(subject),
          TypeConversion.toJenaNode(predicate),
          TypeConversion.toJenaNode(object));
    }
  }

  @Override
    public long countStatements(QuadPattern pattern) {
    String context = (pattern.getContext() != null) ? pattern.getContext()
        .toString() : com.hp.hpl.jena.graph.Node.ANY.getName();
    String subject = pattern.getSubject().toString();
    String predicate = pattern.getPredicate().toString();
    String object = pattern.getObject().toString();

    com.hp.hpl.jena.query.QuerySolutionMap initialBindings =
        new com.hp.hpl.jena.query.QuerySolutionMap();
    if (pattern.getContext() != null) {
      initialBindings.add("c", this.dataset.getDefaultModel()
          .createResource(context));
    }
    initialBindings.add("s",
        this.dataset.getDefaultModel().createResource(subject));
    initialBindings.add("p",
        this.dataset.getDefaultModel().createResource(predicate));
    initialBindings.add("o",
        this.dataset.getDefaultModel().createResource(object));

    String query = "SELECT (count(*) AS ?count) WHERE { GRAPH ?c { ?s ?p ?o } }";

    // Initialize the reusable query
    if (this.countStatementsQuery == null) {
      this.countStatementsQuery = QueryFactory.create(query,
          com.hp.hpl.jena.query.Syntax.syntaxARQ);
    }

    QueryExecution exec = QueryExecutionFactory.create(
        this.countStatementsQuery, this.dataset, initialBindings);
    QueryResultTable result = new QueryResultTableImpl(exec);
    return Long
        .parseLong(result.iterator().next().getLiteralValue("count"));
  }

  @Override
    public ClosableIterator<Statement> findStatements(QuadPattern pattern)
      throws ModelRuntimeException {
    return this.findStatements(pattern.getContext(),
        pattern.getSubject(), pattern.getPredicate(),
        pattern.getObject());
  }
 
  @Override
    public ClosableIterator<Statement> findStatements(UriOrVariable contextURI,
      ResourceOrVariable subject, UriOrVariable predicate,
      NodeOrVariable object) throws ModelRuntimeException {
    return new StatementIterator(this.dataset.asDatasetGraph().find(
        (contextURI != null) ? TypeConversion.toJenaNode(contextURI)
            : com.hp.hpl.jena.graph.Node.ANY,
        TypeConversion.toJenaNode(subject),
        TypeConversion.toJenaNode(predicate),
        TypeConversion.toJenaNode(object)));
  }

  @Override
  public ClosableIterator<Statement> iterator() {
    return new StatementIterator(this.dataset.asDatasetGraph().find());
  }
 
  @Override
  public void commit() throws ModelRuntimeException {
  }

  @Override
  public void setAutocommit(boolean autocommit) {
  }

  @Override
  public String getNamespace(String prefix) {
    // We use the default model because there is no prefix mapping on
    // Dataset itself:
    return this.dataset.getDefaultModel().getNsPrefixURI(prefix);
  }

  @Override
  public Map<String, String> getNamespaces() {
    // We use the default model because there is no prefix mapping on
    // Dataset itself:
    return this.dataset.getDefaultModel().getNsPrefixMap();
  }

  /**
   * Remove the specified namespace from all {@linkplain Model}s
   * in this {@linkplain ModelSet} including the default graph.
   */
  @Override
  public void removeNamespace(String prefix) {
    this.dataset.getDefaultModel().removeNsPrefix(prefix);
    Iterator<Model> it = this.getModels();
    while (it.hasNext()) {
      it.next().removeNamespace(prefix);
    }
  }

  /**
   * Set the specified namespace for all {@linkplain Model}s
   * in this {@linkplain ModelSet} including the default graph.
   */
  @Override
  public void setNamespace(String prefix, String namespaceURI)
      throws IllegalArgumentException {
    this.dataset.getDefaultModel().setNsPrefix(prefix, namespaceURI);
    Iterator<Model> it = this.getModels();
    while (it.hasNext()) {
      it.next().setNamespace(prefix, namespaceURI);
    }
  }

  @Override
  public boolean isLocked() {
    return super.isLocked();
  }

  @Override
  public void lock() throws LockException {
    if (isLocked()) {
      throw new LockException("Already locked");
    }
    else {
      super.lock();
      this.lock.enterCriticalSection(com.hp.hpl.jena.shared.Lock.WRITE);
    }
  }

  @Override
  public void unlock() {
    if (isLocked()) {
      this.lock.leaveCriticalSection();
      super.unlock();
    }
  }

  @Override
  public boolean isEmpty() {
    return this.dataset.asDatasetGraph().isEmpty();
  }

  @Override
  public String toString() {
    return this.dataset.asDatasetGraph().toString();
  }

  @Override
  public boolean addModel(Model model) {
    for (String prefix : model.getNamespaces().keySet()) {
      this.dataset.getDefaultModel().setNsPrefix(prefix, model.getNamespace(prefix));
    }
     
    if (model instanceof ModelImplJena) {
      this.dataset.getNamedModel(model.getContextURI().toString()).add(
          ((com.hp.hpl.jena.rdf.model.Model) model
              .getUnderlyingModelImplementation()));
      return true;
    }
    else {
      return super.addModel(model);
    }
  }

  @Override
  public void addModel(Model model, URI contextURI) {
    for (String prefix : model.getNamespaces().keySet()) {
      this.dataset.getDefaultModel().setNsPrefix(prefix, model.getNamespace(prefix));
    }
   
    if (model instanceof ModelImplJena) {
      this.dataset.getNamedModel(contextURI.toString()).add(
          ((com.hp.hpl.jena.rdf.model.Model) model
              .getUnderlyingModelImplementation()));
    }
    else {
      super.addModel(model, contextURI);
    }
  }
}
TOP

Related Classes of org.ontoware.rdf2go.impl.jena.ModelSetImplJena$ContextIterator

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.