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