public static ContentSpec transform(final ContentSpecWrapper spec, final DataProviderFactory providerFactory,
            final boolean includeChecksum) {
        // local variables that are used to map transformed content
        Map<Integer, Node> nodes = new HashMap<Integer, Node>();
        Map<String, SpecTopic> topicTargets = new HashMap<String, SpecTopic>();
        List<CSNodeWrapper> relationshipFromNodes = new ArrayList<CSNodeWrapper>();
        List<Process> processes = new ArrayList<Process>();

        // Start the transformation
        final ContentSpec contentSpec = new ContentSpec();

        contentSpec.setId(spec.getId());
        transformGlobalOptions(spec, contentSpec);

        // Add all the levels/topics
        boolean localeFound = false;
        if (spec.getChildren() != null) {
            final List<CSNodeWrapper> childNodes = spec.getChildren().getItems();
            final HashMap<CSNodeWrapper, Node> levelNodes = new HashMap<CSNodeWrapper, Node>();
            for (final CSNodeWrapper childNode : childNodes) {
                if (childNode.getNodeType() == CommonConstants.CS_NODE_TOPIC) {
                    final SpecTopic topic = transformSpecTopic(childNode, nodes, topicTargets, relationshipFromNodes);
                    levelNodes.put(childNode, topic);
                } else if (childNode.getNodeType() == CommonConstants.CS_NODE_COMMENT) {
                    final Comment comment = transformComment(childNode);
                    levelNodes.put(childNode, comment);
                } else if (childNode.getNodeType() == CommonConstants.CS_NODE_COMMON_CONTENT) {
                    final CommonContent commonContent = transformCommonContent(childNode);
                    levelNodes.put(childNode, commonContent);
                } else if (childNode.getNodeType() == CommonConstants.CS_NODE_META_DATA || childNode.getNodeType() == CommonConstants
                        .CS_NODE_META_DATA_TOPIC) {
                    if (!IGNORE_META_DATA.contains(childNode.getTitle().toLowerCase())) {
                        final KeyValueNode<?> metaDataNode = transformMetaData(childNode, nodes, topicTargets, relationshipFromNodes);
                        levelNodes.put(childNode, metaDataNode);
                    }
                    if (CommonConstants.CS_LOCALE_TITLE.equalsIgnoreCase(childNode.getTitle())) {
                        localeFound = true;
                    }
                } else {
                    final Level level = transformLevel(childNode, nodes, topicTargets, relationshipFromNodes, processes);
                    levelNodes.put(childNode, level);
                }
            }

            // Sort the level nodes so that they are in the right order based on next/prev values.
            final LinkedHashMap<CSNodeWrapper, Node> sortedMap = CSNodeSorter.sortMap(levelNodes);

            // Add the child nodes to the content spec now that they are in the right order.
            boolean addToBaseLevel = false;
            final Iterator<Map.Entry<CSNodeWrapper, Node>> iter = sortedMap.entrySet().iterator();
            while (iter.hasNext()) {
                final Map.Entry<CSNodeWrapper, Node> entry = iter.next();

                // If a level or spec topic is found then start adding to the base level instead of the content spec
                if ((entry.getValue() instanceof Level || entry.getValue() instanceof SpecTopic) && !addToBaseLevel) {
                    addToBaseLevel = true;

                    // Add the locale if it wasn't specified
                    if (!localeFound) {
                        contentSpec.setLocale(spec.getLocale() == null ? null : spec.getLocale().getValue());
                    }

                    // Add a space between the base metadata and optional metadata
                    contentSpec.appendChild(new TextNode("\n"));
                }

                // Add the node to the right component.
                if (addToBaseLevel) {
                    contentSpec.getBaseLevel().appendChild(entry.getValue());
                    // Add a new line to separate chapters/parts
                    if (isNodeASeparatorLevel(entry.getValue()) && iter.hasNext()) {
                        contentSpec.getBaseLevel().appendChild(new TextNode("\n"));
                    }
                } else {
                    contentSpec.appendChild(entry.getValue());
                }
            }
        }

        // Apply the relationships to the nodes
        applyRelationships(contentSpec, nodes, topicTargets, relationshipFromNodes, processes, providerFactory);

        // Set the line numbers
        setLineNumbers(contentSpec, includeChecksum ? 2 : 1);

        return contentSpec;
    }
public static ContentSpec transform ( final ContentSpecWrapper spec , final DataProviderFactory providerFactory , final boolean includeChecksum ) { Map < Integer , Node > nodes = new HashMap < Integer , Node > ( ) ; Map < String , SpecTopic > topicTargets = new HashMap < String , SpecTopic > ( ) ; List < CSNodeWrapper > relationshipFromNodes = new ArrayList < CSNodeWrapper > ( ) ; List < Process > processes = new ArrayList < Process > ( ) ; final ContentSpec contentSpec = new ContentSpec ( ) ; contentSpec . setId ( spec . getId ( ) ) ; transformGlobalOptions ( spec , contentSpec ) ; boolean localeFound = false ; if ( spec . getChildren ( ) != null ) { final List < CSNodeWrapper > childNodes = spec . getChildren ( ) . getItems ( ) ; final HashMap < CSNodeWrapper , Node > levelNodes = new HashMap < CSNodeWrapper , Node > ( ) ; for ( final CSNodeWrapper childNode : childNodes ) { if ( childNode . getNodeType ( ) == CommonConstants . CS_NODE_TOPIC ) { final SpecTopic topic = transformSpecTopic ( childNode , nodes , topicTargets , relationshipFromNodes ) ; levelNodes . put ( childNode , topic ) ; } else if ( childNode . getNodeType ( ) == CommonConstants . CS_NODE_COMMENT ) { final Comment comment = transformComment ( childNode ) ; levelNodes . put ( childNode , comment ) ; } else if ( childNode . getNodeType ( ) == CommonConstants . CS_NODE_COMMON_CONTENT ) { final CommonContent commonContent = transformCommonContent ( childNode ) ; levelNodes . put ( childNode , commonContent ) ; } else if ( childNode . getNodeType ( ) == CommonConstants . CS_NODE_META_DATA || childNode . getNodeType ( ) == CommonConstants . CS_NODE_META_DATA_TOPIC ) { if ( ! IGNORE_META_DATA . contains ( childNode . getTitle ( ) . toLowerCase ( ) ) ) { final KeyValueNode < ? > metaDataNode = transformMetaData ( childNode , nodes , topicTargets , relationshipFromNodes ) ; levelNodes . put ( childNode , metaDataNode ) ; } if ( CommonConstants . CS_LOCALE_TITLE . equalsIgnoreCase ( childNode . getTitle ( ) ) ) { localeFound = true ; } } else { final Level level = transformLevel ( childNode , nodes , topicTargets , relationshipFromNodes , processes ) ; levelNodes . put ( childNode , level ) ; } } final LinkedHashMap < CSNodeWrapper , Node > sortedMap = CSNodeSorter . sortMap ( levelNodes ) ; boolean addToBaseLevel = false ; final Iterator < Map . Entry < CSNodeWrapper , Node > > iter = sortedMap . entrySet ( ) . iterator ( ) ; while ( iter . hasNext ( ) ) { final Map . Entry < CSNodeWrapper , Node > entry = iter . next ( ) ; if ( ( entry . getValue ( ) instanceof Level || entry . getValue ( ) instanceof SpecTopic ) && ! addToBaseLevel ) { addToBaseLevel = true ; if ( ! localeFound ) { contentSpec . setLocale ( spec . getLocale ( ) == null ? null : spec . getLocale ( ) . getValue ( ) ) ; } contentSpec . appendChild ( new TextNode ( "\n" ) ) ; } if ( addToBaseLevel ) { contentSpec . getBaseLevel ( ) . appendChild ( entry . getValue ( ) ) ; if ( isNodeASeparatorLevel ( entry . getValue ( ) ) && iter . hasNext ( ) ) { contentSpec . getBaseLevel ( ) . appendChild ( new TextNode ( "\n" ) ) ; } } else { contentSpec . appendChild ( entry . getValue ( ) ) ; } } } applyRelationships ( contentSpec , nodes , topicTargets , relationshipFromNodes , processes , providerFactory ) ; setLineNumbers ( contentSpec , includeChecksum ? 2 : 1 ) ; return contentSpec ; }
Transforms a content spec datasource entity into a generic content spec object.

@param spec            The content spec entity to be transformed.
@param providerFactory
@return The generic Content Spec object that was transformed from the entity.