1 | /* This file is part of the project "Hilbert II" - http://www.qedeq.org |
2 | * |
3 | * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>. |
4 | * |
5 | * "Hilbert II" is free software; you can redistribute |
6 | * it and/or modify it under the terms of the GNU General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | */ |
15 | |
16 | package org.qedeq.kernel.bo.module; |
17 | |
18 | import java.util.ArrayList; |
19 | import java.util.HashMap; |
20 | import java.util.List; |
21 | import java.util.Map; |
22 | |
23 | import org.qedeq.base.trace.Trace; |
24 | import org.qedeq.base.utility.EqualsUtility; |
25 | import org.qedeq.kernel.bo.common.ModuleReferenceList; |
26 | import org.qedeq.kernel.bo.common.QedeqBo; |
27 | import org.qedeq.kernel.se.common.IllegalModuleDataException; |
28 | import org.qedeq.kernel.se.common.ModuleContext; |
29 | |
30 | |
31 | /** |
32 | * Represents a reference list of modules. Every entry has a symbolic name for one referenced QEDEQ |
33 | * module. This module label acts as a prefix for all references to that module. The module label |
34 | * must be an unique String. |
35 | * |
36 | * @author Michael Meyling |
37 | */ |
38 | public class KernelModuleReferenceList implements ModuleReferenceList { |
39 | |
40 | /** This class. */ |
41 | private static final Class CLASS = KernelModuleReferenceList.class; |
42 | |
43 | /** Contains all labels. */ |
44 | private final List labels; |
45 | |
46 | /** Contains all module props. */ |
47 | private final List props; |
48 | |
49 | /** Contains all module import contexts. */ |
50 | private final List contexts; |
51 | |
52 | /** Maps labels to context. */ |
53 | private final Map label2Context; |
54 | |
55 | /** |
56 | * Constructs an empty list of module references. |
57 | */ |
58 | public KernelModuleReferenceList() { |
59 | labels = new ArrayList(); |
60 | props = new ArrayList(); |
61 | contexts = new ArrayList(); |
62 | label2Context = new HashMap(); |
63 | } |
64 | |
65 | /** |
66 | * Add module reference to list. |
67 | * |
68 | * @param context Within this context. |
69 | * @param label Referenced module gets this label. Must not be <code>null</code> or empty. |
70 | * @param prop Referenced module has this properties. Must not be <code>null</code>. |
71 | * @throws IllegalModuleDataException The <code>label</code> is empty or <code>null</code>. |
72 | */ |
73 | public void add(final ModuleContext context, final String label, final QedeqBo prop) |
74 | throws IllegalModuleDataException { |
75 | if (label == null || label.length() <= 0) { |
76 | throw new IllegalModuleDataException(10003, "An label was not defined.", |
77 | new ModuleContext(context), null, |
78 | null); // LATER mime 20071026: organize exception codes |
79 | } |
80 | final ModuleContext con = new ModuleContext(context); |
81 | labels.add(label); |
82 | label2Context.put(label, con); |
83 | contexts.add(con); |
84 | Trace.param(CLASS, "add(ModuleContext, String, QedeqBo)", "context", con); |
85 | props.add(prop); |
86 | } |
87 | |
88 | /** |
89 | * Add module reference to list. |
90 | * |
91 | * @param context Within this context. |
92 | * @param label Referenced module gets this label. Must not be <code>null</code> or empty. |
93 | * @param prop Referenced module has this properties. Must not be <code>null</code>. |
94 | * @throws IllegalModuleDataException The <code>id</code> already exists or is |
95 | * <code>null</code>. Also if <code>label</code> is empty or <code>null</code>. |
96 | */ |
97 | public void addLabelUnique(final ModuleContext context, final String label, |
98 | final QedeqBo prop) throws IllegalModuleDataException { |
99 | if (labels.contains(label)) { |
100 | // LATER mime 20071026: organize exception codes |
101 | throw new IllegalModuleDataException(10004, "Label \"" + label |
102 | + "\" defined more than once.", new ModuleContext(context), // use copy constructor! |
103 | (ModuleContext) label2Context.get(label), null); |
104 | } |
105 | add(new ModuleContext(context), label, prop); |
106 | } |
107 | |
108 | public int size() { |
109 | return labels.size(); |
110 | } |
111 | |
112 | public String getLabel(final int index) { |
113 | return (String) labels.get(index); |
114 | } |
115 | |
116 | public QedeqBo getQedeqBo(final int index) { |
117 | return (QedeqBo) props.get(index); |
118 | } |
119 | |
120 | /** |
121 | * Get {@link QedeqBo} of referenced module. |
122 | * |
123 | * @param index Entry index. |
124 | * @return Module properties for that module. |
125 | */ |
126 | public KernelQedeqBo getKernelQedeqBo(final int index) { |
127 | return (KernelQedeqBo) props.get(index); |
128 | } |
129 | |
130 | public ModuleContext getModuleContext(final int index) { |
131 | return (ModuleContext) contexts.get(index); |
132 | } |
133 | |
134 | public QedeqBo getQedeqBo(final String label) { |
135 | final int index = labels.indexOf(label); |
136 | if (index < 0) { |
137 | return null; |
138 | } |
139 | return (QedeqBo) props.get(index); |
140 | } |
141 | |
142 | /** |
143 | * Get KernelQedeqBo of referenced module via label. Might be <code>null</code>. |
144 | * |
145 | * @param label Label for referenced module or <code>null</code> if not found. |
146 | * @return QEQDEQ BO. |
147 | */ |
148 | public KernelQedeqBo getKernelQedeqBo(final String label) { |
149 | final int index = labels.indexOf(label); |
150 | if (index < 0) { |
151 | return null; |
152 | } |
153 | return (KernelQedeqBo) props.get(index); |
154 | } |
155 | |
156 | /** |
157 | * Is the given QEDEQ BO already in this list? |
158 | * |
159 | * @param bo QEDEQ BO. |
160 | * @return Already in list? |
161 | */ |
162 | public boolean contains(final KernelQedeqBo bo) { |
163 | return props.contains(bo); |
164 | } |
165 | |
166 | /** |
167 | * Delete a given QEDEQ BO already from list. |
168 | * |
169 | * @param bo QEDEQ BO. |
170 | */ |
171 | public void remove(final KernelQedeqBo bo) { |
172 | int index; |
173 | while (0 <= (index = props.indexOf(bo))) { |
174 | final String label = (String) labels.get(index); |
175 | label2Context.remove(label); |
176 | props.remove(index); |
177 | labels.remove(index); |
178 | contexts.remove(index); |
179 | } |
180 | } |
181 | |
182 | public boolean equals(final Object obj) { |
183 | if (!(obj instanceof KernelModuleReferenceList)) { |
184 | return false; |
185 | } |
186 | final ModuleReferenceList otherList = (ModuleReferenceList) obj; |
187 | if (size() != otherList.size()) { |
188 | return false; |
189 | } |
190 | for (int i = 0; i < size(); i++) { |
191 | if (!EqualsUtility.equals(getLabel(i), otherList.getLabel(i)) |
192 | || !EqualsUtility.equals(getQedeqBo(i), |
193 | otherList.getQedeqBo(i))) { |
194 | return false; |
195 | } |
196 | } |
197 | return true; |
198 | } |
199 | |
200 | /** |
201 | * Empty reference list. |
202 | */ |
203 | public void clear() { |
204 | labels.clear(); |
205 | props.clear(); |
206 | contexts.clear(); |
207 | label2Context.clear(); |
208 | } |
209 | |
210 | /** |
211 | * Copy all list entry references of <code>list</code> to this instance. |
212 | * |
213 | * @param list Copy from here. |
214 | */ |
215 | public void set(final KernelModuleReferenceList list) { |
216 | clear(); |
217 | this.labels.addAll(list.labels); |
218 | this.props.addAll(list.props); |
219 | this.contexts.addAll(list.contexts); |
220 | this.label2Context.putAll(list.label2Context); |
221 | } |
222 | |
223 | public int hashCode() { |
224 | int hash = 0; |
225 | for (int i = 0; i < size(); i++) { |
226 | hash = hash ^ (i + 1); |
227 | if (getLabel(i) != null) { |
228 | hash = hash ^ getLabel(i).hashCode(); |
229 | hash = hash ^ getQedeqBo(i).hashCode(); |
230 | } |
231 | } |
232 | return hash; |
233 | } |
234 | |
235 | public String toString() { |
236 | final StringBuffer buffer = new StringBuffer("module reference list:\n"); |
237 | for (int i = 0; i < size(); i++) { |
238 | if (i != 0) { |
239 | buffer.append("\n"); |
240 | } |
241 | buffer.append((i + 1) + ":\t"); |
242 | buffer.append(getLabel(i)).append(": ").append(getQedeqBo(i)).append("\n"); |
243 | } |
244 | return buffer.toString(); |
245 | } |
246 | |
247 | } |