Package lupos.distributed.p2p.query.withsubgraph

Source Code of lupos.distributed.p2p.query.withsubgraph.P2P_QueryClient_Instanciator$IConfigurator

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.distributed.p2p.query.withsubgraph;

import static com.google.common.base.Throwables.propagate;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;
import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.bindings.BindingsFactory;
import lupos.datastructures.bindings.BindingsMap;
import lupos.datastructures.items.literal.LiteralFactory;
import lupos.datastructures.items.literal.URILiteral;
import lupos.datastructures.items.literal.LiteralFactory.MapType;
import lupos.distributed.p2p.distributionstrategy.SimplePartitionDistribution;
import lupos.distributed.p2p.network.AbstractP2PNetwork;
import lupos.distributed.p2p.network.P2PNetworkCreator;
import lupos.distributed.p2p.storage.StorageWithDistributionStrategy;
import lupos.distributed.query.QueryClient;
import lupos.distributed.query.QueryClientWithSubgraphTransmission;
import lupos.distributed.storage.IStorage;
import lupos.distributed.storage.distributionstrategy.IDistribution;
import lupos.distributed.storage.distributionstrategy.tripleproperties.KeyContainer;
import lupos.engine.evaluators.QueryEvaluator;
import lupos.optimizations.physical.PhysicalOptimizations;

/**
* This is the query client to be configured in a static way. So for configuration
* use {@link #lock()} and finally {@link #unlock()} to block and set the configuration.
* With {@link #newInstance()} or {@link #newInstance(String[])} you can create the query client instance
* that can be used.
*/
public abstract class P2P_QueryClient_Instanciator extends QueryEvaluator<lupos.sparql1_1.Node>{

  /**
   * new instance (not allowed to call)
   * @throws Exception throws always a RuntimeException
   */
  @Deprecated
  public P2P_QueryClient_Instanciator() throws Exception {
    throw new RuntimeException("Please use instanciating via P2P_QueryClient.newInstace(). This is only a QueryClient to be used in visual lupos query editor.");
  }

  /*
   * do we need subgraph submission?
   */
  private static boolean useSubgraphSubmission = true;
  @SuppressWarnings("rawtypes")
  private static IConfigurator<? super StorageWithDistributionStrategy> storageConfiguration;
 
 
 
 
  /**
   * Sets the configuration for the storage
   * @param cfg the configuration
   */
  @SuppressWarnings("rawtypes")
  public static void setStorageConfiguration(IConfigurator<? super StorageWithDistributionStrategy> cfg) {
    storageConfiguration = cfg;
  }
 
  /**
   * This interface is to be used to manually configure an instance, for example for {@link StorageWithDistributionStrategy}.
   * Because the settings have to be applied on a real existing instance, that is created in a hidden way,
   * here is the possibility to configure the instance before using, but after instantiating.
   * @author Bjoern
   *
   * @param <T> the type of instance to configure
   */
  public static interface IConfigurator<T> {
    public void doConfiguration(T storage);
  }
 
