KernelModuleReferenceList.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  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 propthrows 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                 (ModuleContextlabel2Context.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 (Stringlabels.get(index);
114     }
115 
116     public QedeqBo getQedeqBo(final int index) {
117         return (QedeqBoprops.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 (KernelQedeqBoprops.get(index);
128     }
129 
130     public ModuleContext getModuleContext(final int index) {
131         return (ModuleContextcontexts.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 (QedeqBoprops.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 (KernelQedeqBoprops.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 (<= (index = props.indexOf(bo))) {
174             final String label = (Stringlabels.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 = (ModuleReferenceListobj;
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 }