text:
<!--
  UK Crown Copyright (c) 2016. All Rights Reserved
-->
<!-- Converted by db4-upgrade version 1.0 -->
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ObjectsandRelationships"><info><title>Objects and Relationships</title></info>

  <para>This chapter starts by describing how instances of objects are created
  followed by a description of how instances that have already been created
  are obtained, and how to delete instances.</para>

  <para>We then move onto relationships and mirror the first part of this
  chapter describing how relationships are created followed by a description
  of navigating existing relation-ships, and how to delete
  relationships.</para>

  <section xml:id="ObjectsandRelationshipsCreatingInstances"><info><title>Creating Instances</title></info>

    <para>An instance of an object is created by using a create expression. A
    create expression starts with the reserved word <literal>create</literal>
    followed by the name of an object and an object aggregate. The object
    aggregate is a list of attribute associations, each of which consists of a
    name of an attribute followed by <literal>=></literal> and then some
    expression giving the initial value, all enclosed by brackets.<figure xml:id="ObjectsandRelationshipsAircraftObject"><info><title>Aircraft Object</title></info>

        <mediaobject>
          <imageobject>
            <imagedata align="center" fileref="images/aircraftclass.svg" format="svg" valign="middle"/>
          </imageobject>
        </mediaobject>
      </figure></para>

    <para>Given the <classname>Aircraft</classname> object shown in <xref linkend="ObjectsandRelationshipsAircraftObject"/> we might
    write:<informalexample>
        <programlisting>  create Aircraft(serial_number => 76);</programlisting>
      </informalexample></para>

    <para>This creates a new Aircraft instance with a serial number of
    <literal>76</literal>. The object aggregate must supply initial values for
    all non-referential preferred attributes; otherwise, a compile-time error
    will occur. If, at run-time, these initial values do not define a unique
    instance, object instance with same preferred id(s) already exists, then
    an exception will be raised.</para>

    <para>If the <classname>Aircraft</classname> object was an active object,
    and hence instances of it had a <varname>Current_State</varname>
    attribute, then the initial state of an instance must also be set when it
    is created (this also includes creation states).<informalexample>
        <programlisting>  create Aircraft(serial_number => 76, Current_State => parked);</programlisting>
      </informalexample>This creates a new <classname>Aircraft</classname>
    instance with a serial number of <literal>76</literal>, in the initial
    state <literal>parked</literal>.</para>

    <para>Having created an instance we might want to access its attributes.
    We can do this by assigning the created instance to a variable of the
    appropriate instance type. Each object within a model has a corresponding
    instance type. Variables of a specific instance type can refer to specific
    instances of the corresponding object. To declare a variable of the
    instance type of the <classname>Aircraft</classname> object we might
    write:<informalexample>
        <programlisting>  aircraft_instance : instance of Aircraft;</programlisting>
      </informalexample></para>

    <para>We could then assign the created instance to this
    variable.<informalexample>
        <programlisting>  declare
    aircraft_instance : instance of Aircraft;
  begin
    aircraft_instance := create Aircraft(serial_number => 76);
  end;</programlisting>
      </informalexample></para>

    <para>Attributes of an instance can be denoted by following the instance
    name with a dot and the attribute name. Therefore we might
    write:<informalexample>
        <programlisting>  declare
    serial_number : integer;
  begin
    aircraft_instance := create Aircraft(serial_number => 76);
    serial_number := aircraft.serial_number;
    aircraft_instance.speed := 0;
  end;</programlisting>
      </informalexample></para>

    <para>Notice that we can both set and get the values of attributes.
    Certain types of attributes cannot have their values set in this way. If
    an attribute is either preferred or referential then its value cannot be
    set in this manner.</para>

    <figure xml:id="ObjectsandRelationshipsRelationshipbetweenPilotandAircraft"><info><title>Relationship between Pilot and Aircraft</title></info>

      <mediaobject>
        <imageobject>
          <imagedata align="center" fileref="images/relationshippilotandaircraft.svg" format="svg" valign="middle"/>
        </imageobject>
      </mediaobject>
    </figure>

    <para>For example, given the relationship shown in <xref linkend="ObjectsandRelationshipsRelationshipbetweenPilotandAircraft"/>
    the following assignments are illegal:<informalexample>
        <programlisting>  declare
    aircraft_instance : instance of Aircraft;
    pilot_instance    : instance of Pilot;
  begin
    aircraft_instance  := create Aircraft(serial_number => 76);
    pilot_instance     := create Pilot(name => "Peter Smith");

    aircraft_instance.serial_number := 38;     // illegal : preferred id cannot be reset
    aircraft_instance.pilot_name := "Fred";    // illegal : referential cannot be set
  end;</programlisting>
      </informalexample></para>
  </section>

  <section xml:id="ObjectsandRelationshipsObtainingInstances"><info><title>Obtaining instances</title></info>

    <para>In that last section we showed how we could obtain the instance
    produced by a <literal>create</literal> expression. If we want to obtain
    instances that have already been created we can use a
    <literal>find</literal> expression. There are four forms of find
    expression:</para>

    <itemizedlist>
      <listitem>
        <para><literal>find</literal></para>
      </listitem>

      <listitem>
        <para><literal>find_all</literal></para>
      </listitem>

      <listitem>
        <para><literal>find_one</literal></para>
      </listitem>

      <listitem>
        <para><literal>find_only</literal></para>
      </listitem>
    </itemizedlist>

    <para>The <literal>find</literal> locates all the instances of an object
    satisfying a specified condition. This form starts with the reserved word
    <literal>find</literal> followed by the name of an object and a condition
    enclosed by brackets. Given the <classname>Aircraft</classname> object we
    might write:<informalexample>
        <programlisting>  find Aircraft(speed < 100);</programlisting>
      </informalexample>This finds all instances of the
    <classname>Aircraft</classname> object whose speed is less than
    <literal>100</literal>. The condition can of course, be of arbitrary
    complexity with the restriction that left-hand side of an equality
    (<literal>=</literal> and <literal>/=</literal>) or relational expression
    (<literal>></literal>, <literal><</literal>,
    <literal>>=</literal> and <literal><=</literal>) must be the name of
    an attribute of the object being found. A more complex example might
    be:<informalexample>
        <programlisting>  find Aircraft(speed >= 3 * (10 ** 8) and pilot_name /= "Fred Bloggs");</programlisting>
      </informalexample>This would find all instances of the
    <classname>Aircraft</classname> object whose speed is greater than or
    equal to the speed of light and is not been flown by Fred Bloggs. In order
    to use the set of instances returned from the find expression we must
    assign it to a variable of the appropriate type. Therefore we might
    write:<informalexample>
        <programlisting>  aircraft_set : set of instance of Aircraft;
  begin
    aircraft_set := find Aircraft(speed < 100);
  end;</programlisting>
      </informalexample></para>

    <para>If there are no instances that satisfy the condition then the
    <type>sequence</type> returned from the <literal>find</literal> expression
    will be empty. One of the most common things to do once we have obtained a
    set of instances is to loop around the set performing some operation on
    each instance.<informalexample>
        <programlisting>  for i in aircraft_set'elements loop
    // …
  end loop;</programlisting>
      </informalexample></para>

    <para>The order in which instances from the <type>set</type> are taken is
    arbitrary. If we wanted to use a specific order we would have to use an
    ordering expression. An ordering expression allows the analyst to order a
    collection of instances using a specific attribute of each instance. For
    example we could order the aircraft set by their speeds by writing
    :<informalexample>
        <programlisting>  aircraft_sequence := aircraft_set ordered_by (speed);</programlisting>
      </informalexample>The resultant <type>sequence</type> will be such that
    for each successive element in the <type>sequence</type>, the first will
    be the element with the lowest speed. We could reverse the ordering by
    writing:<informalexample>
        <programlisting>  aircraft_sequence := aircraft_set reverse_ordered_by (speed);</programlisting>
      </informalexample>It is also possible to specify multiple attributes.
    For example:<informalexample>
        <programlisting>  aircraft_sequence := aircraft_set ordered_by (speed, serial_number);. </programlisting>
      </informalexample>The resultant <type>sequence</type> will be sorted by
    the speed, and then within each value of this, by the serial number. It is
    so common to order the set of instances returned from a
    <literal>find</literal> expression that a <literal>find</literal>
    expression can be immediately followed by an ordering expression. Hence,
    we could have written:<informalexample>
        <programlisting>  aircraft_sequence := find Aircraft(speed < 100) ordered_by (serial_number);</programlisting>
      </informalexample></para>

    <para>It is common to want to find all the instances of an object. We
    might try and write:<informalexample>
        <programlisting>  find Aircraft(true);    // illegal</programlisting>
      </informalexample>However, this syntax is illegal. To find all instances
    of an object the second form of find must be used:<informalexample>
        <programlisting>  find_all Aircraft();</programlisting>
      </informalexample>Notice that no condition is supplied, since we are
    finding all the instances.</para>

    <para>The third form of find, finds an arbitrary instance of an object
    satisfying a condition. This form starts with the reserved word
    <literal>find_one</literal> followed by the name of an object and a
    condition enclosed by brackets. So we might write:<informalexample>
        <programlisting>  find_one Aircraft(speed < 100);</programlisting>
      </informalexample>This finds an arbitrary instance of the
    <classname>Aircraft</classname> object whose speed less than
    <literal>100</literal>. Again, the condition can be of arbitrary
    complexity with the same restrictions as before. In order to use the
    instance returned from the <literal>find</literal> expression we must
    assign it to a variable of the appropriate type. Thus we might
    write:<informalexample>
        <programlisting>  aircraft_instance : instance of Aircraft;
  begin
    aircraft_instance := find_one Aircraft(speed < 100);
  end;</programlisting>
      </informalexample>If there are no instances that satisfy the condition
    then the <literal>null</literal> instance is returned. We could check for
    this by writing:<informalexample>
        <programlisting>  if aircraft_instance = null then
    // …
  end if;</programlisting>
      </informalexample></para>

    <para>It is common to want to find an instance of an object and in
    addition make sure that it is the only such instance. The fourth, and
    final, form of find is provided to do this:<informalexample>
        <programlisting>  find_only Aircraft(speed < 100);</programlisting>
      </informalexample>If there is only one <classname>Aircraft</classname>
    instance that satisfies the condition then all is well and the find
    expression returns that instance. If there are either more than one or no
    <classname>Aircraft</classname> instances that satisfy the condition then
    an exception will be raised.</para>

    <para>For each form of find expression, the name of the object being found
    can be replaced with an expression that denotes a collection of instances.
    This can be used to filter a collection of instances to a either a set of
    instances or a specific instance that satisfies a condition. For example
    given the appropriate declarations we might write:<informalexample>
        <programlisting>  aircraft_set := find Aircraft(speed < 100);
  stopped_aircraft_set := find aircraft_set(speed = 0);
  freds_aircraft := find_one aircraft_set(pilot_name = "Fred Bloggs");</programlisting>
      </informalexample></para>

    <para>In summary:</para>

    <itemizedlist>
      <listitem>
        <para><literal>find</literal> locate all the instances satisfying a
        condition.</para>
      </listitem>

      <listitem>
        <para><literal>find_all</literal> finds all the instances.</para>
      </listitem>

      <listitem>
        <para><literal>find_one</literal> finds an arbitrary instance
        satisfying a condition.</para>
      </listitem>

      <listitem>
        <para><literal>find_only</literal> finds the only instance satisfying
        a condition.</para>
      </listitem>

      <listitem>
        <para><literal>ordered_by</literal> orders a collection of instances
        by attribute values.</para>
      </listitem>

      <listitem>
        <para><literal>reverse_ordered_by</literal> reverse orders a
        collection of instances by attribute values.</para>
      </listitem>
    </itemizedlist>
  </section>

  <section xml:id="ObjectsandRelationshipsDeletingInstances"><info><title>Deleting Instances</title></info>

    <para>Once we have finished with an instance or a set of instances we can
    delete them using a <literal>delete</literal> statement. A
    <literal>delete</literal> statement starts with the reserved word
    <literal>delete</literal> followed by an expression that denotes either a
    specific single instance or a collection of instances. Given the examples
    already seen we might write:<informalexample>
        <programlisting>delete aircraft_instance;</programlisting>
      </informalexample>to delete a single aircraft instance,
    or:<informalexample>
        <programlisting>delete aircraft_set;</programlisting>
      </informalexample>to delete all the aircraft instances in a set.</para>

    <para>If an instance that participates in a relationship is deleted,
    before the relationship is unlinked, then an exception will be
    raised.</para>

    <para>Deleting either the null instance or an empty collection does not
    have any effect.</para>
  </section>

  <section xml:id="ObjectsandRelationshipsCreatingRelationships"><info><title>Creating Relationships</title></info>

    <para>Relationships between instances are created using a
    <literal>link</literal> statement. The simplest form of
    <literal>link</literal> statement starts with the reserved word link
    followed by an expression that denotes an specific single instance, a
    specification of a relationship and then another expression that denotes
    another specific single instance. Given the relationship between the
    <classname>Pilot</classname> and <classname>Aircraft</classname> objects
    in <xref linkend="ObjectsandRelationshipsRelationshipbetweenPilotandAircraft"/> we
    might write:<informalexample>
        <programlisting>  link aircraft_instance R3 pilot_instance;</programlisting>
      </informalexample>This links the instance denoted by
    <varname>aircraft_instance</varname> to the instance denoted by
    <varname>pilot_instance</varname> via the relationship
    <literal>R3</literal>.</para>

    <para>The specification of the relationship between the two instances must
    be a valid navigation for the <literal>link</literal> statement to be
    valid. This is discussed in <xref linkend="ObjectsandRelationshipsNavigatingRelationships"/>. If by linking
    the two instances together we "break" the model, then an exception is
    raised. This would happen, for example, if an instance was related to more
    than one instance in a one-to-one relationship.</para>

    <para>When a relationship is created between two instances, any
    referential attributes that are determined by the relationship are set to
    the correct values. In our example, if the name of the pilot was "Fred
    Bloggs" then the pilot name attribute of the aircraft instance would have
    this value set. Relationships are bi-directional, hence, we would have the
    same result if we had written:<informalexample>
        <programlisting>  link pilot_instance R3 aircraft_instance;</programlisting>
      </informalexample></para>

    <para>To create associative relationships the using form of the
    <literal>link</literal> statement is used. This looks exactly like the
    simple form with the addition of the reserved word using followed by an
    expression that denotes a specific single instance of the associative
    object.<figure xml:id="ObjectsandRelationshipsAssociativeRelationship"><info><title>Associative Relationship</title></info>

        <mediaobject>
          <imageobject>
            <imagedata align="center" fileref="images/associativerelationship.svg" format="svg" valign="middle"/>
          </imageobject>
        </mediaobject>
      </figure>Given the relationship shown in <xref linkend="ObjectsandRelationshipsAssociativeRelationship"/> we might
    write:<informalexample>
        <programlisting>  link aircraft_instance R11 pilot_instance using aircraft_pilot_instance;</programlisting>
      </informalexample>This links the instance denoted by
    <varname>aircraft_instance</varname> to the instance denoted by
    <varname>pilot_instance</varname> via the relationship
    <literal>R3</literal> using the instance denoted by
    <varname>aircraft_pilot_instance</varname>. Again, the specification of
    the relationship between the two instances must be a valid navigation for
    the link statement to be valid. In addition, by linking the two instances
    using the third we must not "break" the model, any referential attributes
    that are determined by the relationship are set to the correct values. In
    this example, all the attributes of the associative instance will have
    their values set to the appropriate values.</para>
  </section>

  <section xml:id="ObjectsandRelationshipsNavigatingRelationships"><info><title>Navigating Relationships</title></info>

    <para>Relationships that have been instantiated between instances can be
    navigated using a relationship navigation expression. A relationship
    navigation starts with an expression that denotes either a single instance
    or a collection of instances followed by -> and a specification of the
    relationship. For example, given the relationship shown in <xref linkend="ObjectsandRelationshipsAssociativeRelationship"/> and an
    aircraft instance we could navigate to the corresponding pilot by writing
    any of:<informalexample>
        <programlisting>  pilot_instance := aircraft_instance -> R3;
  pilot_instance := aircraft_instance -> R3.is_being_flown_by;
  pilot_instance := aircraft_instance -> R3.Pilot;
  pilot_instance := aircraft_instance -> R3.is_being_flown_by.Pilot;</programlisting>
      </informalexample>Similarly, if we had a collection of aircraft
    instances we could navigate to the corresponding pilots by
    writing:<informalexample>
        <programlisting>  pilot_bag := aircraft_set -> R3;</programlisting>
      </informalexample>Whether a single instance or a collection of instances
    is returned from a navigation depends upon the multiplicity of the
    relationship in the direction being navigated. This is summarised in <xref linkend="ObjectsandRelationshipsMultiplicityofRelationshipNavigation"/>.</para>

    <table xml:id="ObjectsandRelationshipsMultiplicityofRelationshipNavigation"><info><title>Multiplicity of Relationship Navigation</title></info>

      <tgroup cols="3">
        <colspec align="left" colname="navigation" colnum="1"/>

        <colspec align="center" colname="singlemultiplicity" colnum="2"/>

        <colspec align="center" colname="manymultiplicity" colnum="3"/>

        <thead>
          <row>
            <entry colname="navigation" morerows="1" valign="middle">Navigation Type</entry>

            <entry align="center" nameend="manymultiplicity" namest="singlemultiplicity">Multiplicity of Relationship</entry>
          </row>

          <row>
            <entry align="center" colname="singlemultiplicity">Single</entry>

            <entry align="center" colname="manymultiplicity">Many</entry>
          </row>
        </thead>

        <tbody>
          <row>
            <entry>single instance</entry>

            <entry>single instance</entry>

            <entry>set of instances</entry>
          </row>

          <row>
            <entry>collection of instance</entry>

            <entry>bag of instances</entry>

            <entry>bag of instances</entry>
          </row>
        </tbody>
      </tgroup>
    </table>

    <para>Given the relationship shown in <xref linkend="ObjectsandRelationshipsAssociativeRelationship"/> and an
    aircraft instance we might try to navigate to the corresponding
    associative instance by writing:<informalexample>
        <programlisting>  aircraft_pilot_instance := aircraft_instance -> R11;    // illegal</programlisting>
      </informalexample></para>

    <para>This is invalid, since it is not obvious from the relationship
    specification that we are navigating to the associative instance. Wherever
    a relationship specification is given, the analyst must ensure that the
    following are unambiguously specified: </para>

    <itemizedlist>
      <listitem>
        <para>the relationship</para>
      </listitem>

      <listitem>
        <para>the direction of navigation</para>
      </listitem>

      <listitem>
        <para>the destination object</para>
      </listitem>
    </itemizedlist>

    <para>This is achieved by using one of the four forms of relationship
    specification already seen. For example, in this case we could write
    either of:<informalexample>
        <programlisting>  aircraft_pilot_instance := aircraft_instance -> R11.Aircraft_Pilot;
  aircraft_pilot_instance := aircraft_instance -> R11.is_being_flown_by.Aircraft_Pilot;</programlisting>
      </informalexample>Both of these unambiguously specify the relationship,
    the direction and the destination object. Full examples of all possible
    relationship specifications are given in <xref linkend="MASL06"/></para>

    <para><figure xml:id="ObjectsandRelationshipsRelationshipbetweenAirlineandPilot"><info><title>Relationship between Airline and Pilot</title></info>

        <mediaobject>
          <imageobject>
            <imagedata align="center" fileref="images/relationshippilotairline.svg" format="svg" valign="middle"/>
          </imageobject>
        </mediaobject>
      </figure>It is often the case that we wish to navigate two relationships
    in one go. For example, given the relationship in <xref linkend="ObjectsandRelationshipsRelationshipbetweenPilotandAircraft"/>
    and <xref linkend="ObjectsandRelationshipsRelationshipbetweenAirlineandPilot"/> we
    could find out which aircrafts are been flown by pilots employed by an
    airline by writing:<informalexample>
        <programlisting>  pilot_bag := airline_instance -> R1;
  aircraft_bag := pilot_bag -> R3;</programlisting>
      </informalexample>or we could combine the two navigations into one
    compound navigation.<informalexample>
        <programlisting>  aircraft_bag := airline_instance -> R1 -> R3;</programlisting>
      </informalexample></para>

    <para>Finally, it is common to have two instances that we know are related
    via an associative relationship and to want to find the associative
    instance, or instances, that relate them. For example, given the
    relationship in <xref linkend="ObjectsandRelationshipsAssociativeRelationship"/> we could find
    the associative instance that an <classname>Aircraft</classname> and
    <classname>Pilot</classname> instance are related to by
    writing:<informalexample>
        <programlisting>  aircraft_pilot_bag_1 := airline_instance -> R3.Aircraft_Pilot;
  aircraft_pilot_bag_2 := route_instance -> R3.Aircraft_Pilot;
  aircraft_pilot_set := set of instance of Aircraft_Pilot(aircraft_pilot_bag_1) intersection
  set of instance of Aircraft_Pilot(aircraft_pilot_bag_2);
  aircraft_pilot_instance := find_only aircraft_pilot_set();</programlisting>
      </informalexample>This is all a bit longwinded so a special form is
    provided:<informalexample>
        <programlisting>  aircraft_pilot_instance := aircraft_instance with pilot_instance -> R3.Aircraft_Pilot;</programlisting>
      </informalexample>This is known as correlated navigation.</para>
  </section>

  <section xml:id="ObjectsandRelationshipsDeletingRelationships"><info><title>Deleting Relationships</title></info>

    <para>Once we have finished with a relationship we can delete it using an
    <literal>unlink</literal> statement. The <literal>unlink</literal>
    statement is the exact opposite of a link statement. The simplest form of
    <literal>unlink</literal> statement starts with the reserved word
    <literal>unlink</literal> followed by an expression that denotes a single
    instance, a specification of a relationship and then another expression
    that denotes another specific single instance.</para>

    <para>So to delete the relationship between an
    <classname>Aircraft</classname> and a <classname>Pilot</classname> via the
    relationship shown in <xref linkend="ObjectsandRelationshipsRelationshipbetweenPilotandAircraft"/> we
    might write:<informalexample>
        <programlisting>  unlink aircraft_instance R3 pilot_instance;</programlisting>
      </informalexample>This unlinks the instance denoted by the
    <varname>aircraft_instance</varname> from the instance denoted by
    <varname>pilot_instance</varname> via the relationship
    <literal>R3</literal>. As before the specification of the relationship
    between the two instances must be valid. If the two instances are not
    linked via the relationship then an exception is raised. Any attempt to
    access the values of any referential attributes that where determined by
    the relationship will result in an exception. As before, relationships are
    bidirectional, so we could have deleted the relationship by
    writing:<informalexample>
        <programlisting>  unlink pilot_instance R3 aircraft_instance;</programlisting>
      </informalexample>To delete associative relationships the using form of
    the <literal>unlink</literal> statement must be used. So given the
    relationship shown in <xref linkend="ObjectsandRelationshipsAssociativeRelationship"/> we might
    write:<informalexample>
        <programlisting>  unlink aircraft_instance R11 pilot_instance using aircraft_pilot_instance;</programlisting>
      </informalexample>This unlinks the instance denoted by
    <varname>aircraft_instance</varname> from the instance denoted by
    <varname>pilot_instance</varname> via the relationship
    <literal>R3</literal> using the instance denoted by
    <varname>aircraft_pilot_instance</varname>. Again, the specification of
    the relationship between the two instances must be a valid navigation for
    the <link linkend="ObjectsandRelationshipsAssociativeRelationship">unlink</link>
    statement to be valid. Also the two instances must have been linked
    together using the third otherwise an exception is raised. Like before,
    any attempt to access the values of any referential attributes that where
    determined by the relationship will result in an exception.</para>
  </section>
