
org.ow2.mind.adl.ast.ASTHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of adl-frontend Show documentation
Show all versions of adl-frontend Show documentation
Front-end components for the ADL language of the Mind programming model.
The newest version!
/**
* Copyright (C) 2009 STMicroelectronics
*
* This file is part of "Mind Compiler" is free software: you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Contact: [email protected]
*
* Authors: Matthieu Leclercq
* Contributors:
*/
package org.ow2.mind.adl.ast;
import static java.lang.Integer.parseInt;
import static org.ow2.mind.CommonASTHelper.newNode;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.fractal.adl.ADLException;
import org.objectweb.fractal.adl.Definition;
import org.objectweb.fractal.adl.Loader;
import org.objectweb.fractal.adl.Node;
import org.objectweb.fractal.adl.NodeFactory;
import org.objectweb.fractal.adl.interfaces.Interface;
import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
import org.objectweb.fractal.adl.types.TypeInterface;
import org.objectweb.fractal.api.control.BindingController;
import org.ow2.mind.NodeContainerDecoration;
import org.ow2.mind.PathHelper;
import org.ow2.mind.adl.annotation.predefined.Singleton;
import org.ow2.mind.adl.generic.ast.FormalTypeParameterContainer;
import org.ow2.mind.adl.generic.ast.TypeArgumentContainer;
import org.ow2.mind.adl.parameter.ast.ArgumentContainer;
import org.ow2.mind.adl.parameter.ast.FormalParameterContainer;
import org.ow2.mind.annotation.AnnotationHelper;
/**
* Helper methods for ADL AST nodes.
*/
public class ASTHelper {
protected ASTHelper() {
}
// ---------------------------------------------------------------------------
// Definition helper methods
// ---------------------------------------------------------------------------
/**
* Returns true
if the given definition is a type definition.
*
* @param def a definition.
* @return true
if the given definition is a type definition.
*/
public static boolean isType(final Definition def) {
return !isPrimitive(def) && !isComposite(def);
}
/**
* Returns true
if the given definition is a primitive
* definition.
*
* @param def a definition.
* @return true
if the given definition is a primitive
* definition.
*/
public static boolean isPrimitive(final Definition def) {
return def instanceof ImplementationContainer;
}
/**
* Returns true
if the given definition is a composite
* definition.
*
* @param def a definition.
* @return true
if the given definition is a composite
* definition.
*/
public static boolean isComposite(final Definition def) {
return def instanceof ComponentContainer;
}
/**
* The name of the decoration used to indicate if a definition is singleton.
* This decoration should only be used by StringTemplate.
*/
public static final String SINGLETON_DECORATION_NAME = "is-singleton";
/**
* Returns true
if the given definition has the {@link Singleton}
* decoration.
*
* @param def a definition.
* @return true
if the given definition has the {@link Singleton}
* decoration.
*/
public static boolean isSingleton(final Definition def) {
return AnnotationHelper.getAnnotation(def, Singleton.class) != null;
}
/**
* Sets the {@value #SINGLETON_DECORATION_NAME} decoration to
* true
on the given definition.
*
* @param def a definition.
*/
public static void setSingletonDecoration(final Definition def) {
def.astSetDecoration(SINGLETON_DECORATION_NAME, Boolean.TRUE);
}
/**
* Returns a new {@link Definition} that correspond to a definition of
* primitive component.
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @param name the {@link Definition#getName() name} of the definition.
* @param extended references to the extended definitions (may be
* null
).
* @return a new {@link Definition} that correspond to a definition of
* primitive component.
*/
public static Definition newPrimitiveDefinitionNode(
final NodeFactory nodeFactory, final String name,
final DefinitionReference... extended) {
final MindDefinition d = newNode(nodeFactory, "primitive",
MindDefinition.class, AbstractDefinition.class,
InterfaceContainer.class, AttributeContainer.class,
ImplementationContainer.class, FormalParameterContainer.class);
d.setName(name);
if (extended != null && extended.length > 0) {
final DefinitionReferenceContainer extendz = newNode(nodeFactory,
"extends", DefinitionReferenceContainer.class);
for (final DefinitionReference ext : extended) {
extendz.addDefinitionReference(ext);
}
d.setExtends(extendz);
}
return d;
}
/**
* Returns a new {@link Definition} that correspond to a definition of
* composite component.
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @param name the {@link Definition#getName() name} of the definition.
* @param extended references to the extended definitions (may be
* null
).
* @return a new {@link Definition} that correspond to a definition of
* primitive component.
*/
public static Definition newCompositeDefinitionNode(
final NodeFactory nodeFactory, final String name,
final DefinitionReference... extended) {
final MindDefinition d = newNode(nodeFactory, "primitive",
MindDefinition.class, InterfaceContainer.class,
ComponentContainer.class, BindingController.class,
FormalParameterContainer.class, FormalTypeParameterContainer.class);
d.setName(name);
if (extended != null && extended.length > 0) {
final DefinitionReferenceContainer extendz = newNode(nodeFactory,
"extends", DefinitionReferenceContainer.class);
for (final DefinitionReference ext : extended) {
extendz.addDefinitionReference(ext);
}
d.setExtends(extendz);
}
return d;
}
/**
* Returns a new {@link Definition} that correspond to an unresolved
* definition. This kind of definition node can be used as a return value of
* front-end components that must return a definition but was unable to load
* it.
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @param name the {@link Definition#getName() name} of the definition.
* @return a new {@link Definition} that correspond to an unresolved
* definition.
* @see #isUnresolvedDefinitionNode(Definition)
*/
public static Definition newUnresolvedDefinitionNode(
final NodeFactory nodeFactory, final String name) {
final MindDefinition d = newNode(nodeFactory, "unresolved",
MindDefinition.class);
d.setName(name);
return d;
}
/**
* Returns true
if the given {@link Definition} does not
* correspond to a correct definition, but has been created by
* {@link #newUnresolvedDefinitionNode(NodeFactory, String)}.
*
* @param d a definition node.
* @return true
if the given {@link Definition} correspond to an
* unresolved definition.
* @see #newUnresolvedDefinitionNode(NodeFactory, String)
*/
public static boolean isUnresolvedDefinitionNode(final Definition d) {
return d.astGetType().equals("unresolved");
}
// ---------------------------------------------------------------------------
// Interface helper methods
// ---------------------------------------------------------------------------
/**
* Returns the integer value of the {@link MindInterface#getNumberOfElement()
* numberOfElement} field of the given interface node.
*
* @param itf an {@link Interface} node.
* @return the integer value of the {@link MindInterface#getNumberOfElement()
* numberOfElement} field of the given interface node, or
* -1
if the given interface does not have a
* numberOfElement field.
*/
public static int getNumberOfElement(final Interface itf) {
if (!(itf instanceof MindInterface)) return -1;
final String noe = ((MindInterface) itf).getNumberOfElement();
if (noe == null)
return -1;
else
return parseInt(noe);
}
/**
* Returns the interface node contained by the given container and having the
* given name.
*
* @param itfContainer a container.
* @param name the name of the interface to return.
* @return the interface node contained by the given container and having the
* given name, or null
if the given container is not an
* {@link InterfaceContainer} or does not contain an interface with
* the given name.
*/
public static Interface getInterface(final Node itfContainer,
final String name) {
if (!(itfContainer instanceof InterfaceContainer)) return null;
for (final Interface itf : ((InterfaceContainer) itfContainer)
.getInterfaces()) {
if (name.equals(itf.getName())) return itf;
}
return null;
}
/**
* Create a new {@link MindInterface} node using the given {@link NodeFactory}
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @return a new {@link MindInterface} node.
*/
public static MindInterface newInterfaceNode(final NodeFactory nodeFactory) {
return newNode(nodeFactory, "interface", MindInterface.class);
}
/**
* Create a new client {@link MindInterface} node using the given
* {@link NodeFactory}
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @param name the name of the created interface.
* @param signature the signature of the created interface.
* @return a new {@link MindInterface} node.
*/
public static MindInterface newClientInterfaceNode(
final NodeFactory nodeFactory, final String name, final String signature) {
final MindInterface itf = newInterfaceNode(nodeFactory);
itf.setRole(TypeInterface.CLIENT_ROLE);
itf.setName(name);
itf.setSignature(signature);
return itf;
}
/**
* Create a new server {@link MindInterface} node using the given
* {@link NodeFactory}
*
* @param nodeFactory the {@link NodeFactory} to use to create the node.
* @param name the name of the created interface.
* @param signature the signature of the created interface.
* @return a new {@link MindInterface} node.
*/
public static MindInterface newServerInterfaceNode(
final NodeFactory nodeFactory, final String name, final String signature) {
final MindInterface itf = newInterfaceNode(nodeFactory);
itf.setRole(TypeInterface.SERVER_ROLE);
itf.setName(name);
itf.setSignature(signature);
return itf;
}
// ---------------------------------------------------------------------------
// Flow Interface helper methods
// ---------------------------------------------------------------------------
/**
* The {@link TypeInterface#getRole() role} of 'input' data-flow interface.
*/
public static final String INPUT_ROLE = "input";
/**
* The {@link TypeInterface#getRole() role} of 'output' data-flow interface.
*/
public static final String OUTPUT_ROLE = "output";
/**
* Returns true
if the given interface is a flow interface (i.e.
* if its {@link TypeInterface#getRole() role} is either {@link #INPUT_ROLE}
* or {@link #OUTPUT_ROLE}).
*
* @param itf an interface.
* @return true
if the given interface is a flow interface.
*/
public static boolean isFlowInterface(final Interface itf) {
if (!(itf instanceof TypeInterface)) return false;
final String role = ((TypeInterface) itf).getRole();
return (INPUT_ROLE.equals(role) || OUTPUT_ROLE.equals(role));
}
/**
* Returns true
if the given interface is an output flow
* interface (i.e. if its {@link TypeInterface#getRole() role} is
* {@link #OUTPUT_ROLE}).
*
* @param itf an interface.
* @return true
if the given interface is an output flow
* interface.
*/
public static boolean isOutput(final Interface itf) {
if (!(itf instanceof TypeInterface)) return false;
final String role = ((TypeInterface) itf).getRole();
return OUTPUT_ROLE.equals(role);
}
/**
* Returns true
if the given interface is an input flow interface
* (i.e. if its {@link TypeInterface#getRole() role} is {@link #INPUT_ROLE}).
*
* @param itf an interface.
* @return true
if the given interface is an input flow
* interface.
*/
public static boolean isInput(final Interface itf) {
if (!(itf instanceof TypeInterface)) return false;
final String role = ((TypeInterface) itf).getRole();
return INPUT_ROLE.equals(role);
}
// ---------------------------------------------------------------------------
// DefinitionReference helper methods
// ---------------------------------------------------------------------------
/**
* The name of the {@link Node#astSetDecoration(String, Object) decoration}
* used to attach the resolved {@link Definition} to a
* {@link DefinitionReference}.
*
* @see #setResolvedDefinition(DefinitionReference, Definition)
* @see #getResolvedDefinition(DefinitionReference, Loader, Map)
*/
public static final String RESOLVED_DEFINITION_DECORATION_NAME = "resolved-definition";
/**
* Sets the resolved {@link Definition} corresponding to the given
* {@link DefinitionReference}. The decoration that is actually attached to
* the given defRef
node is an instance of
* {@link DefinitionDecoration}. This imply that, if the defRef
* is serialized, only the {@link Definition#getName() name} of the definition
* is serialized (and not the definition AST).
*
* @param defRef a definition reference.
* @param resolvedDef the corresponding definition.
* @see #getResolvedDefinition(DefinitionReference, Loader, Map)
*/
public static void setResolvedDefinition(final DefinitionReference defRef,
final Definition resolvedDef) {
defRef.astSetDecoration(RESOLVED_DEFINITION_DECORATION_NAME,
new DefinitionDecoration(resolvedDef));
}
/**
* Removes the resolved {@link Definition} on the given
* {@link DefinitionReference}.
*
* @param defRef a definition reference.
*/
public static void unsetResolvedDefinition(final DefinitionReference defRef) {
defRef.astSetDecoration(RESOLVED_DEFINITION_DECORATION_NAME, null);
}
/**
* Retrieve the {@link Definition} corresponding to the given
* {@link DefinitionReference}. Returns null
, if the given
* defRef
node has no
* {@link #RESOLVED_DEFINITION_DECORATION_NAME} decoration. If the decoration
* attached to the given defRef
node contains only the definition
* name and not the definition AST (i.e. the defRef
node has been
* de-serialized), the given loaderItf
is used to load the
* corresponding definition.
*
* @param defRef a definition reference.
* @param loaderItf a {@link Loader} interface that is used if only the name
* of the definition is attached (and not the definition AST). May be
* null
.
* @param context additional parameters. Used only if only the name of the
* definition is attached (and not the definition AST). May be
* null
.
* @return the {@link Definition} corresponding to the given
* {@link DefinitionReference} or null
, if the given
* defRef
node has no
* {@link #RESOLVED_DEFINITION_DECORATION_NAME} decoration or if only
* the name of the definition is attached and loaderItf
* is null
.
* @throws ADLException if an error occurs while
* {@link Loader#load(String, Map) loading} the definition using the
* given loaderItf
.
*/
public static Definition getResolvedDefinition(
final DefinitionReference defRef, final Loader loaderItf,
final Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy