/* * #! * Ontopia Engine * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.utils.ctm; import java.util.Map; import java.util.Set; import java.util.List; import java.util.HashMap; import java.util.HashSet; import java.util.ArrayList; import net.ontopia.infoset.core.LocatorIF; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.xml.InvalidTopicMapException; /** * INTERNAL: Represents a CTM template. Contains a recorded list of * parse events which is replayed when the template is invoked. */ public class Template { private String name; private List<String> parameters; // just the names, in declared order private List events; private Map<String, NamedWildcardTopicGenerator> named_wildcards; /** * Each variable used in the template has a corresponding generator * stored here. On invocation, the invoke() method sets the passed * arguments in the generators stored here. The map is populated * from the declared list of parameters. */ private Map<String, ParameterGenerator> generators; /** * Each variable actually occurring in the template is listed here. * The map is populated by the getGenerator() method. */ private Set<String> used_parameters; public Template(String name, List<String> parameters) { this.name = name; this.parameters = parameters; this.events = new ArrayList(); this.generators = new HashMap<String, ParameterGenerator>(); this.named_wildcards = new HashMap<String, NamedWildcardTopicGenerator>(); this.used_parameters = new HashSet<String>(); for (String param : parameters) generators.put(param, new ParameterGenerator()); } public String getName() { return name; } public int getParameterCount() { return parameters.size(); } public Set<String> getUsedParameters() { return used_parameters; } public void addEvent(ParseEventIF event) { events.add(event); } public ValueGeneratorIF getGenerator(String name) { ValueGeneratorIF gen = generators.get(name); if (gen == null) throw new InvalidTopicMapException("No such parameter: " + name); used_parameters.add(name); return gen; } public Map<String, NamedWildcardTopicGenerator> getWildcardMap() { return named_wildcards; } /** * Invokes the template. * @param arguments a list of generator objects producing the values * for the arguments, in the same order as the * parameters list */ public void invoke(List arguments, ParseEventHandlerIF handler) { if (parameters.size() != arguments.size()) throw new InvalidTopicMapException("Incorrect number of arguments to " + "template " + name + ", got " + arguments.size() + ", expected " + parameters.size()); for (int ix = 0; ix < parameters.size(); ix++) { // name of parameter String name = parameters.get(ix); // generator producing passed argument value ValueGeneratorIF value = (ValueGeneratorIF) arguments.get(ix); // generator producing variable value inside invoked template ParameterGenerator generator = generators.get(name); // connecting parameter with its value generator.setGenerator(value); } for (int ix = 0; ix < events.size(); ix++) { ParseEventIF event = (ParseEventIF) events.get(ix); event.replay(handler); } // release all topics created by named wildcards so that on next // invocation we create new ones for (NamedWildcardTopicGenerator gen : named_wildcards.values()) gen.contextEnd(); } /** * This method is only used by the tolog INSERT statement. It is * <em>not</em> meant to be called during normal operation. If you * do, don't complain if it breaks. */ public void setParameters(List<String> parameters) { this.parameters = parameters; } // --- Parameter generator static class ParameterGenerator implements ValueGeneratorIF { private ValueGeneratorIF gen; public ParameterGenerator() { } public void setGenerator(ValueGeneratorIF gen) { this.gen = gen; } public boolean isTopic() { return gen.isTopic(); } public String getLiteral() { return gen.getLiteral(); } public LocatorIF getDatatype() { return gen.getDatatype(); } public LocatorIF getLocator() { return gen.getLocator(); } public ValueGeneratorIF copy() { return this; } public TopicIF getTopic() { return gen.getTopic(); } public String toString() { return "[ParameterGenerator: " + gen + "]"; } } }