</chapter>


text: D3 Wrapper for use with ng-harmony

redpajama_set_name: RedPajamaGithub


text:
package org.apache.druid.indexing.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.inject.Provider;
import org.apache.druid.client.cache.Cache;
import org.apache.druid.client.cache.CacheConfig;
import org.apache.druid.client.cache.CachePopulatorStats;
import org.apache.druid.client.coordinator.CoordinatorClient;
import org.apache.druid.discovery.DataNodeService;
import org.apache.druid.discovery.DruidNodeAnnouncer;
import org.apache.druid.discovery.LookupNodeService;
import org.apache.druid.indexing.common.actions.SegmentInsertAction;
import org.apache.druid.indexing.common.actions.TaskActionClient;
import org.apache.druid.indexing.common.config.TaskConfig;
import org.apache.druid.indexing.common.task.batch.parallel.ParallelIndexSupervisorTaskClientProvider;
import org.apache.druid.indexing.common.task.batch.parallel.ShuffleClient;
import org.apache.druid.indexing.worker.shuffle.IntermediaryDataManager;
import org.apache.druid.java.util.common.FileUtils;
import org.apache.druid.java.util.emitter.service.ServiceEmitter;
import org.apache.druid.java.util.metrics.Monitor;
import org.apache.druid.java.util.metrics.MonitorScheduler;
import org.apache.druid.query.QueryProcessingPool;
import org.apache.druid.query.QueryRunnerFactoryConglomerate;
import org.apache.druid.rpc.indexing.OverlordClient;
import org.apache.druid.segment.IndexIO;
import org.apache.druid.segment.IndexMergerV9;
import org.apache.druid.segment.handoff.SegmentHandoffNotifierFactory;
import org.apache.druid.segment.incremental.RowIngestionMetersFactory;
import org.apache.druid.segment.join.JoinableFactory;
import org.apache.druid.segment.loading.DataSegmentArchiver;
import org.apache.druid.segment.loading.DataSegmentKiller;
import org.apache.druid.segment.loading.DataSegmentMover;
import org.apache.druid.segment.loading.DataSegmentPusher;
import org.apache.druid.segment.loading.SegmentCacheManager;
import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager;
import org.apache.druid.segment.realtime.firehose.ChatHandlerProvider;
import org.apache.druid.server.DruidNode;
import org.apache.druid.server.coordination.DataSegmentAnnouncer;
import org.apache.druid.server.coordination.DataSegmentServerAnnouncer;
import org.apache.druid.server.security.AuthorizerMapper;
import org.apache.druid.tasklogs.TaskLogPusher;
import org.apache.druid.timeline.DataSegment;
import org.joda.time.Interval;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;