  /*
   * Invoke the constructor for creating the subgraph container with the given
   * parameters.
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  private static StorageWithDistributionStrategy invoke(String className, AbstractP2PNetwork r, IDistribution key,
      BindingsFactory bf) {
   
    try {
      /*
       * get the class, which has to be a subclass of SubgraphContainer
       */
      Class<?> c = Class.forName(className);
      if (!StorageWithDistributionStrategy.class.isAssignableFrom(c)) {
        throw new RuntimeException(
            String.format(
                "The type \"%s\" is not a class extended from %s",
                className,StorageWithDistributionStrategy.class));
      } else {
        Class<? extends StorageWithDistributionStrategy> c1 = (Class<? extends StorageWithDistributionStrategy>) c;
        try {
          Constructor<? extends StorageWithDistributionStrategy> construct = c1
              .getConstructor(AbstractP2PNetwork.class, IDistribution.class,BindingsFactory.class);
          return construct.newInstance(r, key,bf);
        } catch (NoSuchMethodException e) {
          throw new RuntimeException(
              String.format(
                  "The class \"%s\" has no valid constructor.",
                  className));
        } catch (SecurityException e) {
          propagate(e);
        } catch (InstantiationException e) {
          propagate(e);
        } catch (IllegalAccessException e) {
          propagate(e);
        } catch (IllegalArgumentException e) {
          throw new RuntimeException(
              String.format(
                  "The type \"%s\" of subgraph-container has no valid constructor.",
                  className));
        } catch (InvocationTargetException e) {
          propagate(e);
        }
      }
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(
          String.format(
              "The class \"%s\" of subgraph-container is not known in actual class path. Cannot deserialize this subgraph container.",
              className));
    }
    /*
     * if not possible or error occurred.
     */
    return null;
  }
 
  public static QueryClient newInstance() {
    return newInstance(new String[0]);
  }
 
  private static Logger log = Logger.getLogger(P2P_QueryClient_Instanciator.class);
 
  /**
   * Creates a new instance of a query client
   * @return a new instance
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static QueryClient newInstance(String[] args) {
    try {
     
      /*set literalfactory */
      Bindings.instanceClass = BindingsMap.class;
      LiteralFactory.setType(MapType.NOCODEMAP);
      LiteralFactory.setTypeWithoutInitializing(MapType.NOCODEMAP);
     
     
      final int instance = instanceCounter.incrementAndGet();
      if (bindings != null) Bindings.instanceClass = bindings;
      BindingsFactory bf = BindingsFactory.createBindingsFactory();
     
     
     
      String debugString = "\n";
      debugString += (String.format("Creating new P2P query client instance: %d \n",instance));
      AbstractP2PNetwork p2pInstance = networkInstance != null ? networkInstance : getP2PNetworkImplementation();
      if (networkInstance == null) {
        debugString += (String.format("P2P network: %s \nP2P configuration: %s \nP2P instance: %s \nhas local storage %s \n",p2pImplementationConstant,
              (p2pImplementationConfiguration != null) ? getP2PConfig(p2pImplementationConfiguration) : "{}",p2pInstance,
                  p2pInstance.hasLocalStorage()));
      } else {
        debugString += (String.format("P2P network: %s \nP2P instance: %s \nhas local storage: %s \n",p2pInstance.getClass(),
            p2pInstance,p2pInstance.hasLocalStorage()));       
      }
      IDistribution distribution = getDistribution();
      debugString += (String.format("DistributionStrategy: %s [%s] \n",distribution,distribution.getClass()))
     
      P2P_SubgraphExecuter sgExecuter = new P2P_SubgraphExecuter() {
        @Override
        public String toString() {
          return String.format("SubgraphExecuter for query client instance %s on node: %s \n",instance, p2p);
        }
      };
     
      StorageWithDistributionStrategy storageInstance = invoke(storageClass.getName(),p2pInstance,distribution,bf);
      if (storageConfiguration != null) {
        storageConfiguration.doConfiguration(storageInstance);
        debugString += (String.format("Storage: %s [%s] with manual configuration: %s \n",storageInstance,storageInstance.getClass(),storageConfiguration))
       
      } else {
        debugString += (String.format("Storage: %s [%s] \n",storageInstance,storageInstance.getClass()));
      }
     
      P2P_SG_QueryClient_WithSubgraph queryClientInstance = new P2P_SG_QueryClient_WithSubgraph(storageInstance,sgExecuter) {
        @Override
        public String toString() {
          return String.format("QueryClient [%s]",instance);
        }
      };
      if (useSubgraphSubmission)
        debugString += (String.format("Query Client: %s with subgraph submission \n",queryClientInstance));
      else
        debugString += (String.format("Query Client: %s without subgraph submission \n",queryClientInstance));
      queryClientInstance.setUseSubgraphSubmission(useSubgraphSubmission);
      /*
       * if a local storage is supported, use this for subgraph executer
       */
      IStorage localStorage = (p2pInstance.hasLocalStorage()) ? p2pInstance.getLocalStorage(distribution) : storageInstance;
      sgExecuter.setStorage(localStorage);
      sgExecuter.setP2PNetwork(p2pInstance);
      /*
       * create an query evaluator for the local storage, which is evaluated in local storage
       */
      QueryEvaluator localEvaluator = new QueryClientWithSubgraphTransmission(localStorage,distribution,sgExecuter) {
        @Override
        public String toString() {
          return "LocalQueryExecuter for instance " + instance;
        }
      };
      Collection<URILiteral> defaultGraphs = new LinkedList<URILiteral>();
      // init with empty dataset ...
      LiteralFactory.setType(MapType.NOCODEMAP);
      defaultGraphs.add(LiteralFactory
          .createURILiteralWithoutLazyLiteral("<inlinedata:>"));
      Collection<URILiteral> namedGraphs = new LinkedList<URILiteral>();
      localEvaluator.prepareInputData(defaultGraphs, namedGraphs);
      queryClientInstance.prepareInputData(defaultGraphs, namedGraphs);
      try {
        PhysicalOptimizations.memoryReplacements();
      } catch (Exception e) {
        //ignore
      }
      //connect local storage evaluater in subgraph executer
      sgExecuter.setEvaluator(localEvaluator);
      log.info(debugString);
      return queryClientInstance;
    } catch (Exception e) {
      throw new RuntimeException("Cannot instanciate class:" + e.getMessage() );
    }
  }
 
  private static String getP2PConfig(
      Map<String, Object> p2pImplementationConfiguration2) {
    StringBuilder sb = new StringBuilder();
    sb.append("{");
    for (Entry<String, Object> e : p2pImplementationConfiguration2.entrySet()) {
      sb.append("\n\t").append(e.getKey()).append(" = ").append(e.getValue());
    }
    sb.append("\n}");
    return sb.toString();
  }

  @SuppressWarnings({ "rawtypes", "unused" })
  private P2P_SubgraphExecuter sg;
  @SuppressWarnings("rawtypes")
  private static AbstractP2PNetwork p2p;
 
  private static AbstractP2PNetwork<?> getP2PNetworkImplementation() {
    try {
      /*
       * Instantiating the P2P network, specified via static setter
       */
      if (p2pImplementationConfiguration != null) {
        return  P2PNetworkCreator.get(p2pImplementationConstant,p2pImplementationConfiguration);
      }else {
        return  P2PNetworkCreator.get(p2pImplementationConstant);
      }
    } catch (RuntimeException e) {
      Logger.getLogger(P2P_QueryClient_Instanciator.class).error("Error getting P2P network instance.",e);
      return null;
    }
  }

  /*
   * returns the used distribution strategy
   */
  private static IDistribution<KeyContainer<String>> getDistribution() {
    return p2pDistribution;
  }

  private static Map<String,Object> p2pImplementationConfiguration = new HashMap<String,Object>();
 
  /**
   * Returns the map of configuration to be used for instanciation
   * @return the map
   */
  public static Map<String, Object> getP2PImplementationConfiguration() {
    return p2pImplementationConfiguration;
  }

  private static String p2pImplementationConstant = P2PNetworkCreator.TOM_P2P;
  private static IDistribution<KeyContainer<String>> p2pDistribution = new SimplePartitionDistribution();
  /*
   * Lock to be used if changing static parameters during instantiating query client
   */
  private static Lock l = new ReentrantLock();
  @SuppressWarnings("rawtypes")
  private static Class<? extends StorageWithDistributionStrategy> storageClass = StorageWithDistributionStrategy.class;
 
  /**
   * Creates a lock, so that constants could be set for instantiation
   */
  public static void lock() {
    l.lock();
  }
 
  /**
   * Sets, whether subgraph submission is to be used or without
   * @param enabled subgraph submission enabled
   */
  public static void setSubgraphSubmission(boolean enabled) {
    useSubgraphSubmission = enabled;
  }
 
  /**
   * Sets the P2P implementation constant
   * @param p2pNetworkConstant the unique P2P key to be used in {@link P2PNetworkCreator#get(String)}
   */
  public static void setP2PImplementationConstant(String p2pNetworkConstant) {
    p2pImplementationConstant = p2pNetworkConstant;
  }
 
  /**
   * Sets the P2P configuration for the network
   * @param cfg the configuration to set!
   */
  public static void setP2PImplementationConfiguration(Map<String,Object> cfg) {
    p2pImplementationConfiguration = cfg;
  }
 
  /**
   * Sets the distribution used in this query client.
   * @param p2pDistributionType the distribution strategy
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static void setP2PDistributionStrategy(IDistribution p2pDistributionType) {
    p2pDistribution = p2pDistributionType;
  }
 
 
  @SuppressWarnings("rawtypes")
  public static void setStorageType(Class<? extends StorageWithDistributionStrategy> storage) {
    if (storage != null)
      storageClass = storage;
  }
 
 
  /**
   * Removes the lock set in {@link #lock()}
   */
  public static void unlock() {
    l.unlock();
  }
 
 
  /*
   * static counter incrementing if creating new instance
   */
  private static AtomicInteger instanceCounter = new AtomicInteger();
  private static AbstractP2PNetwork<?> networkInstance;
  private static Class<? extends Bindings> bindings;

  /**
   * Sets the network implementation to be used
   * @param p2pNetwork the p2p network
   */
  public static void setP2PNetwork(AbstractP2PNetwork<?> p2pNetwork) {
    networkInstance = p2pNetwork;
  }

 
  /**
   * Sets the needed bindings class to be used
   */
  public static void setBindings(Class<? extends Bindings> b) {
    bindings = b;
  }

 
}
TOP

Related Classes of lupos.distributed.p2p.query.withsubgraph.P2P_QueryClient_Instanciator$IConfigurator

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.