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 data) throws 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, (ModuleContext) label2Context.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 (KernelNodeBo) label2Bo.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 (PredicateDefinition) getPredicateDefinitions().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 = (ModuleContext) predicateContexts.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 (FunctionDefinition) getFunctionDefinitions().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 = (ModuleContext) functionContexts.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 = (RuleKey) ruleMaximum.get(definition.getName());
271 if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
272 && 0 < 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 = (RuleKey) ruleMaximum.get(cr.getName());
293 if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
294 && 0 < 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 (RuleKey) ruleMaximum.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 (Rule) getRuleDefinitions().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 (String) ruleLabels.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 = (ModuleContext) ruleContexts.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 }
|