/// <summary>
        /// Generates localized Baml from translations
        /// </summary>
        /// <param name="options">LocBaml options</param>
        /// <param name="dictionaries">the translation dictionaries</param>
        internal static void Generate(LocBamlOptions options, TranslationDictionariesReader dictionaries)
        {
            // base on the input, we generate differently
            switch (options.InputType)
            {
            case FileType.BAML:
            {
                throw new Exception("Is not supported yet");
                break;
            }

            case FileType.RESOURCES:
            {
                throw new Exception("Is not supported yet");
                break;
            }

            case FileType.EXE:
            case FileType.DLL:
            {
                GenerateAssembly(options, dictionaries);
                break;
            }

            default:
            {
                Debug.Assert(false, "Can't generate to this type");
                break;
            }
            }
        }
Example #2
0
        /// <summary>
        /// Genereate localized baml
        /// </summary>
        private static void GenerateBamlResources(LocBamlOptions options)
        {
            Stream input = File.OpenRead(options.TranslationsFile);

            using (ResourceTextReader reader = new ResourceTextReader(options.TranslationFileType, input))
            {
                TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(reader);
                ResourceGenerator.Generate(options, dictionaries);
            }
        }
 //--------------------------------------------------
 // The function follows Managed code parser
 // implementation. in the future, maybe they should
 // share the same code
 //--------------------------------------------------
 private static void GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
 {
     // there are many names to be used when generating an assembly
     throw new Exception("This vertion doesn't support this function");
 }
        internal static void GenerateAssembly(ResourceGenerationOptions options)
        {
            TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(options.BamlStrings);

            string sourceAssemblyFullName  = options.AssemblyFileName;                           // source assembly full path
            string outputAssemblyLocalName = System.IO.Path.GetFileName(options.OutputFileName); // output assembly name
            string moduleLocalName         = GetAssemblyModuleLocalName(
                options.CultureInfo,
                System.IO.Path.GetFileName(outputAssemblyLocalName));                                     // the module name within the assmbly

            // get the source assembly
            Assembly    sourceAssembly = options.SourceAssembly;
            CultureInfo cultureInfo    = options.CultureInfo;

            // obtain the assembly name
            AssemblyName targetAssemblyNameObj = sourceAssembly.GetName();

            // store the culture info of the source assembly
            CultureInfo srcCultureInfo = targetAssemblyNameObj.CultureInfo;

            // update it to use it for target assembly
            targetAssemblyNameObj.Name        = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
            targetAssemblyNameObj.CultureInfo = cultureInfo;

            // we get a assembly builder
            AssemblyBuilder targetAssemblyBuilder = options.AppDomain.DefineDynamicAssembly(
                targetAssemblyNameObj,                                  // name of the assembly
                AssemblyBuilderAccess.RunAndSave,                       // access rights
                System.IO.Path.GetDirectoryName(options.OutputFileName) // storage dir
                );

            // we create a module builder for embeded resource modules
            ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
                moduleLocalName,
                outputAssemblyLocalName
                );

            //options.WriteLine(StringLoader.Get("GenerateAssembly"));

            // now for each resource in the assembly
            foreach (string resourceName in sourceAssembly.GetManifestResourceNames())
            {
                // get the resource location for the resource
                ResourceLocation resourceLocation = sourceAssembly.GetManifestResourceInfo(resourceName).ResourceLocation;

                // if this resource is in another assemlby, we will skip it
                if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
                {
                    continue;   // in resource assembly, we don't have resource that is contained in another assembly
                }

                // gets the neutral resource name, giving it the source culture info
                string neutralResourceName = GetNeutralResModuleName(resourceName, srcCultureInfo);

                // gets the target resource name, by giving it the target culture info
                string targetResourceName = GetCultureSpecificResourceName(neutralResourceName, cultureInfo);

                // resource stream
                Stream resourceStream = sourceAssembly.GetManifestResourceStream(resourceName);

                // see if it is a .resources
                if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
                {
                    // now we think we have resource stream
                    // get the resource writer
                    IResourceWriter writer;
                    // check if it is a embeded assembly
                    if ((resourceLocation & ResourceLocation.Embedded) != 0)
                    {
                        // gets the resource writer from the module builder
                        writer = moduleBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // resource description
                            ResourceAttributes.Public   // visibilty of this resource to other assembly
                            );
                    }
                    else
                    {
                        // it is a standalone resource, we get the resource writer from the assembly builder
                        writer = targetAssemblyBuilder.DefineResource(
                            targetResourceName,         // resource name
                            targetResourceName,         // description
                            targetResourceName,         // file name to save to
                            ResourceAttributes.Public   // visibility of this resource to other assembly
                            );
                    }

                    // get the resource reader
                    IResourceReader reader = new ResourceReader(resourceStream);

                    // generate the resources
                    GenerateResourceStream(options, resourceName, reader, writer, dictionaries);

                    // we don't call writer.Generate() or writer.Close() here
                    // because the AssemblyBuilder will call them when we call Save() on it.
                }
                else
                {
                    // else it is a stand alone untyped manifest resources.
                    string extension = Path.GetExtension(targetResourceName);

                    string fullFileName = Path.Combine(
                        System.IO.Path.GetDirectoryName(options.AssemblyFileName),
                        targetResourceName);

                    // check if it is a .baml, case-insensitive
                    if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
                    {
                        // try to localized the the baml
                        // find the resource dictionary
                        BamlLocalizationDictionary dictionary = dictionaries[resourceName];

                        // if it is null, just create an empty dictionary.
                        if (dictionary != null)
                        {
                            // it is a baml stream
                            using (Stream output = File.OpenWrite(fullFileName))
                            {
                                options.Write("    ");
                                options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
                                GenerateBamlStream(resourceStream, output, dictionary, options);
                                options.WriteLine(StringLoader.Get("Done"));
                            }
                        }
                        else
                        {
                            // can't find localization of it, just copy it
                            GenerateStandaloneResource(fullFileName, resourceStream);
                        }
                    }
                    else
                    {
                        // it is an untyped resource stream, just copy it
                        GenerateStandaloneResource(fullFileName, resourceStream);
                    }

                    // now add this resource file into the assembly
                    targetAssemblyBuilder.AddResourceFile(
                        targetResourceName,           // resource name
                        targetResourceName,           // file name
                        ResourceAttributes.Public     // visibility of the resource to other assembly
                        );
                }
            }

            // at the end, generate the assembly
            targetAssemblyBuilder.Save(outputAssemblyLocalName);
            options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
        }
        private static void GenerateResourceStream(
            ResourceGenerationOptions options,              // options from the command line
            string resourceName,                            // the name of the .resources file
            IResourceReader reader,                         // the reader for the .resources
            IResourceWriter writer,                         // the writer for the output .resources
            TranslationDictionariesReader dictionaries      // the translations
            )
        {
            //options.WriteLine(StringLoader.Get("GenerateResource", resourceName));
            // enumerate through each resource and generate it
            foreach (DictionaryEntry entry in reader)
            {
                string name          = entry.Key as string;
                object resourceValue = null;

                // See if it looks like a Baml resource
                if (BamlStream.IsResourceEntryBamlStream(name, entry.Value))
                {
                    Stream targetStream = null;
                    //                    options.Write("    ");
                    //options.Write(StringLoader.Get("GenerateBaml", name));

                    // grab the localizations available for this Baml
                    string bamlName = BamlStream.CombineBamlStreamName(resourceName, name);
                    BamlLocalizationDictionary localizations = dictionaries[bamlName];
                    if (localizations != null)
                    {
                        targetStream = new MemoryStream();

                        // generate into a new Baml stream
                        GenerateBamlStream(
                            (Stream)entry.Value,
                            targetStream,
                            localizations,
                            options
                            );
                    }

                    options.WriteLine(StringLoader.Get("Done"));

                    // sets the generated object to be the generated baml stream
                    resourceValue = targetStream;
                }

                if (resourceValue == null)
                {
                    //
                    // The stream is not localized as Baml yet, so we will make a copy of this item into
                    // the localized resources
                    //

                    // We will add the value as is if it is serializable. Otherwise, make a copy
                    resourceValue = entry.Value;

                    object[] serializableAttributes = resourceValue.GetType().GetCustomAttributes(typeof(SerializableAttribute), true);
                    if (serializableAttributes.Length == 0)
                    {
                        // The item returned from resource reader is not serializable
                        // If it is Stream, we can wrap all the values in a MemoryStream and
                        // add to the resource. Otherwise, we had to skip this resource.
                        Stream resourceStream = resourceValue as Stream;
                        if (resourceStream != null)
                        {
                            Stream targetStream = new MemoryStream();
                            byte[] buffer       = new byte[resourceStream.Length];
                            resourceStream.Read(buffer, 0, buffer.Length);
                            targetStream  = new MemoryStream(buffer);
                            resourceValue = targetStream;
                        }
                    }
                }

                if (resourceValue != null)
                {
                    writer.AddResource(name, resourceValue);
                }
            }
        }