/**
 * Stuff that may be needed by a Task in order to conduct its business.
 */
public class TaskToolbox
{
  private final TaskConfig config;
  private final DruidNode taskExecutorNode;
  private final TaskActionClient taskActionClient;
  private final ServiceEmitter emitter;
  private final DataSegmentPusher segmentPusher;
  private final DataSegmentKiller dataSegmentKiller;
  private final DataSegmentArchiver dataSegmentArchiver;
  private final DataSegmentMover dataSegmentMover;
  private final DataSegmentAnnouncer segmentAnnouncer;
  private final DataSegmentServerAnnouncer serverAnnouncer;
  private final SegmentHandoffNotifierFactory handoffNotifierFactory;
  /**
   * Using Provider, not {@link QueryRunnerFactoryConglomerate} directly, to not require {@link
   * org.apache.druid.indexing.overlord.TaskRunner} implementations that create TaskToolboxes to inject query stuff eagerly,
   * because it may be unavailable, e. g. for batch tasks running in Spark or Hadoop.
   */
  private final Provider<QueryRunnerFactoryConglomerate> queryRunnerFactoryConglomerateProvider;
  @Nullable
  private final Provider<MonitorScheduler> monitorSchedulerProvider;
  private final QueryProcessingPool queryProcessingPool;
  private final JoinableFactory joinableFactory;
  private final SegmentCacheManager segmentCacheManager;
  private final ObjectMapper jsonMapper;
  private final File taskWorkDir;
  private final IndexIO indexIO;
  private final Cache cache;
  private final CacheConfig cacheConfig;
  private final CachePopulatorStats cachePopulatorStats;
  private final IndexMergerV9 indexMergerV9;
  private final TaskReportFileWriter taskReportFileWriter;

  private final DruidNodeAnnouncer druidNodeAnnouncer;
  private final DruidNode druidNode;
  private final LookupNodeService lookupNodeService;
  private final DataNodeService dataNodeService;

  private final AuthorizerMapper authorizerMapper;
  private final ChatHandlerProvider chatHandlerProvider;
  private final RowIngestionMetersFactory rowIngestionMetersFactory;
  private final AppenderatorsManager appenderatorsManager;
  private final OverlordClient overlordClient;
  private final CoordinatorClient coordinatorClient;

  // Used by only native parallel tasks
  private final IntermediaryDataManager intermediaryDataManager;
  private final ParallelIndexSupervisorTaskClientProvider supervisorTaskClientProvider;
  private final ShuffleClient shuffleClient;

  private final TaskLogPusher taskLogPusher;
  private final String attemptId;

  public TaskToolbox(
      TaskConfig config,
      DruidNode taskExecutorNode,
      TaskActionClient taskActionClient,
      ServiceEmitter emitter,
      DataSegmentPusher segmentPusher,
      DataSegmentKiller dataSegmentKiller,
      DataSegmentMover dataSegmentMover,
      DataSegmentArchiver dataSegmentArchiver,
      DataSegmentAnnouncer segmentAnnouncer,
      DataSegmentServerAnnouncer serverAnnouncer,
      SegmentHandoffNotifierFactory handoffNotifierFactory,
      Provider<QueryRunnerFactoryConglomerate> queryRunnerFactoryConglomerateProvider,
      QueryProcessingPool queryProcessingPool,
      JoinableFactory joinableFactory,
      @Nullable Provider<MonitorScheduler> monitorSchedulerProvider,
      SegmentCacheManager segmentCacheManager,
      ObjectMapper jsonMapper,
      File taskWorkDir,
      IndexIO indexIO,
      Cache cache,
      CacheConfig cacheConfig,
      CachePopulatorStats cachePopulatorStats,
      IndexMergerV9 indexMergerV9,
      DruidNodeAnnouncer druidNodeAnnouncer,
      DruidNode druidNode,
      LookupNodeService lookupNodeService,
      DataNodeService dataNodeService,
      TaskReportFileWriter taskReportFileWriter,
      IntermediaryDataManager intermediaryDataManager,
      AuthorizerMapper authorizerMapper,
      ChatHandlerProvider chatHandlerProvider,
      RowIngestionMetersFactory rowIngestionMetersFactory,
      AppenderatorsManager appenderatorsManager,
      OverlordClient overlordClient,
      CoordinatorClient coordinatorClient,
      ParallelIndexSupervisorTaskClientProvider supervisorTaskClientProvider,
      ShuffleClient shuffleClient,
      TaskLogPusher taskLogPusher,
      String attemptId
  )
  {
    this.config = config;
    this.taskExecutorNode = taskExecutorNode;
    this.taskActionClient = taskActionClient;
    this.emitter = emitter;
    this.segmentPusher = segmentPusher;
    this.dataSegmentKiller = dataSegmentKiller;
    this.dataSegmentMover = dataSegmentMover;
    this.dataSegmentArchiver = dataSegmentArchiver;
    this.segmentAnnouncer = segmentAnnouncer;
    this.serverAnnouncer = serverAnnouncer;
    this.handoffNotifierFactory = handoffNotifierFactory;
    this.queryRunnerFactoryConglomerateProvider = queryRunnerFactoryConglomerateProvider;
    this.queryProcessingPool = queryProcessingPool;
    this.joinableFactory = joinableFactory;
    this.monitorSchedulerProvider = monitorSchedulerProvider;
    this.segmentCacheManager = segmentCacheManager;
    this.jsonMapper = jsonMapper;
    this.taskWorkDir = taskWorkDir;
    this.indexIO = Preconditions.checkNotNull(indexIO, "Null IndexIO");
    this.cache = cache;
    this.cacheConfig = cacheConfig;
    this.cachePopulatorStats = cachePopulatorStats;
    this.indexMergerV9 = Preconditions.checkNotNull(indexMergerV9, "Null IndexMergerV9");
    this.druidNodeAnnouncer = druidNodeAnnouncer;
    this.druidNode = druidNode;
    this.lookupNodeService = lookupNodeService;
    this.dataNodeService = dataNodeService;
    this.taskReportFileWriter = taskReportFileWriter;
    this.taskReportFileWriter.setObjectMapper(this.jsonMapper);
    this.intermediaryDataManager = intermediaryDataManager;
    this.authorizerMapper = authorizerMapper;
    this.chatHandlerProvider = chatHandlerProvider;
    this.rowIngestionMetersFactory = rowIngestionMetersFactory;
    this.appenderatorsManager = appenderatorsManager;
    this.overlordClient = overlordClient;
    this.coordinatorClient = coordinatorClient;
    this.supervisorTaskClientProvider = supervisorTaskClientProvider;
    this.shuffleClient = shuffleClient;
    this.taskLogPusher = taskLogPusher;
    this.attemptId = attemptId;
  }

  public TaskConfig getConfig()
  {
    return config;
  }

  public DruidNode getTaskExecutorNode()
  {
    return taskExecutorNode;
  }

  public TaskActionClient getTaskActionClient()
  {
    return taskActionClient;
  }

  public ServiceEmitter getEmitter()
  {
    return emitter;
  }

  public DataSegmentPusher getSegmentPusher()
  {
    return segmentPusher;
  }

  public DataSegmentKiller getDataSegmentKiller()
  {
    return dataSegmentKiller;
  }

  public DataSegmentMover getDataSegmentMover()
  {
    return dataSegmentMover;
  }

  public DataSegmentArchiver getDataSegmentArchiver()
  {
    return dataSegmentArchiver;
  }

  public DataSegmentAnnouncer getSegmentAnnouncer()
  {
    return segmentAnnouncer;
  }

  public DataSegmentServerAnnouncer getDataSegmentServerAnnouncer()
  {
    return serverAnnouncer;
  }

  public SegmentHandoffNotifierFactory getSegmentHandoffNotifierFactory()
  {
    return handoffNotifierFactory;
  }

  public QueryRunnerFactoryConglomerate getQueryRunnerFactoryConglomerate()
  {
    return queryRunnerFactoryConglomerateProvider.get();
  }

  public QueryProcessingPool getQueryProcessingPool()
  {
    return queryProcessingPool;
  }

  public JoinableFactory getJoinableFactory()
  {
    return joinableFactory;
  }

  @Nullable
  public MonitorScheduler getMonitorScheduler()
  {
    return monitorSchedulerProvider == null ? null : monitorSchedulerProvider.get();
  }

  /**
   * Adds a monitor to the monitorScheduler if it is configured
   *
   * @param monitor
   */
  public void addMonitor(Monitor monitor)
  {
    MonitorScheduler scheduler = getMonitorScheduler();
    if (scheduler != null) {
      scheduler.addMonitor(monitor);
    }
  }

  /**
   * Adds a monitor to the monitorScheduler if it is configured
   *
   * @param monitor
   */
  public void removeMonitor(Monitor monitor)
  {
    MonitorScheduler scheduler = getMonitorScheduler();
    if (scheduler != null) {
      scheduler.removeMonitor(monitor);
    }
  }

  public ObjectMapper getJsonMapper()
  {
    return jsonMapper;
  }

  public SegmentCacheManager getSegmentCacheManager()
  {
    return segmentCacheManager;
  }

