View Javadoc

    1   /***
    2    *
    3    * Copyright 2004 Protique Ltd
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * 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   **/
    18  package org.codehaus.activemq.filter;
    19
    20  import java.util.ArrayList;
    21  import java.util.HashMap;
    22  import java.util.HashSet;
    23  import java.util.List;
    24  import java.util.Map;
    25  import java.util.Set;
    26
    27  /***
    28   * An implementation class used to implement {@link DestinationMap}
    29   *
    30   * @version $Revision: 1.4 $
    31   */
    32  public class DestinationMapNode {
    33      // we synchornize at the DestinationMap level
    34      private List values = new ArrayList();
    35      private Map childNodes = new HashMap();
    36      private DestinationMapNode anyChild;
    37      protected static final String ANY_CHILD = DestinationMap.ANY_CHILD;
    38      protected static final String ANY_DESCENDENT = DestinationMap.ANY_DESCENDENT;
    39
    40
    41      /***
    42       * Returns the child node for the given named path or null if it does not exist
    43       */
    44      public DestinationMapNode getChild(String path) {
    45          return (DestinationMapNode) childNodes.get(path);
    46      }
    47
    48      /***
    49       * Returns the child node for the given named path, lazily creating one if it does
    50       * not yet exist
    51       */
    52      public DestinationMapNode getChildOrCreate(String path) {
    53          DestinationMapNode answer = (DestinationMapNode) childNodes.get(path);
    54          if (answer == null) {
    55              answer = createChildNode();
    56              childNodes.put(path, answer);
    57          }
    58          return answer;
    59      }
    60
    61      /***
    62       * Returns the node which represents all children (i.e. the * node)
    63       */
    64      public DestinationMapNode getAnyChildNode() {
    65          if (anyChild == null) {
    66              anyChild = createChildNode();
    67          }
    68          return anyChild;
    69      }
    70
    71      /***
    72       * Returns a mutable List of the values available at this node in the tree
    73       */
    74      public List getValues() {
    75          return values;
    76      }
    77
    78      /***
    79       * Returns a list of all the values from this node down the tree
    80       */
    81      public Set getDesendentValues() {
    82          Set answer = new HashSet();
    83          appendDescendantValues(answer);
    84          return answer;
    85      }
    86
    87      public void add(String[] paths, int idx, Object value) {
    88          if (idx >= paths.length) {
    89              values.add(value);
    90          }
    91          else {
    92              if (idx == paths.length - 1) {
    93                  getAnyChildNode().getValues().add(value);
    94              }
    95              else {
    96                  getAnyChildNode().add(paths, idx + 1, value);
    97              }
    98              getChildOrCreate(paths[idx]).add(paths, idx + 1, value);
    99          }
    100     }
    101
    102     public void remove(String[] paths, int idx, Object value) {
    103         if (idx >= paths.length) {
    104             values.remove(value);
    105         }
    106         else {
    107             if (idx == paths.length - 1) {
    108                 getAnyChildNode().getValues().remove(value);
    109             }
    110             else {
    111                 getAnyChildNode().remove(paths, idx + 1, value);
    112             }
    113             getChildOrCreate(paths[idx]).remove(paths, ++idx, value);
    114         }
    115     }
    116
    117     protected void appendDescendantValues(Set answer) {
    118         answer.addAll(values);
    119         if (anyChild != null) {
    120             anyChild.appendDescendantValues(answer);
    121         }
    122     }
    123
    124     /***
    125      * Factory method to create a child node
    126      */
    127     protected DestinationMapNode createChildNode() {
    128         return new DestinationMapNode();
    129     }
    130
    131     public void appendMatchingWildcards(Set answer, String[] paths, int idx) {
    132         DestinationMapNode wildCardNode = getChild(ANY_CHILD);
    133         if (wildCardNode != null) {
    134             wildCardNode.appendMatchingValues(answer, paths, idx + 1);
    135         }
    136         wildCardNode = getChild(ANY_DESCENDENT);
    137         if (wildCardNode != null) {
    138             answer.addAll(wildCardNode.getDesendentValues());
    139         }
    140     }
    141
    142     public void appendMatchingValues(Set answer, String[] paths, int startIndex) {
    143         DestinationMapNode node = this;
    144         for (int i = startIndex, size = paths.length; i < size && node != null; i++) {
    145             String path = paths[i];
    146             if (path.equals(ANY_DESCENDENT)) {
    147                 answer.addAll(node.getDesendentValues());
    148                 break;
    149             }
    150
    151             node.appendMatchingWildcards(answer, paths, i);
    152             if (path.equals(ANY_CHILD)) {
    153                 node = node.getAnyChildNode();
    154             }
    155             else {
    156                 node = node.getChild(path);
    157             }
    158         }
    159         if (node != null) {
    160             answer.addAll(node.getValues());
    161         }
    162     }
    163 }