ModuleLabels.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.HashMap;
019 import java.util.Map;
020 
021 import org.qedeq.kernel.bo.common.ModuleReferenceList;
022 import org.qedeq.kernel.se.base.module.ChangedRule;
023 import org.qedeq.kernel.se.base.module.FunctionDefinition;
024 import org.qedeq.kernel.se.base.module.PredicateDefinition;
025 import org.qedeq.kernel.se.base.module.Rule;
026 import org.qedeq.kernel.se.common.IllegalModuleDataException;
027 import org.qedeq.kernel.se.common.ModuleContext;
028 import org.qedeq.kernel.se.common.RuleKey;
029 import org.qedeq.kernel.se.dto.module.NodeVo;
030 import org.qedeq.kernel.se.visitor.QedeqNumbers;
031 
032 /**
033  * Maps labels of an QEDEQ module to their nodes. Knows all label names.
034  *
035  @author  Michael Meyling
036  */
037 public final class ModuleLabels {
038 
039     /** External QEDEQ module references. */
040     private ModuleReferenceList references = new KernelModuleReferenceList();
041 
042     /** Maps labels to business objects. */
043     private final Map label2Bo = new HashMap();
044 
045     /** Maps labels to context of business objects. */
046     private final Map label2Context = new HashMap();
047 
048     /** Maps predicate identifiers to {@link PredicateDefinition}s. */
049     private final Map predicateDefinitions = new HashMap();
050 
051     /** Maps predicate identifiers to {@link ModuleContext}s. */
052     private final Map predicateContexts = new HashMap();
053 
054     /** Maps function identifiers to {@link FunctionDefinition}s. */
055     private final Map functionDefinitions = new HashMap();
056 
057     /** Maps function identifiers to {@link ModuleContext}s. */
058     private final Map functionContexts = new HashMap();
059 
060     /** Maps rule names to maximum {@link RuleKey}s. (That is rule key with maximum version number). */
061     private final Map ruleMaximum = new HashMap();
062 
063     /** Maps rule keys to {@link Rule}s. */
064     private final Map ruleDefinitions = new HashMap();
065 
066     /** Maps rule keys to {@link ModuleContext}s. */
067     private final Map ruleContexts = new HashMap();
068 
069     /** Maps rule keys to labels. */
070     private final Map ruleLabels = new HashMap();
071 
072     /**
073      * Constructs a new empty module label list.
074      */
075     public ModuleLabels() {
076     }
077 
078     /**
079      * Set list of external QEDEQ module references.
080      *
081      @param   references  External QEDEQ module references.
082      */
083     public void setModuleReferences(final ModuleReferenceList references) {
084         this.references = references;
085     }
086 
087     /**
088      * Get list of external QEDEQ module references.
089      *
090      @return  External QEDEQ module references.
091      */
092     public ModuleReferenceList getReferences() {
093         return this.references;
094     }
095 
096     /**
097      * Add node with certain id. All numbers should start with 1.
098      *
099      @param   node        Add this node.
100      @param   context     The node has this context.
101      @param   qedeq       Parent module the node is within.
102      @param   data        Various number counters.
103      @throws  IllegalModuleDataException  The <code>id</code> already exists (perhaps as a label)
104      *          or is <code>null</code>.
105      */
106     public final void addNode(final ModuleContext context, final NodeVo node, final KernelQedeqBo qedeq,
107             final QedeqNumbers datathrows IllegalModuleDataException {
108         // don't forget to use the copy constructor because the context could change!
109         final ModuleContext con = new ModuleContext(context);
110         if (null == node.getId()) {
111             throw new IllegalModuleDataException(10001"An id was not defined.", con, null,
112                 null);  // LATER mime 20071026: organize exception codes
113         }
114         checkLabelIntern(con, node.getId());
115         label2Context.put(node.getId(), con);
116         final KernelNodeBo nodeBo = new KernelNodeBo(node, context, qedeq, data);
117         label2Bo.put(node.getId(), nodeBo);
118     }
119 
120     /**
121      * Add unique label for module.
122      *
123      @param   label   Add this label.
124      @param   context With this context.
125      @throws  IllegalModuleDataException  The <code>id</code> already exists or is <code>null</code>.
126      */
127     public final void addLabel(final ModuleContext context,  final String label)
128             throws IllegalModuleDataException {
129         // don't forget to use the copy constructor because the context could change!
130         final ModuleContext con = new ModuleContext(context);
131         checkLabelIntern(con, label);
132         label2Context.put(label, con);
133     }
134 
135     /**
136      * Check that label doesn't exist.
137      *
138      @param   label   Check this label.
139      @param   context With this context (already copied).
140      @throws  IllegalModuleDataException  The <code>id</code> already exists or is
141      *          <code>null</code>.
142      */
143     private final void checkLabelIntern(final ModuleContext context,  final String label)
144             throws IllegalModuleDataException {
145         if (label2Context.containsKey(label)) {
146             throw new IllegalModuleDataException(ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_CODE,
147                 ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_TEXT + "\"" + label + "\"",
148                 context, (ModuleContextlabel2Context.get(label)null);
149         }
150     }
151 
152     /**
153      * Get node for given id.
154      *
155      @param   id   Label to search node for.
156      @return  Node for given label. Maybe <code>null</code>.
157      */
158     public final KernelNodeBo getNode(final String id) {
159         return (KernelNodeBolabel2Bo.get(id);
160     }
161 
162     /**
163      * Is the given label id a node? Local node labels are not considered.
164      *
165      @param   id   Label to search node for.
166      @return  Is this an node of this module?
167      */
168     public final boolean isNode(final String id) {
169         return label2Bo.get(id!= null;
170     }
171 
172     /**
173      * Is the given label id a module?
174      *
175      @param   id   Label to search module reference for.
176      @return  Is this an module reference id?
177      */
178     public final boolean isModule(final String id) {
179         return label2Bo.get(id== null && label2Context.get(id!= null;
180     }
181 
182     /**
183      * Add predicate definition. If such a definition already exists it is overwritten.
184      *
185      @param   definition  Definition to add.
186      @param   context     Here the definition stands.
187      */
188     public void addPredicate(final PredicateDefinition definition, final ModuleContext context) {
189         final String identifier = definition.getName() "_" + definition.getArgumentNumber();
190         getPredicateDefinitions().put(identifier, definition);
191         predicateContexts.put(identifier, new ModuleContext(context));
192     }
193 
194     /**
195      * Get predicate definition.
196      *
197      @param   name            Predicate name.
198      @param   argumentNumber  Number of predicate arguments.
199      @return  Definition. Might be <code>null</code>.
200      */
201     public PredicateDefinition getPredicate(final String name, final int argumentNumber) {
202         return (PredicateDefinitiongetPredicateDefinitions().get(name + "_" + argumentNumber);
203     }
204 
205     /**
206      * Get predicate context. This is only a copy.
207      *
208      @param   name            Predicate name.
209      @param   argumentNumber  Number of predicate arguments.
210      @return  Module context. Might be <code>null</code>.
211      */
212     public ModuleContext getPredicateContext(final String name, final int argumentNumber) {
213         final ModuleContext context = (ModuleContextpredicateContexts.get(name + "_" + argumentNumber);
214         if (context != null) {
215             return new ModuleContext(context);
216         }
217         return null;
218     }
219 
220     /**
221      * Add function definition. If such a definition already exists it is overwritten.
222      *
223      @param   definition  Definition to add.
224      @param   context     Here the definition stands.
225      */
226     public void addFunction(final FunctionDefinition definition, final ModuleContext context) {
227         final String identifier = definition.getName() "_" + definition.getArgumentNumber();
228         getFunctionDefinitions().put(identifier, definition);
229         functionContexts.put(identifier, new ModuleContext(context));
230     }
231 
232     /**
233      * Get function definition.
234      *
235      @param   name            Function name.
236      @param   argumentNumber  Number of function arguments.
237      @return  Definition. Might be <code>null</code>.
238      */
239     public FunctionDefinition getFunction(final String name, final int argumentNumber) {
240         return (FunctionDefinitiongetFunctionDefinitions().get(name + "_" + argumentNumber);
241     }
242 
243     /**
244      * Get function context. This is only a copy.
245      *
246      @param   name            Function name.
247      @param   argumentNumber  Number of function arguments.
248      @return  Module context. Might be <code>null</code>.
249      */
250     public ModuleContext getFunctionContext(final String name, final int argumentNumber) {
251         final ModuleContext context = (ModuleContextfunctionContexts.get(name + "_" + argumentNumber);
252         if (context != null) {
253             return new ModuleContext(context);
254         }
255         return null;
256     }
257 
258     /**
259      * Add rule definition. If such a definition already exists it is overwritten. Also sets the
260      * key for the maximum rule version.
261      *
262      @param   label       Node label the rule is defined within.
263      @param   definition  Definition to add.
264      @param   context     Here the definition stands.
265      */
266     public void addRule(final String label, final Rule definition, final ModuleContext context) {
267         final RuleKey key = new RuleKey(definition.getName(), definition.getVersion());
268         ruleLabels.put(key, label);
269         final RuleKey oldMaximum = (RuleKeyruleMaximum.get(definition.getName());
270         if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
271                 && < key.getVersion().compareTo(oldMaximum.getVersion()))) {
272             ruleMaximum.put(definition.getName(), key);
273         }
274         getRuleDefinitions().put(key, definition);
275         ruleContexts.put(key, new ModuleContext(context));
276     }
277 
278     /**
279      * Add rule definition. If such a definition already exists it is overwritten. Also sets the
280      * key for the maximum rule version.
281      *
282      @param   label       Node label the rule is defined within.
283      @param   definition  Here we have the new rule.
284      @param   cr          New modification to an old rule.
285      @param   context     Here the definition stands.
286      */
287     public void addChangedRule(final String label, final Rule definition, final ChangedRule cr,
288             final ModuleContext context) {
289         final RuleKey key = new RuleKey(cr.getName(), cr.getVersion());
290         ruleLabels.put(key, label);
291         final RuleKey oldMaximum = (RuleKeyruleMaximum.get(cr.getName());
292         if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
293                 && < key.getVersion().compareTo(oldMaximum.getVersion()))) {
294             ruleMaximum.put(cr.getName(), key);
295         }
296         getRuleDefinitions().put(key, definition);
297         ruleContexts.put(key, new ModuleContext(context));
298     }
299 
300     /**
301      * Get rule key with maximum rule version.
302      *
303      @param   ruleName    Get maximum rule key for rule with this name.
304      @return  Rule key with maximum rule version. Might be <code>null</code>.
305      */
306     public RuleKey getRuleKey(final String ruleName) {
307         return (RuleKeyruleMaximum.get(ruleName);
308     }
309 
310     /**
311      * Get rule definition.
312      *
313      @param   key            Rule key.
314      @return  Definition. Might be <code>null</code>.
315      */
316     public Rule getRule(final RuleKey key) {
317         return (RulegetRuleDefinitions().get(key);
318     }
319 
320     /**
321      * Get node id of rule key.
322      *
323      @param   key            Rule key.
324      @return  Label. Might be <code>null</code>.
325      */
326     public String getRuleLabel(final RuleKey key) {
327         return (StringruleLabels.get(key);
328     }
329 
330     /**
331      * Get rule context. This is only a copy.
332      *
333      @param   key            Rule key.
334      @return  Module context. Might be <code>null</code>.
335      */
336     public ModuleContext getRuleContext(final RuleKey key) {
337         final ModuleContext context = (ModuleContextruleContexts.get(key);
338         if (context != null) {
339             return new ModuleContext(context);
340         }
341         return null;
342     }
343 
344     /**
345      * Get mapping of predicate definitions.
346      *
347      @return  Mapping of predicate definitions.
348      */
349     public Map getPredicateDefinitions() {
350         return this.predicateDefinitions;
351     }
352 
353     /**
354      * Get mapping of function definitions.
355      *
356      @return  Mapping of function definitions.
357      */
358     public Map getFunctionDefinitions() {
359         return this.functionDefinitions;
360     }
361 
362     /**
363      * Get mapping of rule definitions.
364      *
365      @return  Mapping of rule definitions. Key is {@link RuleKey}, value is {@link Rule}.
366      */
367     public Map getRuleDefinitions() {
368         return this.ruleDefinitions;
369     }
370 
371 }