Example #1
0
 public ContentManager(ContentSettings settings)
 {
     this._state = State.Idle;
     this._repositoryPath = settings.RepositoryPath;
     this._contentPath = settings.ContentPath;
     this._ignoreVersionComponent = settings.IgnoreVersionComponent;
     this._buildQueue = new ConcurrentQueue<Trigger>();
     this._workQueue = new BlockingCollection<Trigger>(this._buildQueue);
     this._template = settings.Template;
     this._contentLock = new ReaderWriterLockSlim();
     this._workProcess = new TaskFactory().StartNew(this.WorkerMethod);
     string contentRefPath = Path.Combine(this._contentPath, _CONTENT_REF_NAME);
     if (File.Exists(contentRefPath))
         this._currentContentRef = File.ReadAllText(contentRefPath).Trim();
     else
         this._currentContentRef = null;
 }
 // TODO see if we can't get rid of this CompositionContainer
 public Template Load(CompositionContainer container)
 {
     Template ret = new Template(container);
     ret.Load(this);
     return ret;
 }
Example #3
0
        public void Invoke(CompositionContainer container)
        {
            var traceListener = new ConsolidatedConsoleTraceListener(
                new Dictionary<string, string>
                    {
                        {
                            "LostDoc.Core.Template",
                            "Template"
                        },
                        {
                            "LostDoc.Core.Bundle",
                            "Bundle"
                        },
                        {
                            "LostDoc.Core.Template.AssetResolver",
                            "Resolve"
                        }
                    });

            
            TraceSources.TemplateSource.Listeners.Add(traceListener);
            TraceSources.AssetResolverSource.Listeners.Add(traceListener);
            try
            {
                if (this.Quiet.IsPresent)
                {
                    const SourceLevels quietLevel = SourceLevels.Error | SourceLevels.Warning | SourceLevels.Critical;
                    TraceSources.TemplateSource.Switch.Level = quietLevel;
                    TraceSources.AssetResolverSource.Switch.Level = quietLevel;
                    TraceSources.BundleSource.Listeners.Add(traceListener);
                }
                else if (this.Verbose.IsPresent)
                {
                    const SourceLevels verboseLevel = SourceLevels.All;
                    TraceSources.TemplateSource.Switch.Level = verboseLevel;
                    TraceSources.AssetResolverSource.Switch.Level = verboseLevel;
                    TraceSources.BundleSource.Listeners.Add(traceListener);
                }
                else
                {
                    const SourceLevels normalLevel = SourceLevels.Information | SourceLevels.Warning | SourceLevels.Error | SourceLevels.ActivityTracing;
                    TraceSources.TemplateSource.Switch.Level = normalLevel;
                    TraceSources.AssetResolverSource.Switch.Level = normalLevel;
                }

                LinkedList<FileInfo> includedFiles = new LinkedList<FileInfo>();

                if (File.Exists(this.Path))
                    includedFiles.AddLast(new FileInfo(this.Path));
                else if (Directory.Exists(this.Path))
                {
                    Directory.GetFiles(this.Path, "*.ldoc", SearchOption.AllDirectories)
                             .Aggregate(includedFiles,
                                        (l, f) => l.AddLast(new FileInfo(f)).List);
                }
                else
                    throw new FileNotFoundException(System.IO.Path.GetFullPath(this.Path));


                Bundle bundle = new Bundle(this.IgnoreVersionComponent);

                TraceSources.TemplateSource.TraceInformation("Merging LostDoc files into bundle.");

                foreach (FileInfo file in includedFiles)
                {
                    TraceSources.TemplateSource.TraceEvent(TraceEventType.Information, 0, "Source: {0}", file.Name);
                    XDocument fileDoc = XDocument.Load(file.FullName);

                    bundle.Add(fileDoc);
                }

                var lazyProviders = container.GetExports<IFileProvider>(ContractNames.TemplateProvider);
                var realProviders = lazyProviders.Select(lazy => lazy.Value);
                TemplateResolver templateResolver = new TemplateResolver(realProviders.ToArray());

                Template template = new Template(container);
                template.Load(templateResolver, this.Template);

                string outputDir = this.Output
                                   ?? (Directory.Exists(this.Path)
                                           ? this.Path
                                           : System.IO.Path.GetDirectoryName(this.Path));
                AssetRedirectCollection assetRedirects;
                XDocument mergedDoc = bundle.Merge(out assetRedirects);

                var templateData = new TemplateData(mergedDoc)
                                       {
                                           AssetRedirects = assetRedirects,
                                           OverwriteExistingFiles = this.Force.IsPresent,
                                           IgnoredVersionComponent = this.IgnoreVersionComponent,
                                           Arguments = this.Arguments,
                                           OutputFileProvider = new ScopedFileProvider(new DirectoryFileProvider(), outputDir)
                                       };

                template.Generate(templateData);
            }
            finally
            {
                TraceSources.TemplateSource.Listeners.Remove(traceListener);
                TraceSources.AssetResolverSource.Listeners.Remove(traceListener);
            }
        }
