From: Daniel C. \(kzu\) <dca...@us...> - 2005-01-03 17:51:59
|
Update of /cvsroot/mvp-xml/Design/v1/src/CustomTools/ResX In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9289/v1/src/CustomTools/ResX Added Files: ResX2Cs.cs ResX2CsConstants.cs ResXTool.cs Log Message: Initial version of XmlValidate custom tool and ResX two Class tool. --- NEW FILE: ResX2CsConstants.cs --- using System; using System.CodeDom; using System.Collections; using System.IO; using System.Reflection; using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; using System.Xml.Serialization; using Microsoft.ApplicationBlocks.IPE.Transformations.ComponentModel; namespace Microsoft.ApplicationBlocks.IPE.Transformations.Tests.Assets.ResX { /// <summary> /// Generates a resource file. /// </summary> public class ResX2CsConstants : TaskBase { #region Constants public const string FileNameParameter = "FileName"; public const string TargetNamespaceParameter = "TargetNamespace"; private const string SkeletonSnippet = @" private static ResourceManager _resourceManager = new ResourceManager( typeof( SR ).FullName, typeof( SR ).Module.Assembly ); private SR() {} /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The object resource.</returns> internal static object GetObject( string key ) { return _resourceManager.GetObject( key ); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The string resource.</returns> internal static string GetString( string key ) { return _resourceManager.GetString( key ); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/> and /// formats it with the arguments received. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <param name='args'>The arguments to format the resource with.</param> /// <returns>The string resource.</returns> internal static string GetString ( string key, params object[] args ) { return String.Format( GetString( key ), args ); } "; private readonly Regex ValueWithParams = new Regex(@"(?<={)\d+(?=})", RegexOptions.Compiled); #endregion Constants #region ITask Members public override void Run() { IParameterService prms = ( IParameterService ) GetService( typeof( IParameterService ) ); string file = ( string )prms[FileNameParameter]; string target = ( string )prms[TargetNamespaceParameter]; CodeCompileUnit unit = new CodeCompileUnit(); CodeNamespace ns = new CodeNamespace( target ); unit.Namespaces.Add( ns ); ns.Imports.Add( new CodeNamespaceImport( "System" ) ); ns.Imports.Add( new CodeNamespaceImport( "System.Resources" ) ); ns.Imports.Add( new CodeNamespaceImport( "System.Threading" ) ); CodeCommentStatement remarks = new CodeCommentStatement( "<remaks/>", true ); using ( FileStream fs = new FileStream( file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) { XPathDocument doc = new XPathDocument( fs ); CodeTypeDeclaration sr = new CodeTypeDeclaration( "SR" ); sr.TypeAttributes = TypeAttributes.NestedAssembly | TypeAttributes.Sealed; sr.Comments.Add(new CodeCommentStatement( "<summary>Contains resources for the application.</summary>", true)); ns.Types.Add( sr ); // Add the default snippet. sr.Members.Add( new CodeSnippetTypeMember( SkeletonSnippet ) ); XPathNodeIterator it = doc.CreateNavigator().Select( "/root/data" ); while ( it.MoveNext() ) { // Work with a copy to avoid cursor movements. string key = it.Current.GetAttribute( "name", String.Empty ); if ( key != null ) { // Remove invalid characters from name chosen by the user. string name = CodeIdentifier.MakeValid( key ); // We can use a property as it's a simple object/string. CodeMemberField fld = new CodeMemberField(typeof(string), name); fld.Attributes = MemberAttributes.Const | MemberAttributes.Public; fld.InitExpression = new CodePrimitiveExpression(name); sr.Members.Add( fld ); } } } IOutputService output = ( IOutputService ) GetService( typeof ( IOutputService ) ); output.Add( OutputKey.CodeDom, unit ); } #endregion } } --- NEW FILE: ResX2Cs.cs --- using System; using System.CodeDom; using System.Collections; using System.IO; using System.Reflection; using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; using System.Xml.Serialization; using Microsoft.ApplicationBlocks.IPE.Transformations.ComponentModel; namespace Microsoft.ApplicationBlocks.IPE.Transformations.Tests.Assets.ResX { /// <summary> /// Generates a typed class for a resource file /// <see cref="XmlWriter"/>. /// </summary> public class ResX2Cs : TaskBase { #region Constants public const string FileNameParameter = "FileName"; public const string TargetNamespaceParameter = "TargetNamespace"; private const string SkeletonSnippet = @" private static ResourceManager _resourceManager = new ResourceManager( typeof( SR ).FullName, typeof( SR ).Module.Assembly ); private SR() {} /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The object resource.</returns> internal static object GetObject( string key ) { return _resourceManager.GetObject( key ); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/>. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <returns>The string resource.</returns> internal static string GetString( string key ) { return _resourceManager.GetString( key ); } /// <summary> /// Gets the specified resource for the <see cref='Thread.CurrentUICulture'/> and /// formats it with the arguments received. /// </summary> /// <param name='key'>The key of the resource to retrieve.</param> /// <param name='args'>The arguments to format the resource with.</param> /// <returns>The string resource.</returns> internal static string GetString ( string key, params object[] args ) { return String.Format( GetString( key ), args ); } "; private readonly Regex ValueWithParams = new Regex(@"(?<={)\d+(?=})", RegexOptions.Compiled); #endregion Constants #region ITask Members public override void Run() { IParameterService prms = ( IParameterService ) GetService( typeof( IParameterService ) ); string file = ( string )prms[FileNameParameter]; string target = ( string )prms[TargetNamespaceParameter]; CodeCompileUnit unit = new CodeCompileUnit(); CodeNamespace ns = new CodeNamespace( target ); unit.Namespaces.Add( ns ); ns.Imports.Add( new CodeNamespaceImport( "System" ) ); ns.Imports.Add( new CodeNamespaceImport( "System.Resources" ) ); ns.Imports.Add( new CodeNamespaceImport( "System.Threading" ) ); CodeCommentStatement remarks = new CodeCommentStatement( "<remaks/>", true ); using ( FileStream fs = new FileStream( file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) { XPathDocument doc = new XPathDocument( fs ); CodeTypeDeclaration sr = new CodeTypeDeclaration( "SR" ); sr.TypeAttributes = TypeAttributes.NestedAssembly | TypeAttributes.Sealed; sr.Comments.Add(new CodeCommentStatement( "<summary>Contains resources for the application.</summary>", true)); ns.Types.Add( sr ); // Add the default snippet. sr.Members.Add( new CodeSnippetTypeMember( SkeletonSnippet ) ); XPathNodeIterator it = doc.CreateNavigator().Select( "/root/data" ); while ( it.MoveNext() ) { // Work with a copy to avoid cursor movements. XPathNavigator item = it.Current.Clone(); string key = item.GetAttribute( "name", String.Empty ); if ( key != null ) { string type = item.GetAttribute( "type", String.Empty ); if ( type == null ) type = "System.String"; // Remove invalid characters from name chosen by the user. string name = CodeIdentifier.MakeValid( key ); // Get the value used to check for parameters. string value = String.Empty; item.MoveToFirstChild(); if (item.LocalName == "value") value = item.Value; // Build the call to GetString/GetObject CodeMethodInvokeExpression getres = new CodeMethodInvokeExpression(); // Build the return statement. CodeMethodReturnStatement ret = new CodeMethodReturnStatement(); // Will hold the member that is to be added to the SR class. CodeTypeMember member = null; // If type is not string, modify GetString with GetObject and cast to type. if (type != "System.String") { getres.Method = new CodeMethodReferenceExpression( new CodeTypeReferenceExpression( "SR" ), "GetObject"); ret.Expression = new CodeCastExpression(type, getres); } else { getres.Method = new CodeMethodReferenceExpression( new CodeTypeReferenceExpression( "SR" ), "GetString"); ret.Expression = getres; } if (ValueWithParams.IsMatch( value ) ) { // We have a value that receives parameters. Make a method instead of a property. CodeMemberMethod method = new CodeMemberMethod(); method.ReturnType = new CodeTypeReference(type); method.Name = name; Match p = ValueWithParams.Match( value ); while ( p.Success ) { method.Parameters.Add( new CodeParameterDeclarationExpression( typeof(object), "arg" + p.Value ) ); getres.Parameters.Add( new CodeFieldReferenceExpression( null, "arg" + p.Value) ); p = p.NextMatch(); } method.Statements.Add( ret ); // Set as the member to add. member = method; } else { // We can use a property as it's a simple object/string. CodeMemberProperty prop = new CodeMemberProperty(); prop.Type = new CodeTypeReference(type); prop.Name = name; prop.GetStatements.Add( ret ); // Set as the member to add. member = prop; } // Add the first parameter to the call which is always the key. getres.Parameters.Insert(0, new CodePrimitiveExpression( key ) ); string comment = ( string ) it.Current.Evaluate( "string( comment/text() )" ); if ( comment != null ) { member.Comments.Add( new CodeCommentStatement( "<summary>" + comment.Replace( "\r", "" ).Replace( "\n", "" ).Replace( "\t", "" ) + "</summary>", true ) ); } member.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static; sr.Members.Add( member ); } } } IOutputService output = ( IOutputService ) GetService( typeof ( IOutputService ) ); output.Add( OutputKey.CodeDom, unit ); } #endregion } } --- NEW FILE: ResXTool.cs --- #region using using System; using System.CodeDom; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Xml; using System.Xml.XPath; using EnvDTE; using VSLangProj; #endregion namespace Mvp.Xml.Design.CustomTools.XGen { /// <summary> /// Generates custom typed XmlSerializers. /// </summary> /// <remarks> /// On any class set the Custom Tool property to "SGen". /// This tool supports C# projects only, as that's the code generated /// by the XmlSerializer class. /// </remarks> [Guid("B8F154A6-E234-4c6f-9AD4-675713F4AABD")] [CustomTool("Mvp.Xml.ResX", "MVP XML Strongly Typed Resources Generator", true)] [ComVisible(true)] [VersionSupport("7.1")] [VersionSupport("7.0")] [CategorySupport(CategorySupportAttribute.CSharpCategory)] [CategorySupport(CategorySupportAttribute.VBCategory)] public class ResXTool : CustomTool { #region GenerateCode /// <summary> /// Generates the output. /// </summary> protected override byte[] GenerateCode(string inputFileName, string inputFileContent) { try { CodeCompileUnit unit = new CodeCompileUnit(); CodeNamespace ns = new CodeNamespace(base.FileNameSpace); unit.Namespaces.Add(ns); ns.Imports.Add(new CodeNamespaceImport("System")); ns.Imports.Add(new CodeNamespaceImport("System.Resources")); ns.Imports.Add(new CodeNamespaceImport("System.Threading")); // Cached remarks for empty comments. CodeCommentStatement remarks = new CodeCommentStatement("<remaks/>", true); XPathDocument doc = new XPathDocument(new StringReader(inputFileContent)); CodeTypeDeclaration sr = new CodeTypeDeclaration( "SR" ); sr.TypeAttributes = TypeAttributes.NestedAssembly | TypeAttributes.Sealed; sr.Comments.Add(new CodeCommentStatement( "<summary>Contains resources for the application.</summary>", true)); ns.Types.Add( sr ); // Add the default snippet. sr.Members.Add( new CodeSnippetTypeMember( SkeletonSnippet ) ); XPathNodeIterator it = doc.CreateNavigator().Select( "/root/data" ); while ( it.MoveNext() ) { // Work with a copy to avoid cursor movements. string key = it.Current.GetAttribute( "name", String.Empty ); if ( key != null ) { // Remove invalid characters from name chosen by the user. string name = CodeIdentifier.MakeValid( key ); // We can use a property as it's a simple object/string. CodeMemberField fld = new CodeMemberField(typeof(string), name); fld.Attributes = MemberAttributes.Const | MemberAttributes.Public; fld.InitExpression = new CodePrimitiveExpression(name); sr.Members.Add( fld ); } } string code; using (StreamReader reader = new StreamReader(codefile)) { code = reader.ReadToEnd(); } return System.Text.Encoding.ASCII.GetBytes(code); } catch (Exception e) { return System.Text.Encoding.ASCII.GetBytes(SR.XGenTool_GeneralError(e)); } finally { if (domain != null) { AppDomain.Unload(domain); } } } #endregion GenerateCode #region Registration and Installation /// <summary> /// Registers the generator. /// </summary> [ComRegisterFunction] public static void RegisterClass(Type type) { CustomTool.Register(typeof(ResXTool)); } /// <summary> /// Unregisters the generator. /// </summary> [ComUnregisterFunction] public static void UnregisterClass(Type t) { CustomTool.UnRegister(typeof(ResXTool)); } #endregion Registration and Installation } } |