  public void publishSegments(Iterable<DataSegment> segments) throws IOException
  {
    // Request segment pushes for each set
    final Multimap<Interval, DataSegment> segmentMultimap = Multimaps.index(
        segments,
        new Function<DataSegment, Interval>()
        {
          @Override
          public Interval apply(DataSegment segment)
          {
            return segment.getInterval();
          }
        }
    );
    for (final Collection<DataSegment> segmentCollection : segmentMultimap.asMap().values()) {
      getTaskActionClient().submit(new SegmentInsertAction(ImmutableSet.copyOf(segmentCollection)));
    }
  }

  public IndexIO getIndexIO()
  {
    return indexIO;
  }

  public Cache getCache()
  {
    return cache;
  }

  public CacheConfig getCacheConfig()
  {
    return cacheConfig;
  }

  public CachePopulatorStats getCachePopulatorStats()
  {
    return cachePopulatorStats;
  }

  public IndexMergerV9 getIndexMergerV9()
  {
    return indexMergerV9;
  }

  public File getIndexingTmpDir()
  {
    final File tmpDir = new File(taskWorkDir, "indexing-tmp");
    try {
      FileUtils.mkdirp(tmpDir);
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }
    return tmpDir;
  }

  public File getMergeDir()
  {
    return new File(taskWorkDir, "merge");
  }

  public File getPersistDir()
  {
    return new File(taskWorkDir, "persist");
  }

  public DruidNodeAnnouncer getDruidNodeAnnouncer()
  {
    return druidNodeAnnouncer;
  }

  public LookupNodeService getLookupNodeService()
  {
    return lookupNodeService;
  }

  public DataNodeService getDataNodeService()
  {
    return dataNodeService;
  }

  public DruidNode getDruidNode()
  {
    return druidNode;
  }

  public TaskReportFileWriter getTaskReportFileWriter()
  {
    return taskReportFileWriter;
  }

  public IntermediaryDataManager getIntermediaryDataManager()
  {
    return intermediaryDataManager;
  }

  public AuthorizerMapper getAuthorizerMapper()
  {
    return authorizerMapper;
  }

  public ChatHandlerProvider getChatHandlerProvider()
  {
    return chatHandlerProvider;
  }

  public RowIngestionMetersFactory getRowIngestionMetersFactory()
  {
    return rowIngestionMetersFactory;
  }

  public AppenderatorsManager getAppenderatorsManager()
  {
    return appenderatorsManager;
  }

  public OverlordClient getOverlordClient()
  {
    return overlordClient;
  }

  public CoordinatorClient getCoordinatorClient()
  {
    return coordinatorClient;
  }

  public ParallelIndexSupervisorTaskClientProvider getSupervisorTaskClientProvider()
  {
    return supervisorTaskClientProvider;
  }

  public ShuffleClient getShuffleClient()
  {
    return shuffleClient;
  }

  public TaskLogPusher getTaskLogPusher()
  {
    return taskLogPusher;
  }

  public String getAttemptId()
  {
    return attemptId;
  }

  public static class Builder
  {
    private TaskConfig config;
    private DruidNode taskExecutorNode;
    private TaskActionClient taskActionClient;
    private ServiceEmitter emitter;
    private DataSegmentPusher segmentPusher;
    private DataSegmentKiller dataSegmentKiller;
    private DataSegmentMover dataSegmentMover;
    private DataSegmentArchiver dataSegmentArchiver;
    private DataSegmentAnnouncer segmentAnnouncer;
    private DataSegmentServerAnnouncer serverAnnouncer;
    private SegmentHandoffNotifierFactory handoffNotifierFactory;
    private Provider<QueryRunnerFactoryConglomerate> queryRunnerFactoryConglomerateProvider;
    private QueryProcessingPool queryProcessingPool;
    private JoinableFactory joinableFactory;
    private Provider<MonitorScheduler> monitorSchedulerProvider;
    private SegmentCacheManager segmentCacheManager;
    private ObjectMapper jsonMapper;
    private File taskWorkDir;
    private IndexIO indexIO;
    private Cache cache;
    private CacheConfig cacheConfig;
    private CachePopulatorStats cachePopulatorStats;
    private IndexMergerV9 indexMergerV9;
    private DruidNodeAnnouncer druidNodeAnnouncer;
    private DruidNode druidNode;
    private LookupNodeService lookupNodeService;
    private DataNodeService dataNodeService;
    private TaskReportFileWriter taskReportFileWriter;
    private AuthorizerMapper authorizerMapper;
    private ChatHandlerProvider chatHandlerProvider;
    private RowIngestionMetersFactory rowIngestionMetersFactory;
    private AppenderatorsManager appenderatorsManager;
    private OverlordClient overlordClient;
    private CoordinatorClient coordinatorClient;
    private IntermediaryDataManager intermediaryDataManager;
    private ParallelIndexSupervisorTaskClientProvider supervisorTaskClientProvider;
    private ShuffleClient shuffleClient;
    private TaskLogPusher taskLogPusher;
    private String attemptId;

    public Builder()
    {
    }

    public Builder(TaskToolbox other)
    {
      this.config = other.config;
      this.taskExecutorNode = other.taskExecutorNode;
      this.taskActionClient = other.taskActionClient;
      this.emitter = other.emitter;
      this.segmentPusher = other.segmentPusher;
      this.dataSegmentKiller = other.dataSegmentKiller;
      this.dataSegmentMover = other.dataSegmentMover;
      this.dataSegmentArchiver = other.dataSegmentArchiver;
      this.segmentAnnouncer = other.segmentAnnouncer;
      this.serverAnnouncer = other.serverAnnouncer;
      this.handoffNotifierFactory = other.handoffNotifierFactory;
      this.queryRunnerFactoryConglomerateProvider = other.queryRunnerFactoryConglomerateProvider;
      this.queryProcessingPool = other.queryProcessingPool;
      this.joinableFactory = other.joinableFactory;
      this.monitorSchedulerProvider = other.monitorSchedulerProvider;
      this.segmentCacheManager = other.segmentCacheManager;
      this.jsonMapper = other.jsonMapper;
      this.taskWorkDir = other.taskWorkDir;
      this.indexIO = other.indexIO;
      this.cache = other.cache;
      this.cacheConfig = other.cacheConfig;
      this.cachePopulatorStats = other.cachePopulatorStats;
      this.indexMergerV9 = other.indexMergerV9;
      this.druidNodeAnnouncer = other.druidNodeAnnouncer;
      this.druidNode = other.druidNode;
      this.lookupNodeService = other.lookupNodeService;
      this.dataNodeService = other.dataNodeService;
      this.taskReportFileWriter = other.taskReportFileWriter;
      this.authorizerMapper = other.authorizerMapper;
      this.chatHandlerProvider = other.chatHandlerProvider;
      this.rowIngestionMetersFactory = other.rowIngestionMetersFactory;
      this.appenderatorsManager = other.appenderatorsManager;
      this.overlordClient = other.overlordClient;
      this.coordinatorClient = other.coordinatorClient;
      this.intermediaryDataManager = other.intermediaryDataManager;
      this.supervisorTaskClientProvider = other.supervisorTaskClientProvider;
      this.shuffleClient = other.shuffleClient;
    }

    public Builder config(final TaskConfig config)
    {
      this.config = config;
      return this;
    }

    public Builder taskExecutorNode(final DruidNode taskExecutorNode)
    {
      this.taskExecutorNode = taskExecutorNode;
      return this;
    }

    public Builder taskActionClient(final TaskActionClient taskActionClient)
    {
      this.taskActionClient = taskActionClient;
      return this;
    }

    public Builder emitter(final ServiceEmitter emitter)
    {
      this.emitter = emitter;
      return this;
    }

    public Builder segmentPusher(final DataSegmentPusher segmentPusher)
    {
      this.segmentPusher = segmentPusher;
      return this;
    }

    public Builder dataSegmentKiller(final DataSegmentKiller dataSegmentKiller)
    {
      this.dataSegmentKiller = dataSegmentKiller;
      return this;
    }

    public Builder dataSegmentMover(final DataSegmentMover dataSegmentMover)
    {
      this.dataSegmentMover = dataSegmentMover;
      return this;
    }

    public Builder dataSegmentArchiver(final DataSegmentArchiver dataSegmentArchiver)
    {
      this.dataSegmentArchiver = dataSegmentArchiver;
      return this;
    }

    public Builder segmentAnnouncer(final DataSegmentAnnouncer segmentAnnouncer)
    {
      this.segmentAnnouncer = segmentAnnouncer;
      return this;
    }

    public Builder serverAnnouncer(final DataSegmentServerAnnouncer serverAnnouncer)
    {
      this.serverAnnouncer = serverAnnouncer;
      return this;
    }

    public Builder handoffNotifierFactory(final SegmentHandoffNotifierFactory handoffNotifierFactory)
    {
      this.handoffNotifierFactory = handoffNotifierFactory;
      return this;
    }

    public Builder queryRunnerFactoryConglomerateProvider(final Provider<QueryRunnerFactoryConglomerate> queryRunnerFactoryConglomerateProvider)
    {
      this.queryRunnerFactoryConglomerateProvider = queryRunnerFactoryConglomerateProvider;
      return this;
    }

    public Builder queryProcessingPool(final QueryProcessingPool queryProcessingPool)
    {
      this.queryProcessingPool = queryProcessingPool;
      return this;
    }

    public Builder joinableFactory(final JoinableFactory joinableFactory)
    {
      this.joinableFactory = joinableFactory;
      return this;
    }

    public Builder monitorSchedulerProvider(final Provider<MonitorScheduler> monitorSchedulerProvider)
    {
      this.monitorSchedulerProvider = monitorSchedulerProvider;
      return this;
    }

    public Builder segmentCacheManager(final SegmentCacheManager segmentCacheManager)
    {
      this.segmentCacheManager = segmentCacheManager;
      return this;
    }

    public Builder jsonMapper(final ObjectMapper jsonMapper)
    {
      this.jsonMapper = jsonMapper;
      return this;
    }

    public Builder taskWorkDir(final File taskWorkDir)
    {
      this.taskWorkDir = taskWorkDir;
      return this;
    }

    public Builder indexIO(final IndexIO indexIO)
    {
      this.indexIO = indexIO;
      return this;
    }

    public Builder cache(final Cache cache)
    {
      this.cache = cache;
      return this;
    }

    public Builder cacheConfig(final CacheConfig cacheConfig)
    {
      this.cacheConfig = cacheConfig;
      return this;
    }

    public Builder cachePopulatorStats(final CachePopulatorStats cachePopulatorStats)
    {
      this.cachePopulatorStats = cachePopulatorStats;
      return this;
    }

    public Builder indexMergerV9(final IndexMergerV9 indexMergerV9)
    {
      this.indexMergerV9 = indexMergerV9;
      return this;
    }

    public Builder druidNodeAnnouncer(final DruidNodeAnnouncer druidNodeAnnouncer)
    {
      this.druidNodeAnnouncer = druidNodeAnnouncer;
      return this;
    }

    public Builder druidNode(final DruidNode druidNode)
    {
      this.druidNode = druidNode;
      return this;
    }

    public Builder lookupNodeService(final LookupNodeService lookupNodeService)
    {
      this.lookupNodeService = lookupNodeService;
      return this;
    }

    public Builder dataNodeService(final DataNodeService dataNodeService)
    {
      this.dataNodeService = dataNodeService;
      return this;
    }

    public Builder taskReportFileWriter(final TaskReportFileWriter taskReportFileWriter)
    {
      this.taskReportFileWriter = taskReportFileWriter;
      return this;
    }

    public Builder authorizerMapper(final AuthorizerMapper authorizerMapper)
    {
      this.authorizerMapper = authorizerMapper;
      return this;
    }

    public Builder chatHandlerProvider(final ChatHandlerProvider chatHandlerProvider)
    {
      this.chatHandlerProvider = chatHandlerProvider;
      return this;
    }

