ModuleLabels.java
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.HashMap;
019 import java.util.Map;
020 
021 import org.qedeq.kernel.bo.common.ModuleReferenceList;
022 import org.qedeq.kernel.se.base.module.FunctionDefinition;
023 import org.qedeq.kernel.se.base.module.PredicateDefinition;
024 import org.qedeq.kernel.se.common.IllegalModuleDataException;
025 import org.qedeq.kernel.se.common.ModuleContext;
026 import org.qedeq.kernel.se.dto.module.NodeVo;
027 import org.qedeq.kernel.se.visitor.QedeqNumbers;
028 
029 /**
030  * Maps labels of an QEDEQ module to their nodes. Knows all label names.
031  *
032  @author  Michael Meyling
033  */
034 public final class ModuleLabels {
035 
036     /** External QEDEQ module references. */
037     private ModuleReferenceList references = new KernelModuleReferenceList();
038 
039     /** Maps labels to business objects. */
040     private final Map label2Bo;
041 
042     /** Maps labels to context of business objects. */
043     private final Map label2Context;
044 
045     /** Maps predicate identifiers to {@link PredicateDefinition}s. */
046     private final Map predicateDefinitions = new HashMap();
047 
048     /** Maps predicate identifiers to {@link ModuleContext}s. */
049     private final Map predicateContexts = new HashMap();
050 
051     /** Maps function identifiers to {@link FunctionDefinition}s. */
052     private final Map functionDefinitions = new HashMap();
053 
054     /** Maps predicate identifiers to {@link ModuleContext}s. */
055     private final Map functionContexts = new HashMap();
056 
057     /**
058      * Constructs a new empty module label list.
059      */
060     public ModuleLabels() {
061         label2Bo = new HashMap();
062         label2Context = new HashMap();
063     }
064 
065     /**
066      * Set list of external QEDEQ module references.
067      *
068      @param   references  External QEDEQ module references.
069      */
070     public void setModuleReferences(final ModuleReferenceList references) {
071         this.references = references;
072     }
073 
074     /**
075      * Get list of external QEDEQ module references.
076      *
077      @return  External QEDEQ module references.
078      */
079     public ModuleReferenceList getReferences() {
080         return this.references;
081     }
082 
083     /**
084      * Add node with certain id. All numbers should start with 1.
085      *
086      @param   node        Add this node.
087      @param   context     The node has this context.
088      @param   qedeq       Parent module the node is within.
089      @param   data        Various number counters.
090      @throws  IllegalModuleDataException  The <code>id</code> already exists (perhaps as a label)
091      *          or is <code>null</code>.
092      */
093     public final void addNode(final ModuleContext context, final NodeVo node, final KernelQedeqBo qedeq,
094             final QedeqNumbers datathrows IllegalModuleDataException {
095         // don't forget to use the copy constructor because the context could change!
096         final ModuleContext con = new ModuleContext(context);
097         if (null == node.getId()) {
098             throw new IllegalModuleDataException(10001"An id was not defined.", con, null,
099                 null);  // LATER mime 20071026: organize exception codes
100         }
101         checkLabelIntern(con, node.getId());
102         label2Context.put(node.getId(), con);
103         final KernelNodeBo nodeBo = new KernelNodeBo(node, context, qedeq, data);
104         label2Bo.put(node.getId(), nodeBo);
105     }
106 
107     /**
108      * Add unique label for module.
109      *
110      @param   label   Add this label.
111      @param   context With this context.
112      @throws  IllegalModuleDataException  The <code>id</code> already exists or is <code>null</code>.
113      */
114     public final void addLabel(final ModuleContext context,  final String label)
115             throws IllegalModuleDataException {
116         // don't forget to use the copy constructor because the context could change!
117         final ModuleContext con = new ModuleContext(context);
118         checkLabelIntern(con, label);
119         label2Context.put(label, con);
120     }
121 
122     /**
123      * Check that label doesn't exist.
124      *
125      @param   label   Check this label.
126      @param   context With this context (already copied).
127      @throws  IllegalModuleDataException  The <code>id</code> already exists or is
128      *          <code>null</code>.
129      */
130     private final void checkLabelIntern(final ModuleContext context,  final String label)
131             throws IllegalModuleDataException {
132         if (label2Context.containsKey(label)) {
133             throw new IllegalModuleDataException(ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_CODE,
134                 ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_TEXT + "\"" + label + "\"",
135                 context, (ModuleContextlabel2Context.get(label)null);
136         }
137     }
138 
139     /**
140      * Get node for given id.
141      *
142      @param   id   Label to search node for.
143      @return  Node for given label. Maybe <code>null</code>.
144      */
145     public final KernelNodeBo getNode(final String id) {
146         return (KernelNodeBolabel2Bo.get(id);
147     }
148 
149     /**
150      * Is the given label id a node? Local node labels are not considered.
151      *
152      @param   id   Label to search node for.
153      @return  Is this an node of this module?
154      */
155     public final boolean isNode(final String id) {
156         return label2Bo.get(id!= null;
157     }
158 
159     /**
160      * Is the given label id a module?
161      *
162      @param   id   Label to search module reference for.
163      @return  Is this an module reference id?
164      */
165     public final boolean isModule(final String id) {
166         return label2Bo.get(id== null && label2Context.get(id!= null;
167     }
168 
169     /**
170      * Add predicate definition. If such a definition already exists it is overwritten.
171      *
172      @param   definition  Definition to add.
173      @param   context     Here the definition stands.
174      */
175     public void addPredicate(final PredicateDefinition definition, final ModuleContext context) {
176         final String identifier = definition.getName() "_" + definition.getArgumentNumber();
177         getPredicateDefinitions().put(identifier, definition);
178         predicateContexts.put(identifier, new ModuleContext(context));
179     }
180 
181     /**
182      * Get predicate definition.
183      *
184      @param   name            Predicate name.
185      @param   argumentNumber  Number of predicate arguments.
186      @return  Definition. Might be <code>null</code>.
187      */
188     public PredicateDefinition getPredicate(final String name, final int argumentNumber) {
189         return (PredicateDefinitiongetPredicateDefinitions().get(name + "_" + argumentNumber);
190     }
191 
192     /**
193      * Get predicate context. This is only a copy.
194      *
195      @param   name            Predicate name.
196      @param   argumentNumber  Number of predicate arguments.
197      @return  Module context. Might be <code>null</code>.
198      */
199     public ModuleContext getPredicateContext(final String name, final int argumentNumber) {
200         return new ModuleContext((ModuleContextpredicateContexts.get(name + "_" + argumentNumber));
201     }
202 
203     /**
204      * Add function definition. If such a definition already exists it is overwritten.
205      *
206      @param   definition  Definition to add.
207      @param   context     Here the definition stands.
208      */
209     public void addFunction(final FunctionDefinition definition, final ModuleContext context) {
210         final String identifier = definition.getName() "_" + definition.getArgumentNumber();
211         getFunctionDefinitions().put(identifier, definition);
212         functionContexts.put(identifier, new ModuleContext(context));
213     }
214 
215     /**
216      * Get function definition.
217      *
218      @param   name            Function name.
219      @param   argumentNumber  Number of function arguments.
220      @return  Definition. Might be <code>null</code>.
221      */
222     public FunctionDefinition getFunction(final String name, final int argumentNumber) {
223         return (FunctionDefinitiongetFunctionDefinitions().get(name + "_" + argumentNumber);
224     }
225 
226     /**
227      * Get function context. This is only a copy.
228      *
229      @param   name            Function name.
230      @param   argumentNumber  Number of function arguments.
231      @return  Module context. Might be <code>null</code>.
232      */
233     public ModuleContext getFunctionContext(final String name, final int argumentNumber) {
234         return new ModuleContext((ModuleContextfunctionContexts.get(name + "_" + argumentNumber));
235     }
236 
237     /**
238      * Get mapping of predicate definitions.
239      *
240      @return  Mapping of predicate definitions.
241      */
242     public Map getPredicateDefinitions() {
243         return this.predicateDefinitions;
244     }
245 
246     /**
247      * Get mapping of function definitions.
248      *
249      @return  Mapping of function definitions.
250      */
251     public Map getFunctionDefinitions() {
252         return this.functionDefinitions;
253     }
254 
255 }