org.codehaus.aspectwerkz.xmldef.definition.DocumentParser.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.aspectwerkz.xmldef.definition.DocumentParser.java

Source

/**************************************************************************************
 * Copyright (c) Jonas Bonr, Alexandre Vasseur. All rights reserved.                 *
 * http://aspectwerkz.codehaus.org                                                    *
 * ---------------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the LGPL license      *
 * a copy of which has been included with this distribution in the license.txt file.  *
 **************************************************************************************/
package org.codehaus.aspectwerkz.xmldef.definition;

import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Element;

import org.codehaus.aspectwerkz.System;
import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
import org.codehaus.aspectwerkz.exception.DefinitionException;
import org.codehaus.aspectwerkz.definition.PointcutDefinition;
import org.codehaus.aspectwerkz.definition.AspectWerkzDefinition;
import org.codehaus.aspectwerkz.definition.PatternFactory;
import org.codehaus.aspectwerkz.definition.expression.Expression;
import org.codehaus.aspectwerkz.definition.expression.PointcutType;
import org.codehaus.aspectwerkz.definition.expression.ExpressionTemplate;
import org.codehaus.aspectwerkz.definition.expression.ExpressionNamespace;

/**
 * Parses the xmldef XML definition file using <tt>dom4j</tt>.
 *
 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonr</a>
 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
 */
public class DocumentParser {

    public static final String METHOD = "method";
    public static final String GET_FIELD = "getfield";
    public static final String SET_FIELD = "setfield";
    public static final String THROWS = "throws";
    public static final String CALLER_SIDE = "callerside";
    public static final String CFLOW = "cflow";
    public static final String CLASS = "class";

    /**
     * Parses the <tt>system</tt> element.
     *
     * @param systemElement the system element
     * @param basePackage the base package
     * @return the definition for the system
     */
    public static AspectWerkzDefinition parseSystemElement(final Element systemElement, final String basePackage) {
        String uuid = systemElement.attributeValue("id");
        if (uuid == null || uuid.equals("")) {
            // TODO: LOG a warning "no id specified in the definition, using default (AspectWerkz.DEFAULT_SYSTEM)"
            uuid = System.DEFAULT_SYSTEM;
        }
        return parseElements(systemElement, basePackage, uuid);
    }

    /**
     * Parses the definition elements.
     *
     * @param systemElement the system element
     * @param basePackage
     * @param uuid the definition UUID
     * @return the definition for the system
     */
    public static AspectWerkzDefinition parseElements(final Element systemElement, final String basePackage,
            final String uuid) {
        final AspectWerkzDefinitionImpl definition = new AspectWerkzDefinitionImpl();

        definition.setUuid(uuid);

        // parse the include and exclude elements
        org.codehaus.aspectwerkz.definition.DocumentParser.parseIncludePackageElements(systemElement, definition,
                basePackage);
        org.codehaus.aspectwerkz.definition.DocumentParser.parseExcludePackageElements(systemElement, definition,
                basePackage);

        boolean hasDef = false;
        // parse without package elements
        if (parseIntroductionElements(systemElement, definition, basePackage))
            hasDef = true;
        if (parseAdviceElements(systemElement, definition, basePackage))
            hasDef = true;
        if (parseAdviceStackElements(systemElement, definition))
            hasDef = true;
        if (parseAspectElements(systemElement, definition, basePackage))
            hasDef = true;

        // parse with package elements
        if (parsePackageElements(systemElement, definition, basePackage))
            hasDef = true;

        if (hasDef) {
            return definition;
        } else {
            return null;
        }
    }

    /**
     * Parses the <tt>package</tt> elements.
     *
     * @param systemElement the system element
     * @param definition the definition
     * @param basePackage the base package
     * @return flag that says if we have a definition of this kind or not
     */
    private static boolean parsePackageElements(final Element systemElement,
            final AspectWerkzDefinitionImpl definition, final String basePackage) {
        boolean hasDef = false;
        for (Iterator it1 = systemElement.elementIterator("package"); it1.hasNext();) {
            final Element packageElement = ((Element) it1.next());
            final String packageName = basePackage + getPackage(packageElement);

            // parse without package elements
            if (parseIntroductionElements(packageElement, definition, packageName))
                hasDef = true;
            if (parseAdviceElements(packageElement, definition, packageName))
                hasDef = true;
            if (parseAdviceStackElements(packageElement, definition))
                hasDef = true;
            if (parseAspectElements(packageElement, definition, packageName))
                hasDef = true;
        }
        return hasDef;
    }

