/// <summary>
        /// Initializes a new <see cref="CdConfigLocalizationResolver"/> instance.
        /// </summary>
        public CdConfigLocalizationResolver()
        {
            using (new Tracer())
            {
                string    cdDynamicConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\config\cd_dynamic_conf.xml");
                XDocument cdDynamicConfigDoc  = XDocument.Load(cdDynamicConfigPath);

                // sorting Publications by Path in decending order so default Path ("/" or "") is last in list
                // using Path of first Host element found in a Publication, assuming the Paths of all of these Host elements will be equal
                XElement publicationsElement = cdDynamicConfigDoc.Descendants("Publications").First();
                IOrderedEnumerable <XElement> publicationElements = publicationsElement.Elements("Publication").OrderByDescending(e => e.Element("Host").Attribute("Path").Value);
                foreach (XElement publicationElement in publicationElements)
                {
                    string publicationId = publicationElement.Attribute("Id").Value;

                    // there could be multiple Host elements per Publication, add them all
                    foreach (XElement hostElement in publicationElement.Elements("Host"))
                    {
                        Uri           baseUrl = GetBaseUrl(hostElement);
                        ILocalization localization;
                        if (!KnownLocalizations.TryGetValue(publicationId, out localization))
                        {
                            localization = new Localization
                            {
                                Id   = publicationId,
                                Path = hostElement.Attribute("Path").Value
                            };
                            KnownLocalizations.Add(publicationId, localization);
                        }
                        _urlToLocalizationMapping.Add(new KeyValuePair <Uri, ILocalization>(baseUrl, localization));
                    }
                }
            }
        }
コード例 #2
0
        protected virtual Localization ResolveDocsLocalization(Uri url)
        {
            // Try if the URL looks like a Tridion Docs / DDWebApp URL
            string urlPath = url.GetComponents(UriComponents.Path, UriFormat.Unescaped);

            if (string.IsNullOrEmpty(urlPath))
            {
                return(null); // No, it doesn't
            }
            Match match = DocsPattern.Match(urlPath);

            if (!match.Success)
            {
                return(null); // No, it doesn't
            }
            string       localizationId = match.Groups["pubId"].Value;
            Localization result;

            if (!KnownLocalizations.TryGetValue(localizationId, out result))
            {
                result = new DocsLocalization {
                    Id = localizationId
                };
                KnownLocalizations.Add(localizationId, result);
            }

            result.EnsureInitialized();
            return(result);
        }
コード例 #3
0
        public override Localization GetLocalization(string localizationId)
        {
            using (new Tracer(localizationId))
            {
                Localization result;
                if (!KnownLocalizations.TryGetValue(localizationId, out result))
                {
                    // Check for namespace prefix (ish: or tcm:)
                    if (localizationId.StartsWith("ish:"))
                    {
                        CmUri uri = CmUri.FromString(localizationId);
                        result = new DocsLocalization(uri.PublicationId);
                    }
                    else if (localizationId.StartsWith("tcm:"))
                    {
                        CmUri uri = CmUri.FromString(localizationId);
                        result = new Localization {
                            Id = uri.ItemId.ToString()
                        };
                    }
                    else
                    {
                        // Attempt to resolve it from Docs
                        var         client      = ApiClientFactory.Instance.CreateClient();
                        Publication publication = client.GetPublication(ContentNamespace.Docs, int.Parse(localizationId), null, null);
                        result = publication != null ? new DocsLocalization(publication.PublicationId) : base.GetLocalization(localizationId);
                    }

                    KnownLocalizations.Add(localizationId, result);
                }

                return(result);
            }
        }
