Ejemplo n.º 1
0
        /// <summary>
        /// Uninstall
        /// </summary>
        private void UnInstallInternal(AppletManifest applet)
        {
            // We're good to go!
            this.m_appletCollection.Remove(applet);

            var appletConfig = ApplicationContext.Current.Configuration.GetSection <AppletConfigurationSection>();

            // Delete the applet registration data
            appletConfig.Applets.RemoveAll(o => o.Id == applet.Info.Id);

            if (ApplicationContext.Current.ConfigurationPersister.IsConfigured)
            {
                ApplicationContext.Current.ConfigurationPersister.Save(ApplicationContext.Current.Configuration);
            }

            if (File.Exists(Path.Combine(appletConfig.AppletDirectory, applet.Info.Id)))
            {
                File.Delete(Path.Combine(appletConfig.AppletDirectory, applet.Info.Id));
            }
            if (Directory.Exists(Path.Combine(appletConfig.AppletDirectory, "assets", applet.Info.Id)))
            {
                Directory.Delete(Path.Combine(appletConfig.AppletDirectory, "assets", applet.Info.Id), true);
            }

            AppletCollection.ClearCaches();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Uninstall the applet package
        /// </summary>
        public bool UnInstall(String packageId)
        {
            this.m_tracer.TraceInformation("Un-installing {0}", packageId);
            // Applet check
            var applet = this.m_appletCollection.FirstOrDefault(o => o.Info.Id == packageId);

            if (applet == null)
            {
                throw new FileNotFoundException($"Applet {packageId} is not installed");
            }

            // Dependency check
            var dependencies = this.m_appletCollection.Where(o => o.Info.Dependencies.Any(d => d.Id == packageId));

            if (dependencies.Any())
            {
                throw new InvalidOperationException($"Uninstalling {packageId} would break : {String.Join(", ", dependencies.Select(o => o.Info))}");
            }

            // We're good to go!
            this.m_appletCollection.Remove(applet);

            lock (this.m_fileDictionary)
                if (this.m_fileDictionary.ContainsKey(packageId))
                {
                    File.Delete(this.m_fileDictionary[packageId]);
                }

            AppletCollection.ClearCaches();

            return(true);
        }
Ejemplo n.º 3
0
 public void Close()
 {
     Application.SynchronizationContext.Post(_ =>
     {
         this.m_tracer.TraceInfo("Received close() request");
         ApplicationContext.Current.Stop();
         AppletCollection.ClearCaches();
         ApplicationContext.Current.Exit();
         //(this.m_context as Activity).Finish();
     }, null);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Register applet
 /// </summary>
 /// <param name="applet">Applet.</param>
 public virtual bool LoadApplet(AppletManifest applet)
 {
     if (applet.Info.Id == (ApplicationContext.Current.Configuration.GetSection <AppletConfigurationSection>().StartupAsset ?? "org.openiz.core"))
     {
         this.m_appletCollection.DefaultApplet = applet;
     }
     applet.Initialize();
     this.m_appletCollection.Add(applet);
     AppletCollection.ClearCaches();
     return(true);
 }
Ejemplo n.º 5
0
        public void TestLayoutBundleReferences()
        {
            var coll = new AppletCollection();

            coll.Add(AppletManifest.Load(typeof(TestRenderApplets).Assembly.GetManifestResourceStream("SanteDB.Core.Applets.Test.LayoutAngularTest.xml")));

            var    asset  = coll.ResolveAsset("app://org.santedb.applet.test.layout/index.html");
            var    render = coll.RenderAssetContent(asset);
            string html   = Encoding.UTF8.GetString(render);

            Assert.IsTrue(html.Contains("index-controller"), "Missing index-controller");
            Assert.IsTrue(html.Contains("layout-controller"), "Missing layout-controller");
            Assert.IsTrue(html.Contains("index-style"), "Missing index-style");
            Assert.IsTrue(html.Contains("layout-controller"), "Missing layout-style");
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Compile
        /// </summary>
        static int Compile(ConsoleParameters parameters)
        {
            int retVal = 0;

            // First is there a Manifest.xml?
            if (!Path.IsPathRooted(parameters.Source))
            {
                parameters.Source = Path.Combine(Environment.CurrentDirectory, parameters.Source);
            }

            // Applet collection
            AppletCollection ac  = new AppletCollection();
            XmlSerializer    xsz = new XmlSerializer(typeof(AppletManifest));
            XmlSerializer    xpz = new XmlSerializer(typeof(AppletPackage));

            if (parameters.References != null)
            {
                foreach (var itm in parameters.References)
                {
                    if (File.Exists(itm))
                    {
                        using (var fs = File.OpenRead(itm))
                        {
                            if (Path.GetExtension(itm) == ".pak")
                            {
                                using (var gzs = new GZipStream(fs, CompressionMode.Decompress))
                                {
                                    var pack = xpz.Deserialize(gzs) as AppletPackage;
                                    var mfst = pack.Unpack();
                                    mfst.Initialize();
                                    ac.Add(mfst);
                                    Console.WriteLine("Added reference to {0}; v={1}", mfst.Info.Id, mfst.Info.Version);
                                }
                            }
                            else
                            {
                                var mfst = xsz.Deserialize(fs) as AppletManifest;
                                mfst.Initialize();
                                ac.Add(mfst);
                                Console.WriteLine("Added reference to {0}; v={1}", mfst.Info.Id, mfst.Info.Version);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("Processing {0}...", parameters.Source);
            String manifestFile = Path.Combine(parameters.Source, "manifest.xml");

            if (!File.Exists(manifestFile))
            {
                Console.WriteLine("Directory must have manifest.xml");
            }
            else
            {
                Console.WriteLine("\t Reading Manifest...", parameters.Source);

                using (var fs = File.OpenRead(manifestFile))
                {
                    AppletManifest mfst = xsz.Deserialize(fs) as AppletManifest;
                    mfst.Assets.AddRange(ProcessDirectory(parameters.Source, parameters.Source, parameters));
                    foreach (var i in mfst.Assets)
                    {
                        i.Name = i.Name.Substring(1);
                    }

                    if (mfst.Info.Version.Contains("*"))
                    {
                        mfst.Info.Version = mfst.Info.Version.Replace("*", (((DateTime.Now.Subtract(new DateTime(DateTime.Now.Year, 1, 1)).Ticks >> 24) % 10000)).ToString("0000"));
                    }

                    if (!Directory.Exists(Path.GetDirectoryName(parameters.Output)) && !String.IsNullOrEmpty(Path.GetDirectoryName(parameters.Output)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(parameters.Output));
                    }

                    AppletPackage pkg = null;

                    // Is there a signature?
                    if (!String.IsNullOrEmpty(parameters.SignKey))
                    {
                        pkg = CreateSignedPackage(mfst, parameters);
                        if (pkg == null)
                        {
                            return(-102);
                        }
                    }
                    else
                    {
                        Console.WriteLine("WARNING:>>> THIS PACKAGE IS NOT SIGNED - MOST OPEN IZ TOOLS WILL NOT LOAD IT");
                        mfst.Info.PublicKeyToken = null;
                        pkg = mfst.CreatePackage(parameters.Compression);
                        //pkg.Meta.PublicKeyToken = null;
                    }
                    pkg.Meta.Hash = SHA256.Create().ComputeHash(pkg.Manifest);

                    using (var ofs = File.Create(Path.ChangeExtension(parameters.Output ?? "out.pak", ".pak")))
                    {
                        pkg.Save(ofs);
                    }
                    // Render the build directory

                    if (!String.IsNullOrEmpty(parameters.Deploy))
                    {
                        var bindir = Path.Combine(Path.GetDirectoryName(parameters.Output), "bin");

                        if (String.IsNullOrEmpty(parameters.Deploy))
                        {
                            if (Directory.Exists(bindir) && parameters.Clean)
                            {
                                Directory.Delete(bindir, true);
                            }
                            bindir = Path.Combine(bindir, mfst.Info.Id);
                            Directory.CreateDirectory(bindir);
                        }
                        else
                        {
                            bindir = parameters.Deploy;
                        }

                        mfst.Initialize();
                        ac.Add(mfst);

                        foreach (var lang in mfst.Strings)
                        {
                            string wd = Path.Combine(bindir, lang.Language);
                            if (String.IsNullOrEmpty(parameters.Lang))
                            {
                                Directory.CreateDirectory(wd);
                            }
                            else if (parameters.Lang == lang.Language)
                            {
                                wd = bindir;
                            }
                            else
                            {
                                continue;
                            }

                            foreach (var m in ac)
                            {
                                foreach (var itm in m.Assets)
                                {
                                    try
                                    {
                                        String fn = Path.Combine(wd, m.Info.Id, itm.Name.Replace("/", "\\"));
                                        Console.WriteLine("\tRendering {0}...", fn);
                                        if (!Directory.Exists(Path.GetDirectoryName(fn)))
                                        {
                                            Directory.CreateDirectory(Path.GetDirectoryName(fn));
                                        }
                                        File.WriteAllBytes(fn, ac.RenderAssetContent(itm, lang.Language));
                                    }
                                    catch (Exception e)
                                    {
                                        Console.WriteLine("E: {0}: {1} {2}", itm, e.GetType().Name, e);
                                        retVal = -1000;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(retVal);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Package an APK to the output directory
        /// </summary>
        private void PackageApk()
        {
            Emit.Message("INFO", "Will package {0}.apk ...", this.m_package.Meta.Id);

            var workingDir = Path.Combine(Path.GetTempPath(), "dcg-apk", this.m_package.Meta.Id);

            if (!String.IsNullOrEmpty(this.m_parameters.DcdrAssetOutput))
            {
                workingDir = Path.Combine(this.m_parameters.DcdrAssetOutput, "dcg-apk");
            }
            if (!Directory.Exists(workingDir))
            {
                Directory.CreateDirectory(workingDir);
            }

            this.CloneTarget("https://github.com/santedb/santedb-dc-android", workingDir, this.m_parameters.SourceBranch);

            var appletCollection = new AppletCollection();

            // Next slip in the applets from our output
            Emit.Message("INFO", "Slipstreaming Applets");
            if (this.m_package is AppletSolution solution)
            {
                foreach (var f in Directory.GetFiles(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Assets", "Applets"), "*.pak"))
                {
                    Emit.Message("WARN", "Removing stale applet {0}", f);
                    File.Delete(f);
                }
                foreach (var pkg in solution.Include)
                {
                    Emit.Message("INFO", "Injecting applet {0}", pkg.Meta.Id);
                    this.SerializeApplet(pkg, Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Assets", "Applets"), Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "SanteDB.DisconnectedClient.Android.csproj"));
                    appletCollection.Add(pkg.Unpack());
                }
            }
            else
            {
                this.SerializeApplet(this.m_package, Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Assets", "Applets"), Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "SanteDB.DisconnectedClient.Android.csproj"));
                appletCollection.Add(this.m_package.Unpack());
            }

            // Next setup the android manifest
            var manifest    = new XmlDocument();
            var versionCode = new Version(this.m_package.Meta.Version);

            manifest.Load(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Properties", "AndroidManifest.xml"));
            manifest.DocumentElement.SetAttribute("versionCode", "http://schemas.android.com/apk/res/android", $"{versionCode.Major:00}{versionCode.Minor:00}{versionCode.Build:000}");
            manifest.DocumentElement.SetAttribute("versionName", "http://schemas.android.com/apk/res/android", this.m_package.Meta.Version);
            manifest.DocumentElement.SetAttribute("package", this.m_package.Meta.Id);

            var providerNode = manifest.SelectSingleNode("/manifest/application/provider") as XmlElement;

            providerNode.SetAttribute("authorities", "http://schemas.android.com/apk/res/android", $"{this.m_package.Meta.Id}.fileprovider");

            manifest.Save(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Properties", "AndroidManifest.xml"));

            // Generate the stub for the app info
            using (var tw = File.CreateText(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android.Core", "AndroidApplicationInfo.cs")))
            {
                tw.WriteLine("namespace SanteDB.DisconnectedClient.Android.Core \r\n{\r\n\tstatic class AndroidApplicationInfo\r\n\t{");
                tw.WriteLine("\t\tinternal const string ApplicationId = \"{0}\";", this.m_package.Meta.Id);
                tw.WriteLine("\t\tinternal const string ApplicationKey = \"{0}\";", this.m_package.Meta.Uuid);
                tw.WriteLine("\t\tinternal const string DefaultSecret = \"{0}\";", this.m_package.Meta.PublicKeyToken ?? "$$DEFAULT_PWD$$");
                tw.WriteLine("\t}\r\n}");
            }
            // Get the icon
            var iconAsset = appletCollection.ResolveAsset(this.m_package.Meta.Icon);

            if (iconAsset?.MimeType == "image/png")
            {
                var imageData = appletCollection.RenderAssetContent(iconAsset);
                Emit.Message("INFO", "Slipstream Icons...");
                File.WriteAllBytes(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources", "drawable", "icon.png"), imageData);
                File.WriteAllBytes(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources", "drawable", "logo.png"), imageData);
                File.WriteAllBytes(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources", "drawable", "logo_lg.png"), imageData);

                foreach (var dir in Directory.GetDirectories(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources"), "mipmap-*"))
                {
                    File.WriteAllBytes(Path.Combine(dir, "Icon.png"), imageData);
                }
            }

            // Swap out the translation
            var strings = new XmlDocument();

            strings.Load(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources", "values", "Strings.xml"));
            strings.SelectSingleNode("//*[local-name() = 'string'][@name = 'app_name']").InnerText = this.m_package.Meta.GetName("en", true);
            strings.Save(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "Resources", "values", "Strings.xml"));

            // Locate MSBUILD Path
            if (String.IsNullOrEmpty(this.m_parameters.MsBuild))
            {
                var vsDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio");
                if (Directory.Exists(vsDir))
                {
                    this.m_parameters.MsBuild = Directory.GetFiles(vsDir, "msbuild.exe", SearchOption.AllDirectories).LastOrDefault();
                }
            }

            if (!File.Exists(this.m_parameters.MsBuild))
            {
                Emit.Message("ERROR", "Cannot find Visual Studio MSBUILD Tooling");
                throw new InvalidOperationException("Missing Visual Studio Build Tooling");
            }

            var arguments = new String[] {
                $"/p:Configuration=Pakman /m:1 /t:restore \"{Path.Combine(workingDir, "santedb-dc-android.sln")}\"",
                $"/p:Configuration=Pakman /m:1 /t:SignAndroidPackage \"{Path.Combine(workingDir, "santedb-dc-android.sln")}\""
            };


            foreach (var args in arguments)
            {
                var processInfo = new ProcessStartInfo(this.m_parameters.MsBuild);
                processInfo.Arguments              = args;
                processInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                processInfo.RedirectStandardOutput = true;
                processInfo.RedirectStandardError  = true;
                processInfo.UseShellExecute        = false;
                Emit.Message("INFO", "Running {0} {1}", processInfo.FileName, processInfo.Arguments);

                using (var process = new Process())
                {
                    process.StartInfo           = processInfo;
                    process.EnableRaisingEvents = true;

                    var mre = new ManualResetEventSlim(false);
                    process.ErrorDataReceived  += (o, e) => Console.WriteLine(e.Data);
                    process.OutputDataReceived += (o, e) => Console.WriteLine(e.Data);
                    process.Start();
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();

                    process.WaitForExit();
                    process.Close();
                }
            }

            // Copy the output of the APK
            foreach (var apk in Directory.GetFiles(Path.Combine(workingDir, "SanteDB.DisconnectedClient.Android", "bin", "Pakman"), "*.apk"))
            {
                var dest = Path.Combine(Path.GetDirectoryName(this.m_parameters.Output), Path.GetFileName(apk));
                Emit.Message("INFO", "Copying {0} to {1}...", apk, dest);
                File.Copy(apk, dest, true);
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Local applet manager ctor
 /// </summary>
 public LocalAppletManagerService()
 {
     this.m_appletCollection         = new AppletCollection();
     this.m_readonlyAppletCollection = this.m_appletCollection.AsReadonly();
     this.m_readonlyAppletCollection.CollectionChanged += (o, e) => this.Changed?.Invoke(o, e);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Local applet manager ctor
 /// </summary>
 public LocalAppletManagerService()
 {
     this.m_appletCollection         = new AppletCollection();
     this.m_readonlyAppletCollection = this.m_appletCollection.AsReadonly();
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Performs an installation
        /// </summary>
        public bool Install(AppletPackage package, bool isUpgrade, AppletSolution owner)
        {
            this.m_tracer.TraceInfo("Installing {0}", package.Meta);


            var appletScope = owner?.Meta.Id ?? String.Empty;

            // TODO: Verify package hash / signature
            if (!this.VerifyPackage(package))
            {
                throw new SecurityException("Applet failed validation");
            }
            else if (!this.m_appletCollection[appletScope].VerifyDependencies(package.Meta))
            {
                this.m_tracer.TraceWarning($"Applet {package.Meta} depends on : [{String.Join(", ", package.Meta.Dependencies.Select(o => o.ToString()))}] which are missing or incompatible");
            }

            // Save the applet
            var appletDir = this.m_configuration.AppletDirectory;

            if (!Path.IsPathRooted(appletDir))
            {
                appletDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), this.m_configuration.AppletDirectory);
            }
            if (owner != null)
            {
                appletDir = Path.Combine(appletDir, owner.Meta.Id);
            }
            if (!Directory.Exists(appletDir))
            {
                Directory.CreateDirectory(appletDir);
            }

            // Install
            var pakFile = Path.Combine(appletDir, package.Meta.Id + ".pak");

            if (this.m_appletCollection[appletScope].Any(o => o.Info.Id == package.Meta.Id) && File.Exists(pakFile) && !isUpgrade)
            {
                throw new InvalidOperationException($"Cannot replace {package.Meta} unless upgrade is specifically specified");
            }

            using (var fs = File.Create(pakFile))
            {
                package.Save(fs);
            }

            lock (this.m_fileDictionary)
                if (!this.m_fileDictionary.ContainsKey($"{appletScope}{package.Meta.Id}"))
                {
                    this.m_fileDictionary.Add($"{appletScope}{package.Meta.Id}", pakFile);
                }

            var pkg = package.Unpack();

            // remove the package from the collection if this is an upgrade
            if (isUpgrade)
            {
                this.m_appletCollection[appletScope].Remove(pkg);
            }

            this.m_appletCollection[appletScope].Add(pkg);

            // We want to install the templates & protocols into the DB
            this.m_tracer.TraceInfo("Installing templates...");

            // Install templates
            var idp = ApplicationServiceContext.Current.GetService <ITemplateDefinitionRepositoryService>();

            if (idp != null)
            {
                foreach (var itm in pkg.Templates)
                {
                    if (idp.GetTemplateDefinition(itm.Mnemonic) == null)
                    {
                        this.m_tracer.TraceInfo("Installing {0}...", itm.Mnemonic);
                        idp.Insert(new TemplateDefinition()
                        {
                            Oid         = itm.Oid,
                            Mnemonic    = itm.Mnemonic,
                            Description = itm.Description,
                            Name        = itm.Mnemonic
                        });
                    }
                }
            }

            AppletCollection.ClearCaches();

            return(true);
        }