Logo Search packages:      
Sourcecode: aspectj version File versions  Download package

WeaverAdapter.java

/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aspectj.ajdt.internal.compiler;

import java.util.Iterator;
import java.util.Map;

import org.aspectj.asm.internal.CharOperation;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IProgressListener;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.aspectj.weaver.IClassFileProvider;
import org.aspectj.weaver.IUnwovenClassFile;
import org.aspectj.weaver.IWeaveRequestor;
import org.eclipse.core.runtime.OperationCanceledException;

/**
 * @author colyer This class provides the weaver with a source of class files to weave (via the iterator and IClassFileProvider
 *         interfaces). It receives results back from the weaver via the IWeaveRequestor interface.
 */
00030 public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Iterator {

      private final AbstractCompilerAdapter compilerAdapter;
      private Iterator resultIterator;
      private int classFileIndex = 0;
      private InterimCompilationResult nowProcessing;
      private InterimCompilationResult lastReturnedResult;
      private final WeaverMessageHandler weaverMessageHandler;
      private final IProgressListener progressListener;
      private boolean finalPhase = false;
      private int localIteratorCounter;

      // Fields related to progress monitoring
      private int progressMaxTypes;
      private String progressPhasePrefix;
      private double fromPercent;
      private final double toPercent = 100.0;
      private int progressCompletionCount;

      public WeaverAdapter(AbstractCompilerAdapter forCompiler, WeaverMessageHandler weaverMessageHandler,
                  IProgressListener progressListener) {
            this.compilerAdapter = forCompiler;
            this.weaverMessageHandler = weaverMessageHandler;
            this.progressListener = progressListener;
      }

      /*
       * (non-Javadoc)
       * 
       * @see org.aspectj.weaver.IClassFileProvider#getClassFileIterator()
       */
00061       public Iterator getClassFileIterator() {
            classFileIndex = 0;
            localIteratorCounter = 0;
            nowProcessing = null;
            lastReturnedResult = null;
            resultIterator = compilerAdapter.getResultsPendingWeave().iterator();
            return this;
      }

      /*
       * (non-Javadoc)
       * 
       * @see org.aspectj.weaver.IClassFileProvider#getRequestor()
       */
00075       public IWeaveRequestor getRequestor() {
            return this;
      }

00079       public boolean isApplyAtAspectJMungersOnly() {
            return false;
      }

      // Iteration
      // ================================================================

      /*
       * (non-Javadoc)
       * 
       * @see java.util.Iterator#hasNext()
       */
      public boolean hasNext() {
            if (nowProcessing == null) {
                  if (!resultIterator.hasNext())
                        return false;
                  nowProcessing = (InterimCompilationResult) resultIterator.next();
                  classFileIndex = 0;
            }
            while (nowProcessing.unwovenClassFiles().length == 0) {
                  if (!resultIterator.hasNext())
                        return false;
                  nowProcessing = (InterimCompilationResult) resultIterator.next();
            }
            if (classFileIndex < nowProcessing.unwovenClassFiles().length) {
                  return true;
            } else {
                  classFileIndex = 0;
                  if (!resultIterator.hasNext())
                        return false;
                  nowProcessing = (InterimCompilationResult) resultIterator.next();
                  while (nowProcessing.unwovenClassFiles().length == 0) {
                        if (!resultIterator.hasNext())
                              return false;
                        nowProcessing = (InterimCompilationResult) resultIterator.next();
                  }
            }
            return true;
      }

      /*
       * (non-Javadoc)
       * 
       * @see java.util.Iterator#next()
       */
      public Object next() {
            if (!hasNext())
                  return null; // sets up indices correctly
            if (finalPhase) {
                  if ((lastReturnedResult != null) && (lastReturnedResult != nowProcessing)) {
                        // we're done with the lastReturnedResult
                        finishedWith(lastReturnedResult);
                  }
            }
            localIteratorCounter++;
            lastReturnedResult = nowProcessing;
            weaverMessageHandler.setCurrentResult(nowProcessing.result());
            // weaverMessageHandler.handleMessage(new Message("weaving " + nowProcessing.fileName(),IMessage.INFO, null, null));
            return nowProcessing.unwovenClassFiles()[classFileIndex++];
      }

      /*
       * (non-Javadoc)
       * 
       * @see java.util.Iterator#remove()
       */
      public void remove() {
            throw new UnsupportedOperationException();
      }

      // IWeaveRequestor
      // =====================================================================================

      // weave phases as indicated by bcelWeaver...
      public void processingReweavableState() {

            // progress reporting logic
            fromPercent = 50.0; // Assume weaving takes 50% of the progress bar...
            // recordProgress("processing reweavable state");
      }

      public void addingTypeMungers() {

            // progress reporting logic
            // At this point we have completed one iteration through all the classes/aspects
            // we'll be dealing with, so let us remember this max value for localIteratorCounter
            // (for accurate progress reporting)
            // recordProgress("adding type mungers");
            progressMaxTypes = localIteratorCounter;
      }

      public void weavingAspects() {

            // progress reporting logic
            progressPhasePrefix = "woven aspect ";
            progressCompletionCount = 0; // Start counting from *now*
      }

      public void weavingClasses() {
            finalPhase = true;

            // progress reporting logic
            progressPhasePrefix = "woven class ";
      }

      public void weaveCompleted() {
            if ((lastReturnedResult != null) && (!lastReturnedResult.result().hasBeenAccepted)) {
                  finishedWith(lastReturnedResult);
            }
            lastReturnedResult = null;
      }

      /*
       * (non-Javadoc)
       * 
       * @see org.aspectj.weaver.IWeaveRequestor#acceptResult(org.aspectj.weaver.bcel.UnwovenClassFile)
       */
      public void acceptResult(IUnwovenClassFile result) {
            char[] key = result.getClassNameAsChars();
            removeFromMap(lastReturnedResult.result().compiledTypes, key);
            AjClassFile ajcf = new AjClassFile(key, result.getBytes());
            lastReturnedResult.result().record(ajcf.fileName(), ajcf);
            if (!weaverMessageHandler.isIgnoring(IMessage.INFO) || progressListener != null) {
                  StringBuffer msg = new StringBuffer();
                  msg.append(progressPhasePrefix).append(result.getClassName()).append(" (from ").append(nowProcessing.fileName())
                              .append(")");
                  weaverMessageHandler.handleMessage(MessageUtil.info(msg.toString()));
                  if (progressListener != null) {
                        progressCompletionCount++;

                        // Smoothly take progress from 'fromPercent' to 'toPercent'
                        recordProgress(fromPercent + ((progressCompletionCount / (double) progressMaxTypes) * (toPercent - fromPercent)),
                                    msg.toString());
                        // progressPhasePrefix+result.getClassName()+" (from "+nowProcessing.fileName()+")");

                        if (progressListener.isCancelledRequested()) {
                              throw new AbortCompilation(true, new OperationCanceledException("Weaving cancelled as requested"));
                        }
                  }
            }
      }

      // helpers...
      // =================================================================

      private void finishedWith(InterimCompilationResult result) {
            compilerAdapter.acceptResult(result.result());
      }

      private boolean removeFromMap(Map aMap, char[] key) {
            // jdt uses char[] as a key in the hashtable, which is not very useful as equality is based on being
            // the same array, not having the same content.
            // String skey = new String(key);
            // OPTIMIZE what is this code for?
            if (aMap.remove(key) != null) {
                  return true;
            }
            char[] victim = null;
            for (Iterator iter = aMap.keySet().iterator(); iter.hasNext();) {
                  char[] thisKey = (char[]) iter.next();
                  if (CharOperation.equals(thisKey, key)) {
                        // if (skey.equals(new String(thisKey))) {
                        victim = thisKey;
                        break;
                  }
            }
            if (victim != null) {
                  aMap.remove(victim);
                  return true;
            }
            return false;
      }

      private void recordProgress(double percentage, String message) {
            if (progressListener != null) {
                  progressListener.setProgress(percentage / 100);
                  progressListener.setText(message);
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index