/*
* #!
* 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.List;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.utils.OntopiaRuntimeException;
import net.ontopia.topicmaps.xml.InvalidTopicMapException;
/**
* INTERNAL: An event handler which produces a template object,
* containing recorded events ready to be replayed when the template
* is invoked.
*/
public class TemplateEventHandler implements ParseEventHandlerIF {
private Template template;
public TemplateEventHandler(String name, List<String> parameters,
ParseEventHandlerIF real_handler) {
this.template = new Template(name, parameters);
}
// --- ParseEventHandlerIF implementation
public void startTopicItemIdentifier(ValueGeneratorIF loc) {
template.addEvent(new GenericParseEvent("startTopicItemIdentifier", loc));
}
public void startTopicSubjectIdentifier(ValueGeneratorIF loc) {
template.addEvent(new GenericParseEvent("startTopicSubjectIdentifier", loc));
}
public void startTopicSubjectLocator(ValueGeneratorIF loc) {
template.addEvent(new GenericParseEvent("startTopicSubjectLocator", loc));
}
public void startTopic(ValueGeneratorIF topicgen) {
template.addEvent(new GenericParseEvent("startTopic", topicgen));
}
public void addItemIdentifier(ValueGeneratorIF locator) {
template.addEvent(new GenericParseEvent("addItemIdentifier", locator));
}
public void addSubjectIdentifier(ValueGeneratorIF locator) {
template.addEvent(new GenericParseEvent("addSubjectIdentifier", locator));
}
public void addSubjectLocator(ValueGeneratorIF locator) {
template.addEvent(new GenericParseEvent("addSubjectLocator", locator));
}
public void addTopicType(ValueGeneratorIF type) {
template.addEvent(new GenericParseEvent("addTopicType", type));
}
public void addSubtype(ValueGeneratorIF subtype) {
template.addEvent(new GenericParseEvent("addSubtype", subtype));
}
public void startName(ValueGeneratorIF type, ValueGeneratorIF value) {
template.addEvent(new GenericParseEvent("startName", type, value));
}
public void addScopingTopic(ValueGeneratorIF topic) {
template.addEvent(new GenericParseEvent("addScopingTopic", topic));
}
public void addReifier(ValueGeneratorIF topic) {
template.addEvent(new GenericParseEvent("addReifier", topic));
}
public void startVariant(ValueGeneratorIF value) {
template.addEvent(new GenericParseEvent("startVariant", value));
}
public void endName() {
template.addEvent(new GenericParseEvent("endName"));
}
public void startOccurrence(ValueGeneratorIF type, ValueGeneratorIF value) {
template.addEvent(new GenericParseEvent("startOccurrence", type, value));
}
public void endOccurrence() {
template.addEvent(new GenericParseEvent("endOccurrence"));
}
public void endTopic() {
template.addEvent(new GenericParseEvent("endTopic"));
}
public void startAssociation(ValueGeneratorIF type) {
template.addEvent(new GenericParseEvent("startAssociation", type));
}
public void addRole(ValueGeneratorIF type, ValueGeneratorIF player) {
template.addEvent(new GenericParseEvent("addRole", type, player));
}
public void endRoles() {
template.addEvent(new GenericParseEvent("endRoles"));
}
public void endAssociation() {
template.addEvent(new GenericParseEvent("endAssociation"));
}
public void startEmbeddedTopic() {
template.addEvent(new GenericParseEvent("startEmbeddedTopic"));
}
public ValueGeneratorIF endEmbeddedTopic() {
GenericParseEvent event = new GenericParseEvent("endEmbeddedTopic");
template.addEvent(event);
return new EventTopicGenerator(event);
}
public void templateInvocation(String name, List arguments) {
template.addEvent(new GenericParseEvent("templateInvocation",
name, arguments));
}
// --- Own methods
public Template getTemplate() {
return template;
}
// --- Event class
class GenericParseEvent implements ParseEventIF {
private Method method;
private Object[] parameters;
private Object value;
public GenericParseEvent(String method_name) {
this.method = getMethod(method_name);
this.parameters = null;
}
public GenericParseEvent(String method_name, Object parameter) {
this.method = getMethod(method_name);
this.parameters = new Object[1];
parameters[0] = copy(parameter);
}
public GenericParseEvent(String method_name, Object p1, Object p2) {
this.method = getMethod(method_name);
this.parameters = new Object[2];
parameters[0] = copy(p1);
parameters[1] = copy(p2);
}
public void replay(ParseEventHandlerIF handler) throws InvalidTopicMapException {
try {
value = method.invoke(handler, parameters);
} catch (IllegalAccessException e) {
throw new OntopiaRuntimeException(e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof InvalidTopicMapException)
throw (InvalidTopicMapException) e.getCause();
throw new OntopiaRuntimeException(e.getCause());
}
}
public Object getValue() {
return value;
}
private Method getMethod(String name) {
Method[] methods = ParseEventHandlerIF.class.getMethods();
for (int ix = 0; ix < methods.length; ix++)
if (methods[ix].getName().equals(name))
return methods[ix];
return null;
}
private Object copy(Object parameter) {
if (parameter instanceof ValueGeneratorIF)
return ((ValueGeneratorIF) parameter).copy();
else
return parameter;
}
}
// --- EventTopicGenerator
class EventTopicGenerator extends AbstractTopicGenerator {
private GenericParseEvent event;
public EventTopicGenerator(GenericParseEvent event) {
this.event = event;
}
public TopicIF getTopic() {
ValueGeneratorIF gen = (ValueGeneratorIF) event.getValue();
return gen.getTopic();
}
public ValueGeneratorIF copy() {
return this;
}
}
}