    public Builder rowIngestionMetersFactory(final RowIngestionMetersFactory rowIngestionMetersFactory)
    {
      this.rowIngestionMetersFactory = rowIngestionMetersFactory;
      return this;
    }

    public Builder appenderatorsManager(final AppenderatorsManager appenderatorsManager)
    {
      this.appenderatorsManager = appenderatorsManager;
      return this;
    }

    public Builder overlordClient(final OverlordClient overlordClient)
    {
      this.overlordClient = overlordClient;
      return this;
    }

    public Builder coordinatorClient(final CoordinatorClient coordinatorClient)
    {
      this.coordinatorClient = coordinatorClient;
      return this;
    }

    public Builder intermediaryDataManager(final IntermediaryDataManager intermediaryDataManager)
    {
      this.intermediaryDataManager = intermediaryDataManager;
      return this;
    }

    public Builder supervisorTaskClientProvider(final ParallelIndexSupervisorTaskClientProvider supervisorTaskClientProvider)
    {
      this.supervisorTaskClientProvider = supervisorTaskClientProvider;
      return this;
    }

    public Builder shuffleClient(final ShuffleClient shuffleClient)
    {
      this.shuffleClient = shuffleClient;
      return this;
    }

    public Builder taskLogPusher(final TaskLogPusher taskLogPusher)
    {
      this.taskLogPusher = taskLogPusher;
      return this;
    }

    public Builder attemptId(final String attemptId)
    {
      this.attemptId = attemptId;
      return this;
    }

    public TaskToolbox build()
    {
      return new TaskToolbox(
          config,
          taskExecutorNode,
          taskActionClient,
          emitter,
          segmentPusher,
          dataSegmentKiller,
          dataSegmentMover,
          dataSegmentArchiver,
          segmentAnnouncer,
          serverAnnouncer,
          handoffNotifierFactory,
          queryRunnerFactoryConglomerateProvider,
          queryProcessingPool,
          joinableFactory,
          monitorSchedulerProvider,
          segmentCacheManager,
          jsonMapper,
          taskWorkDir,
          indexIO,
          cache,
          cacheConfig,
          cachePopulatorStats,
          indexMergerV9,
          druidNodeAnnouncer,
          druidNode,
          lookupNodeService,
          dataNodeService,
          taskReportFileWriter,
          intermediaryDataManager,
          authorizerMapper,
          chatHandlerProvider,
          rowIngestionMetersFactory,
          appenderatorsManager,
          overlordClient,
          coordinatorClient,
          supervisorTaskClientProvider,
          shuffleClient,
          taskLogPusher,
          attemptId
      );
    }
  }
}


text:
#ifndef _CX3D_NODE_H_
#define _CX3D_NODE_H_

#include <iostream>
#include <fstream>
#include <assert.h>

#include <cybergarage/x3d/CyberX3DConfig.h>

#include <cybergarage/x3d/Vector.h>
#include <cybergarage/x3d/Field.h>
#include <cybergarage/x3d/StringUtil.h>
#include <cybergarage/x3d/LinkedList.h>
#include <cybergarage/x3d/JNode.h>

#include <cybergarage/x3d/NodeType.h>
#include <cybergarage/x3d/NodeString.h>

namespace CyberX3D {

class	SceneGraph;

class	SFMatrix;

class	AnchorNode;
class	AppearanceNode;
class	AudioClipNode;
class	BackgroundNode;
class	BillboardNode;
class	BoxNode;
class	CollisionNode;
class	ColorNode;
class	ColorInterpolatorNode;
class	ConeNode;
class	CoordinateNode;
class	CoordinateInterpolatorNode;
class	CylinderNode;
class	CylinderSensorNode;
class	DirectionalLightNode;
class	ElevationGridNode;
class	ExtrusionNode;
class	FogNode;
class	FontStyleNode;
class	GroupNode;
class	ImageTextureNode;
class	IndexedFaceSetNode;
class	IndexedLineSetNode;
class	InlineNode;
class	LODNode;
class	MaterialNode;
class	MovieTextureNode;
class	NavigationInfoNode;
class	NormalNode;
class	NormalInterpolatorNode;
class	OrientationInterpolatorNode;
class	PixelTextureNode;
class	PlaneSensorNode;
class	PointLightNode;
class	PointSetNode;
class	PositionInterpolatorNode;
class	ProximitySensorNode;
class	ScalarInterpolatorNode;
class	ScriptNode;
class	ShapeNode;
class	SoundNode;
class	SphereNode;
class	SphereSensorNode;
class	SpotLightNode;
class	SwitchNode;
class	TextNode;
class	TextureNode;
class	TextureCoordinateNode;
class	TextureTransformNode;
class	TimeSensorNode;
class	TouchSensorNode;
class	TransformNode;
class	ViewpointNode;
class	VisibilitySensorNode;
class	WorldInfoNode;

// 9. Networking component (X3D)
class LoadSensorNode;
// 10. Grouping component (X3D)
class StaticGroupNode;
// 11. Rendering component (X3D)
class ColorRGBANode;
class IndexedTriangleSetNode;
class TriangleSetNode;
class TriangleFanSetNode;
class TriangleStripSetNode;
// 12. Shape component (X3D)
class FillPropertiesNode;
class LinePropertiesNode;
// 14. Geometry2D component (X3D)
class Arc2DNode;
class ArcClose2DNode;
class Circle2DNode;
class Disk2DNode;
class Polyline2DNode;
class Polypoint2DNode;
class Rectangle2DNode;
class TriangleSet2DNode;
// 18. Texturing component (x3D)
class MultiTextureNode;
class MultiTextureCoordinateNode;
class MultiTextureTransformNode;
class TextureCoordinateGeneratorNode;
// 19. Interpolation component (X3D)
class CoordinateInterpolator2DNode;
class PositionInterpolator2DNode;
// 21. Key device sensor component (X3D)
class KeySensorNode;
class StringSensorNode;
// 30. Event Utilities component (X3D)
class BooleanFilterNode;
class BooleanToggleNode;
class BooleanTriggerNode;
class BooleanSequencerNode;
class IntegerTriggerNode;
class IntegerSequencerNode;
class TimeTriggerNode;
// Deprecated components (X3D)
class NodeSequencerNode;
class Shape2DNode;
class BooleanTimeTriggerNode;
class Transform2DNode;
// Extensions (X3D)
class CommonSurfaceShaderNode;

class	GroupingNode;
class	Geometry3DNode;

class	DEFNode;
class NodeListener;
class Node : public LinkedListNode<Node> {
public:

class NodeListener
{
public:
	NodeListener() {}
	virtual ~NodeListener() {}
	virtual void onUpdated(Node* node) = 0;
	virtual void onDeleted(Node* node) = 0;
};

	String				*mName;
	int						mType;
	Vector<Field>		*mExposedField;
	Vector<Field>		*mEventInField;
	Vector<Field>		*mEventOutField;
	Vector<Field>		*mField;
	Vector<Field>		*mPrivateField;
	Vector<Node>		*mPrivateNodeVector;
	bool				*mInitialized;

	String				*mOrgName;
	int						mOrgType;
	Vector<Field>		*mOrgExposedField;
	Vector<Field>		*mOrgEventInField;
	Vector<Field>		*mOrgEventOutField;
	Vector<Field>		*mOrgField;
	Vector<Field>		*mOrgPrivateField;

private:
	NodeListener		*mNodeListener;
	Node				*mParentNode;
	LinkedList<Node>	*mChildNodes;
	SceneGraph			*mSceneGraph;

#if defined(CX3D_SUPPORT_JSAI)
	JNode				*mJNode;
#endif

	void				*mValue;
	Node				*mReferenceNode;

public:

	Node();

	Node(const int nodeType, const char * nodeName);

	virtual ~Node();

	void initializeMember();

	void remove();

	void setName(const char * name);
	const char *getName() const;
	bool hasName() const;

	void setType(const int type);
	int getType() const;
	const char *getTypeString() const;

	void setNodeListener(NodeListener * listener);
	NodeListener *getNodeListener() const;

	////////////////////////////////////////////////
	//	Java
	////////////////////////////////////////////////

#if defined(CX3D_SUPPORT_JSAI)

	void createJavaNodeObject() {
		mJNode = new JNode(this);
	}

	void setJavaNodeObject(JNode *jnode) {
		mJNode = jnode;
	}

	JNode *getJavaNodeObject() {
		return mJNode;
	}

#endif

	////////////////////////////////////////////////
	//	Field
	////////////////////////////////////////////////

	static Field *createField(int type);
	int getNAllFields() const;

	Field *findField(const char *name) const;
	bool hasMField() const;

	////////////////////////////////////////////////
	//	EventIn
	////////////////////////////////////////////////

	Field *getEventIn(const char * fieldString) const;
	int getNEventIn() const;
	void addEventIn(Field *field);
	void addEventIn(const char * name, Field *field);
	void addEventIn(const char * name, int fieldType);
	Field *getEventIn(int index) const;
	int getEventInNumber(Field *field) const;

	////////////////////////////////////////////////
	//	EventOut
	////////////////////////////////////////////////

	Field *getEventOut(const char *fieldString) const;
	int getNEventOut() const;
	void addEventOut(Field *field);
	void addEventOut(const char *name, Field *field);
	void addEventOut(const char * name, int fieldType);
	Field *getEventOut(int index) const;
	int getEventOutNumber(Field *field) const;

	////////////////////////////////////////////////
	//	ExposedField
	////////////////////////////////////////////////

	Field *getExposedField(const char * fieldString) const;
	int getNExposedFields() const;
	void addExposedField(Field *field);
	void addExposedField(const char * name, Field *field);
	void addExposedField(const char * name, int fieldType);
	Field *getExposedField(int index) const;
	int getExposedFieldNumber(Field *field) const;

	////////////////////////////////////////////////
	//	Field
	////////////////////////////////////////////////

	Field *getField(const char *fieldString) const;
	int getNFields() const;
	void addField(Field *field);
	void addField(const char * name, Field *field);
	void addField(const char * name, int fieldType);
	Field *getField(int index) const;
	int getFieldNumber(Field *field) const;

	////////////////////////////////////////////////
	//	PrivateField
	////////////////////////////////////////////////

	Field *getPrivateField(const char *fieldString) const;
	int getNPrivateFields() const;
	void addPrivateField(Field *field);
	void addPrivateField(const char * name, Field *field);
	Field *getPrivateField(int index) const;
	int getPrivateFieldNumber(Field *field) const;

	////////////////////////////////////////////////
	//	PrivateField
	////////////////////////////////////////////////

	int getNPrivateNodeElements() const;
	void addPrivateNodeElement(Node *node);
	Node *getPrivateNodeElementAt(int n) const;
	void removeAllNodeElement();

	////////////////////////////////////////////////
	//	Parent node
	////////////////////////////////////////////////

	void setParentNode(Node *parentNode);
	Node *getParentNode() const;
	bool isParentNode(Node *node) const;
	bool isAncestorNode(Node *node) const;

	////////////////////////////////////////////////
	//	Traversal node list
	////////////////////////////////////////////////

	Node *nextTraversal() const;
	Node *nextTraversalByType(const int type) const;
	Node *nextTraversalByName(const char *nameString) const;

	Node *nextTraversalSameType() const {
		return nextTraversalByType(getType());
	}

	////////////////////////////////////////////////
	//	next node list
	////////////////////////////////////////////////

	Node *next() const;
	Node *next(const int type) const;

	////////////////////////////////////////////////
	//	child node list
	////////////////////////////////////////////////

	Node *getChildNodes() const;
	Node *getChildNodeByType(int type) const;
	Node *getChildNode(int n) const;

	int getNChildNodes() const;
	bool hasChildNodes() const;

	virtual bool isChildNodeType(Node *node) const = 0;

	void addChildNode(Node *node, bool initialize = true);
	void addChildNodeAtFirst(Node *node, bool initialize = true);

