Search code examples
tridiontridion-2011

Tridion RepositoryLocalObject.GetBluePrintChain Method (BluePrintChainFilter) thows exception on shared items


I'm trying to get a list of parent items that a RepositoryLocalObject (e.g. Component) is inherited from. So if I have a pub ID 1 with component tcm:1-80 and a child pub ID 2, then this component is shared in the child pub as tcm:2-80. So I want to get tcm:2-80's parent, or anything that's in the tree moving up.

I've tried the GetBluePrintChain() method on a local copy of a component where it works fine. However, on shared component it returns an InvalidActionException: "This item is shared". The documentation mentions that this exception is thrown on shared items. But how does this make sense? Obviously if any item that has a blueprint chain beyond itself would be shared (or be a local copy). So to me it doesn't make sense to have this method throw an exception on something that has a blueprint chain. It seems contradictory.

My question is somewhat related to Getting root publication of component, but it is different. I need to understand why this exception is thrown on shared items. Can someone please explain and perhaps share a use case to support it?


Solution

  • As far as I know the GetBluePrintChain methods are meant to look down a BluePrint when you're standing at the top of it. So in your case, you should get the item in its owning publication context and then invoke GetBluePrintChain.

    Item item = package.GetByName("Component");
    Component component = new Component(item.GetAsXmlDocument().DocumentElement,
                                        engine.GetSession());
    TcmUri id = TemplateUtilities.CreateTcmUriForPublication(
            component.OwningRepository.Id.ItemId, component.Id);
    
    var blueprintchain = ((Component)engine.GetObject(id)).GetBluePrintChain();
    
    package.PushItem(package.CreateStringItem(ContentType.Text, 
                                              blueprintchain.ToString()));
    package.PushItem(package.CreateStringItem(ContentType.Text,
                                 ""+System.Linq.Enumerable.Count(blueprintchain)));
    foreach (var item in blueprintchain)
    {
        package.PushItem(package.CreateTridionItem(ContentType.Component, item));
    }
    

    I just ran the above C# fragment as a TBB in two scenarios:

    1. in a child publication on a shared Component
    2. in a child publication on a localized Component

    In case 1 the blueprintchain will contain a single item: the shared Component. In case 2 the blueprintchain will contain two items: the shared Component and the localized Component.