/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * This file is part of the debugger and core tools for the AspectJ(tm) * programming language; see http://aspectj.org * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is AspectJ. * * The Initial Developer of the Original Code is Xerox Corporation. Portions * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation. * All Rights Reserved. */ package org.aspectj.tools.ajdoc; import org.aspectj.ajdoc.AdviceDoc; import org.aspectj.ajdoc.AspectDoc; import org.aspectj.ajdoc.IntroductionDoc; import org.aspectj.ajdoc.OfClauseDoc; import org.aspectj.compiler.base.ast.Decs; import org.aspectj.compiler.crosscuts.ast.AdviceDec; import org.aspectj.compiler.crosscuts.ast.AspectDec; import org.aspectj.compiler.crosscuts.ast.IntroducedSuperDec; import com.sun.javadoc.ClassDoc; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; public class AspectDocImpl extends ClassDocImpl implements AspectDoc { /** Array of AdviceDoc created from this AspectDecs AdviceDecs. */ private final Collection advice; /** Array of IntroductionDec created from this AspectDecs introductions. */ private final Collection introductions; /** The of clause this aspect has -- may be null. */ private final OfClauseDoc ofClause; /** The aspects that dominate this aspect. */ private final Collection dominators = new ArrayList(); /** The aspects that are dominated by this aspect. */ private final Collection dominatees = new ArrayList(); /** * Constructs an AspectDoc with the containing ClassDoc * and underlying AspectDec. * * @param containingClass contained ClassDoc. * @param aspectDec underlying AspectDec. */ public AspectDocImpl(ClassDoc containingClass, AspectDec aspectDec) { super(containingClass, aspectDec); introductions = createIntroductions(); advice = createAdvice(); ofClause = createOfClause(); } /** * Returns an instance of AdviceDocImpl corresponding to * the AdviceDec passed in. * * @param dec the AdviceDec mapping to the desired * AdviceDocImpl. * @return an instance of AdviceDocImpl corresponding to * the AdviceDec passed in. */ public AdviceDocImpl docForDec(AdviceDec dec) { for (Iterator i = advice.iterator(); i.hasNext();) { AdviceDocImpl ad = (AdviceDocImpl)i.next(); if (ad.dec() == dec) return ad; } return null; } /** * Returns an instance of IntroducedSuperDocImpl corresponding to * the IntroducedSuperDec passed in. * * @param dec the IntroducedSuperDec mapping to the * desired IntroducedSuperDocImpl * @return an instance of IntroducedSuperDocImpl * corresponding to the IntroducedSuperDec * passed in. */ public IntroducedSuperDocImpl introDocForDec(IntroducedSuperDec dec) { for (Iterator i = introductions.iterator(); i.hasNext();) { ProgramElementDocImpl id = (ProgramElementDocImpl)i.next(); if (id.dec() == dec) return (IntroducedSuperDocImpl)id; } return null; } /** * Returns the underlying AspectDec. * * @return the underlying AspectDec. */ protected AspectDec aspectDec() { return (AspectDec)typeDec(); } /** * Returns the visible advice in this aspect. * * @return an array of AdviceDoc representing the * visible advice in this aspect. */ public AdviceDoc[] advice() { return (AdviceDocImpl[])advice.toArray (new AdviceDocImpl[advice.size()]); } /** * Returns the aspects that are dominated by this aspect. * * @return an array of AspectDec representing the aspects * that are dominated by this aspect. */ public AspectDoc[] dominatees() { return (AspectDoc[])dominatees.toArray (new AspectDoc[dominatees.size()]); } /** * Return the aspects that dominate this aspect. * * @return an array of AspectDoc representing the aspects * that dominate this aspect. */ public AspectDoc[] dominators() { return (AspectDoc[])dominators.toArray (new AspectDoc[dominators.size()]); } /** * TODO * Returns the visible introductions of this aspect. * * @return an array of IntroductionDoc representing the * visible introductions in this aspect. */ public IntroductionDoc[] introductions() { return (IntroductionDocImpl[])introductions.toArray (new IntroductionDocImpl[introductions.size()]); } /** * Returns the of clause of this aspect. * * @return the of clause of this aspect. */ public OfClauseDoc ofClause() { return ofClause; } /** * Returns true. * * @return true. */ public boolean isAspect() { return true; } /** * Returns true if this aspects dominates * the passed in aspect. * * @param other an AspectDoc that represents another * aspect in this world. * @return true if this aspects dominates * the passed in aspect. */ public boolean dominates(AspectDoc other) { if (!(other instanceof AspectDocImpl)) { return false; } return aspectDec().dominates(((AspectDocImpl)other).aspectDec()); } /** * Adds a dominates relation from dominator to * this. For example, somewhere in the code * the line * * aspect dominator dominates this { ... } * * exists. * * @param dominator an instance of AspectDocImpl that * dominates this. */ public void addDominator(AspectDoc dominator) { dominators.add(dominator); } /** * Adds a dominates relation from dominator to * this. For example, somewhere in the code * the line * * aspect this dominates dominatee { ... } * * exists. * * @param dominatee an instance of AspectDocImpl that * is dominated by this. */ public void addDominatee(AspectDoc dominatee) { dominatees.add(dominatee); } /** * Returns a Collection of IntroductionDocImpl representing * the introductions declared in this aspect. * * @return a Collection of IntroductionDocImpl representing * the introductions declared in this aspect. */ private Collection createIntroductions() { Decs decs = aspectDec().getBody(); if (decs.size() < 1) return Collections.EMPTY_LIST; Collection list = new HashSet(); for (Iterator i = decs.getList().iterator(); i.hasNext();) { Object o = IntroductionDocImpl.getInstance(this, i.next()); if (o != null) list.add(o); } return list; } /** * Returns a Collection of AdviceDocImpl representing * the advice declared in this aspect. * * @return a Collection of AdviceDocImpl representing * the advice declared in this aspect. */ private Collection createAdvice() { // pluck the AdviceDec from the list of JpPlannerMakers List decs = aspectDec().getJpPlannerMakers(); if (null != decs) { final int QUIT = 2; for (int tries = 0; tries < QUIT; tries++) { try { for (Iterator i = decs.iterator(); i.hasNext();) { Object o = i.next(); if (!(o instanceof AdviceDec)) { i.remove(); } } tries = QUIT; } catch (UnsupportedOperationException o) { if (0 != tries) { tries = QUIT; } else { ArrayList list = new ArrayList(); list.addAll(decs); decs = list; } } } } if ((null == decs) || (decs.size() < 1)) { return Collections.EMPTY_LIST; } List list = new ArrayList(); for (Iterator i = decs.iterator(); i.hasNext();) { list.add(new AdviceDocImpl(this, (AdviceDec)i.next())); } return list; } /** * Returns an instance of OfClauseDoc representing * the of clause declared by this aspect. * * @return an instance of OfClauseDoc representing * the of clause declared by this aspect. */ private OfClauseDoc createOfClause() { return OfClauseDocImpl.getInstance(aspectDec().getPerClause()); } }