summaryrefslogtreecommitdiffstats
path: root/ajde.core/src
diff options
context:
space:
mode:
authoraclement <aclement>2007-01-11 16:04:29 +0000
committeraclement <aclement>2007-01-11 16:04:29 +0000
commitcfd711b9628154e0b2eb2df174124699cf831f83 (patch)
tree83b9afa0e996777cf4cdcdff23f3b69f72df031b /ajde.core/src
parent41fefd58f8b716468b2bdba2335eb921e5eb3a7b (diff)
downloadaspectj-cfd711b9628154e0b2eb2df174124699cf831f83.tar.gz
aspectj-cfd711b9628154e0b2eb2df174124699cf831f83.zip
new ajde.core module
Diffstat (limited to 'ajde.core/src')
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/AjCompiler.java141
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java56
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java50
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java95
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java56
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/JavaOptions.java126
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java393
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java50
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java47
-rw-r--r--ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java48
10 files changed, 1062 insertions, 0 deletions
diff --git a/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java b/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java
new file mode 100644
index 000000000..9f2672414
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java
@@ -0,0 +1,141 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core;
+
+import org.aspectj.ajde.core.internal.AjdeCoreBuildManager;
+import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.Message;
+import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * The class to be used by tools to drive a build. An AjCompiler is created
+ * with a unique id (for example the absolute pathname of a project
+ * or .lst file) along with implementations of ICompilerConfiguration,
+ * IBuildProgressMonitor and IBuildMessageHandler. Tools then call
+ * build() or buildFresh() on this AjCompiler.
+ *
+ * <p>An AjCompiler is associated with one id, therefore a new one
+ * needs to be created for a new id (project, .lst file etc.). It is the
+ * responsibility of the tools to manage the lifecycle of the AjCompiler's.
+ */
+public class AjCompiler {
+
+ private ICompilerConfiguration compilerConfig;
+ private IBuildProgressMonitor monitor;
+ private IBuildMessageHandler handler;
+ private String compilerId;
+
+ private AjdeCoreBuildManager buildManager;
+
+ /**
+ * Creates a new AjCompiler for the given id, ICompilerConfiguration,
+ * IBuildProgressMonitor and IBuildMessageHandler. None of the arguments
+ * can be null.
+ *
+ * @param compilerId - Unique String used to identify this AjCompiler
+ * @param compilerConfig - ICompilerConfiguration implementation
+ * @param buildProgressMonitor - IBuildProgressMonitor implementation
+ * @param buildMessageHandler - IBuildMessageHandler implementation
+ */
+ public AjCompiler(
+ String compilerId,
+ ICompilerConfiguration compilerConfig,
+ IBuildProgressMonitor buildProgressMonitor,
+ IBuildMessageHandler buildMessageHandler) {
+ this.compilerConfig = compilerConfig;
+ this.monitor = buildProgressMonitor;
+ this.handler = buildMessageHandler;
+ this.compilerId = compilerId;
+
+ buildManager = new AjdeCoreBuildManager(this);
+ }
+
+ /**
+ * @return the id for this AjCompiler
+ */
+ public String getId() {
+ return compilerId;
+ }
+
+ /**
+ * @return the ICompilerConfiguration associated with this AjCompiler
+ */
+ public ICompilerConfiguration getCompilerConfiguration() {
+ return compilerConfig;
+ }
+
+ /**
+ * @return the IBuildProgressMonitor associated with this AjCompiler
+ */
+ public IBuildProgressMonitor getBuildProgressMonitor() {
+ return monitor;
+ }
+
+ /**
+ * @return the IBuildMessageHandler associated with this AjCompiler
+ */
+ public IBuildMessageHandler getMessageHandler() {
+ return handler;
+ }
+
+ /**
+ * Perform an incremental build if possible, otherwise it will
+ * default to a full build.
+ */
+ public void build() {
+ if (hasValidId()) {
+ buildManager.doBuild(false);
+ }
+ }
+
+ /**
+ * Perform a full build
+ */
+ public void buildFresh() {
+ if (hasValidId()) {
+ buildManager.doBuild(true);
+ }
+ }
+
+ /**
+ * Clear the incremental state associated with this AjCompiler
+ * from the IncrementalStateManager. This is necessary until AjState
+ * is reworked and there's an AjState associated with an AjCompiler
+ * rather than requiring a map of them.
+ */
+ public void clearLastState() {
+ IncrementalStateManager.removeIncrementalStateInformationFor(compilerId);
+ }
+
+ /**
+ * @return true if the underlying version of the compiler
+ * is compatible with Java 6, returns false otherwise.
+ */
+ public boolean isJava6Compatible() {
+ return CompilerOptions.versionToJdkLevel(JavaOptions.VERSION_16) != 0;
+ }
+
+ /**
+ * Ensures that the id associated with this compiler is non-null. If
+ * it is null then sends an ABORT message to the messageHandler
+ */
+ private boolean hasValidId() {
+ if (compilerId == null) {
+ Message msg = new Message("compiler didn't have an id associated " +
+ "with it",IMessage.ABORT,null,null);
+ handler.handleMessage(msg);
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java b/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java
new file mode 100644
index 000000000..064e37c92
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java
@@ -0,0 +1,56 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+
+/**
+ * Interface that handles messages sent from the compiler.
+ * Implementations define which messages are logged and whether
+ * the handler aborts the process.
+ */
+public interface IBuildMessageHandler {
+
+ /**
+ * Handle message by reporting and/or throwing an AbortException.
+ *
+ * @param message the IMessage to handle - never null
+ * @return true if this message was handled by this handler
+ * @throws IllegalArgumentException if message is null
+ * @throws AbortException depending on handler logic.
+ */
+ boolean handleMessage(IMessage message) throws AbortException;
+
+ /**
+ * Signal whether this will ignore messages of a given type.
+ * Clients may use this to avoid constructing or sending
+ * certain messages.
+ *
+ * @return true if this handler is ignoring all messages of this type
+ */
+ boolean isIgnoring(IMessage.Kind kind);
+
+ /**
+ * Allow fine grained configuration after initialization.
+ *
+ * @param kind
+ */
+ void dontIgnore(IMessage.Kind kind);
+
+ /**
+ * Allow fine grained configuration after initialization.
+ *
+ * @param kind
+ */
+ void ignore(IMessage.Kind kind);
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java b/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java
new file mode 100644
index 000000000..120dda25a
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java
@@ -0,0 +1,50 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core;
+
+/**
+ * Interface that presents the user with information about the
+ * progress of the build
+ */
+public interface IBuildProgressMonitor {
+
+ /**
+ * Start the progress monitor
+ */
+ public void begin();
+
+ /**
+ * Sets the label describing the current progress phase.
+ */
+ public void setProgressText(String text);
+
+ /**
+ * Stop the progress monitor
+ *
+ * @param wasFullBuild - true if was a full build, false otherwise
+ */
+ public void finish(boolean wasFullBuild);
+
+ /**
+ * Sets the current progress done
+ *
+ * @param percentDone
+ */
+ public void setProgress(double percentDone);
+
+ /**
+ * Checks whether the user has chosen to cancel the progress monitor
+ *
+ * @return true if progress monitor has been cancelled and false otherwise
+ */
+ public boolean isCancelRequested();
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java
new file mode 100644
index 000000000..35a8eb51c
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java
@@ -0,0 +1,95 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Inteface that contains all the configuration required for the
+ * compiler to be able to perform a build
+ */
+public interface ICompilerConfiguration {
+
+ /**
+ * Returns the table of the current custom java options.
+ * <p>
+ * For a complete description of the configurable options, see
+ * {@link org.aspectj.ajde.core.JavaOptions#getDefaultJavaOptions}
+ * or {@link org.aspectj.org.eclipse.jdt.core.IJavaProject#getOptions(boolean)}
+ * </p>
+ *
+ * @return table of current settings of all options
+ * (key type: <code>String</code>; value type: <code>String</code>)
+ * @see org.aspectj.ajde.core.JavaOptions#getDefaultJavaOptions or
+ * org.aspectj.org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
+ */
+ public Map /*String --> String */getJavaOptionsMap();
+
+ /**
+ * The non-standard options, typically prefaced with -X when used
+ * with a command line compiler. The default is no non-standard
+ * options. Options should be separated by a space, for example
+ * "-showWeaveInfo -XnoInline"
+ */
+ public String getNonStandardOptions();
+
+ /**
+ * @return a list of those files to include in the build
+ */
+ public List /*String*/ getProjectSourceFiles();
+
+ /**
+ * @return the classpath to use
+ */
+ public String getClasspath();
+
+ /**
+ * @return the IOutputLocationManager associated with this
+ * compiler configuration
+ */
+ public IOutputLocationManager getOutputLocationManager();
+
+ /**
+ * @return the set of input path elements for this compilation.
+ * Set members should be of the type java.io.File.
+ * An empty set or null is acceptable for this option.
+ * From -inpath
+ */
+ public Set /*java.io.File*/ getInpath();
+
+ /**
+ * @return the output jar file for the compilation results.
+ * Return null to leave classfiles unjar'd in output directory
+ * From -outjar
+ */
+ public String getOutJar();
+
+ /**
+ * @return the set of aspect jar files to be used for the compilation.
+ * Returning null or an empty set disables this option. Set members
+ * should be of type java.io.File.
+ * From -aspectpath
+ */
+ public Set /*java.io.File*/ getAspectPath();
+
+ /**
+ * Get the set of non-Java resources for this compilation.
+ * Set members should be of type java.io.File.
+ * An empty set or null is acceptable for this option.
+ *
+ * @return map from unique resource name to absolute path to source
+ * resource (String to File)
+ */
+ public Map /*String --> java.io.File */getSourcePathResources();
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java b/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java
new file mode 100644
index 000000000..7025f44b0
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java
@@ -0,0 +1,56 @@
+/********************************************************************
+ * Copyright (c) 2006 Contributors.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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * Helen Hawkins bug 166580 and 148190
+ * ******************************************************************/
+package org.aspectj.ajde.core;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Interface that handles where the compilation output is sent. Allows
+ * for the output folder to be different for different source files.
+ */
+public interface IOutputLocationManager {
+
+ /**
+ * Return the directory root under which the results of compiling the given
+ * source file. For example, if the source file contains the type a.b.C, and
+ * this method returns "target/classes" the resulting class file will be written
+ * to "target/classes/a/b/C.class"
+ *
+ * @param compilationUnit the compilation unit that has been compiled
+ * @return a File object representing the root directory under which compilation results for this
+ * unit should be written
+ */
+ File getOutputLocationForClass(File compilationUnit);
+
+ /**
+ * When copying resources from source folders to output location, return the
+ * root directory under which the resource should be copied.
+ *
+ * @param resource the resource to be copied
+ * @return a File object representing the root directory under which this resource
+ * should be copied
+ */
+ File getOutputLocationForResource(File resource);
+
+ /**
+ * Return a list of all output locations handled by this OutputLocationManager
+ */
+ List /*File*/ getAllOutputLocations();
+
+ /**
+ * Return the default output location (for example, <my_project>/bin). This is
+ * where classes which are on the inpath will be placed.
+ */
+ File getDefaultOutputLocation();
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java b/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java
new file mode 100644
index 000000000..765e36a37
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java
@@ -0,0 +1,126 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * Class containing the current custom java options
+ */
+public final class JavaOptions {
+
+ public static final String COMPLIANCE_LEVEL = CompilerOptions.OPTION_Compliance;
+ public static final String SOURCE_COMPATIBILITY_LEVEL = CompilerOptions.OPTION_Source;
+ public static final String TARGET_COMPATIBILITY_LEVEL = CompilerOptions.OPTION_TargetPlatform;
+ // Version constants
+ public static final String VERSION_13 = CompilerOptions.VERSION_1_3;
+ public static final String VERSION_14 = CompilerOptions.VERSION_1_4;
+ public static final String VERSION_15 = CompilerOptions.VERSION_1_5;
+ public static final String VERSION_16 = "1.6"; // current version of the compiler doesn't support java6
+
+ // by default will use the platform default encoding
+ public static final String CHARACTER_ENCODING = CompilerOptions.OPTION_Encoding;
+
+ // indicates if unused/optimizable local variables need to be preserved (debugging purpose)
+ public static final String PRESERVE_ALL_LOCALS = CompilerOptions.OPTION_PreserveUnusedLocal;
+ public static final String PRESERVE = CompilerOptions.PRESERVE;
+ public static final String OPTIMIZE = CompilerOptions.OPTIMIZE_OUT;
+
+ // Warning constants
+ public static final String WARN_METHOD_WITH_CONSTRUCTOR_NAME = CompilerOptions.OPTION_ReportMethodWithConstructorName;
+ public static final String WARN_OVERRIDING_PACKAGE_DEFAULT_METHOD = CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod;
+ public static final String WARN_DEPRECATION = CompilerOptions.OPTION_ReportDeprecation;
+ public static final String WARN_HIDDEN_CATCH_BLOCKS = CompilerOptions.OPTION_ReportHiddenCatchBlock;
+ public static final String WARN_UNUSED_LOCALS = CompilerOptions.OPTION_ReportUnusedLocal;
+ public static final String WARN_UNUSED_PARAMETER = CompilerOptions.OPTION_ReportUnusedParameter;
+ public static final String WARN_UNUSED_IMPORTS = CompilerOptions.OPTION_ReportUnusedImport;
+ public static final String WARN_SYNTHETIC_ACCESS = CompilerOptions.OPTION_ReportSyntheticAccessEmulation;
+ public static final String WARN_ASSERT_IDENITIFIER = CompilerOptions.OPTION_ReportAssertIdentifier;
+ public static final String WARN_NON_NLS = CompilerOptions.OPTION_ReportNonExternalizedStringLiteral;
+ // warning option constants
+ public static final String IGNORE = CompilerOptions.IGNORE;
+ public static final String WARNING = CompilerOptions.WARNING;
+
+ // Debug constants
+ public static final String DEBUG_SOURCE = CompilerOptions.OPTION_SourceFileAttribute;
+ public static final String DEBUG_LINES = CompilerOptions.OPTION_LocalVariableAttribute;
+ public static final String DEBUG_VARS = CompilerOptions.OPTION_LineNumberAttribute;
+ // Debug option constants
+ public static final String GENERATE = CompilerOptions.GENERATE;
+ public static final String DO_NOT_GENERATE = CompilerOptions.DO_NOT_GENERATE;
+
+ private static Map defaultOptionsMap;
+
+ /**
+ * @return the java options map with the default settings
+ */
+ public static Map getDefaultJavaOptions() {
+ if (defaultOptionsMap != null) return defaultOptionsMap;
+
+ defaultOptionsMap = new HashMap();
+ defaultOptionsMap.put(COMPLIANCE_LEVEL, VERSION_14);
+ defaultOptionsMap.put(SOURCE_COMPATIBILITY_LEVEL, VERSION_13);
+ defaultOptionsMap.put(PRESERVE_ALL_LOCALS, OPTIMIZE);
+ defaultOptionsMap.put(WARN_METHOD_WITH_CONSTRUCTOR_NAME, IGNORE);
+ defaultOptionsMap.put(WARN_OVERRIDING_PACKAGE_DEFAULT_METHOD, IGNORE);
+ defaultOptionsMap.put(WARN_DEPRECATION, IGNORE);
+ defaultOptionsMap.put(WARN_HIDDEN_CATCH_BLOCKS, IGNORE);
+ defaultOptionsMap.put(WARN_UNUSED_LOCALS, IGNORE);
+ defaultOptionsMap.put(WARN_UNUSED_PARAMETER, IGNORE);
+ defaultOptionsMap.put(WARN_UNUSED_IMPORTS, IGNORE);
+ defaultOptionsMap.put(WARN_SYNTHETIC_ACCESS, IGNORE);
+ defaultOptionsMap.put(WARN_ASSERT_IDENITIFIER, IGNORE);
+ defaultOptionsMap.put(WARN_NON_NLS, IGNORE);
+ defaultOptionsMap.put(DEBUG_SOURCE, GENERATE);
+ defaultOptionsMap.put(DEBUG_LINES, GENERATE);
+ defaultOptionsMap.put(DEBUG_VARS, DO_NOT_GENERATE);
+
+ return defaultOptionsMap;
+ }
+
+ /**
+ * @return true if the given value is a valid JVM version
+ * (JavaOptions.VERSION_13, JavaOptions.VERSION_134, JavaOptions.VERSION_15,
+ * JavaOptions.VERSION_16) and false otherwise
+ */
+ public static boolean isValidJvmVersion(String value) {
+ return VERSION_13.equals(value) || VERSION_14.equals(value)
+ || VERSION_15.equals(value) || VERSION_16.equals(value);
+ }
+
+ /**
+ * @return true if the given option is JavaOptions.PRESERVE or
+ * JavaOptions.OPTIMIZE and false otherwise
+ */
+ public static boolean isValidPreserveAllLocalsOption(String option) {
+ return PRESERVE.equals(option) || OPTIMIZE.equals(option);
+ }
+
+ /**
+ * @return true if the given option is JavaOptions.IGNORE or
+ * JavaOptions.WARNING and false otherwise
+ */
+ public static boolean isIgnoreOrWarning(String option) {
+ return IGNORE.equals(option) || WARNING.equals(option);
+ }
+
+ /**
+ * @return true if the given option is JavaOptions.GENERATE or
+ * JavaOptions.DO_NOT_GENERATE and false otherwise
+ */
+ public static boolean isGenerateOrNot(String option) {
+ return GENERATE.equals(option) || DO_NOT_GENERATE.equals(option);
+ }
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java
new file mode 100644
index 000000000..46db93884
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java
@@ -0,0 +1,393 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core.internal;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.aspectj.ajde.core.AjCompiler;
+import org.aspectj.ajde.core.ICompilerConfiguration;
+import org.aspectj.ajde.core.IOutputLocationManager;
+import org.aspectj.ajde.core.JavaOptions;
+import org.aspectj.ajdt.ajc.AjdtCommand;
+import org.aspectj.ajdt.ajc.BuildArgParser;
+import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
+import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
+import org.aspectj.ajdt.internal.core.builder.AjState;
+import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager;
+import org.aspectj.asm.AsmManager;
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.CountingMessageHandler;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.bridge.context.CompilationAndWeavingContext;
+import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.aspectj.util.ConfigParser;
+import org.aspectj.util.LangUtil;
+
+/**
+ * Build Manager which drives the build for a given AjCompiler.
+ * Tools call build on the AjCompiler which drives this.
+ */
+public class AjdeCoreBuildManager {
+
+ private AjCompiler compiler;
+
+ private AjdeCoreBuildNotifierAdapter currNotifier = null;
+ private AjBuildManager ajBuildManager;
+ private IMessageHandler msgHandlerAdapter;
+
+ public AjdeCoreBuildManager(AjCompiler compiler) {
+ this.compiler = compiler;
+ msgHandlerAdapter = new AjdeCoreMessageHandlerAdapter(compiler.getMessageHandler());
+ ajBuildManager = new AjBuildManager(msgHandlerAdapter);
+ ajBuildManager.environmentSupportsIncrementalCompilation(true);
+ // this static information needs to be set to ensure
+ // incremental compilation works correctly
+ IncrementalStateManager.recordIncrementalStates=true;
+ IncrementalStateManager.debugIncrementalStates=true;
+ AsmManager.attemptIncrementalModelRepairs = true;
+ }
+
+ /**
+ * @param buildFresh - true if want to force a full build, false otherwise
+ */
+ public void doBuild(boolean buildFresh) {
+ if (!buildFresh) {
+ buildFresh = updateAsmManagerInformation();
+ }
+ try {
+ startNotifiers();
+
+ // record the options passed to the compiler
+ handleMessage(new Message(getFormattedOptionsString(),IMessage.INFO,null,null));
+
+ CompilationAndWeavingContext.reset();
+ AjBuildConfig buildConfig = genAjBuildConfig();
+ if (buildConfig == null) return;
+
+ if (buildFresh) {
+ ajBuildManager.batchBuild(buildConfig,msgHandlerAdapter);
+ } else {
+ ajBuildManager.incrementalBuild(buildConfig,msgHandlerAdapter);
+ }
+ IncrementalStateManager.recordSuccessfulBuild(compiler.getId(),ajBuildManager.getState());
+
+ } catch (ConfigParser.ParseException pe) {
+ handleMessage(new Message("Config file entry invalid, file: " + pe.getFile().getPath()
+ + ", line number: " + pe.getLine(),IMessage.WARNING,null,null));
+ } catch (AbortException e) {
+ final IMessage message = e.getIMessage();
+ if (message == null) {
+ handleMessage(new Message(LangUtil.unqualifiedClassName(e) + " thrown: "
+ + e.getMessage(),IMessage.ERROR,e,null));
+ } else {
+ handleMessage(new Message(message.getMessage() + "\n"
+ + CompilationAndWeavingContext.getCurrentContext(),IMessage.ERROR,e,null));
+ };
+ } catch (Throwable t) {
+ handleMessage(new Message("Compile error: " + LangUtil.unqualifiedClassName(t) + " thrown: " +
+ "" + t.getMessage(),IMessage.ABORT,t,null));
+ } finally {
+ compiler.getBuildProgressMonitor().finish(ajBuildManager.wasFullBuild());
+ }
+ }
+
+ /**
+ * Starts the various notifiers which are interested in the build progress
+ */
+ private void startNotifiers() {
+ compiler.getBuildProgressMonitor().begin();
+ currNotifier = new AjdeCoreBuildNotifierAdapter(compiler.getBuildProgressMonitor());
+ ajBuildManager.setProgressListener(currNotifier);
+ }
+
+ /**
+ * Switches the relationshipMap and hierarchy used by AsmManager to be
+ * the one for the current compiler - this will not be necessary once
+ * the static nature is removed from the asm.
+ */
+ private boolean updateAsmManagerInformation() {
+ AjState updatedState = IncrementalStateManager.retrieveStateFor(compiler.getId());
+ if (updatedState == null) {
+ return true;
+ } else {
+ AsmManager.getDefault().setRelationshipMap(updatedState.getRelationshipMap());
+ AsmManager.getDefault().setHierarchy(updatedState.getStructureModel());
+ }
+ return false;
+ }
+
+ // AMC - updated for AspectJ 1.1 options
+ private String getFormattedOptionsString() {
+ ICompilerConfiguration compilerConfig = compiler.getCompilerConfiguration();
+ return "Building with settings: "
+ + "\n-> output paths: " + formatCollection(compilerConfig.getOutputLocationManager()
+ .getAllOutputLocations())
+ + "\n-> classpath: " + compilerConfig.getClasspath()
+ + "\n-> -inpath " + formatCollection(compilerConfig.getInpath())
+ + "\n-> -outjar " + formatOptionalString(compilerConfig.getOutJar())
+ + "\n-> -aspectpath " + formatCollection(compilerConfig.getAspectPath())
+ + "\n-> -sourcePathResources " + formatMap(compilerConfig.getSourcePathResources())
+ + "\n-> non-standard options: " + compilerConfig.getNonStandardOptions()
+ + "\n-> javaoptions:" + formatMap(compilerConfig.getJavaOptionsMap());
+ }
+
+ private String formatCollection( Collection options ) {
+ if ( options == null ) return "<default>";
+ if ( options.isEmpty() ) return "none";
+
+ StringBuffer formattedOptions = new StringBuffer();
+ Iterator it = options.iterator();
+ while (it.hasNext()) {
+ String o = it.next().toString();
+ if (formattedOptions.length() > 0) formattedOptions.append(", ");
+ formattedOptions.append( o );
+ }
+ return formattedOptions.toString();
+ }
+
+ private String formatMap( Map options) {
+ if (options == null) return "<default>";
+ if (options.isEmpty()) return "none";
+
+ return options.toString();
+ }
+
+ private String formatOptionalString( String s ) {
+ if ( s == null ) { return "" ; }
+ else { return s; }
+ }
+
+ /**
+ * Generate a new AjBuildConfig from the compiler configuration
+ * associated with this AjdeCoreBuildManager
+ *
+ * @return null if invalid configuration, corresponding
+ * AjBuildConfig otherwise
+ */
+ public AjBuildConfig genAjBuildConfig() {
+ File configFile = new File(compiler.getId());
+ String[] args = null;
+ if (configFile.exists() && configFile.isFile()) {
+ args = new String[] { "@" + configFile.getAbsolutePath() };
+ } else {
+ List l = compiler.getCompilerConfiguration().getProjectSourceFiles();
+ if (l == null) return null;
+ args = new String[l.size()];
+ int counter = 0;
+ for (Iterator iter = l.iterator(); iter.hasNext();) {
+ String element = (String) iter.next();
+ args[counter] = element;
+ counter++;
+ }
+ }
+ CountingMessageHandler handler = CountingMessageHandler.makeCountingMessageHandler(
+ msgHandlerAdapter);
+ BuildArgParser parser = new BuildArgParser(handler);
+
+ AjBuildConfig config = new AjBuildConfig();
+ parser.populateBuildConfig(config, args, false, configFile);
+ configureCompilerOptions(config);
+
+ ISourceLocation location = null;
+ if (config.getConfigFile() != null) {
+ location = new SourceLocation(config.getConfigFile(), 0);
+ }
+
+ String message = parser.getOtherMessages(true);
+ if (null != message) {
+ IMessage m = new Message(message, IMessage.ERROR, null, location);
+ handler.handleMessage(m);
+ }
+
+ // always force model generation in AJDE
+ config.setGenerateModelMode(true);
+ // always be in incremental mode in AJDE
+ config.setIncrementalMode(true);
+ return config;
+ }
+
+ /**
+ * Check that the user hasn't specified Java 6 for the compliance, source and
+ * target levels. If they have then an error is thrown.
+ */
+ private void checkNotAskedForJava6Compliance() {
+ // bug 164384 - Throwing an IMessage.ERRROR rather than an IMessage.ABORT
+ // means that we'll continue to try to compile the code. This means that
+ // the user may see other errors (for example, if they're using annotations
+ // then they'll get errors saying that they require 5.0 compliance).
+ // Throwing IMessage.ABORT would prevent this, however, 'abort' is really
+ // for compiler exceptions.
+ Map javaOptions = compiler.getCompilerConfiguration().getJavaOptionsMap();
+ if (javaOptions != null){
+ String version = (String)javaOptions.get(CompilerOptions.OPTION_Compliance);
+ String sourceVersion = (String)javaOptions.get(CompilerOptions.OPTION_Source);
+ String targetVersion = (String)javaOptions.get(CompilerOptions.OPTION_TargetPlatform);
+ if (version!=null && version.equals(JavaOptions.VERSION_16)) {
+ String msg = "Java 6.0 compliance level is unsupported";
+ IMessage m = new Message(msg, IMessage.ERROR, null, null);
+ compiler.getMessageHandler().handleMessage(m);
+ } else if (sourceVersion!=null && sourceVersion.equals(JavaOptions.VERSION_16)) {
+ String msg = "Java 6.0 source level is unsupported";
+ IMessage m = new Message(msg, IMessage.ERROR, null, null);
+ compiler.getMessageHandler().handleMessage(m);
+ } else if (targetVersion!=null && targetVersion.equals(JavaOptions.VERSION_16)) {
+ String msg = "Java 6.0 target level is unsupported";
+ IMessage m = new Message(msg, IMessage.ERROR, null, null);
+ compiler.getMessageHandler().handleMessage(m);
+ }
+ }
+ }
+
+ /**
+ * Configure the given AjBuildConfig with the options found in the
+ * ICompilerConfiguration implementation associated with the AjCompiler
+ * for this AjdeCoreBuildManager
+ *
+ * @param config
+ */
+ private void configureCompilerOptions(AjBuildConfig config) {
+ checkNotAskedForJava6Compliance();
+
+ String propcp = compiler.getCompilerConfiguration().getClasspath();
+ if (!LangUtil.isEmpty(propcp)) {
+ StringTokenizer st = new StringTokenizer(propcp, File.pathSeparator);
+ List configClasspath = config.getClasspath();
+ ArrayList toAdd = new ArrayList();
+ while (st.hasMoreTokens()) {
+ String entry = st.nextToken();
+ if (!configClasspath.contains(entry)) {
+ toAdd.add(entry);
+ }
+ }
+ if (0 < toAdd.size()) {
+ ArrayList both = new ArrayList(configClasspath.size() + toAdd.size());
+ both.addAll(configClasspath);
+ both.addAll(toAdd);
+ config.setClasspath(both);
+ }
+ }
+
+ // set the outputjar
+ if (config.getOutputJar() == null) {
+ String outJar = compiler.getCompilerConfiguration().getOutJar();
+ if (!LangUtil.isEmpty(outJar)) {
+ config.setOutputJar(new File( outJar ) );
+ }
+ }
+
+ // set compilation result destination manager
+ IOutputLocationManager outputLocationManager = compiler.getCompilerConfiguration().getOutputLocationManager();
+ if (config.getCompilationResultDestinationManager() == null && outputLocationManager != null) {
+ config.setCompilationResultDestinationManager(new OutputLocationAdapter(outputLocationManager));
+ }
+
+ join(config.getInpath(),compiler.getCompilerConfiguration().getInpath());
+ // bug 168840 - calling 'setInPath(..)' creates BinarySourceFiles which
+ // are used to see if there have been changes in classes on the inpath
+ if (config.getInpath() != null) config.setInPath(config.getInpath());
+ config.setSourcePathResources(compiler.getCompilerConfiguration().getSourcePathResources());
+ join(config.getAspectpath(), compiler.getCompilerConfiguration().getAspectPath());
+
+ Map jom = compiler.getCompilerConfiguration().getJavaOptionsMap();
+ if (jom!=null) {
+ String version = (String)jom.get(CompilerOptions.OPTION_Compliance);
+ if (version!=null && version.equals(CompilerOptions.VERSION_1_5)) {
+ config.setBehaveInJava5Way(true);
+ }
+ config.getOptions().set(jom);
+ }
+
+ configureNonStandardOptions(config);
+ }
+
+ private void join(Collection target, Collection source) {
+ if ((null == target) || (null == source)) {
+ return;
+ }
+ for (Iterator iter = source.iterator(); iter.hasNext();) {
+ Object next = iter.next();
+ if (! target.contains(next)) {
+ target.add(next);
+ }
+ }
+ }
+
+ /**
+ * Helper method for configure build options. This reads all command-line
+ * options specified in the non-standard options text entry and sets any
+ * corresponding unset values in config.
+ */
+ private void configureNonStandardOptions(AjBuildConfig config) {
+
+ String nonStdOptions = compiler.getCompilerConfiguration().getNonStandardOptions();
+ if (LangUtil.isEmpty(nonStdOptions)) {
+ return;
+ }
+
+ // Break a string into a string array of non-standard options.
+ // Allows for one option to include a ' '. i.e. assuming it has been quoted, it
+ // won't accidentally get treated as a pair of options (can be needed for xlint props file option)
+ List tokens = new ArrayList();
+ int ind = nonStdOptions.indexOf('\"');
+ int ind2 = nonStdOptions.indexOf('\"',ind+1);
+ if ((ind > -1) && (ind2 > -1)) { // dont tokenize within double quotes
+ String pre = nonStdOptions.substring(0,ind);
+ String quoted = nonStdOptions.substring(ind+1,ind2);
+ String post = nonStdOptions.substring(ind2+1,nonStdOptions.length());
+ tokens.addAll(tokenizeString(pre));
+ tokens.add(quoted);
+ tokens.addAll(tokenizeString(post));
+ } else {
+ tokens.addAll(tokenizeString(nonStdOptions));
+ }
+ String[] args = (String[])tokens.toArray(new String[]{});
+
+
+ // set the non-standard options in an alternate build config
+ // (we don't want to lose the settings we already have)
+ CountingMessageHandler counter
+ = CountingMessageHandler.makeCountingMessageHandler(msgHandlerAdapter);
+ AjBuildConfig altConfig = AjdtCommand.genBuildConfig(args, counter);
+ if (counter.hasErrors()) {
+ return;
+ }
+ // copy globals where local is not set
+ config.installGlobals(altConfig);
+ }
+
+ /** Local helper method for splitting option strings */
+ private List tokenizeString(String str) {
+ List tokens = new ArrayList();
+ StringTokenizer tok = new StringTokenizer(str);
+ while ( tok.hasMoreTokens() ) {
+ tokens.add(tok.nextToken());
+ }
+ return tokens;
+ }
+
+ /**
+ * Helper method to ask the messagehandler to handle the
+ * given message
+ */
+ private void handleMessage(Message msg) {
+ compiler.getMessageHandler().handleMessage(msg);
+ }
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java
new file mode 100644
index 000000000..9cc5ecfc9
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java
@@ -0,0 +1,50 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * 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:
+ * Xerox/PARC initial implementation
+ * Helen Hawkins converted to new interface (pr148190)
+ * ******************************************************************/
+
+
+package org.aspectj.ajde.core.internal;
+
+import org.aspectj.ajde.core.IBuildProgressMonitor;
+import org.aspectj.bridge.IProgressListener;
+
+/**
+ * Enables the compiler/weaver progres to be related to the user via the
+ * IBuildProgressMonitor as well as relating whether or not the user has
+ * cancelled the build progress back to the compiler/weaver.
+ */
+public class AjdeCoreBuildNotifierAdapter implements IProgressListener {
+
+ private IBuildProgressMonitor progressMonitor;
+
+ public AjdeCoreBuildNotifierAdapter(IBuildProgressMonitor progressMonitor) {
+ this.progressMonitor = progressMonitor;
+ }
+
+ public void setProgress(double percentDone) {
+ progressMonitor.setProgress(percentDone);
+ }
+
+ public void setText(String text) {
+ progressMonitor.setProgressText(text);
+ }
+
+ public boolean isCancelledRequested() {
+ return progressMonitor.isCancelRequested();
+ }
+
+ public void setCancelledRequested(boolean cancelRequested) {
+ // do nothing - since ask the progressMonitor whether
+ // cancel has been requested
+ }
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java
new file mode 100644
index 000000000..8cb53e047
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java
@@ -0,0 +1,47 @@
+/********************************************************************
+ * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ * Helen Hawkins - initial version (bug 148190)
+ *******************************************************************/
+package org.aspectj.ajde.core.internal;
+
+import org.aspectj.ajde.core.IBuildMessageHandler;
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessage.Kind;
+
+/**
+ * Enables the messages from the compiler/weaver to be passed on
+ * to the tool's implementation so they can handle it as they wish
+ */
+public class AjdeCoreMessageHandlerAdapter implements IMessageHandler {
+
+ private IBuildMessageHandler handler;
+
+ public AjdeCoreMessageHandlerAdapter(IBuildMessageHandler messageHandler) {
+ this.handler = messageHandler;
+ }
+
+ public void dontIgnore(Kind kind) {
+ handler.dontIgnore(kind);
+ }
+
+ public boolean handleMessage(IMessage message) throws AbortException {
+ return handler.handleMessage(message);
+ }
+
+ public void ignore(Kind kind) {
+ handler.ignore(kind);
+ }
+
+ public boolean isIgnoring(Kind kind) {
+ return handler.isIgnoring(kind);
+ }
+
+}
diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java
new file mode 100644
index 000000000..95c12daee
--- /dev/null
+++ b/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java
@@ -0,0 +1,48 @@
+/********************************************************************
+ * Copyright (c) 2006 Contributors.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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * Helen Hawkins converted to new interface (bug 148190)
+ *
+ *******************************************************************/
+package org.aspectj.ajde.core.internal;
+
+import java.io.File;
+import java.util.List;
+
+import org.aspectj.ajde.core.IOutputLocationManager;
+import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
+
+/**
+ * Enables the output locations detailed by the IOutputLocationManager
+ * implementation to be related to the comipler/weaver.
+ */
+public class OutputLocationAdapter implements CompilationResultDestinationManager {
+
+ private IOutputLocationManager locationManager;
+
+ public OutputLocationAdapter(IOutputLocationManager mgr) {
+ this.locationManager = mgr;
+ }
+
+ public File getOutputLocationForClass(File compilationUnit) {
+ return this.locationManager.getOutputLocationForClass(compilationUnit);
+ }
+
+ public File getOutputLocationForResource(File resource) {
+ return this.locationManager.getOutputLocationForResource(resource);
+ }
+
+ public List getAllOutputLocations() {
+ return this.locationManager.getAllOutputLocations();
+ }
+
+ public File getDefaultOutputLocation() {
+ return this.locationManager.getDefaultOutputLocation();
+ }
+}