Example #4
0
        protected void Application_Start()
        {
            // TODO maybe put this somewhere else (not in global.asax)
            // TODO maybe move all of this into the App class with "IAppConfig"

            // initialize logger
            TraceListener traceListener =
                new TextWriterTraceListener(Path.Combine(AppConfig.LogPath, 
                                                         string.Format("repository_{0:yyyy'-'MM'-'dd__HHmmss}.log", 
                                                                       DateTime.Now)));

            // TODO introduce flags/settings for controlling logging levels, but for now include everything
            traceListener.Filter = new EventTypeFilter(SourceLevels.All);

            traceListener.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;

            Web.TraceSources.Content.Listeners.Add(traceListener);
            Web.TraceSources.AddInManager.Listeners.Add(traceListener);
            Repository.TraceSources.ContentManagerSource.Listeners.Add(traceListener);
            Repository.TraceSources.ContentSearcherSource.Listeners.Add(traceListener);

            // this might be stupid, but it fixes things for iisexpress
            Directory.SetCurrentDirectory(HostingEnvironment.ApplicationPhysicalPath);

            // set up add-in system
            AddInSource officalSource = new AddInSource("Official LostDoc repository add-in feed", 
                                                        AppConfig.AddInRepository, 
                                                        isOfficial: true);

            // intialize MEF

            // core 'add-ins'
            var currentAssembly = Assembly.GetExecutingAssembly();
            var assemblyName = currentAssembly.GetName();
            string corePackageId = assemblyName.Name;
            string corePackageVersion = assemblyName.Version.ToString();
            AggregateCatalog catalog = new AggregateCatalog();

            // load other sources from site-settings (not config)
            AddInRepository repository = new AddInRepository(officalSource);
            AddInManager addInManager = new AddInManager(repository, 
                                                         AppConfig.AddInInstallPath, 
                                                         AppConfig.AddInPackagePath);

            // when the catalog changes, discover and route all ApiControllers
            catalog.Changed += (sender, args) => this.UpdateWebApiRegistry(args);

            //// TODO for debugging only
            //Debugger.Break();
            //Debugger.Launch();

            // now register core libs
            catalog.Catalogs.Add(new AddInCatalog(new ApplicationCatalog(), corePackageId, corePackageVersion));

            // hook event so that installed add-ins get registered in the catalog, if composition occurs after this fires
            // or if recomposition is enabled, no restart should be requried
            addInManager.Installed +=
                (sender, args) => catalog.Catalogs.Add(new AddInCatalog(new DirectoryCatalog(args.InstallationPath), 
                                                                        args.Package.Id, 
                                                                        args.Package.Version));

            // delete and redeploy all installed packages, this will trigger the Installed event ^
            // this acts as a crude "remove/overwrite plugins that were in use when un/installed" hack
            addInManager.Restore();

            // create container
            CompositionContainer container = new CompositionContainer(catalog);

            // set up template resolver
            var lazyProviders = container.GetExports<IFileProvider>(ContractNames.TemplateProvider);
            var realProviders = lazyProviders.Select(lazy => lazy.Value);
            TemplateResolver templateResolver = new TemplateResolver(realProviders.ToArray());

            // load template
            Template template = new Template(container);
            template.Load(templateResolver, AppConfig.Template);

            // set up content manager
            ContentManager contentManager = new ContentManager(new ContentSettings
                                                                   {
                                                                       ContentPath = AppConfig.ContentPath, 
                                                                       // TODO make this configurable
                                                                       IgnoreVersionComponent = VersionComponent.Patch, 
                                                                       RepositoryPath = AppConfig.RepositoryPath, 
                                                                       Template = template
                                                                   });

            // set up notifaction system
            NotificationManager notifications = new NotificationManager();

            // initialize app-singleton
            App.Initialize(container, contentManager, addInManager, notifications, traceListener);

            // MVC init
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            // inject our custom IControllerFactory for the Admin interface
            IControllerFactory oldControllerFactory = ControllerBuilder.Current.GetControllerFactory();
            IControllerFactory newControllerFactory = new AddInControllerFactory(AdministrationAreaRegistration.Name, 
                                                                                 container, 
                                                                                 oldControllerFactory);
            ControllerBuilder.Current.SetControllerFactory(newControllerFactory);

            // TODO figure out if we actually need this
            // hook in our MEF based IHttpController instead of the default one
            //GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerTypeResolver), new AddInHttpControllerTypeResolver(App.Instance.Container));
        }
