View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">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 }