    /**
     * Parses the <tt>introduction</tt> elements.
     *
     * @param root the root element
     * @param definition the definition object
     * @param packageName the package name
     * @return flag that says if we have a definition of this kind or not
     */
    private static boolean parseIntroductionElements(final Element root, final AspectWerkzDefinitionImpl definition,
            final String packageName) {
        boolean hasDef = false;
        for (Iterator it1 = root.elementIterator("introduction-def"); it1.hasNext();) {
            final IntroductionDefinition introDef = new IntroductionDefinition();

            Element introduction = (Element) it1.next();
            for (Iterator it2 = introduction.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();

                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    introDef.setName(value);
                } else if (name.equals("interface")) {
                    introDef.setInterface(packageName + value);
                } else if (name.equals("implementation")) {
                    introDef.setImplementation(packageName + value);
                } else if (name.equals("deployment-model")) {
                    introDef.setDeploymentModel(value);
                } else if (name.equals("attribute")) {
                    introDef.setAttribute(value);
                }
            }
            definition.addIntroduction(introDef);
            hasDef = true;
        }
        return hasDef;
    }

    /**
     * Parses the <tt>advice</tt> elements.
     *
     * @param root the root element
     * @param definition the definition object
     * @param packageName the package name
     * @return flag that says if we have a definition of this kind or not
     */
    private static boolean parseAdviceElements(final Element root, final AspectWerkzDefinitionImpl definition,
            final String packageName) {
        boolean hasDef = false;
        for (Iterator it1 = root.elementIterator("advice-def"); it1.hasNext();) {
            final AdviceDefinition adviceDef = new AdviceDefinition();

            Element advice = (Element) it1.next();
            for (Iterator it2 = advice.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();

                if (name.equals("name")) {
                    adviceDef.setName(value);
                } else if (name.equals("class")) {
                    adviceDef.setAdviceClassName(packageName + value);
                } else if (name.equals("deployment-model")) {
                    adviceDef.setDeploymentModel(value);
                } else if (name.equals("attribute")) {
                    adviceDef.setAttribute(value);
                }
            }
            for (Iterator it2 = advice.elementIterator(); it2.hasNext();) {
                Element nestedAdviceElement = (Element) it2.next();
                if (nestedAdviceElement.getName().trim().equals("param")) {
                    adviceDef.addParameter(nestedAdviceElement.attributeValue("name"),
                            nestedAdviceElement.attributeValue("value"));
                }
            }
            definition.addAdvice(adviceDef);
            hasDef = true;
        }
        return hasDef;
    }

    /**
     * Parses the <tt>aspect</tt> elements.
     *
     * @param root the root element
     * @param definition the definition object
     * @param packageName the package name
     * @return flag that says if we have a definition of this kind or not
     */
    private static boolean parseAspectElements(final Element root, final AspectWerkzDefinitionImpl definition,
            final String packageName) {

        // register the pointcuts before parsing the rest of the aspect
        // to be able to resolve all dependencies correctly
        for (Iterator it1 = root.elementIterator("aspect"); it1.hasNext();) {
            final Element aspect = (Element) it1.next();
            String aspectName = null;
            for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    aspectName = value;
                    continue;
                } else if (name.equals("extends")) {
                    aspectName = value;
                    break;
                }
            }
            // if the aspect has an abstract aspect register the pointcuts under the abstract aspects name
            registerPointcuts(aspect, aspectName, packageName);
        }
        for (Iterator it1 = root.elementIterator("abstract-aspect"); it1.hasNext();) {
            final Element aspect = (Element) it1.next();
            String aspectName = null;
            for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    aspectName = value;
                    break;
                }
            }
            registerPointcuts(aspect, aspectName, packageName);
        }

        // parse the aspect with its pointcut-def, bind-advice and bind-introduction rules
        boolean hasDef = false;
        for (Iterator it1 = root.elementIterator("aspect"); it1.hasNext();) {
            final AspectDefinition aspectDef = new AspectDefinition();
            final Element aspect = (Element) it1.next();
            for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    aspectDef.setName(value);
                } else if (name.equals("extends")) {
                    aspectDef.setExtends(value);
                    continue;
                }
            }

            parsePointcutElements(aspect, aspectDef, packageName);
            parseControllerElements(aspect, aspectDef);
            parseBindIntroductionElements(aspect, aspectDef, packageName);
            parseBindAdviceElements(aspect, aspectDef, packageName);

            definition.addAspect(aspectDef);
            hasDef = true;
        }
        for (Iterator it1 = root.elementIterator("abstract-aspect"); it1.hasNext();) {
            final AspectDefinition aspectDef = new AspectDefinition();
            aspectDef.setAbstract(true);

            final Element aspect = (Element) it1.next();
            for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    aspectDef.setName(value);
                }
            }
            parsePointcutElements(aspect, aspectDef, packageName);
            parseControllerElements(aspect, aspectDef);
            parseBindIntroductionElements(aspect, aspectDef, packageName);
            parseBindAdviceElements(aspect, aspectDef, packageName);

            definition.addAbstractAspect(aspectDef);
            hasDef = true;
        }

        for (Iterator it = definition.getAspectDefinitions().iterator(); it.hasNext();) {
            AspectDefinition aspectDef = (AspectDefinition) it.next();
            handleAbstractAspectDependencies(aspectDef, definition);
        }

        return hasDef;
    }

    /**
     * Handles the abstract dependencies for a concrete aspect.
     *
     * @param aspectDef the aspect definition
     * @param definition the aspectwerkz definition
     */
    private static void handleAbstractAspectDependencies(final AspectDefinition aspectDef,
            final AspectWerkzDefinitionImpl definition) {
        String extendsRef = aspectDef.getExtends();
        if (extendsRef != null) {
            final AspectDefinition abstractAspect = definition.getAbstractAspectDefinition(extendsRef);
            if (abstractAspect == null) {
                throw new DefinitionException("abstract aspect [" + aspectDef.getExtends() + "] is not defined");
            }
            for (Iterator it = abstractAspect.getPointcutDefs().iterator(); it.hasNext();) {
                final PointcutDefinition pointcutDef = (PointcutDefinition) it.next();
                aspectDef.addPointcutDef(pointcutDef);
            }
            for (Iterator it = abstractAspect.getBindAdviceRules().iterator(); it.hasNext();) {
                final BindAdviceRule bindAdviceRule = (BindAdviceRule) it.next();
                //                for (Iterator it2 = aspectDef.getPointcutDefs().iterator(); it2.hasNext();) {
                //                    addPointcutPattern((PointcutDefinition)it2.next(), bindAdviceRule);
                //                }
                aspectDef.addBindAdviceRule(bindAdviceRule);
            }
            for (Iterator it = abstractAspect.getBindIntroductionRules().iterator(); it.hasNext();) {
                final BindIntroductionRule bindIntroductionRule = (BindIntroductionRule) it.next();
                aspectDef.addBindIntroductionRule(bindIntroductionRule);
            }
        }
    }

    /**
     * Parses and registers the pointcut elements.
     *
     * @param aspect the aspect element
     * @param aspectName the name of the aspect
     * @param packageName the name of the package
     */
    private static void registerPointcuts(final Element aspect, final String aspectName, final String packageName) {
        for (Iterator it2 = aspect.elementIterator(); it2.hasNext();) {
            final Element nestedAdviceElement = (Element) it2.next();
            if (nestedAdviceElement.getName().trim().equals("pointcut-def")) {
                String pointcutName = null;
                String expression = null;
                PointcutType pointcutType = null;
                try {
                    for (Iterator it3 = nestedAdviceElement.attributeIterator(); it3.hasNext();) {
                        Attribute attribute = (Attribute) it3.next();
                        final String name = attribute.getName().trim();
                        final String value = attribute.getValue().trim();

                        if (name.equals("name")) {
                            pointcutName = value;
                        } else if (name.equals("type")) {
                            if (value.equalsIgnoreCase(METHOD)) {
                                pointcutType = PointcutType.EXECUTION;
                                expression = PatternFactory.createMethodPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(CFLOW)) {
                                pointcutType = PointcutType.CFLOW;
                                expression = PatternFactory.createCallPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(SET_FIELD)) {
                                pointcutType = PointcutType.SET;
                                expression = PatternFactory.createMethodPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(GET_FIELD)) {
                                pointcutType = PointcutType.GET;
                                expression = PatternFactory.createFieldPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(THROWS)) {
                                pointcutType = PointcutType.THROWS;
                                expression = PatternFactory.createThrowsPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(CALLER_SIDE)) {
                                pointcutType = PointcutType.CALL;
                                expression = PatternFactory.createCallPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            } else if (value.equalsIgnoreCase(CLASS)) {
                                pointcutType = PointcutType.CLASS;
                                expression = PatternFactory.createClassPattern(
                                        nestedAdviceElement.attributeValue("pattern"), packageName);
                            }
                        }
                    }
                    // create and register the expression
                    //                    ExpressionTemplate expressionTemplate =
                    //                            Expression.createExpressionTemplate(
                    //                                    aspectName,
                    //                                    expression,
                    //                                    packageName,
                    //                                    pointcutName,
                    //                                    pointcutType
                    //                            );
                    //                    Expression.registerExpressionTemplate(expressionTemplate);
                    ExpressionNamespace space = ExpressionNamespace.getExpressionNamespace(aspectName);
                    space.registerExpression(expression, packageName, pointcutName, pointcutType);
                } catch (Exception e) {
                    throw new WrappedRuntimeException(e);
                }
            }
        }
    }

    /**
     * Parses the pointcut elements.
     *
     * @TODO does not handle packages correctly
     *
     * @param aspect the aspect element
     * @param aspectDef the aspect definition
     * @param packageName the name of the package
     */
    private static void parsePointcutElements(final Element aspect, final AspectDefinition aspectDef,
            final String packageName) {
        for (Iterator it2 = aspect.elementIterator(); it2.hasNext();) {
            final Element nestedAdviceElement = (Element) it2.next();
            if (nestedAdviceElement.getName().trim().equals("pointcut-def")) {
                try {
                    final PointcutDefinition pointcutDef = new PointcutDefinition();

                    for (Iterator it3 = nestedAdviceElement.attributeIterator(); it3.hasNext();) {
                        Attribute attribute = (Attribute) it3.next();
                        final String name = attribute.getName().trim();
                        final String value = attribute.getValue().trim();
                        if (name.equals("name")) {
                            pointcutDef.setName(value);
                        } else if (name.equals("type")) {
                            PointcutType type = null;
                            String expression = nestedAdviceElement.attributeValue("pattern");
                            if (expression == null || expression.length() == 0)
                                expression = nestedAdviceElement.attributeValue("expression");
                            if (value.equalsIgnoreCase(METHOD)) {
                                type = PointcutType.EXECUTION;
                                pointcutDef
                                        .setExpression(PatternFactory.createMethodPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(CFLOW)) {
                                //needed during AttributeC merge
                                type = PointcutType.CFLOW;
                                pointcutDef
                                        .setExpression(PatternFactory.createMethodPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(SET_FIELD)) {
                                type = PointcutType.SET;
                                pointcutDef
                                        .setExpression(PatternFactory.createFieldPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(GET_FIELD)) {
                                type = PointcutType.GET;
                                pointcutDef
                                        .setExpression(PatternFactory.createFieldPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(THROWS)) {
                                type = PointcutType.THROWS;
                                pointcutDef
                                        .setExpression(PatternFactory.createThrowsPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(CALLER_SIDE)) {
                                type = PointcutType.CALL;
                                pointcutDef
                                        .setExpression(PatternFactory.createCallPattern(expression, packageName));
                            } else if (value.equalsIgnoreCase(CLASS)) {
                                type = PointcutType.CLASS;
                                pointcutDef
                                        .setExpression(PatternFactory.createClassPattern(expression, packageName));
                            }
                            pointcutDef.setType(type);
                        } else if (name.equals("non-reentrant")) {
                            pointcutDef.setNonReentrant(value);
                        }
                    }
                    aspectDef.addPointcutDef(pointcutDef);
                } catch (Exception e) {
                    throw new WrappedRuntimeException(e);
                }
            }
        }
    }

    /**
     * Parses the controller elements.
     *
     * @TODO implement controller support
     *
     * @param aspect the aspect element
     * @param aspectDef the aspect definition
     */
    private static void parseControllerElements(final Element aspect, final AspectDefinition aspectDef) {
        //        for (Iterator it2 = aspect.elementIterator(); it2.hasNext();) {
        //            final Element nestedAdviceElement = (Element)it2.next();
        //            if (nestedAdviceElement.getName().trim().equals("controller-def") ||
        //                    nestedAdviceElement.getName().trim().equals("controller")) {
        //                try {
        //                    final ControllerDefinition controllerDef = new ControllerDefinition();
        //
        //                    for (Iterator it3 = nestedAdviceElement.attributeIterator(); it3.hasNext();) {
        //                        Attribute attribute = (Attribute)it3.next();
        //                        final String name = attribute.getName().trim();
        //                        final String value = attribute.getValue().trim();
        //                        if (name.equals("pointcut") || name.equals("expression")) {
        //                            controllerDef.setExpression(value);
        //                        }
        //                        else if (name.equals("class")) {
        //                            controllerDef.setClassName(value);
        //                        }
        //                    }
        //                    // add the pointcut patterns to simplify the matching
        //                    if (!aspectDef.isAbstract()) {
        //                        for (Iterator it = aspectDef.getPointcutDefs().iterator(); it.hasNext();) {
        //                            final PointcutDefinition pointcutDef = (PointcutDefinition)it.next();
        //                            if (pointcutDef.getType().equalsIgnoreCase(PointcutDefinition.METHOD)) {
        //                                controllerDef.addMethodPointcutPattern(pointcutDef);
        //                            }
        //                        }
        //                    }
        //                    aspectDef.addControllerDef(controllerDef);
        //                }
        //                catch (Exception e) {
        //                    throw new DefinitionException("controller definition in aspect " + aspectDef.getName() + " is not well-formed: " + e.toString());
        //                }
        //            }
        //        }
    }

    /**
     * Parses the introduce elements.
     *
     * @param aspect the aspect element
     * @param aspectDef the aspect definition
     * @param packageName the name of the package
     */
    private static void parseBindIntroductionElements(final Element aspect, final AspectDefinition aspectDef,
            final String packageName) {
        for (Iterator it2 = aspect.elementIterator(); it2.hasNext();) {
            final Element nestedAdviceElement = (Element) it2.next();
            if (nestedAdviceElement.getName().trim().equals("bind-introduction")) {
                try {
                    final BindIntroductionRule bindIntroductionRule = new BindIntroductionRule();
                    for (Iterator it3 = nestedAdviceElement.attributeIterator(); it3.hasNext();) {
                        Attribute attribute = (Attribute) it3.next();
                        final String name = attribute.getName().trim();
                        final String value = attribute.getValue().trim();
                        if (name.equals("class")) {
                            bindIntroductionRule.setExpression(
                                    //                                    Expression.createRootExpression(
                                    //                                            aspectDef.getName(),
                                    //                                            packageName + value,
                                    //                                            PointcutType.CLASS // needed for anonymous expressions
                                    //                                    ));
                                    ExpressionNamespace.getExpressionNamespace(aspectDef.getName())
                                            .createExpression(packageName + value, PointcutType.CLASS));
                        } else if (name.equals("introduction-ref")) {
                            bindIntroductionRule.addIntroductionRef(value);
                        }
                    }
                    parseIntroductionWeavingRuleNestedElements(nestedAdviceElement, bindIntroductionRule);
                    aspectDef.addBindIntroductionRule(bindIntroductionRule);
                } catch (Exception e) {
                    throw new DefinitionException("introduction definition in aspect " + aspectDef.getName()
                            + " is not well-formed: " + e.toString());
                }
            }
        }
    }

    /**
     * Parses the advise elements.
     *
     * @TODO: how to handle cflow?
     *
     * @param aspect the aspect element
     * @param aspectDef the aspect definition
     * @param packageName the name of the package
     */
    private static void parseBindAdviceElements(final Element aspect, final AspectDefinition aspectDef,
            final String packageName) {
        for (Iterator it2 = aspect.elementIterator(); it2.hasNext();) {
            final Element nestedAdviceElement = (Element) it2.next();
            if (nestedAdviceElement.getName().trim().equals("bind-advice")) {
                try {
                    final BindAdviceRule bindAdviceRule = new BindAdviceRule();
                    String pointcutExpression = "";
                    for (Iterator it3 = nestedAdviceElement.attributeIterator(); it3.hasNext();) {
                        Attribute attribute = (Attribute) it3.next();
                        final String name = attribute.getName().trim();
                        final String value = attribute.getValue().trim();
                        if (name.equals("cflow")) {
                            // support for old system cflow=.. pc=..
                            pointcutExpression += " IN (" + value + ")";
                            //                            bindAdviceRule.setCflowExpression(
                            //                                    Expression.createCflowExpression(
                            //                                        aspectDef.getName(),
                            //                                        aspectDef.getPointcutDef(value).getExpression(),
                            //                                        packageName,
                            //                                        value)
                            //                            );
                        } else if (name.equals("pointcut") || name.equals("expression")) {
                            pointcutExpression = value + pointcutExpression;
                            //                            bindAdviceRule.setExpression(
                            //                                    Expression.createRootExpression(
                            //                                            aspectDef.getName(),
                            //                                            value
                            //                                    ));
                        } else if (name.equals("advice-ref")) {
                            bindAdviceRule.addAdviceRef(value);
                        }
                    }
                    // add binding here once cflow expr has been assembled (@since jjtree)
                    ExpressionNamespace space = ExpressionNamespace.getExpressionNamespace(aspectDef.getName());
                    bindAdviceRule.setExpression(space.createExpression(pointcutExpression));

                    parseAdviceWeavingRuleNestedElements(nestedAdviceElement, bindAdviceRule);
                    aspectDef.addBindAdviceRule(bindAdviceRule);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new DefinitionException("advice definition in aspect " + aspectDef.getName()
                            + " is not well-formed: " + e.toString());
                }
            }
        }
    }

    /**
     * Parses the nested <tt>introduction-ref</tt> and <tt>advice-ref</tt> elements.
     *
     * @param introductionElement the root introduction element
     * @param introWeavingRule the IntroducutionWeavingRule definition
     */
    private static void parseIntroductionWeavingRuleNestedElements(final Element introductionElement,
            final BindIntroductionRule introWeavingRule) {
        for (Iterator it = introductionElement.elementIterator(); it.hasNext();) {
            Element nestedElement = (Element) it.next();
            if (nestedElement.getName().trim().equals("introduction-ref")) {
                introWeavingRule.addIntroductionRef(nestedElement.attributeValue("name"));
            }
        }
    }

    /**
     * Parses the nested <tt>advice-ref</tt> elements.
     *
     * @param adviceElement the root advice element
     * @param adviceWeavingRule the AdviceWeavingRule definition
     */
    private static void parseAdviceWeavingRuleNestedElements(final Element adviceElement,
            final BindAdviceRule adviceWeavingRule) {
        for (Iterator it = adviceElement.elementIterator(); it.hasNext();) {
            Element nestedElement = (Element) it.next();
            if (nestedElement.getName().trim().equals("advice-ref")) {
                adviceWeavingRule.addAdviceRef(nestedElement.attributeValue("name"));
            } else if (nestedElement.getName().trim().equals("advices-ref")) {
                adviceWeavingRule.addAdviceStackRef(nestedElement.attributeValue("name"));
            }
        }
    }

    /**
     * Parses the <tt>advices</tt> elements.
     *
     * @param root the root element
     * @param definition the definition object
     * @return flag that says if we have a definition of this kind or not
     */
    private static boolean parseAdviceStackElements(final Element root,
            final AspectWerkzDefinitionImpl definition) {
        boolean hasDef = false;
        for (Iterator it1 = root.elementIterator("advices-def"); it1.hasNext();) {
            final AdviceStackDefinition adviceStackDef = new AdviceStackDefinition();

            Element adviceStack = (Element) it1.next();
            for (Iterator it2 = adviceStack.attributeIterator(); it2.hasNext();) {
                Attribute attribute = (Attribute) it2.next();
                final String name = attribute.getName().trim();
                final String value = attribute.getValue().trim();
                if (name.equals("name")) {
                    adviceStackDef.setName(value);
                }
            }
            for (Iterator it2 = adviceStack.elementIterator(); it2.hasNext();) {
                Element nestedElement = (Element) it2.next();
                if (nestedElement.getName().trim().equals("advice-ref")) {
                    adviceStackDef.addAdvice(nestedElement.attributeValue("name"));
                }
            }
            definition.addAdviceStack(adviceStackDef);
            hasDef = true;
        }
        return hasDef;
    }

    /**
     * Retrieves and returns the package.
     *
     * @param packageElement the package element
     * @return the package
     */
    private static String getPackage(final Element packageElement) {
        String packageName = "";
        for (Iterator it2 = packageElement.attributeIterator(); it2.hasNext();) {
            Attribute attribute = (Attribute) it2.next();
            if (attribute.getName().trim().equals("name")) {
                packageName = attribute.getValue().trim();
                if (packageName.endsWith(".*")) {
                    packageName = packageName.substring(0, packageName.length() - 1);
                } else if (packageName.endsWith(".")) {
                    ;// skip
                } else {
                    packageName += ".";
                }
                break;
            } else {
                continue;
            }
        }
        return packageName;
    }
}