From: Chris M. <cm...@us...> - 2006-04-28 04:40:41
|
User: cmicali Date: 06/04/27 21:40:37 Modified: etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn AndroMDA.VS80AddIn.csproj AssemblyInfo.cs MDASolutionManager.cs MavenProxy.cs VS80AddIn.cs etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Commands AddInCommandBase.cs etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils AddInUtils.cs etc/andromda-dotnet/AndroMDA.VS80AddIn Readme.doc Added: etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn AddIn.ico etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils AsyncOperation.cs VSExternalToolEventArgs.cs VSExternalToolProxy.cs Log: - Added better error handling when projects are not available on solution load - Added better error reporting when the common or core projects can not be found - Added a Reload MDA Config button that is displayed if the solution has MDA configuration files but the add-in could not be loaded for some reason - Fixed serious crash when the Stop button is pressed to stop maven - Rewrote maven proxy code to better handle the Stop button and properly close the running process - Improved error messages that can occur when running maven - Removed message boxes that appeared when errors occurred while running maven (messages are redirected to the output window) Revision Changes Path 1.4 +11 -2 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn.csproj Index: AndroMDA.VS80AddIn.csproj =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn.csproj,v retrieving revision 1.3 retrieving revision 1.4 diff -u -w -r1.3 -r1.4 --- AndroMDA.VS80AddIn.csproj 19 Apr 2006 23:30:52 -0000 1.3 +++ AndroMDA.VS80AddIn.csproj 28 Apr 2006 04:40:37 -0000 1.4 @@ -11,15 +11,17 @@ <NoStandardLibraries>false</NoStandardLibraries> <AssemblyName>AndroMDA.VS80AddIn</AssemblyName> <RootNamespace>AndroMDA.VS80AddIn</RootNamespace> + <ApplicationIcon>AddIn.ico</ApplicationIcon> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> + <OutputPath>C:\Documents and Settings\cmical\My Documents\Visual Studio 2005\AddIns\</OutputPath> <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging> <DefineConstants>DEBUG;TRACE</DefineConstants> <WarningLevel>4</WarningLevel> <IncrementalBuild>false</IncrementalBuild> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugSymbols>false</DebugSymbols> @@ -46,6 +48,7 @@ </Compile> <Compile Include="Commands\AboutCommand.cs" /> <Compile Include="Commands\AddInCommandBase.cs" /> + <Compile Include="Commands\ReloadMDAConfigCommand.cs" /> <Compile Include="Commands\OpenModelCommand.cs" /> <Compile Include="Commands\ResyncCommand.cs" /> <Compile Include="Commands\RunMavenCommand.cs" /> @@ -97,7 +100,6 @@ <DependentUpon>MDASolutionWizard.cs</DependentUpon> </Compile> <Compile Include="MavenProxy.cs" /> - <Compile Include="MavenProxyEventArgs.cs" /> <Compile Include="MDAProject.cs" /> <Compile Include="MDASolutionManager.cs" /> <Compile Include="MDASolutionProcessor.cs" /> @@ -140,8 +142,11 @@ <Compile Include="SharpZipLib\Zip\ZipNameTransform.cs" /> <Compile Include="SharpZipLib\Zip\ZipOutputStream.cs" /> <Compile Include="Utils\AddInUtils.cs" /> + <Compile Include="Utils\AsyncOperation.cs" /> <Compile Include="Utils\FileUtils.cs" /> + <Compile Include="Utils\VSExternalToolEventArgs.cs" /> <Compile Include="Utils\ValidationUtils.cs" /> + <Compile Include="Utils\VSExternalToolProxy.cs" /> <Compile Include="Utils\VSSolutionUtils.cs" /> <Compile Include="VS80AddIn.cs" /> <Compile Include="Wizard\Header.cs"> @@ -260,6 +265,7 @@ <Content Include="AndroMDA.VS80AddIn.AddIn"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="AddIn.ico" /> <None Include="Resources\maven.xml" /> <None Include="Resources\project.properties" /> <None Include="Resources\project.xml" /> @@ -284,6 +290,9 @@ <None Include="Resources\Lib\NHibernate.dll" /> <None Include="Resources\Lib\NHibernate.Nullables2.dll" /> </ItemGroup> + <ItemGroup> + <Folder Include="MavenProxy\" /> + </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> <PropertyGroup> <PreBuildEvent> 1.4 +1 -1 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/AssemblyInfo.cs Index: AssemblyInfo.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/AssemblyInfo.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -u -w -r1.3 -r1.4 --- AssemblyInfo.cs 19 Apr 2006 23:31:29 -0000 1.3 +++ AssemblyInfo.cs 28 Apr 2006 04:40:37 -0000 1.4 @@ -34,7 +34,7 @@ // You can specify all the value or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.1.0")] +[assembly: AssemblyVersion("1.0.2.0")] // // In order to sign your assembly you must specify a key to use. Refer to the 1.2 +81 -70 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/MDASolutionManager.cs Index: MDASolutionManager.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/MDASolutionManager.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- MDASolutionManager.cs 18 Apr 2006 16:14:43 -0000 1.1 +++ MDASolutionManager.cs 28 Apr 2006 04:40:37 -0000 1.2 @@ -14,6 +14,7 @@ using System.Resources; using System.Reflection; using System.Globalization; +using System.ComponentModel; #endregion @@ -27,6 +28,7 @@ #region Member variables private bool m_solutionIsUsingMDA = false; + private bool m_enabled = false; private DTE m_applicationObject = null; private ConfigFile m_projectProperties = new ConfigFile(); @@ -40,7 +42,8 @@ private bool m_restartBuild = false; private Mutex m_restartBuildMutex = new Mutex(false); - private MavenProxy m_mavenProxy = null; + //private MavenProxy m_mavenProxy = null; + private VSExternalToolProxy m_mavenProxy = null; private int m_progress; @@ -50,7 +53,7 @@ public bool IsMavenRunning { - get { return m_mavenProxy.IsMavenRunning; } + get { return m_mavenProxy.IsRunning; } } public bool RestartBuild @@ -76,7 +79,12 @@ public bool IsEnabled { - get { return m_solutionIsUsingMDA && m_applicationObject.Solution.IsOpen; } + get { return m_enabled && m_applicationObject.Solution.IsOpen; } + } + + public bool IsSolutionUsingMDA + { + get { return m_solutionIsUsingMDA; } } public DateTime? MavenLastRunDateTime @@ -145,12 +153,14 @@ { m_applicationObject = applicationObject; m_addInSettings = addInSettings; - m_mavenProxy = new MavenProxy(applicationObject, m_addInSettings); + m_mavenProxy = new MavenProxy(m_applicationObject, m_addInSettings); + m_mavenProxy.Completed += new EventHandler(m_mavenProxy_Completed); } public void OnSolutionOpened() { - m_solutionIsUsingMDA = IsSolutionUsingMDA(m_applicationObject.Solution); + m_solutionIsUsingMDA = MDAConfigFilesExist(m_applicationObject.Solution); + m_enabled = false; if (m_solutionIsUsingMDA) { try @@ -176,6 +186,8 @@ // Iterate through the projects and search for the core and common directories foreach (Project p in m_applicationObject.Solution.Projects) { + try + { // Get the project's directory string projectPath = FileUtils.GetPathFromFilename(p.FileName); @@ -197,27 +209,35 @@ m_commonProject = new MDAProject(p, FileUtils.GetFilename(projectPath), projectPath, generatedPath, string.Empty); } } + catch (NotImplementedException) + { + // Swallow this exception (it means the project was not loaded for some reason) + } + } // Show an error message if either the core or common projects could not be found if (m_coreProject == null || m_commonProject == null) { - string errorMessage = "The "; + string errorMessage = "The open solution appears to be using AndroMDA, but the "; if (m_coreProject == null) { errorMessage += "core "; if (m_commonProject == null) { errorMessage += "and "; } } - if (m_coreProject == null) { errorMessage += "common "; } - errorMessage += "project could not be found."; + if (m_commonProject == null) { errorMessage += "common "; } + errorMessage += "project"; + if (m_commonProject == null && m_coreProject == null) errorMessage += "s"; + errorMessage += " could not be found.\nThe AndroMDA add-in is being disabled. Please reload the solution or click Reload MDA Config."; throw new Exception(errorMessage); } m_solutionSettings = new ConfigFile(solutionPath + "\\mda\\vsmdaaddin.properties"); m_applicationObject.StatusBar.Highlight(false); m_applicationObject.StatusBar.Text = "AndroMDA: Configuration loaded."; + m_enabled = true; } catch (Exception e) { - m_solutionIsUsingMDA = false; - AddInUtils.ShowError(e.Message); + m_enabled = false; + AddInUtils.ShowWarning(e.Message); } } } @@ -263,23 +283,21 @@ public void StopMaven() { - if (m_mavenProxy.IsMavenRunning) - { - m_mavenProxy.StopMaven(); + m_mavenProxy.Stop(); MavenLastRunDateTime = null; } - } public void RunMaven() { if (IsEnabled) { + if (m_mavenProxy.OutputWindow == null) + { OutputWindowPane owp = GetOutputWindowPane("AndroMDA"); m_mavenProxy.OutputWindow = m_applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput); m_mavenProxy.OutputWindowPane = owp; - m_mavenProxy.SolutionPath = VSSolutionUtils.GetSolutionPath(m_applicationObject.Solution); - m_mavenProxy.OnMavenComplete += new MavenProxy.MavenCompleteDelegate(proxy_OnMavenComplete); - m_mavenProxy.RunMaven(); + } + m_mavenProxy.Start(); } else { @@ -287,14 +305,14 @@ } } - private void proxy_OnMavenComplete(MavenProxyEventArgs e) + void m_mavenProxy_Completed(object sender, EventArgs e) { + VSExternalToolEventArgs args = e as VSExternalToolEventArgs; bool restartBuild = m_restartBuild; - m_restartBuild = false; - switch (e.ExitStatus) - { - case MavenProxy.ExitStatus.Success: + RestartBuild = false; + switch (args.ExitStatus) { + case VSExternalToolProxy.ToolExitStatus.Success: MavenLastRunDateTime = DateTime.Now; m_applicationObject.StatusBar.Text = "AndroMDA: Generation successful."; m_applicationObject.StatusBar.Highlight(false); @@ -303,15 +321,9 @@ { m_applicationObject.ExecuteCommand("Build.BuildSolution", string.Empty); } - } break; - case MavenProxy.ExitStatus.ModelValidationFailed: - m_applicationObject.StatusBar.Text = "AndroMDA: Code generation canceled because the model validation failed."; - m_applicationObject.StatusBar.Highlight(true); - break; - case MavenProxy.ExitStatus.UnknownError: - m_applicationObject.StatusBar.Text = "AndroMDA: An error occured while running running maven."; - m_applicationObject.StatusBar.Highlight(true); + case VSExternalToolProxy.ToolExitStatus.Error: + m_applicationObject.StatusBar.Text = "AndroMDA: Generation failed"; break; } } @@ -445,7 +457,6 @@ return -1; } UpdateResyncProgressBar(projectName + "/" + item.Name); - // Get the UI nodes so we can collapse the projects UIHierarchy solutionExplorer = (UIHierarchy)m_applicationObject.Windows.Item(Constants.vsext_wk_SProjectWindow).Object; UIHierarchyItem uiCommonProject = null; @@ -625,7 +636,7 @@ return d1 > d2; } - private static bool IsSolutionUsingMDA(Solution currentSolution) + private static bool MDAConfigFilesExist(Solution currentSolution) { return System.IO.File.Exists(GetProjectPropertiesPath(currentSolution)); } 1.2 +180 -273 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/MavenProxy.cs Index: MavenProxy.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/MavenProxy.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- MavenProxy.cs 18 Apr 2006 16:14:43 -0000 1.1 +++ MavenProxy.cs 28 Apr 2006 04:40:37 -0000 1.2 @@ -5,7 +5,7 @@ #region Using statements using System; -using System.Collections.Generic; +using System.Collections; using System.Text; using System.Threading; using System.ComponentModel; @@ -21,279 +21,186 @@ namespace AndroMDA.VS80AddIn { - public class MavenProxy + public class MavenProxyKnownException : Exception { + public MavenProxyKnownException(string message) + : base(message) { } + public MavenProxyKnownException(string message, Exception innerException) + : base(message, innerException) { } + } - public enum ExitStatus { Success, ModelValidationFailed, UnknownError }; - - #region Delegates - - public delegate void MavenCompleteDelegate(MavenProxyEventArgs e); - - #endregion - - #region Member variables - - public event MavenCompleteDelegate OnMavenComplete; + public class MavenProxy : VSExternalToolProxy + { - private DTE m_applicationObject = null; - private System.Diagnostics.Process m_process = null; - private OutputWindowPane m_outputWindowPane = null; - private Window m_outputWindow = null; - private string m_solutionPath = string.Empty; - private System.Threading.Thread m_thread = null; - private Mutex m_processMutex = new Mutex(false); private AddInSettings m_addInSettings = null; - private string m_mavenExecutable = string.Empty; - private string m_commandLine = string.Empty; - private bool m_mavenRunning = false; - private MavenProxyEventArgs m_eventArgs; - - #endregion + private string m_mavenOptions; - #region Properties - - public bool IsMavenRunning - { - get + public MavenProxy(EnvDTE.DTE applicationObject, AddInSettings addInSettings) + : base(applicationObject) { - if (m_process == null) return false; - return m_mavenRunning; - /* - try - { - return !m_process.HasExited; - } - catch - { - return false; - } - */ - } - } + Initialize(applicationObject, addInSettings); - public System.Threading.Thread Thread - { - get { return m_thread; } } - public string SolutionPath + public MavenProxy(ISynchronizeInvoke target, EnvDTE.DTE applicationObject, AddInSettings addInSettings) : base(target, applicationObject) { - get { return m_solutionPath; } - set { m_solutionPath = value; } + Initialize(applicationObject, addInSettings); } - public Window OutputWindow + private void Initialize(EnvDTE.DTE applicationObject, AddInSettings addInSettings) { - get { return m_outputWindow; } - set { m_outputWindow = value; } + m_addInSettings = addInSettings; + this.Failed += new ThreadExceptionEventHandler(m_mavenProxy_Failed); + this.Cancelled += new EventHandler(m_mavenProxy_Cancelled); + this.ProcessStdOut += new ProcessTextDelegate(MavenProxy_ProcessOutput); + this.ProcessStdErr += new ProcessTextDelegate(MavenProxy_ProcessOutput); } - public OutputWindowPane OutputWindowPane + void m_mavenProxy_Cancelled(object sender, EventArgs e) { - get { return m_outputWindowPane; } - set { m_outputWindowPane = value; } + this.OutputWindowPane.OutputString("\n"); + this.OutputWindowPane.OutputString("Generation cancelled\n"); + ApplicationObject.StatusBar.Text = "AndroMDA: Generation cancelled"; } - public System.Diagnostics.Process Process - { - get { return m_process; } - set + void m_mavenProxy_Failed(object sender, ThreadExceptionEventArgs e) { - lock (this) + if (e.Exception is MavenProxyKnownException) { - // m_processMutex.WaitOne(); - m_process = value; - // m_processMutex.ReleaseMutex(); - } - } + this.OutputWindowPane.OutputString(e.Exception.Message); } - - #endregion - - public MavenProxy(DTE applicationObject, AddInSettings addInSettings) + else { - m_applicationObject = applicationObject; - m_addInSettings = addInSettings; + this.OutputWindowPane.OutputString("Error: An unhandled error occurred while attempting to run maven\n"); + this.OutputWindowPane.OutputString("Error: Exception details: " + e.Exception.Message + "\n"); + } + ApplicationObject.StatusBar.Text = "AndroMDA: Generation failed"; + ApplicationObject.StatusBar.Highlight(true); } - public void RunMaven() + void MavenProxy_ProcessOutput(ref string text, ref bool cancelOutput) { - m_mavenExecutable = m_addInSettings.MavenExecutablePath; - if (System.IO.File.Exists(m_mavenExecutable)) + if (text.Length > 0) { - ThreadStart startInfo = new System.Threading.ThreadStart(this.RunMavenThread); - m_thread = new System.Threading.Thread(startInfo); - if (m_addInSettings.MavenUseCustomCommandLine) + // Filter out the full java strack trace from any errors that occur when maven runs + if (text.Trim()[0] == '\t' || text.Contains(".java:") || text.Contains("(Native Method)")) { - m_commandLine = m_addInSettings.MavenCustomCommandLine; + cancelOutput = true; } else { - m_commandLine = "mda"; - if (m_addInSettings.MavenCleanFirst) + if (text.Contains("'jar:file:")) { - m_commandLine = "clean " + m_commandLine; ; + // Get rid of the jar: prefix from URLs so we don't scare the .NET people + text = text.Replace("'jar:file:", "'file:"); } - if (m_addInSettings.MavenUseOfflineMode) - { - m_commandLine = "-o " + m_commandLine; ; } } - m_outputWindow.Activate(); - m_outputWindowPane.Clear(); - m_outputWindowPane.OutputString("Launching 'maven " + m_commandLine + "'...\n\n"); - m_outputWindowPane.Activate(); - m_thread.Start(); - } - else - { - AddInUtils.ShowError("The maven executable could not be found. Please ensure the path is correct in the AndroMDA Add-In options page (Tools | Options | AndroMDA Add-In)"); - } } - public void StopMaven() + public override void BeforeStart() { - StopMaven(true); - } + ApplicationObject.StatusBar.Text = "AndroMDA: Generation started..."; + + this.OutputWindow.Activate(); + this.OutputWindowPane.Clear(); + this.OutputWindowPane.Activate(); + + this.ExecutablePath = m_addInSettings.MavenExecutablePath; - public void StopMaven(bool isCancel) + if (m_addInSettings.MavenUseCustomCommandLine) { - if (this.Process != null) + m_mavenOptions = m_addInSettings.MavenCustomCommandLine; + } + else { - m_thread.Abort(); - if (isCancel) + m_mavenOptions = "mda"; + if (m_addInSettings.MavenCleanFirst) { - m_outputWindowPane.OutputString("Generation canceled"); + m_mavenOptions = "clean " + m_mavenOptions; } - this.Process = null; - m_thread = null; - lock (this) { m_mavenRunning = false; } + if (m_addInSettings.MavenUseOfflineMode) + { + m_mavenOptions = "-o " + m_mavenOptions; } } - private void ReadStdOutput() - { - RedirectStream(m_process.StandardOutput); - } + this.OutputWindowPane.OutputString("Launching 'maven " + m_mavenOptions + "'...\n\n"); - private void ReadStdErr() - { - RedirectStream(m_process.StandardError); - } + string java_home = System.Environment.GetEnvironmentVariable("JAVA_HOME"); + string maven_home = System.Environment.GetEnvironmentVariable("MAVEN_HOME"); + string maven_home_local = System.Environment.GetEnvironmentVariable("MAVEN_HOME_LOCAL"); + string maven_java_exe = java_home + "\\bin\\java.exe"; + string maven_classpath = maven_home + "\\lib\\forehead-1.0-beta-5.jar"; + string maven_forehead_conf = maven_home + "\\bin\\forehead.conf"; + string maven_main_class = "com.werken.forehead.Forehead"; + string maven_endorsed = java_home + "\\lib\\endorsed;" + maven_home + "\\lib\\endorsed"; + string maven_opts = System.Environment.GetEnvironmentVariable("MAVEN_OPTS"); + string maven_cmd_line_args = m_mavenOptions; - private void RedirectStream(System.IO.StreamReader sr) - { - string str; - while ( - m_mavenRunning && - (str = sr.ReadLine()) != null - ) - { - if (sr == m_process.StandardError && m_eventArgs.OuputOccuredOnStdErr == false) + if (java_home == null || java_home == string.Empty) { - lock (this) { m_eventArgs.OuputOccuredOnStdErr = true; } + throw new MavenProxyKnownException("Error: Maven cannot run because the JAVA_HOME environment variable is not set.\nError: Please check your java installation."); } - if (str.ToLower().Contains("model validation failed")) - { - lock (this) { m_eventArgs.ExitStatus = ExitStatus.ModelValidationFailed; } - } -// if (str.Length > 0 && str[0] == '\t') - // Remove stack trace lines - if (str.Length > 0 && (str.Trim()[0] == '\t' || str.Contains(".java:") || str.Contains("(Native Method)"))) + if (maven_home == null || maven_home == string.Empty) { - //m_outputWindowPane.OutputString("(erase)"); + throw new MavenProxyKnownException("Error: Maven cannot run because the MAVEN_HOME environment variable is not set.\nError: Please check that maven 1.x has been correctly installed."); } - else + + if (!System.IO.File.Exists(maven_classpath) || !System.IO.File.Exists(maven_forehead_conf)) { - m_outputWindowPane.OutputString(str + "\n"); - } - System.Threading.Thread.Sleep(0); - } + throw new MavenProxyKnownException("Error: Although the MAVEN_HOME variable was set, maven could not be found.\nError: Please check that maven 1.x has been correctly installed."); } - private void RunMavenThread() + if (maven_opts == null || maven_opts == string.Empty) { + maven_opts = "-Xmx256m"; + } - // Set up process info. - System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(); - psi.FileName = m_mavenExecutable; - psi.Arguments = m_commandLine; - psi.WorkingDirectory = m_solutionPath; - psi.CreateNoWindow = true; - psi.UseShellExecute = false; - psi.RedirectStandardOutput = true; - psi.RedirectStandardError = true; - - // Create the process. - this.Process = new System.Diagnostics.Process(); - - // Associate process info with the process. - m_process.StartInfo = psi; - - System.Threading.Thread stdOutThread = null; - System.Threading.Thread stdErrThread = null; - ThreadStart tstart = null; - tstart = new ThreadStart(ReadStdOutput); - stdOutThread = new System.Threading.Thread(tstart); - tstart = new ThreadStart(ReadStdErr); - stdErrThread = new System.Threading.Thread(tstart); + this.ExecutablePath = maven_java_exe; + this.CommandLine = "-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl " + + "-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl " + + "\"-Dmaven.home=" + maven_home + "\" "; - try + if (maven_home_local != null && maven_home_local != string.Empty) { - // Run the process. - lock (this) { m_mavenRunning = true; } - m_eventArgs = new MavenProxyEventArgs(); - lock (this) { m_eventArgs.OuputOccuredOnStdErr = false; } - bool fStarted = m_process.Start(); + this.CommandLine += "\"-Dmaven.home.local=" + maven_home_local + "\" "; + } - m_applicationObject.MainWindow.SetFocus(); + this.CommandLine = this.CommandLine + + "\"-Dtools.jar=" + java_home + "\\lib\\tools.jar\" " + + "\"-Dforehead.conf.file=" + maven_forehead_conf + "\" " + + "-Djava.endorsed.dirs=\"" + maven_endorsed + "\" " + + maven_opts + " " + + "-classpath \"" + maven_classpath + "\" \"" + maven_main_class + "\" "; - stdOutThread.Start(); - stdErrThread.Start(); + this.CommandLine += maven_cmd_line_args; - // Loop until the process has completed - while (!this.Process.HasExited) - { - System.Threading.Thread.Sleep(500); + base.BeforeStart(); } - m_eventArgs.ExitCode = m_process.ExitCode; - if (m_process.ExitCode == 0 && m_eventArgs.OuputOccuredOnStdErr == false) + + protected override void DoWork() { - lock (this) { m_eventArgs.ExitStatus = ExitStatus.Success; } - } - lock (this) { m_mavenRunning = false; } - } - catch (System.Threading.ThreadAbortException) + this.WorkingDirectory = VSSolutionUtils.GetSolutionPath(this.ApplicationObject.Solution); + ApplicationObject.StatusBar.Text = "AndroMDA: Generation Progress"; + try { - lock (this) { m_mavenRunning = false; } - this.Process = null; + base.DoWork(); } - catch (Exception e) + catch (System.ComponentModel.Win32Exception we) { - if (e.Message != "Thread was being aborted.") + if (we.Message == "The system cannot find the file specified") { - m_outputWindowPane.OutputString("error: An unhandled error occurred while attempting to run maven\n"); - m_outputWindowPane.OutputString("error: Exception details: " + e.Message + "\n"); + throw new MavenProxyKnownException("Error: The java executable could not be found to run maven.\nError: Please check your java installation and ensure that the JAVA_HOME variable is set correctly\n"); } - this.Process = null; -// CommandBars c = (CommandBars)m_applicationObject.CommandBars; - lock (this) { m_mavenRunning = false; } + else { throw; } } - // Fire the processing complete event - if (OnMavenComplete != null) - { - if (OnMavenComplete.Target is System.Windows.Forms.Control) + VSExternalToolEventArgs args = this.EventArguments as VSExternalToolEventArgs; + if (args.ExitCode != 0) { - System.Windows.Forms.Control target = OnMavenComplete.Target as System.Windows.Forms.Control; - target.BeginInvoke(OnMavenComplete, new Object[] { m_eventArgs }); - } - else - { - OnMavenComplete(m_eventArgs); - } + args.ExitStatus = ToolExitStatus.Error; } } 1.2 +14 -19 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/VS80AddIn.cs Index: VS80AddIn.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/VS80AddIn.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- VS80AddIn.cs 18 Apr 2006 16:14:43 -0000 1.1 +++ VS80AddIn.cs 28 Apr 2006 04:40:37 -0000 1.2 @@ -75,18 +75,19 @@ m_commands.Clear(); // Add commands to the add-in + m_commands.Add(new ReloadMDAConfigCommand()); m_commands.Add(new RunSolutionWizardCommand()); m_commands.Add(new RunMavenCommand()); m_commands.Add(new ResyncCommand()); m_commands.Add(new StopCommand()); m_commands.Add(new OpenModelCommand()); m_commands.Add(new AboutCommand()); - // Set the context for each command foreach (AddInCommandBase cmd in m_commands) { cmd.SetContext(m_applicationObject, m_addInInstance, m_solutionManager, m_addInSettings); } + } /// <summary> @@ -118,20 +119,14 @@ string command_line = m_applicationObject.CommandLineArguments.ToLower(); foreach (string sw in new string[] { "/build", "/rebuild", "/clean", "/deploy" }) { if (command_line.IndexOf(sw) != -1) return; } - try - { m_addInSettings = new AddInSettings(m_applicationObject); m_solutionManager = new MDASolutionManager(m_applicationObject, m_addInSettings); BindEvents(); CreateCommands(); RegisterCommands(); RegisterToolbar(); - } - finally - { m_connected = true; } - } catch (Exception e) { AddInUtils.ShowError("An exception occured while trying to instantiate the add-in: " + e.ToString()); 1.1 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/AddIn.ico <<Binary file>> 1.2 +17 -3 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Commands/AddInCommandBase.cs Index: AddInCommandBase.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Commands/AddInCommandBase.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- AddInCommandBase.cs 18 Apr 2006 16:14:44 -0000 1.1 +++ AddInCommandBase.cs 28 Apr 2006 04:40:37 -0000 1.2 @@ -20,7 +20,7 @@ #region Enumerations - public enum AddInCommandType { AlwaysEnabled, NoMDAAlwaysEnabled, MDAAlwaysEnabled, MDAEnabledWhileMavenNotRunning, MDAEnabledWhileMavenRunning } + public enum AddInCommandType { AlwaysEnabled, NoMDAAlwaysEnabled, MDADisabled, MDAAlwaysEnabled, MDAEnabledWhileMavenNotRunning, MDAEnabledWhileMavenRunning } #endregion @@ -57,6 +57,11 @@ get { return m_name; } } + public CommandBarControl CommandBarControl + { + get { return m_commandBarButton; } + } + #endregion public AddInCommandBase() @@ -144,9 +149,18 @@ case AddInCommandType.AlwaysEnabled: status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; break; - + case AddInCommandType.MDADisabled: + if (!m_solutionManager.IsEnabled && m_solutionManager.IsSolutionUsingMDA && m_application.Solution.IsOpen) + { + status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; + } + else + { + status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusInvisible; + } + break; case AddInCommandType.NoMDAAlwaysEnabled: - if (!m_solutionManager.IsEnabled && m_application.Solution.IsOpen) + if (!m_solutionManager.IsEnabled && !m_solutionManager.IsSolutionUsingMDA && m_application.Solution.IsOpen) { status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; } 1.2 +5 -0 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils/AddInUtils.cs Index: AddInUtils.cs =================================================================== RCS file: /cvsroot/andromdaplugins/plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils/AddInUtils.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- AddInUtils.cs 18 Apr 2006 16:14:47 -0000 1.1 +++ AddInUtils.cs 28 Apr 2006 04:40:37 -0000 1.2 @@ -20,5 +20,10 @@ System.Windows.Forms.MessageBox.Show(errorMessage, "AndroMDA Add-In Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } + public static void ShowWarning(string errorMessage) + { + System.Windows.Forms.MessageBox.Show(errorMessage, "AndroMDA Add-In", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); + } + } } 1.1 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils/AsyncOperation.cs Index: AsyncOperation.cs =================================================================== // AndroMDA Visual Studio 2005 Add-In // (c)2006 Sapient Corporation // AsyncOperation.cs - A base class for cancellable operations // (C) 2001-2002 I D Griffiths // // This base class is designed to be used by lengthy operations that wish to // support cancellation. #region Using statements using System; using System.Windows.Forms; using System.Threading; using System.ComponentModel; #endregion namespace AndroMDA.VS80AddIn { /// <summary> /// Exception thrown by AsyncUtils.AsyncOperation.Start when an /// operation is already in progress. /// </summary> public class AlreadyRunningException : System.ApplicationException { public AlreadyRunningException() : base("Asynchronous operation already running") { } } public abstract class AsyncOperation { /// <summary> /// Initialises an AsyncOperation with an association to the /// supplied ISynchronizeInvoke. All events raised from this /// object will be delivered via this target. (This might be a /// Control object, so events would be delivered to that Control's /// UI thread.) /// </summary> /// <param name="target">An object implementing the /// ISynchronizeInvoke interface. All events will be delivered /// through this target, ensuring that they are delivered to the /// correct thread.</param> public AsyncOperation() { isiTarget = null; isRunning = false; eventArguments = EventArgs.Empty; } public AsyncOperation(ISynchronizeInvoke target) { isiTarget = target; isRunning = false; eventArguments = EventArgs.Empty; } public abstract void BeforeStart(); /// <summary> /// Launch the operation on a worker thread. This method will /// return immediately, and the operation will start asynchronously /// on a worker thread. /// </summary> public void Start() { lock (this) { if (isRunning) { throw new AlreadyRunningException(); } // Set this flag here, not inside InternalStart, to avoid // race condition when Start called twice in quick // succession. isRunning = true; try { BeforeStart(); ThreadStart ts = new ThreadStart(InternalStart); workerThread = new Thread(ts); } catch (Exception e) { FailOperation(e); return; } } workerThread.Start(); //new MethodInvoker(InternalStart).BeginInvoke(null, null); } Thread workerThread; /// <summary> /// Attempt to cancel the current operation. This returns /// immediately to the caller. No guarantee is made as to /// whether the operation will be successfully cancelled. All /// that can be known is that at some point, one of the /// three events Completed, Cancelled, or Failed will be raised /// at some point. /// </summary> public void Cancel() { lock (this) { cancelledFlag = true; } } /// <summary> /// Attempt to cancel the current operation and block until either /// the cancellation succeeds or the operation completes. /// </summary> /// <returns>true if the operation was successfully cancelled /// or it failed, false if it ran to completion.</returns> public bool CancelAndWait() { lock (this) { // Set the cancelled flag cancelledFlag = true; // Now sit and wait either for the operation to // complete or the cancellation to be acknowledged. // (Wake up and check every second - shouldn't be // necessary, but it guarantees we won't deadlock // if for some reason the Pulse gets lost - means // we don't have to worry so much about bizarre // race conditions.) while (!IsDone) { Monitor.Wait(this, 1000); } } return !HasCompleted; } /// <summary> /// Blocks until the operation has either run to completion, or has /// been successfully cancelled, or has failed with an internal /// exception. /// </summary> /// <returns>true if the operation completed, false if it was /// cancelled before completion or failed with an internal /// exception.</returns> public bool WaitUntilDone() { lock (this) { // Wait for either completion or cancellation. As with // CancelAndWait, we don't sleep forever - to reduce the // chances of deadlock in obscure race conditions, we wake // up every second to check we didn't miss a Pulse. while (!IsDone) { Monitor.Wait(this, 1000); } } return HasCompleted; } /// <summary> /// Returns false if the operation is still in progress, or true if /// it has either completed successfully, been cancelled /// successfully, or failed with an internal exception. /// </summary> public bool IsDone { get { lock (this) { return completeFlag || cancelAcknowledgedFlag || failedFlag; } } } /// <summary> /// This event will be fired if the operation runs to completion /// without being cancelled. This event will be raised through the /// ISynchronizeTarget supplied at construction time. Note that /// this event may still be received after a cancellation request /// has been issued. (This would happen if the operation completed /// at about the same time that cancellation was requested.) But /// the event is not raised if the operation is cancelled /// successfully. /// </summary> public event EventHandler Completed; /// <summary> /// This event will be fired when the operation is successfully /// stoped through cancellation. This event will be raised through /// the ISynchronizeTarget supplied at construction time. /// </summary> public event EventHandler Cancelled; /// <summary> /// This event will be fired if the operation throws an exception. /// This event will be raised through the ISynchronizeTarget /// supplied at construction time. /// </summary> public event System.Threading.ThreadExceptionEventHandler Failed; /// <summary> /// The ISynchronizeTarget supplied during construction - this can /// be used by deriving classes which wish to add their own events. /// </summary> protected ISynchronizeInvoke Target { get { return isiTarget; } } private ISynchronizeInvoke isiTarget; /// <summary> /// To be overridden by the deriving class - this is where the work /// will be done. The base class calls this method on a worker /// thread when the Start method is called. /// </summary> protected abstract void DoWork(); /// <summary> /// Flag indicating whether the request has been cancelled. Long- /// running operations should check this flag regularly if they can /// and cancel their operations as soon as they notice that it has /// been set. /// </summary> protected bool CancelRequested { get { lock (this) { return cancelledFlag; } } } private bool cancelledFlag; /// <summary> /// Flag indicating whether the request has run through to /// completion. This will be false if the request has been /// successfully cancelled, or if it failed. /// </summary> protected bool HasCompleted { get { lock (this) { return completeFlag; } } } private bool completeFlag; /// <summary> /// This is called by the operation when it wants to indicate that /// it saw the cancellation request and honoured it. /// </summary> protected void AcknowledgeCancel() { lock (this) { cancelAcknowledgedFlag = true; isRunning = false; /* if (workerThread.IsAlive) { workerThread.Abort(); } */ // Pulse the event in case the main thread is blocked // waiting for us to finish (e.g. in CancelAndWait or // WaitUntilDone). Monitor.Pulse(this); // Using async invocation to avoid a potential deadlock // - using Invoke would involve a cross-thread call // whilst we still held the object lock. If the event // handler on the UI thread tries to access this object // it will block because we have the lock, but using // async invocation here means that once we've fired // the event, we'll run on and release the object lock, // unblocking the UI thread. FireAsync(Cancelled, this, EventArguments); } } private bool cancelAcknowledgedFlag; // Set to true if the operation fails with an exception. private bool failedFlag; // Set to true if the operation is running private bool isRunning; public bool IsRunning { get { return isRunning; } } protected EventArgs EventArguments { get { lock (this) { return eventArguments; } } set { lock (this) { eventArguments = value; } } } private EventArgs eventArguments; // This method is called on a worker thread (via asynchronous // delegate invocation). This is where we call the operation (as // defined in the deriving class's DoWork method). private void InternalStart() { // Reset our state - we might be run more than once. cancelledFlag = false; completeFlag = false; cancelAcknowledgedFlag = false; failedFlag = false; // isRunning is set during Start to avoid a race condition try { DoWork(); } catch (ThreadAbortException) { } catch (Exception e) { // Raise the Failed event. We're in a catch handler, so we // had better try not to throw another exception. try { FailOperation(e); } catch (Exception) { } /* // The documentation recommends not catching // SystemExceptions, so having notified the caller we // rethrow if it was one of them. if (e is SystemException) { throw; } */ } lock (this) { // If the operation wasn't cancelled (or if the UI thread // tried to cancel it, but the method ran to completion // anyway before noticing the cancellation) and it // didn't fail with an exception, then we complete the // operation - if the UI thread was blocked waiting for // cancellation to complete it will be unblocked, and // the Completion event will be raised. if (!cancelAcknowledgedFlag && !failedFlag) { CompleteOperation(); } } } // This is called when the operation runs to completion. // (This is private because it is called automatically // by this base class when the deriving class's DoWork // method exits without having cancelled private void CompleteOperation() { lock (this) { completeFlag = true; isRunning = false; Monitor.Pulse(this); // See comments in AcknowledgeCancel re use of // Async. FireAsync(Completed, this, EventArguments); } } private void FailOperation(Exception e) { lock (this) { failedFlag = true; isRunning = false; Monitor.Pulse(this); FireAsync(Failed, this, new ThreadExceptionEventArgs(e)); } } // Utility function for firing an event through the target. // It uses C#'s variable length parameter list support // to build the parameter list. // This functions presumes that the caller holds the object lock. // (This is because the event list is typically modified on the UI // thread, but events are usually raised on the worker thread.) protected void FireAsync(Delegate dlg, params object[] pList) { if (dlg != null) { if (Target is Control) Target.BeginInvoke(dlg, pList); else dlg.Method.Invoke(dlg.Target, pList); } } } } 1.1 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils/VSExternalToolEventArgs.cs Index: VSExternalToolEventArgs.cs =================================================================== // AndroMDA Visual Studio 2005 Add-In // (c)2006 Sapient Corporation #region Using statements using System; using System.Collections.Generic; using System.Text; #endregion namespace AndroMDA.VS80AddIn { public class VSExternalToolEventArgs : EventArgs { private VSExternalToolProxy.ToolExitStatus m_exitStatus; private string m_errorMessage; private int m_exitCode; public VSExternalToolProxy.ToolExitStatus ExitStatus { get { return m_exitStatus; } set { m_exitStatus = value; } } public int ExitCode { get { return m_exitCode; } set { m_exitCode = value; } } public string ErrorMessage { get { return m_errorMessage; } set { m_errorMessage = value; } } public VSExternalToolEventArgs() { m_exitStatus = VSExternalToolProxy.ToolExitStatus.DidNotExit; m_exitCode = 0; m_errorMessage = string.Empty; } public VSExternalToolEventArgs(VSExternalToolProxy.ToolExitStatus exitStatus, int exitCode, string errorMessage) { m_exitStatus = exitStatus; m_exitCode = exitCode; m_errorMessage = errorMessage; } } } 1.1 plugins/etc/andromda-dotnet/AndroMDA.VS80AddIn/AndroMDA.VS80AddIn/Utils/VSExternalToolProxy.cs Index: VSExternalToolProxy.cs =================================================================== // AndroMDA Visual Studio 2005 Add-In // (c)2006 Sapient Corporation #region Using statements using System; using System.Collections; using System.Collections.Specialized; using System.Text; using System.Threading; using System.ComponentModel; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; #endregion namespace AndroMDA.VS80AddIn { public class VSExternalToolProxy : AsyncOperation { public delegate void ProcessTextDelegate(ref string text, ref bool cancelOutput); public event ProcessTextDelegate ProcessStdOut; public event ProcessTextDelegate ProcessStdErr; public enum ToolExitStatus { DidNotExit, Cancelled, Error, Success }; private string m_executablePath = string.Empty; private string m_workingDirectory = string.Empty; private string m_commandLine = string.Empty; private EnvDTE.DTE m_applicationObject = null; private EnvDTE.OutputWindowPane m_outputWindowPane = null; private EnvDTE.Window m_outputWindow = null; private NameValueCollection m_environmentVariables = new NameValueCollection(); public ArrayList m_outputLines; public string m_output = string.Empty; public string Output { get { if (m_output == string.Empty) { lock (m_outputLines.SyncRoot) { foreach (string s in m_outputLines) { m_output += s; } } } return m_output; } } public ArrayList OutputLines { get { return ArrayList.Synchronized(m_outputLines); } } public NameValueCollection EnvironmentVariables { get { return m_environmentVariables; } set { m_environmentVariables = value; } } public EnvDTE.DTE ApplicationObject { get { return m_applicationObject; } } public EnvDTE.Window OutputWindow { get { return m_outputWindow; } set { m_outputWindow = value; } } public EnvDTE.OutputWindowPane OutputWindowPane { get { return m_outputWindowPane; } set { m_outputWindowPane = value; } } public string CommandLine { get { return m_commandLine; } set { m_commandLine = value; } } public string WorkingDirectory { get { return m_workingDirectory; } set { m_workingDirectory = value; } } public string ExecutablePath { get { return m_executablePath; } set { m_executablePath = value; } } public VSExternalToolProxy(EnvDTE.DTE applicationObject) : base() { m_applicationObject = applicationObject; } public VSExternalToolProxy(ISynchronizeInvoke target, EnvDTE.DTE applicationObject) : base(target) { m_applicationObject = applicationObject; } public override void BeforeStart() { m_psi = new System.Diagnostics.ProcessStartInfo(); foreach (string key in m_environmentVariables.Keys) { m_psi.EnvironmentVariables.Add(key, m_environmentVariables[key]); } m_output = string.Empty; m_outputLines = new ArrayList(); } public void Stop() { if (this.IsRunning) { this.CancelAndWait(); } } private void RedirectStream(object parameters) { object[] paramlist = parameters as object[]; System.IO.StreamReader sr = paramlist[0] as System.IO.StreamReader; bool isStdErr = (bool)paramlist[1] ; if (sr == null) { return; } string str; bool cancelOutput; while (this.IsRunning && !CancelRequested && (str = sr.ReadLine()) != null) { cancelOutput = false; if (isStdErr) { ProcessStdErr(ref str, ref cancelOutput); } else { ProcessStdOut(ref str, ref cancelOutput); } /* if (str.ToLower().Contains("model validation failed")) { lock (this) { m_eventArgs.ExitStatus = ExitStatus.ModelValidationFailed; } } */ if (!cancelOutput) { this.OutputLines.Add(str); m_outputWindowPane.OutputString(str + "\n"); } System.Threading.Thread.Sleep(0); } } System.Diagnostics.ProcessStartInfo m_psi = null; protected override void DoWork() { Process toolProcess = new Process(); // Set up process info. System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(); m_psi.FileName = m_executablePath; m_psi.Arguments = m_commandLine; m_psi.WorkingDirectory = m_workingDirectory; m_psi.CreateNoWindow = true; m_psi.UseShellExecute = false; m_psi.RedirectStandardOutput = true; m_psi.RedirectStandardError = true; // Associate process info with the process. toolProcess.StartInfo = m_psi; VSExternalToolEventArgs eventArguments = new VSExternalToolEventArgs(); this.EventArguments = eventArguments; if (CancelRequested) { eventArguments.ExitStatus = ToolExitStatus.Cancelled; AcknowledgeCancel(); return; } if (!toolProcess.Start()) { throw new Exception("External tool failed to start"); } try { Thread stdoutThread = new Thread(new ParameterizedThreadStart(RedirectStream)); Thread stderrThread = new Thread(new ParameterizedThreadStart(RedirectStream)); m_applicationObject.MainWindow.SetFocus(); stdoutThread.Start(new object[] { toolProcess.StandardOutput, false }); stderrThread.Start(new object[] { toolProcess.StandardError, true }); // Loop until the process has completed while (!toolProcess.WaitForExit(250) && !CancelRequested) { } if (!CancelRequested) { ev... [truncated message content] |