001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2011, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.module;
017
018 import java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 import org.qedeq.base.trace.Trace;
024 import org.qedeq.base.utility.EqualsUtility;
025 import org.qedeq.kernel.bo.common.ModuleReferenceList;
026 import org.qedeq.kernel.bo.common.QedeqBo;
027 import org.qedeq.kernel.se.common.IllegalModuleDataException;
028 import org.qedeq.kernel.se.common.ModuleContext;
029
030
031 /**
032 * Represents a reference list of modules. Every entry has a symbolic name for one referenced QEDEQ
033 * module. This module label acts as a prefix for all references to that module. The module label
034 * must be an unique String.
035 *
036 * @author Michael Meyling
037 */
038 public class KernelModuleReferenceList implements ModuleReferenceList {
039
040 /** This class. */
041 private static final Class CLASS = KernelModuleReferenceList.class;
042
043 /** Contains all labels. */
044 private final List labels;
045
046 /** Contains all module props. */
047 private final List props;
048
049 /** Contains all module import contexts. */
050 private final List contexts;
051
052 /** Maps labels to context. */
053 private final Map label2Context;
054
055 /**
056 * Constructs an empty list of module references.
057 */
058 public KernelModuleReferenceList() {
059 labels = new ArrayList();
060 props = new ArrayList();
061 contexts = new ArrayList();
062 label2Context = new HashMap();
063 }
064
065 /**
066 * Add module reference to list.
067 *
068 * @param context Within this context.
069 * @param label Referenced module gets this label. Must not be <code>null</code> or empty.
070 * @param prop Referenced module has this properties. Must not be <code>null</code>.
071 * @throws IllegalModuleDataException The <code>label</code> is empty or <code>null</code>.
072 */
073 public void add(final ModuleContext context, final String label, final QedeqBo prop)
074 throws IllegalModuleDataException {
075 if (label == null || label.length() <= 0) {
076 throw new IllegalModuleDataException(10003, "An label was not defined.",
077 new ModuleContext(context), null,
078 null); // LATER mime 20071026: organize exception codes
079 }
080 final ModuleContext con = new ModuleContext(context);
081 labels.add(label);
082 label2Context.put(label, con);
083 contexts.add(con);
084 Trace.param(CLASS, "add(ModuleContext, String, QedeqBo)", "context", con);
085 props.add(prop);
086 }
087
088 /**
089 * Add module reference to list.
090 *
091 * @param context Within this context.
092 * @param label Referenced module gets this label. Must not be <code>null</code> or empty.
093 * @param prop Referenced module has this properties. Must not be <code>null</code>.
094 * @throws IllegalModuleDataException The <code>id</code> already exists or is
095 * <code>null</code>. Also if <code>label</code> is empty or <code>null</code>.
096 */
097 public void addLabelUnique(final ModuleContext context, final String label,
098 final QedeqBo prop) throws IllegalModuleDataException {
099 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 }
|