	void moveChildNode(Node *node);
	void moveChildNodeAtFirst(Node *node);

	void deleteChildNodes(void);

	void removeRoutes();
	void removeSFNodes();
	void removeInstanceNodes();

	////////////////////////////////////////////////
	//	Add / Remove children (for Groupingnode)
	////////////////////////////////////////////////

	bool isChildNode(Node *parentNode, Node *node) const;
	bool isChildNode(Node *node) const;

	////////////////////////////////////////////////
	//	get child node list
	////////////////////////////////////////////////

	GroupingNode *getGroupingNodes() const;
	Geometry3DNode *getGeometry3DNode() const;
	TextureNode *getTextureNode() const;

	AnchorNode *getAnchorNodes() const {
		return (AnchorNode *)getChildNodeByType(ANCHOR_NODE);
	}

	AppearanceNode *getAppearanceNodes() const {
		return (AppearanceNode *)getChildNodeByType(APPEARANCE_NODE);
	}

	AudioClipNode *getAudioClipNodes() const {
		return (AudioClipNode *)getChildNodeByType(AUDIOCLIP_NODE);
	}

	BackgroundNode *getBackgroundNodes() const {
		return (BackgroundNode *)getChildNodeByType(BACKGROUND_NODE);
	}

	BillboardNode *getBillboardNodes() const {
		return (BillboardNode *)getChildNodeByType(BILLBOARD_NODE);
	}

	BoxNode *getBoxeNodes() const {
		return (BoxNode *)getChildNodeByType(BOX_NODE);
	}

	CollisionNode *getCollisionNodes() const {
		return (CollisionNode *)getChildNodeByType(COLLISION_NODE);
	}

	ColorNode *getColorNodes() const {
		return (ColorNode *)getChildNodeByType(COLOR_NODE);
	}

	ColorInterpolatorNode *getColorInterpolatorNodes() const {
		return (ColorInterpolatorNode *)getChildNodeByType(COLORINTERPOLATOR_NODE);
	}

	ConeNode *getConeNodes() const {
		return (ConeNode *)getChildNodeByType(CONE_NODE);
	}

	CoordinateNode *getCoordinateNodes() const {
		return (CoordinateNode *)getChildNodeByType(COORDINATE_NODE);
	}

	CoordinateInterpolatorNode *getCoordinateInterpolatorNodes() const {
		return (CoordinateInterpolatorNode *)getChildNodeByType(COORDINATEINTERPOLATOR_NODE);
	}

	CylinderNode *getCylinderNodes() const {
		return (CylinderNode *)getChildNodeByType(CYLINDER_NODE);
	}

	CylinderSensorNode *getCylinderSensorNodes() const {
		return (CylinderSensorNode *)getChildNodeByType(CYLINDERSENSOR_NODE);
	}

	DirectionalLightNode *getDirectionalLightNodes() const {
		return (DirectionalLightNode *)getChildNodeByType(DIRECTIONALLIGHT_NODE);
	}

	ElevationGridNode *getElevationGridNodes() const {
		return (ElevationGridNode *)getChildNodeByType(ELEVATIONGRID_NODE);
	}

	ExtrusionNode *getExtrusionNodes() const {
		return (ExtrusionNode *)getChildNodeByType(EXTRUSION_NODE);
	}

	FogNode *getFogNodes() const {
		return (FogNode *)getChildNodeByType(FOG_NODE);
	}

	FontStyleNode *getFontStyleNodes() const {
		return (FontStyleNode *)getChildNodeByType(FONTSTYLE_NODE);
	}

	GroupNode *getGroupNodes() const {
		return (GroupNode *)getChildNodeByType(GROUP_NODE);
	}

	ImageTextureNode *getImageTextureNodes() const {
		return (ImageTextureNode *)getChildNodeByType(IMAGETEXTURE_NODE);
	}

	IndexedFaceSetNode *getIndexedFaceSetNodes() const {
		return (IndexedFaceSetNode *)getChildNodeByType(INDEXEDFACESET_NODE);
	}

	IndexedLineSetNode *getIndexedLineSetNodes() const {
		return (IndexedLineSetNode *)getChildNodeByType(INDEXEDLINESET_NODE);
	}

	InlineNode *getInlineNodes() const {
		return (InlineNode *)getChildNodeByType(INLINE_NODE);
	}

	LODNode *getLODNodes() const {
		return (LODNode *)getChildNodeByType(LOD_NODE);
	}

	MaterialNode *getMaterialNodes() const {
		return (MaterialNode *)getChildNodeByType(MATERIAL_NODE);
	}

	MovieTextureNode *getMovieTextureNodes() const {
		return (MovieTextureNode *)getChildNodeByType(MOVIETEXTURE_NODE);
	}

	NavigationInfoNode *getNavigationInfoNodes() const {
		return (NavigationInfoNode *)getChildNodeByType(NAVIGATIONINFO_NODE);
	}

	NormalNode *getNormalNodes() const {
		return (NormalNode *)getChildNodeByType(NORMAL_NODE);
	}

	NormalInterpolatorNode *getNormalInterpolatorNodes() const {
		return (NormalInterpolatorNode *)getChildNodeByType(NORMALINTERPOLATOR_NODE);
	}

	OrientationInterpolatorNode *getOrientationInterpolatorNodes() const {
		return (OrientationInterpolatorNode *)getChildNodeByType(ORIENTATIONINTERPOLATOR_NODE);
	}

	PixelTextureNode *getPixelTextureNodes() const {
		return (PixelTextureNode *)getChildNodeByType(PIXELTEXTURE_NODE);
	}

	PlaneSensorNode *getPlaneSensorNodes() const {
		return (PlaneSensorNode *)getChildNodeByType(PLANESENSOR_NODE);
	}

	PointLightNode *getPointLightNodes() const {
		return (PointLightNode *)getChildNodeByType(POINTLIGHT_NODE);
	}

	PointSetNode *getPointSetNodes() const {
		return (PointSetNode *)getChildNodeByType(POINTSET_NODE);
	}

	PositionInterpolatorNode *getPositionInterpolatorNodes() const {
		return (PositionInterpolatorNode *)getChildNodeByType(POSITIONINTERPOLATOR_NODE);
	}

	ProximitySensorNode *getProximitySensorNodes() const {
		return (ProximitySensorNode *)getChildNodeByType(PROXIMITYSENSOR_NODE);
	}

	ScalarInterpolatorNode *getScalarInterpolatorNodes() const {
		return (ScalarInterpolatorNode *)getChildNodeByType(SCALARINTERPOLATOR_NODE);
	}

	ScriptNode *getScriptNodes() const {
		return (ScriptNode *)getChildNodeByType(SCRIPT_NODE);
	}

	ShapeNode *getShapeNodes() const {
		return (ShapeNode *)getChildNodeByType(SHAPE_NODE);
	}

	SoundNode *getSoundNodes() const {
		return (SoundNode *)getChildNodeByType(SOUND_NODE);
	}

	SphereNode *getSphereNodes() const {
		return (SphereNode *)getChildNodeByType(SPHERE_NODE);
	}

	SphereSensorNode *getSphereSensorNodes() const {
		return (SphereSensorNode *)getChildNodeByType(SPHERESENSOR_NODE);
	}

	SpotLightNode *getSpotLightNodes() const {
		return (SpotLightNode *)getChildNodeByType(SPOTLIGHT_NODE);
	}

	SwitchNode *getSwitchNodes() const {
		return (SwitchNode *)getChildNodeByType(SWITCH_NODE);
	}

	TextNode *getTextNodes() const {
		return (TextNode *)getChildNodeByType(TEXT_NODE);
	}

	TextureCoordinateNode *getTextureCoordinateNodes() const {
		return (TextureCoordinateNode *)getChildNodeByType(TEXTURECOORDINATE_NODE);
	}

	TextureTransformNode *getTextureTransformNodes() const {
		return (TextureTransformNode *)getChildNodeByType(TEXTURETRANSFORM_NODE);
	}

	TimeSensorNode *getTimeSensorNodes() const {
		return (TimeSensorNode *)getChildNodeByType(TIMESENSOR_NODE);
	}

	TouchSensorNode *getTouchSensorNodes() const {
		return (TouchSensorNode *)getChildNodeByType(TOUCHSENSOR_NODE);
	}

	TransformNode *getTransformNodes() const {
		return (TransformNode *)getChildNodeByType(TRANSFORM_NODE);
	}

	ViewpointNode *getViewpointNodes() const {
		return (ViewpointNode *)getChildNodeByType(VIEWPOINT_NODE);
	}

	VisibilitySensorNode *getVisibilitySensorNodes() const {
		return (VisibilitySensorNode *)getChildNodeByType(VISIBILITYSENSOR_NODE);
	}

	WorldInfoNode *getWorldInfoNodes() const {
		return (WorldInfoNode *)getChildNodeByType(WORLDINFO_NODE);
	}

	// 9. Networking component (X3D)

	LoadSensorNode *getLoadSensorNodes() const {
		return (LoadSensorNode *)getChildNodeByType(LOADSENSOR_NODE);
	}

	// 10. Grouping component (X3D)

	StaticGroupNode *getStaticGroupNodes() const {
		return (StaticGroupNode *)getChildNodeByType(STATICGROUP_NODE);
	}

	// 11. Rendering component (X3D)

	ColorRGBANode *getColorRGBANodes() const {
		return (ColorRGBANode *)getChildNodeByType(COLORRGBA_NODE);
	}

	TriangleSetNode *getTriangleSetNodes() const {
		return (TriangleSetNode *)getChildNodeByType(TRIANGLESET_NODE);
	}

	TriangleFanSetNode *getTriangleFanSetNodes() const {
		return (TriangleFanSetNode *)getChildNodeByType(TRIANGLEFANSET_NODE);
	}

	TriangleStripSetNode *getTriangleStripSetNodes() const {
		return (TriangleStripSetNode *)getChildNodeByType(TRIANGLESTRIPSET_NODE);
	}

	// 12. Shape component (X3D)

	FillPropertiesNode *getFillPropertiesNodes() const {
		return (FillPropertiesNode *)getChildNodeByType(FILLPROPERTIES_NODE);
	}

	LinePropertiesNode *getLinePropertiesNodes() const {
		return (LinePropertiesNode *)getChildNodeByType(LINEPROPERTIES_NODE);
	}

	// 14. Geometry2D component (X3D)

	Arc2DNode *getArc2DNodes() const {
		return (Arc2DNode *)getChildNodeByType(ARC2D_NODE);
	}

	ArcClose2DNode *getArcClose2DNodes() const {
		return (ArcClose2DNode *)getChildNodeByType(ARCCLOSE2D_NODE);
	}

	Circle2DNode *getCircle2DNodes() const {
		return (Circle2DNode *)getChildNodeByType(CIRCLE2D_NODE);
	}

	Disk2DNode *getDisk2DNodes() const {
		return (Disk2DNode *)getChildNodeByType(DISK2D_NODE);
	}

	Polyline2DNode *getPolyline2DNodes() const {
		return (Polyline2DNode *)getChildNodeByType(POLYLINE2D_NODE);
	}

	Polypoint2DNode *getPolypoint2DNodes() const {
		return (Polypoint2DNode *)getChildNodeByType(POLYPOINT2D_NODE);
	}

	Rectangle2DNode *getRectangle2DNodes() const {
		return (Rectangle2DNode *)getChildNodeByType(RECTANGLE2D_NODE);
	}

	TriangleSet2DNode *getTriangleSet2DNodes() const {
		return (TriangleSet2DNode *)getChildNodeByType(TRIANGLESET2D_NODE);
	}

	// 18. Texturing component (x3D)

	MultiTextureNode *getMultiTextureNodes() const {
		return (MultiTextureNode *)getChildNodeByType(MULTITEXTURE_NODE);
	}

