NntpThreadContainer.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF 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.apache.commons.net.nntp;

  18. /**
  19.  * A placeholder utility class, used for constructing a tree of Threadables Original implementation by Jamie Zawinski. See the Grendel source for more details
  20.  * <a href="https://lxr.mozilla.org/mozilla/source/grendel/sources/grendel/view/Threader.java#511">here</a> Threadable objects
  21.  */
  22. final class NntpThreadContainer {
  23.     Threadable threadable;
  24.     NntpThreadContainer parent;
  25. //    NntpThreadContainer prev;
  26.     NntpThreadContainer next;
  27.     NntpThreadContainer child;

  28.     /**
  29.      *
  30.      * @param target
  31.      * @return true if child is under self's tree. Detects circular references
  32.      */
  33.     boolean findChild(final NntpThreadContainer target) {
  34.         if (child == null) {
  35.             return false;
  36.         }
  37.         if (child == target) {
  38.             return true;
  39.         }
  40.         return child.findChild(target);
  41.     }

  42.     // Copy the NntpThreadContainer tree structure down into the underlying Threadable objects
  43.     // (Make the Threadable tree look like the NntpThreadContainer tree)
  44.     // TODO convert this to an iterative function - this can blow the stack
  45.     // with very large Threadable trees
  46.     void flush() {
  47.         if (parent != null && threadable == null) {
  48.             throw new IllegalStateException("no threadable in " + toString());
  49.         }

  50.         parent = null;

  51.         if (threadable != null) {
  52.             threadable.setChild(child == null ? null : child.threadable);
  53.         }

  54.         if (child != null) {
  55.             child.flush();
  56.             child = null;
  57.         }

  58.         if (threadable != null) {
  59.             threadable.setNext(next == null ? null : next.threadable);
  60.         }

  61.         if (next != null) {
  62.             next.flush();
  63.             next = null;
  64.         }

  65.         threadable = null;
  66.     }

  67.     /**
  68.      * Reverse the entire set of children
  69.      */
  70.     void reverseChildren() {
  71.         if (child != null) {
  72.             NntpThreadContainer kid, prev, rest;
  73.             for (prev = null, kid = child, rest = kid.next; kid != null; prev = kid, kid = rest, rest = rest == null ? null : rest.next) {
  74.                 kid.next = prev;
  75.             }

  76.             child = prev;

  77.             // Do it for the kids
  78.             for (kid = child; kid != null; kid = kid.next) {
  79.                 kid.reverseChildren();
  80.             }
  81.         }
  82.     }
  83. }