| TreeKey.java |
1 package org.crosswire.jsword.passage;
2
3 /**
4 * Distribution License:
5 * JSword is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License, version 2.1 as published by
7 * the Free Software Foundation. This program is distributed in the hope
8 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
9 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the GNU Lesser General Public License for more details.
11 *
12 * The License is available on the internet at:
13 * http://www.gnu.org/copyleft/lgpl.html
14 * or by writing to:
15 * Free Software Foundation, Inc.
16 * 59 Temple Place - Suite 330
17 * Boston, MA 02111-1307, USA
18 *
19 * Copyright: 2005
20 * The copyright to this program is held by it's authors.
21 *
22 * ID: $Id: TreeKey.java 2114 2011-03-12 16:35:31Z dmsmith $
23 */
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27
28 import org.crosswire.common.util.Logger;
29
30 /**
31 * A Key that knows where the data is in the real file.
32 *
33 * @see gnu.lgpl.License for license details.<br>
34 * The copyright to this program is held by it's authors.
35 * @author DM Smith [dmsmith555 at yahoo dot com]
36 */
37 public class TreeKey extends AbstractKeyList {
38 /**
39 * Setup with the key name and positions of data in the file
40 */
41 public TreeKey(String name, Key parent) {
42 super(name);
43 this.parent = parent;
44 this.children = new ArrayList<Key>();
45 }
46
47 /**
48 * Setup with the key name. Use solely for searching.
49 */
50 public TreeKey(String text) {
51 this(text, null);
52 }
53
54 /* (non-Javadoc)
55 * @see org.crosswire.jsword.passage.Key#canHaveChildren()
56 */
57 public boolean canHaveChildren() {
58 return true;
59 }
60
61 /* (non-Javadoc)
62 * @see org.crosswire.jsword.passage.Key#getChildCount()
63 */
64 public int getChildCount() {
65 return children.size();
66 }
67
68 /* (non-Javadoc)
69 * @see org.crosswire.jsword.passage.Key#getCardinality()
70 */
71 public int getCardinality() {
72 int cardinality = 1; // count this node
73 for (Key child : children) {
74 cardinality += child.getCardinality();
75 }
76
77 return cardinality;
78 }
79
80 @Override
81 public boolean isEmpty() {
82 return children.isEmpty();
83 }
84
85 @Override
86 public boolean contains(Key key) {
87 if (children.contains(key)) {
88 return true;
89 }
90
91 for (Key child : children) {
92 if (child.contains(key)) {
93 return true;
94 }
95 }
96
97 return false;
98 }
99
100 /* (non-Javadoc)
101 * @see java.lang.Iterable#iterator()
102 */
103 public Iterator<Key> iterator() {
104 return new KeyIterator(this);
105 }
106
107 /* (non-Javadoc)
108 * @see org.crosswire.jsword.passage.Key#addAll(org.crosswire.jsword.passage.Key)
109 */
110 public void addAll(Key key) {
111 children.add(key);
112 }
113
114 /* (non-Javadoc)
115 * @see org.crosswire.jsword.passage.Key#removeAll(org.crosswire.jsword.passage.Key)
116 */
117 public void removeAll(Key key) {
118 children.remove(key);
119 }
120
121 /* (non-Javadoc)
122 * @see org.crosswire.jsword.passage.Key#clear()
123 */
124 public void clear() {
125 children.clear();
126 }
127
128 /* (non-Javadoc)
129 * @see org.crosswire.jsword.passage.Key#get(int)
130 */
131 public Key get(int index) {
132 return children.get(index);
133 }
134
135 /* (non-Javadoc)
136 * @see org.crosswire.jsword.passage.Key#indexOf(org.crosswire.jsword.passage.Key)
137 */
138 public int indexOf(Key that) {
139 return children.indexOf(that);
140 }
141
142 /* (non-Javadoc)
143 * @see org.crosswire.jsword.passage.Key#getParent()
144 */
145 public Key getParent() {
146 return parent;
147 }
148
149 /* (non-Javadoc)
150 * @see org.crosswire.jsword.passage.Key#blur(int, org.crosswire.jsword.passage.RestrictionType)
151 */
152 public void blur(int by, RestrictionType restrict) {
153 log.warn("attempt to blur a non-blur-able list");
154 }
155
156 @Override
157 public TreeKey clone() {
158 return (TreeKey) super.clone();
159 }
160
161 @Override
162 public String getRootName() {
163 String rootName = getName();
164 for (Key parentKey = this; parentKey != null && parentKey.getName().length() > 0; parentKey = parentKey.getParent()) {
165 rootName = parentKey.getName();
166 }
167 return rootName;
168 }
169
170 @Override
171 public String getOsisRef() {
172 return getOsisID();
173 }
174
175 @Override
176 public String getOsisID() {
177 StringBuilder b = new StringBuilder(100);
178 b.append(osisify(getName()));
179 for (Key parentKey = this.getParent(); parentKey != null && parentKey.getName().length() > 0; parentKey = parentKey.getParent()) {
180 b.insert(0, ".");
181 b.insert(0, osisify(parentKey.getName()));
182 }
183 // Remove the leading .
184 return b.toString();
185 }
186
187 private String osisify(String str) {
188 // FIXME(DMS): An osisID cannot have lots of stuff that a name can have.
189 // It can only have _, a-z, A-Z, 0-9.
190 // Need to normalize the name by
191 // replacing ' ' with '_'
192 // Stripping punctuation, accents, ...
193 // ...
194 return str.replace(' ', '_');
195 }
196
197 /**
198 * The parent of this key.
199 */
200 private Key parent;
201
202 /**
203 * The immediate children of this tree node.
204 */
205 private List<Key> children;
206
207 /**
208 * Serialization ID
209 */
210 private static final long serialVersionUID = -6560408145705717977L;
211
212 /**
213 * The log stream
214 */
215 private static final Logger log = Logger.getLogger(TreeKey.class);
216 }
217