/** * <copyright> * * Copyright (c) 2008,2010 E.D.Willink and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * E.D.Willink - initial API and implementation * * </copyright> * * $Id: CommonASTVisitor.java,v 1.2 2010/04/08 06:26:14 ewillink Exp $ */ package org.eclipse.ocl.examples.parser.utils; import java.util.Collection; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.ocl.examples.common.plugin.OCLExamplesCommonPlugin; /** * CommonCSTVisitor defines a default visitor to an Ecore * (EObject or Resource or ResourceSet) AST using EObject.eContents(), * Resource.getContents(), ResourceSet.getResources() to perform tree descent. */ public abstract class CommonASTVisitor<T, N> implements ICommonASTVisitor<T, N> { protected final Class<N> nodeClass; protected T result = null; /** * Construct a visit for a tree of objects that subtype nodeClass. */ protected CommonASTVisitor(Class<N> nodeClass) { this.nodeClass = nodeClass; } /** * Perform the visit of object. * <br> * The default implementation returns the result of invoking visit, if the * object satisfies the node class predicate, or unexpectedVisit if not. */ public T enter(Object object) { if (object == null) return null; else if (nodeClass.isAssignableFrom(object.getClass())) { @SuppressWarnings("unchecked") N astNode = (N) object; return visit(astNode); } else if (object instanceof Collection<?>) { Collection<?> collection = (Collection<?>)object; return enterCollection(collection); } else return unexpectedVisit(object); } /** * Perform the visit to an object that procvers to a Collection rather * than an N as contracted. * <br> * The default implementation invokes unexpectedVisit. */ protected T enterCollection(Collection<?> collection) { return unexpectedVisit(collection); } /** * Perform any post-order activity at the end of a visit to astNode. * Return the visit result. * <br> * Default result is returned from the result field. */ protected T postVisit(N astNode) { return result; } /** * Perform any pre-order activity at the start of a visit to astNode. * Return true to continue with the visit, false to inhibit the * visit to astNode and its children. * <br> * Default implementation returns true. */ protected boolean preVisit(N astNode) { return true; } /** * Perform any activity associated with visiting an astNode that does * not satisfy the AST tree node type predicate. * <br> * Default logs an error. */ protected T unexpectedVisit(Object astNode) { OCLExamplesCommonPlugin.logError("Unexpected visit to a '" + astNode.getClass().getName() + "' by a '" + getClass().getSimpleName() + "'", null); return null; } /** * Perform the visit to astNode returning an appropriate result. * <br> * The default implementation first invokes preVisit, which may return * to curtail the visit. One of visitEObject, visitResource, * visitResourceSet or else vistNode to perform the actual * visit. Finally postVisit is invoked to provide the return. */ public T visit(N astNode) { if (!preVisit(astNode)) return null; if (astNode instanceof EObject) visitEObject(astNode); else if (astNode instanceof Resource) visitResource((Resource)astNode); else if (astNode instanceof ResourceSet) visitResourceSet((ResourceSet)astNode); else vistNode(astNode); return postVisit(astNode); } /** * Perform the node visit to an EObject astNode. * <br> * The default implementation enters each of astNode.eContents(). */ protected void visitEObject(N astNode) { for (EObject eObject : ((EObject)astNode).eContents()) enter(eObject); } /** * Perform the node visit to a non-EObject, non-Ressource, non-ResourceSet astNode. * <br> * The default implementation logs an error. */ protected void vistNode(Object astNode) { OCLExamplesCommonPlugin.logError("Unimplemented visit to a '" + astNode.getClass().getName() + "' by a '" + getClass().getSimpleName() + "'", null); } /** * Perform the node visit to an Resource astNode. * <br> * The default implementation enters each of astNode.getContents(). */ protected void visitResource(Resource astNode) { for (EObject eObject : astNode.getContents()) enter(eObject); } /** * Perform the node visit to an ResourceSet astNode. * <br> * The default implementation enters each of astNode.getResources(). */ protected void visitResourceSet(ResourceSet astNode) { for (Resource resource : astNode.getResources()) enter(resource); } }