コード例 #4
0
        /// <summary>
        /// Resolves a matching <see cref="Localization"/> for a given URL.
        /// </summary>
        /// <param name="url">The URL to resolve.</param>
        /// <returns>A <see cref="Localization"/> instance which base URL matches that of the given URL.</returns>
        /// <exception cref="DxaUnknownLocalizationException">If no matching Localization can be found.</exception>
        public override Localization ResolveLocalization(Uri url)
        {
            using (new Tracer(url))
            {
                string urlLeftPart = url.GetLeftPart(UriPartial.Path);

                // TODO PERF: to optimize caching, we could only take the first part of the URL path (e.g. one or two levels)
                int espaceIndex = urlLeftPart.IndexOf("%");
                if (espaceIndex > 0)
                {
                    // TODO: This is a work-around for a bug in SDL Web 8 Publication Mapping: URLs with escaped characters don't resolve properly (CRQ-1585).
                    // Therefore we truncate the URL at the first escaped character for now (assuming that the URL is still specific enough to resolve the right Publication).
                    urlLeftPart = urlLeftPart.Substring(0, espaceIndex);
                }

                IPublicationMapping mapping = null;
                try
                {
                    // NOTE: we're not using UrlToLocalizationMapping here, because we may match too eagerly on a base URL when there is a matching mapping with a more specific URL.
                    mapping = _mappingsRetriever.GetPublicationMapping(urlLeftPart);
                }
                catch (Exception ex)
                {
                    // CIL throws Sdl.Web.Delivery.Service.InvalidResourceException if the mapping cannot be resolved.
                    // We don't have a direct reference to Sdl.Web.Delivery.Service, so we just check the type name
                    if (ex.GetType().FullName != "Sdl.Web.Delivery.Service.InvalidResourceException")
                    {
                        throw;
                    }
                    Log.Debug("Exception occurred in DynamicMappingsRetriever.GetPublicationMapping('{0}'):\n{1}", urlLeftPart, ex.ToString());
                    // Let mapping be null, we'll handle it below.
                }
                if (mapping == null || mapping.Port != url.Port.ToString()) // See CRQ-1195
                {
                    throw new DxaUnknownLocalizationException(string.Format("No matching Localization found for URL '{0}'", urlLeftPart));
                }

                Localization result;
                lock (KnownLocalizations)
                {
                    string localizationId = mapping.PublicationId.ToString();
                    if (!KnownLocalizations.TryGetValue(localizationId, out result))
                    {
                        result = new Localization
                        {
                            LocalizationId = localizationId,
                            Path           = mapping.Path
                        };
                        KnownLocalizations.Add(localizationId, result);
                    }
                }

                result.EnsureInitialized();
                return(result);
            }
        }
        /// <summary>
        /// Resolves a matching <see cref="ILocalization"/> for a given URL.
        /// </summary>
        /// <param name="url">The URL to resolve.</param>
        /// <returns>A <see cref="ILocalization"/> instance which base URL matches that of the given URL.</returns>
        /// <exception cref="DxaUnknownLocalizationException">If no matching Localization can be found.</exception>
        public override Localization ResolveLocalization(Uri url)
        {
            using (new Tracer(url))
            {
                string urlLeftPart = url.GetLeftPart(UriPartial.Path);

                // TODO PERF: to optimize caching, we could only take the first part of the URL path (e.g. one or two levels)
                int espaceIndex = urlLeftPart.IndexOf("%");
                if (espaceIndex > 0)
                {
                    // TODO: This is a work-around for a bug in SDL Web 8 Publication Mapping: URLs with escaped characters don't resolve properly (CRQ-1585).
                    // Therefore we truncate the URL at the first escaped character for now (assuming that the URL is still specific enough to resolve the right Publication).
                    urlLeftPart = urlLeftPart.Substring(0, espaceIndex);
                }

                // NOTE: we're not using UrlToLocalizationMapping here, because we may match too eagerly on a base URL when there is a matching mapping with a more specific URL.
                PublicationMapping mapping = null;
                try
                {
                    mapping = ApiClientFactory.Instance.CreateClient().GetPublicationMapping(ContentNamespace.Sites, urlLeftPart);
                }
                catch
                {
                    Log.Error($"Failed to get publication mapping for url {urlLeftPart}");
                }

                if (mapping == null || mapping.Port != url.Port.ToString()) // See CRQ-1195
                {
                    throw new DxaUnknownLocalizationException($"No matching Localization found for URL '{urlLeftPart}'");
                }

                Localization result;
                lock (KnownLocalizations)
                {
                    string localizationId = mapping.PublicationId.ToString();
                    if (!KnownLocalizations.TryGetValue(localizationId, out result))
                    {
                        result = new Localization
                        {
                            Id   = localizationId,
                            Path = mapping.Path
                        };
                        KnownLocalizations.Add(localizationId, result);
                    }
                    else
                    {
                        // we fill in the path regardless as it may of been
                        // a partially created localization.
                        result.Path = mapping.Path;
                    }
                }

                result.EnsureInitialized();
                return(result);
            }
        }