	MultiTextureCoordinateNode *getMultiTextureCoordinateNodes() const {
		return (MultiTextureCoordinateNode *)getChildNodeByType(MULTITEXTURECOORD_NODE);
	}

	MultiTextureTransformNode *getMultiTextureTransformNodes() const {
		return (MultiTextureTransformNode *)getChildNodeByType(MULTITEXTURETRANSFORM_NODE);
	}

	TextureCoordinateGeneratorNode *getTextureCoordinateGeneratorNodes() const {
		return (TextureCoordinateGeneratorNode *)getChildNodeByType(TEXCOORDGEN_NODE);
	}

	// 19. Interpolation component (X3D)

	CoordinateInterpolator2DNode *getCoordinateInterpolator2DNodes() const {
		return (CoordinateInterpolator2DNode *)getChildNodeByType(COORDINATEINTERPOLATOR2D_NODE);
	}

	PositionInterpolator2DNode *getPositionInterpolator2DNodes() const {
		return (PositionInterpolator2DNode *)getChildNodeByType(POSITIONINTERPOLATOR2D_NODE);
	}

	// 21. Key device sensor component (X3D)

	KeySensorNode *getKeySensorNodes() const {
		return (KeySensorNode *)getChildNodeByType(KEYSENSOR_NODE);
	}

	StringSensorNode *getStringSensorNodes() const {
		return (StringSensorNode *)getChildNodeByType(STRINGSENSOR_NODE);
	}

	// 30. Event Utilities component (X3D)

	BooleanFilterNode *getBooleanFilterNodes() const {
		return (BooleanFilterNode *)getChildNodeByType(BOOLEANFILTER_NODE);
	}

	BooleanToggleNode *getBooleanToggleNodes() const {
		return (BooleanToggleNode *)getChildNodeByType(BOOLEANTOGGLE_NODE);
	}

	BooleanTriggerNode *getBooleanTriggerNodes() const {
		return (BooleanTriggerNode *)getChildNodeByType(BOOLEANTRIGGER_NODE);
	}

	BooleanSequencerNode *getBooleanSequencerNodes() const {
		return (BooleanSequencerNode *)getChildNodeByType(BOOLEANSEQUENCER_NODE);
	}

	IntegerTriggerNode *getIntegerTriggerNodes() const {
		return (IntegerTriggerNode *)getChildNodeByType(INTEGERTRIGGER_NODE);
	}

	IntegerSequencerNode *getIntegerSequencerNodes() const {
		return (IntegerSequencerNode *)getChildNodeByType(INTEGERSEQUENCER_NODE);
	}

	TimeTriggerNode *getTimeTriggerNodes() const {
		return (TimeTriggerNode *)getChildNodeByType(TIMETRIGGER_NODE);
	}

	// Deprecated components (X3D)

	NodeSequencerNode *getNodeSequencerNodes() const {
		return (NodeSequencerNode *)getChildNodeByType(NODESEQUENCER_NODE);
	}

	Shape2DNode *getShape2DNodes() const {
		return (Shape2DNode *)getChildNodeByType(SHAPE2D_NODE);
	}

	BooleanTimeTriggerNode *getBooleanTimeTriggerNodes() const {
		return (BooleanTimeTriggerNode *)getChildNodeByType(BOOLEANTIMETRIGGER_NODE);
	}

	Transform2DNode *getTransform2DNodes() const {
		return (Transform2DNode *)getChildNodeByType(TRANSFORM2D_NODE);
	}

    // Extensions (X3D)

	CommonSurfaceShaderNode *getCommonSurfaceShaderNodes() const {
		return (CommonSurfaceShaderNode *)getChildNodeByType(COMMONSURFACESHADER_NODE);
	}

	////////////////////////////////////////////////
	//	is*
	////////////////////////////////////////////////

	bool isNode(const int type) const;
	bool isRootNode() const;
	bool isDEFNode() const;
	bool isInlineChildNode() const;

	bool isGroupingNode() const {
		if (isAnchorNode() || isBillboardNode() || isCollisionNode() || isGroupNode() || isLODNode() || isSwitchNode() || isTransformNode())
			return true;
		return false;
	}

	bool isBoundedGroupingNode() const {
		return isGroupingNode();
	}

	bool isSpecialGroupNode() const {
		if (isInlineNode() || isLODNode() || isSwitchNode())
			return true;
		return false;
	}

	bool isCommonNode() const {
		if (isLightNode() || isAudioClipNode() || isScriptNode() || isShapeNode() || isSoundNode() || isWorldInfoNode())
			return true;
		return false;
	}

	bool isLightNode() const {
		if (isDirectionalLightNode() || isSpotLightNode() || isPointLightNode())
			return true;
		return false;
	}

	bool isGeometry3DNode() const {
                if (isBoxNode() || isConeNode() || isCylinderNode() || isElevationGridNode() || isExtrusionNode() || isIndexedFaceSetNode() || isIndexedLineSetNode() || isPointSetNode() || isSphereNode() || isTextNode() || isIndexedTriangleSetNode() || isIndexedTriangleFanSetNode() || isIndexedTriangleStripSetNode())
			return true;
		return false;
	}

	bool isGeometry3DPropertyNode() const {
		if (isColorNode() || isCoordinateNode() || isNormalNode() || isTextureCoordinateNode())
			return true;
		return false;
	}

	bool isTextureNode() const {
		if (isMovieTextureNode() || isPixelTextureNode() || isImageTextureNode() )
			return true;
		return false;
	}

	bool isSensorNode() const {
		if (isCylinderSensorNode() || isPlaneSensorNode() || isSphereSensorNode() || isProximitySensorNode() || isTimeSensorNode() || isTouchSensorNode() || isVisibilitySensorNode())
			return true;
		return false;
	}

	bool isInterpolatorNode() const {
		if (isColorInterpolatorNode() || isCoordinateInterpolatorNode() || isNormalInterpolatorNode() || isOrientationInterpolatorNode() || isPositionInterpolatorNode() || isScalarInterpolatorNode())
			return true;
		return false;
	}

	bool isBindableNode() const {
		if (isBackgroundNode() || isFogNode() || isNavigationInfoNode() || isViewpointNode())
			return true;
		return false;
	}

	// VRML97 component

	bool isAnchorNode() const {
		return isNode(ANCHOR_NODE);
	}

	bool isAppearanceNode() const {
		return isNode(APPEARANCE_NODE);
	}

	bool isAudioClipNode() const {
		return isNode(AUDIOCLIP_NODE);
	}

	bool isBackgroundNode() const {
		return isNode(BACKGROUND_NODE);
	}

	bool isBillboardNode() const {
		return isNode(BILLBOARD_NODE);
	}

	bool isBoxNode() const {
		return isNode(BOX_NODE);
	}

	bool isCollisionNode() const {
		return isNode(COLLISION_NODE);
	}

	bool isColorNode() const {
		return isNode(COLOR_NODE);
	}

	bool isColorInterpolatorNode() const {
		return isNode(COLORINTERPOLATOR_NODE);
	}

	bool isConeNode() const {
		return isNode(CONE_NODE);
	}

	bool isCoordinateNode() const {
		return isNode(COORDINATE_NODE);
	}

	bool isCoordinateInterpolatorNode() const {
		return isNode(COORDINATEINTERPOLATOR_NODE);
	}

	bool isCylinderNode() const {
		return isNode(CYLINDER_NODE);
	}

	bool isCylinderSensorNode() const {
		return isNode(CYLINDERSENSOR_NODE);
	}

	bool isDirectionalLightNode() const {
		return isNode(DIRECTIONALLIGHT_NODE);
	}

	bool isElevationGridNode() const {
		return isNode(ELEVATIONGRID_NODE);
	}

	bool isExtrusionNode() const {
		return isNode(EXTRUSION_NODE);
	}

	bool isFogNode() const {
		return isNode(FOG_NODE);
	}

	bool isFontStyleNode() const {
		return isNode(FONTSTYLE_NODE);
	}

	bool isGroupNode() const {
		return isNode(GROUP_NODE);
	}

	bool isImageTextureNode() const {
		return isNode(IMAGETEXTURE_NODE);
	}

	bool isIndexedFaceSetNode() const {
		return isNode(INDEXEDFACESET_NODE);
	}

	bool isIndexedLineSetNode() const {
		return isNode(INDEXEDLINESET_NODE);
	}

	bool isInlineNode() const {
		return isNode(INLINE_NODE);
	}

	bool isLODNode() const {
		return isNode(LOD_NODE);
	}

	bool isMaterialNode() const {
		return isNode(MATERIAL_NODE);
	}

	bool isMovieTextureNode() const {
		return isNode(MOVIETEXTURE_NODE);
	}

	bool isNavigationInfoNode() const {
		return isNode(NAVIGATIONINFO_NODE);
	}

	bool isNormalNode() const {
		return isNode(NORMAL_NODE);
	}

	bool isNormalInterpolatorNode() const {
		return isNode(NORMALINTERPOLATOR_NODE);
	}

	bool isOrientationInterpolatorNode() const {
		return isNode(ORIENTATIONINTERPOLATOR_NODE);
	}

	bool isPixelTextureNode() const {
		return isNode(PIXELTEXTURE_NODE);
	}

	bool isPlaneSensorNode() const {
		return isNode(PLANESENSOR_NODE);
	}

	bool isPointLightNode() const {
		return isNode(POINTLIGHT_NODE);
	}

	bool isPointSetNode() const {
		return isNode(POINTSET_NODE);
	}

	bool isPositionInterpolatorNode() const {
		return isNode(POSITIONINTERPOLATOR_NODE);
	}

	bool isProximitySensorNode() const {
		return isNode(PROXIMITYSENSOR_NODE);
	}

	bool isScalarInterpolatorNode() const {
		return isNode(SCALARINTERPOLATOR_NODE);
	}

	bool isScriptNode() const {
		return isNode(SCRIPT_NODE);
	}

	bool isShapeNode() const {
		return isNode(SHAPE_NODE);
	}

	bool isSoundNode() const {
		return isNode(SOUND_NODE);
	}

	bool isSphereNode() const {
		return isNode(SPHERE_NODE);
	}

	bool isSphereSensorNode() const {
		return isNode(SPHERESENSOR_NODE);
	}

	bool isSpotLightNode() const {
		return isNode(SPOTLIGHT_NODE);
	}

	bool isSwitchNode() const {
		return isNode(SWITCH_NODE);
	}

	bool isTextNode() const {
		return isNode(TEXT_NODE);
	}

	bool isTextureCoordinateNode() const {
		return isNode(TEXTURECOORDINATE_NODE);
	}

	bool isTextureTransformNode() const {
		return isNode(TEXTURETRANSFORM_NODE);
	}

	bool isTimeSensorNode() const {
		return isNode(TIMESENSOR_NODE);
	}

	bool isTouchSensorNode() const {
		return isNode(TOUCHSENSOR_NODE);
	}

	bool isTransformNode() const {
		return isNode(TRANSFORM_NODE);
	}

	bool isViewpointNode() const {
		return isNode(VIEWPOINT_NODE);
	}

	bool isVisibilitySensorNode() const {
		return isNode(VISIBILITYSENSOR_NODE);
	}

	bool isWorldInfoNode() const {
		return isNode(WORLDINFO_NODE);
	}

	// 9. Networking component (X3D)

	bool isLoadSensorNode() const {
		return isNode(LOADSENSOR_NODE);
	}

	// 10. Grouping component (X3D)

	bool isStaticGroupNode() const {
		return isNode(STATICGROUP_NODE);
	}

	// 11. Rendering component (X3D)

	bool isColorRGBANode() const {
		return isNode(COLORRGBA_NODE);
	}

        bool isIndexedTriangleSetNode() const {
                return isNode(INDEXEDTRIANGLESET_NODE);
        }

        bool isIndexedTriangleFanSetNode() const {
                return isNode(INDEXEDTRIANGLEFANSET_NODE);
        }

        bool isIndexedTriangleStripSetNode() const {
                return isNode(INDEXEDTRIANGLESTRIPSET_NODE);
        }