Example #5
0
        protected virtual ParsedTemplate PrepareTemplate(TemplateData templateData, Stack<IFileProvider> providers = null)
        {
            // set up temp file container
            TempFileCollection tempFiles = new TempFileCollection(templateData.TemporaryFilesPath,
                                                                  templateData.KeepTemporaryFiles);

            if (!Directory.Exists(tempFiles.TempDir))
                Directory.CreateDirectory(tempFiles.TempDir);

            if (providers == null)
                providers = new Stack<IFileProvider>();

            // clone orig doc
            XDocument workingDoc;

            // this is required to preserve the line information 
            using (var xmlReader = this._templateDefinition.CreateReader())
                workingDoc = XDocument.Load(xmlReader, LoadOptions.SetLineInfo);
            
            // template inheritence
            XAttribute templateInheritsAttr = workingDoc.Root.Attribute("inherits");
            if (templateInheritsAttr != null)
            {
               
                int depth = providers.Count + 1;
                Template inheritedTemplate = new Template(this._container);
                inheritedTemplate.Load(this._templateResolver, templateInheritsAttr.Value);
                ParsedTemplate parsedTemplate = inheritedTemplate.PrepareTemplate(templateData, providers);

                providers.Push(inheritedTemplate.GetScopedFileProvider());

                // a little hacky but it should work with the Reverse()/AddFirst()
                foreach (XElement elem in parsedTemplate.Source.Root.Elements().Reverse())
                {
                    workingDoc.Root.AddFirst(new XElement(elem));
                }

                // create and register temp file (this can be overriden later if there are meta-template directives
                // in the template
                this._templateSourcePath = this.SaveTempFile(tempFiles, workingDoc, "inherited." + depth);
            }

            // add our file provider to the top of the stack
            providers.Push(this.GetScopedFileProvider());

            // start by loading any parameters as they are needed for meta-template evaluation
            CustomXsltContext customContext = CreateCustomXsltContext(templateData.IgnoredVersionComponent);

            XElement[] paramNodes = workingDoc.Root.Elements("parameter").ToArray();
            var globalParams =
                paramNodes.Select(paramNode =>
                                  new ExpressionXPathVariable(this.GetAttributeValue(paramNode, "name"),
                                                              this.GetAttributeValueOrDefault(paramNode, "select")))
                          .ToArray();

            customContext.PushVariableScope(workingDoc, globalParams);

            var arguments = templateData.Arguments
                                        .Select(argument => new ConstantXPathVariable(argument.Key, argument.Value))
                                        .ToArray();

            customContext.PushVariableScope(workingDoc, arguments);

            // we're going to need this later
            XmlFileProviderResolver fileResolver = new XmlFileProviderResolver(providers, this._basePath);

            // expand any meta-template directives
            workingDoc = ApplyMetaTransforms(workingDoc, customContext, providers, tempFiles);

            // there was neither inheretance, nor any meta-template directives
            if (this._templateSourcePath == null)
            {
                // save current template to disk
                this._templateSourcePath = this.SaveTempFile(tempFiles, workingDoc);
            }

            // loading template
            List<Stylesheet> stylesheets = new List<Stylesheet>();
            List<Resource> resources = new List<Resource>();
            List<Index> indices = new List<Index>();
            foreach (XElement elem in workingDoc.Root.Elements())
            {
                // we alread proessed the parameters
                if (elem.Name.LocalName == "parameter")
                    continue;

                if (elem.Name.LocalName == "apply-stylesheet")
                {
                    stylesheets.Add(this.ParseStylesheet(providers, stylesheets, elem));
                }
                else if (elem.Name.LocalName == "index")
                {
                    indices.Add(this.ParseIndexDefinition(elem));
                }
                else if (elem.Name.LocalName == "include-resource")
                {
                    resources.Add(ParseResouceDefinition(providers, elem));
                }
                else
                {
                    throw new Exception("Unknown element: " + elem.Name.LocalName);
                }
            }

            return new ParsedTemplate
                       {
                           Parameters = globalParams,
                           Source = workingDoc,
                           Resources = resources.ToArray(),
                           Stylesheets = stylesheets.ToArray(),
                           Indices = indices.ToArray(),
                           TemporaryFiles = tempFiles,
                       };
        }