1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.jsword.passage;
21  
22  import org.crosswire.jsword.versification.Versification;
23  import org.crosswire.jsword.versification.system.Versifications;
24  
25  /**
26   * .
27   * 
28   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
29   * @author Joe Walker
30   * @author DM Smith
31   */
32  public final class KeyUtil {
33      /**
34       * Prevent instantiation
35       */
36      private KeyUtil() {
37      }
38  
39      /**
40       * Walk through a tree visiting the nodes and branches in the tree
41       * 
42       * @param key
43       *            The node tree to walk through
44       * @param visitor
45       *            The visitor to notify whenever a node is found
46       */
47      public static void visit(Key key, KeyVisitor visitor) {
48          for (Key subkey : key) {
49              if (subkey.canHaveChildren()) {
50                  visitor.visitBranch(subkey);
51                  visit(subkey, visitor);
52              } else {
53                  visitor.visitLeaf(subkey);
54              }
55          }
56      }
57  
58      /**
59       * Cast a Key to a Verse. Only those keys that are a Verse or can
60       * contain Verses (i.e. Passage and VerseRange) may be cast to one.
61       * Verse containers (i.e. Passage and VerseRange) return their
62       * first verse.
63       * 
64       * @param key The key to cast
65       * @return The key cast to a Verse
66       * @throws ClassCastException
67       */
68      public static Verse getVerse(Key key) {
69          if (key instanceof Verse) {
70              return (Verse) key;
71          }
72  
73          if (key instanceof VerseRange) {
74              VerseRange range = (VerseRange) key;
75              return range.getStart();
76          }
77  
78          if (key instanceof Passage) {
79              Passage ref = (Passage) key;
80              return ref.getVerseAt(0);
81          }
82  
83          throw new ClassCastException("Expected key to be a Verse, VerseRange or Passage");
84      }
85  
86      /**
87       * Cast a Key to a Passage. Only those keys that are a Passage or can
88       * be held by a Passage (i.e. Verse and VerseRange) may be cast to one.
89       * If you pass a null key into this method, you get a null Passage out.
90       * 
91       * @param key The key to cast
92       * @return The key cast to a Passage
93       * @throws ClassCastException
94       */
95      public static Passage getPassage(Key key) {
96          if (key == null) {
97              return null;
98          }
99  
100         if (key instanceof Passage) {
101             return (Passage) key;
102         }
103 
104         if (key instanceof VerseKey) {
105             VerseKey verseKey = (VerseKey) key;
106             Key ref = PassageKeyFactory.instance().createEmptyKeyList(verseKey.getVersification());
107             ref.addAll(verseKey);
108             return (Passage) ref;
109         }
110 
111         throw new ClassCastException("Expected key to be a Verse, VerseRange or Passage");
112     }
113 
114     /**
115      * Get the versification for the key or the default versification.
116      * 
117      * @param key the key that should provide for the Versification
118      * @return the versification for the key
119      */
120     public static Versification getVersification(Key key) {
121         if (key instanceof VerseKey) {
122             return ((VerseKey) key).getVersification();
123         }
124         return Versifications.instance().getVersification(Versifications.DEFAULT_V11N);
125     }
126 }
127