	bool isTriangleSetNode() const {
		return isNode(TRIANGLESET_NODE);
	}

	bool isTriangleFanSetNode() const {
		return isNode(TRIANGLEFANSET_NODE);
	}

	bool isTriangleStripSetNode() const {
		return isNode(TRIANGLESTRIPSET_NODE);
	}

	// 12. Shape component (X3D)

	bool isFillPropertiesNode() const {
		return isNode(FILLPROPERTIES_NODE);
	}

	bool isLinePropertiesNode() const {
		return isNode(LINEPROPERTIES_NODE);
	}

	// 14. Geometry2D component (X3D)

	bool isArc2DNode() const {
		return isNode(ARC2D_NODE);
	}

	bool isArcClose2DNode() const {
		return isNode(ARCCLOSE2D_NODE);
	}

	bool isCircle2DNode() const {
		return isNode(CIRCLE2D_NODE);
	}

	bool isDisk2DNode() const {
		return isNode(DISK2D_NODE);
	}

	bool isPolyline2DNode() const {
		return isNode(POLYLINE2D_NODE);
	}

	bool isPolypoint2DNode() const {
		return isNode(POLYPOINT2D_NODE);
	}

	bool isRectangle2DNode() const {
		return isNode(RECTANGLE2D_NODE);
	}

	bool isTriangleSet2DNode() const {
		return isNode(TRIANGLESET2D_NODE);
	}

	// 18. Texturing component (x3D)

	bool isMultiTextureNode() const {
		return isNode(MULTITEXTURE_NODE);
	}

	bool isMultiTextureCoordinateNode() const {
		return isNode(MULTITEXTURECOORD_NODE);
	}

	bool isMultiTextureTransformNode() const {
		return isNode(MULTITEXTURETRANSFORM_NODE);
	}

	bool isTextureCoordinateGeneratorNode() const {
		return isNode(TEXCOORDGEN_NODE);
	}

	// 19. Interpolation component (X3D)

	bool isCoordinateInterpolator2DNode() const {
		return isNode(COORDINATEINTERPOLATOR2D_NODE);
	}

	bool isPositionInterpolator2DNode() const {
		return isNode(POSITIONINTERPOLATOR2D_NODE);
	}

	// 21. Key device sensor component (X3D)

	bool isKeySensorNode() const {
		return isNode(KEYSENSOR_NODE);
	}

	bool isStringSensorNode() const {
		return isNode(STRINGSENSOR_NODE);
	}

	// 30. Event Utilities component (X3D)

	bool isBooleanFilterNode() const {
		return isNode(BOOLEANFILTER_NODE);
	}

	bool isBooleanToggleNode() const {
		return isNode(BOOLEANTOGGLE_NODE);
	}

	bool isBooleanTriggerNode() const {
		return isNode(BOOLEANTRIGGER_NODE);
	}

	bool isBooleanSequencerNode() const {
		return isNode(BOOLEANSEQUENCER_NODE);
	}

	bool isIntegerTriggerNode() const {
		return isNode(INTEGERTRIGGER_NODE);
	}

	bool isIntegerSequencerNode() const {
		return isNode(INTEGERSEQUENCER_NODE);
	}

	bool isTimeTriggerNode() const {
		return isNode(TIMETRIGGER_NODE);
	}

	// Deprecated components (X3D)

	bool isNodeSequencerNode() const {
		return isNode(NODESEQUENCER_NODE);
	}

	bool isShape2DNode() const {
		return isNode(SHAPE2D_NODE);
	}

	bool isBooleanTimeTriggerNode() const {
		return isNode(BOOLEANTIMETRIGGER_NODE);
	}

	bool isTransform2DNode() const {
		return isNode(TRANSFORM2D_NODE);
	}

    // Extensions (X3D)

	bool isCommonSurfaceShaderNode() const {
		return isNode(COMMONSURFACESHADER_NODE);
	}

	////////////////////////////////////////////////
	//	is* (XML)
	////////////////////////////////////////////////

	bool isXMLNode() const {
		return isNode(XML_NODE);
	}

	////////////////////////////////////////////////
	//	isRouteNode (X3D)
	////////////////////////////////////////////////

	bool isRouteNode() const {
		return isNode(ROUTE_NODE);
	}

	////////////////////////////////////////////////
	//	is (VRML97|X3D)Node
	////////////////////////////////////////////////

	bool isX3DNode() const {
		if (isXMLNode())
			return true;
		return false;
	}

	bool isVRML97Node() const {
		return !isX3DNode();
	}

	////////////////////////////////////////////////
	//	output (VRML97)
	////////////////////////////////////////////////

	char *getIndentLevelString(int nIndentLevel) const;
	char *getSpaceString(int nSpaces) const;

	void outputHead(std::ostream& printStream, const char *indentString) const;

	void outputTail(std::ostream& printStream, const char * indentString) const;

	virtual void outputContext(std::ostream &printStream, const char *indentString) const = 0;

	void outputContext(std::ostream& printStream, const char *indentString1, const char *indentString2) const;

	void output(std::ostream& printStream, int indentLevet) const;

	void print(std::ostream& printStream, int indentLevel) const {
		output(printStream, indentLevel);
	}

	void print() const {
		output(std::cout, 0);
	}

	void save(std::ofstream outputStream) const {
		output(outputStream, 0);
	}

	int save(const char * filename) const {
		std::ofstream outputFile(filename, std::ios::out);
		if (outputFile) {
			output(outputFile, 0);
			return 1;
		}
		else
			return 0;
	}

	////////////////////////////////////////////////
	//	output (XML)
	////////////////////////////////////////////////

	void outputXML(std::ostream& printStream, int indentLevet) const;
	void outputXMLField(std::ostream& printStream, Field *field, int indentLevel) const;
	void outputXMLField(std::ostream& printStream, Field *field, int indentLevel, bool isSingleLine) const;

	void printXML(std::ostream& printStream, int indentLevel) const {
		outputXML(printStream, indentLevel);
	}

	void printXML() const {
		outputXML(std::cout, 0);
	}

	int saveXML(const char * filename) const {
		std::ofstream outputFile(filename, std::ios::out);
		if (outputFile) {
			output(outputFile, 0);
			return 1;
		}
		else
			return 0;
	}

	////////////////////////////////////////////////
	//	Virtual functions
	////////////////////////////////////////////////

	virtual void update()		= 0;
	virtual void initialize()	= 0;
	virtual void uninitialize()	= 0;

	////////////////////////////////////////////////
	//	Transform matrix
	////////////////////////////////////////////////

	void	getTransformMatrix(SFMatrix *matrix) const;
	void	getTransformMatrix(float value[4][4]) const;

	////////////////////////////////////////////////
	//	Translation matrix
	////////////////////////////////////////////////

	void	getTranslationMatrix(SFMatrix *matrix) const;
	void	getTranslationMatrix(float value[4][4]) const;

	////////////////////////////////////////////////
	//	SceneGraph
	////////////////////////////////////////////////

	void setSceneGraph(SceneGraph *sceneGraph);
	SceneGraph	*getSceneGraph() const;

	////////////////////////////////////////////////
	//	Route
	////////////////////////////////////////////////

	void		sendEvent(Field *eventOutField);
	void		sendEvent(const char *eventOutFieldString);

	////////////////////////////////////////////////
	//	Value
	////////////////////////////////////////////////

	void		setValue(void *value) { mValue = value; }
	void		*getValue() const     { return mValue; }

	////////////////////////////////////////////////
	//	Initialized
	////////////////////////////////////////////////

	void		setInitialized(bool flag)	{ *mInitialized = flag; }
	bool		isInitialized()	const  	{ return *mInitialized; }

	////////////////////////////////////////////////
	//	BoundingBox
	////////////////////////////////////////////////

	virtual void recomputeBoundingBox() {
	}

	////////////////////////////////////////////////
	//	DisplayList
	////////////////////////////////////////////////

#ifdef CX3D_SUPPORT_OPENGL

	virtual void recomputeDisplayList() {
	}

#endif

	////////////////////////////////////////////////
	//	Instance node
	////////////////////////////////////////////////

	bool isInstanceNode() const {
		return (getReferenceNode() != NULL ? true : false);
	}

	void setReferenceNodeMembers(Node *node);

	void setOriginalMembers();

	void setReferenceNode(Node *node) {
		mReferenceNode = node;
	}

	Node *getReferenceNode() const {
		return mReferenceNode;
	}

	void setAsInstanceNode(Node *node) {
		setReferenceNode(node);
		setReferenceNodeMembers(node);
	}

	Node *createInstanceNode();

	////////////////////////////////////////////////
	//	DEF node
	////////////////////////////////////////////////

	DEFNode *createDEFNode();
};

}

#endif


text:
create class xoo ( a int , b int, c int);
insert into xoo values(1, 1, 1);
insert into xoo values(2, 2, 2);

select incr(a), incr(b) from xoo where c = 1 order by 1;

select incr(a), incr(b) from xoo where c = 1 order by 1;

select incr(a), incr(b) from xoo where c = 1 order by 1;

select incr(a), incr(b) from xoo where c = 1 order by 1;

select incr(a), incr(b) from xoo where c = 1 order by 1;

select a from xoo where c = 2 WITH INCREMENT FOR  b order by 1;

select * from xoo order by 1 desc;

drop xoo;


text:
layout: updates/post
title: "Go to a line number at a specific column"
published_on: 2015-05-08
updated_on: 2015-05-20
tags:
  - devtools
authors:
  - umarhansa
description: "Learn how to jump to specific line numbers in the Sources panel."
featured_image: /web/updates/images/2015-05-19-devtools-go-to-a-line-number-at-a-specific-column/go-to-column.gif
source_name: DevTips
source_url: https://umaar.com/dev-tips/9-go-to-column
---

GOTO a line number with a specified column using the format :linenumber:columnnumber in the CMD+O dialogue from the Sources panel editor.

Hit CMD + O from the Sources Panel with an open file

Enter :5:9

Notice you are taken to line 5, column 9!


text:
const frame = figma.createFrame();
frame.appendChild(figma.createRectangle());

figma.on('selectionchange', () => {
    figma.currentPage.selection;
});

figma.clientStorage.setAsync('happy', true);
figma.clientStorage.setAsync('happy', { a: 123 });

async () => {
    const { a } = await figma.clientStorage.getAsync('happy');
};

if (frame.cornerRadius !== figma.mixed) {
    frame.topLeftRadius = frame.cornerRadius;
}

figma.closePlugin();


text:
<?php
namespace Aura\Router\Rule;

use Aura\Router\Route;
use Psr\Http\Message\ServerRequestInterface;

// must match **all** cookies
class Cookies
{
    /**
     *
     * Checks that cookie values match their related regular expressions, and
     * captures the cookies as attributes.
     *
     * @param ServerRequestInterface $request The HTTP request.
     *
     * @param Route $route The route.
     *
     * @return bool True on success, false on failure.
     *
     */
    public function __invoke(ServerRequestInterface $request, Route $route)
    {
        $routeCookies = $route->cookies;
        if (! $routeCookies) {
            return true;
        }

        $requestCookies = $request->getCookieParams();
        $attributes = [];
        foreach ($routeCookies as $name => $regex) {
            $match = $this->match($requestCookies, $name, $regex);
            if ($match === false) {
                return false;
            }
            $attributes[$name] = $match;
        }

        $route->addAttributes($attributes);
        return true;
    }

    /**
     *
     * Does a cookie value match a regex?
     *
     * @param $headers The array of all request headers.
     *
     * @param string $name The header name to look for.
     *
     * @param string $regex The regex to match against.
     *
     * @return string The match.
     *
     */
    protected function match($cookies, $name, $regex)
    {
        if (! isset($cookies[$name])) {
            return false;
        }

        if (preg_match($regex, $cookies[$name], $matches)) {
            return $cookies[$name];
        }

        return false;
    }
}