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