OrphanFrame.java

  1. /* Copyright 2002-2013 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.frames;

  18. import java.io.Serializable;
  19. import java.util.ArrayList;
  20. import java.util.Collections;
  21. import java.util.List;

  22. import org.orekit.errors.OrekitException;
  23. import org.orekit.errors.OrekitMessages;


  24. /** Prototype frame that can be built from leaf to roots and later attached to a tree.
  25.  *
  26.  * <p>Regular {@link Frame} instances can be built only from a parent frame, i.e.
  27.  * the frames tree can be built only from root to leafs. In some cases, it may
  28.  * desirable to build a subset tree and attach it to the main tree after build
  29.  * time, which means the tree is built from leafs to root. This class allows
  30.  * building this subtree.</p>
  31.  * <p>
  32.  * During the build process, the {@link Frame} associated with each {@link OrphanFrame}
  33.  * is not available. It becomes available only once the {@link OrphanFrame} has been
  34.  * attached to the main tree, and at this time it can be used to compute
  35.  * {@link Transform transforms}.
  36.  * </p>
  37.  *
  38.  * @author Luc Maisonobe
  39.  * @since 6.0
  40.  */
  41. public class OrphanFrame implements Serializable {

  42.     /** Serializable UID. */
  43.     private static final long serialVersionUID = 20130409L;

  44.     /** Instance name. */
  45.     private final String name;

  46.     /** Children of the frame. */
  47.     private final List<OrphanFrame> children;

  48.     /** Parent orphan frame. */
  49.     private OrphanFrame orphanParent;

  50.     /** Provider for transform from parent frame to instance. */
  51.     private TransformProvider provider;

  52.     /** Indicator for pseudo-inertial frames. */
  53.     private boolean pseudoInertial;

  54.     /** Associated frame (available only once attached to the main frames tree). */
  55.     private Frame frame;

  56.     /** Simple constructor.
  57.      * @param name name of the frame
  58.      */
  59.     public OrphanFrame(final String name) {
  60.         children  = new ArrayList<OrphanFrame>();
  61.         this.name = name;
  62.     }

  63.     /** Add a child.
  64.      * <p>
  65.      * If a child is added after the instance has been attached, the child and
  66.      * all its tree will be attached immediately too.
  67.      * </p>
  68.      * @param child child to add
  69.      * @param transform transform from instance to child
  70.      * @param isPseudoInertial true if child is considered pseudo-inertial
  71.      * (i.e. suitable for propagating orbit)
  72.      * @exception OrekitException if child frame has already been attached to
  73.      * either an {@link OrphanFrame} or to a {@link Frame}
  74.      */
  75.     public void addChild(final OrphanFrame child, final Transform transform,
  76.                          final boolean isPseudoInertial)
  77.         throws OrekitException {
  78.         addChild(child, new FixedTransformProvider(transform), isPseudoInertial);
  79.     }

  80.     /** Add a child.
  81.      * <p>
  82.      * If a child is added after the instance has been attached, the child and
  83.      * all its tree will be attached immediately too.
  84.      * </p>
  85.      * @param child child to add
  86.      * @param transformProvider provider for transform from instance to child
  87.      * @param isPseudoInertial true if child is considered pseudo-inertial
  88.      * (i.e. suitable for propagating orbit)
  89.      * @exception OrekitException if child frame has already been attached to
  90.      * either an {@link OrphanFrame} or to a {@link Frame}
  91.      */
  92.     public void addChild(final OrphanFrame child, final TransformProvider transformProvider,
  93.                          final boolean isPseudoInertial)
  94.         throws OrekitException {

  95.         // safety check
  96.         if (child.orphanParent != null) {
  97.             throw new OrekitException(OrekitMessages.FRAME_ALREADY_ATTACHED,
  98.                                       child.name, child.orphanParent.name);
  99.         }

  100.         children.add(child);
  101.         child.orphanParent   = this;
  102.         child.provider       = transformProvider;
  103.         child.pseudoInertial = isPseudoInertial;

  104.         if (frame != null) {
  105.             // we are attaching a child after having attached the instance,
  106.             // we process the tree immediately
  107.             buildTree();
  108.         }

  109.     }

  110.     /** Attach the instance (and all its children down to leafs) to the main tree.
  111.      * @param parent parent frame to attach to
  112.      * @param transform transform from parent frame to instance
  113.      * @param isPseudoInertial true if frame is considered pseudo-inertial
  114.      * (i.e. suitable for propagating orbit)
  115.      * @exception OrekitException if child frame has already been attached to
  116.      * either an {@link OrphanFrame} or to a {@link Frame}
  117.      */
  118.     public void attachTo(final Frame parent, final Transform transform,
  119.                          final boolean isPseudoInertial)
  120.         throws OrekitException {
  121.         attachTo(parent, new FixedTransformProvider(transform), isPseudoInertial);
  122.     }

  123.     /** Attach the instance (and all its children down to leafs) to the main tree.
  124.      * @param parent parent frame to attach to
  125.      * @param transformProvider provider for transform from parent frame to instance
  126.      * @param isPseudoInertial true if frame is considered pseudo-inertial
  127.      * (i.e. suitable for propagating orbit)
  128.      * @exception OrekitException if child frame has already been attached to
  129.      * either an {@link OrphanFrame} or to a {@link Frame}
  130.      */
  131.     public void attachTo(final Frame parent, final TransformProvider transformProvider,
  132.                          final boolean isPseudoInertial)
  133.         throws OrekitException {

  134.         // safety check
  135.         if (orphanParent != null) {
  136.             throw new OrekitException(OrekitMessages.FRAME_ALREADY_ATTACHED,
  137.                                       name, orphanParent.name);
  138.         }

  139.         // set up the attach point
  140.         final OrphanFrame op = new OrphanFrame(parent.getName());
  141.         op.frame = parent;
  142.         op.addChild(this, transformProvider, isPseudoInertial);

  143.     }

  144.     /** Get all children of the instance.
  145.      * @return unmodifiable list of children
  146.      */
  147.     public List<OrphanFrame> getChildren() {
  148.         return Collections.unmodifiableList(children);
  149.     }

  150.     /** Get the associated {@link Frame frame}.
  151.      * @return associated frame
  152.      * @exception OrekitException if instance has not been attached to the frames tree
  153.      */
  154.     public Frame getFrame() throws OrekitException {

  155.         // safety check
  156.         if (frame == null) {
  157.             throw new OrekitException(OrekitMessages.FRAME_NOT_ATTACHED, name);
  158.         }

  159.         return frame;

  160.     }

  161.     /** Recursively build the frames tree starting at instance, which is already associated.
  162.      */
  163.     private void buildTree() {
  164.         for (final OrphanFrame child : children) {

  165.             if (child.frame == null) {

  166.                 // associate the child with a regular frame
  167.                 child.frame = new Frame(frame, child.provider, child.name, child.pseudoInertial);

  168.                 // recursively build the rest of the tree
  169.                 child.buildTree();

  170.             }

  171.         }
  172.     }

  173.     /** {@inheritDoc} */
  174.     @Override
  175.     public String toString() {
  176.         return this.name;
  177.     }

  178. }