Search in sources :

Example 1 with XmlMergeException

use of org.craftercms.core.exception.XmlMergeException in project core by craftercms.

the class ContentBundleMergeStrategy method getDescriptors.

@Override
public List<MergeableDescriptor> getDescriptors(Context context, CachingOptions cachingOptions, String mainDescriptorUrl, Document mainDescriptorDom, boolean mainDescriptorOptional) throws XmlMergeException {
    List<MergeableDescriptor> descriptors = new ArrayList<>();
    List<MergeableDescriptor> tmp;
    ContentBundleUrl parsedUrl = urlParser.getContentBundleUrl(mainDescriptorUrl);
    // prefix = folder1/
    String prefix = parsedUrl.getPrefix();
    // baseNameAndExtensionToken =
    String baseNameAndExtensionToken = parsedUrl.getBaseNameAndExtensionToken();
    // folder2_es
    // suffix = /file.xml
    String suffix = parsedUrl.getSuffix();
    // If the prefix is the same length as the initial URI, ignore, otherwise process
    if (prefix.length() < mainDescriptorUrl.length()) {
        // Get the index of the delimiter that separates the base name from the extension token (the _ in
        // folder2_es).
        String baseName = baseNameAndExtensionToken;
        int delimiterIdx = baseName.lastIndexOf(baseDelimiter);
        boolean baseFound = false;
        while (delimiterIdx > 0 && !baseFound) {
            // baseName = folder2
            baseName = baseName.substring(0, delimiterIdx);
            // baseDescriptor = folder1/folder2/file.xml
            String baseDescriptor = prefix + baseName + suffix;
            Document baseDescriptorDom;
            baseDescriptorDom = getDescriptorDom(context, cachingOptions, baseDescriptor);
            if (baseDescriptorDom != null) {
                baseFound = true;
            } else if (logger.isDebugEnabled()) {
                logger.debug("No base descriptor " + baseDescriptor + " was found");
            }
            if (baseFound) {
                // This can recurse if the selected strategy is also an ContentBundleMergeStrategy and the base
                // descriptor path has more families.
                DescriptorMergeStrategy baseMergeStrategy = baseMergeStrategyResolver.getStrategy(baseDescriptor, baseDescriptorDom);
                if (baseMergeStrategy == null) {
                    throw new XmlMergeException("No merge strategy for descriptor " + baseDescriptor);
                }
                tmp = baseMergeStrategy.getDescriptors(context, cachingOptions, baseDescriptor, baseDescriptorDom, true);
                descriptors.addAll(tmp);
            } else {
                delimiterIdx = baseName.lastIndexOf(baseDelimiter);
            }
        }
        // Keep only after the prefix (folder2_es/file.xml)
        String noPrefix = mainDescriptorUrl.substring(prefix.length(), mainDescriptorUrl.length());
        // Add all level descriptors after the prefix using the regular strategy (this is up to us/part of our spec)
        tmp = regularMergeStrategy.getDescriptors(context, cachingOptions, noPrefix, mainDescriptorDom, mainDescriptorOptional);
        // if it's not already in the results.
        for (MergeableDescriptor descriptor : tmp) {
            descriptor.setUrl(prefix + descriptor.getUrl());
            if (!descriptors.contains(descriptor)) {
                descriptors.add(descriptor);
            }
        }
    } else {
        descriptors.add(new MergeableDescriptor(mainDescriptorUrl, mainDescriptorOptional));
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Final merge list for " + mainDescriptorUrl + ": " + descriptors);
    }
    return descriptors;
}
Also used : DescriptorMergeStrategy(org.craftercms.core.xml.mergers.DescriptorMergeStrategy) ArrayList(java.util.ArrayList) MergeableDescriptor(org.craftercms.core.xml.mergers.MergeableDescriptor) ContentBundleUrl(org.craftercms.core.util.url.ContentBundleUrl) Document(org.dom4j.Document) XmlMergeException(org.craftercms.core.exception.XmlMergeException)

Example 2 with XmlMergeException

use of org.craftercms.core.exception.XmlMergeException in project core by craftercms.

the class ContentStoreServiceImpl method doMerging.

/**
 * Executes merging for the specified {@link Item}:
 * <p/>
 * <ol>
 * <li>Gets the {@link org.craftercms.core.xml.mergers.DescriptorMergeStrategy} for the item's descriptor from
 * the {@link DescriptorMergeStrategyResolver}.</li>
 * <li>Gets the actual descriptors to merge from the returned merge strategy.</li>
 * <li>Retrieves the descriptor documents from the underlying repository.</li>
 * <li>Merges the descriptor documents.</li>
 * <li>Returns the item with the merged descriptor document.</li>
 * </ol>
 */
protected Item doMerging(Context context, CachingOptions cachingOptions, Item item) throws CrafterException {
    if (context.isMergingOn()) {
        if (logger.isDebugEnabled()) {
            logger.debug("Doing merge for " + item + "...");
        }
        String mainDescriptorUrl = item.getDescriptorUrl();
        Document mainDescriptorDom = item.getDescriptorDom();
        DescriptorMergeStrategy strategy = mergeStrategyResolver.getStrategy(mainDescriptorUrl, mainDescriptorDom);
        if (strategy == null) {
            logger.warn("No merge strategy was found for " + mainDescriptorUrl + ". Merging skipped");
            return item;
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Merge strategy for " + mainDescriptorUrl + ": " + strategy);
        }
        List<MergeableDescriptor> descriptorsToMerge = strategy.getDescriptors(context, cachingOptions, mainDescriptorUrl, mainDescriptorDom);
        if (descriptorsToMerge == null) {
            throw new XmlMergeException("There aren't any descriptors to merge for " + mainDescriptorUrl);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Descriptors to merge for " + mainDescriptorUrl + ": " + descriptorsToMerge);
        }
        List<Document> documentsToMerge = new ArrayList<Document>(descriptorsToMerge.size());
        for (MergeableDescriptor descriptorToMerge : descriptorsToMerge) {
            String descriptorUrl = descriptorToMerge.getUrl();
            Item descriptorItem = context.getStoreAdapter().findItem(context, cachingOptions, descriptorUrl, true);
            if (descriptorItem != null) {
                Document descriptorDom = descriptorItem.getDescriptorDom();
                if (descriptorDom == null && !descriptorToMerge.isOptional()) {
                    throw new XmlMergeException("Descriptor file " + descriptorUrl + " not found and is marked as " + "required for merging");
                }
                documentsToMerge.add(descriptorDom);
                item.addDependencyKey(descriptorItem.getKey());
            } else if (!descriptorToMerge.isOptional()) {
                throw new XmlMergeException("Descriptor file " + descriptorUrl + " not found and is marked as required for merging");
            }
        }
        Document mergedDoc = merger.merge(documentsToMerge);
        if (logger.isDebugEnabled()) {
            logger.debug("Merged descriptor DOM for " + item + ":\n" + XmlUtils.documentToPrettyString(mergedDoc));
        }
        item.setDescriptorDom(mergedDoc);
    }
    return item;
}
Also used : Item(org.craftercms.core.service.Item) DescriptorMergeStrategy(org.craftercms.core.xml.mergers.DescriptorMergeStrategy) ArrayList(java.util.ArrayList) MergeableDescriptor(org.craftercms.core.xml.mergers.MergeableDescriptor) Document(org.dom4j.Document) XmlMergeException(org.craftercms.core.exception.XmlMergeException)

Example 3 with XmlMergeException

use of org.craftercms.core.exception.XmlMergeException in project core by craftercms.

the class ExplicitParentMergeStrategy method getDescriptors.

@Override
public List<MergeableDescriptor> getDescriptors(Context context, CachingOptions cachingOptions, String mainDescriptorUrl, Document mainDescriptorDom, boolean mainDescriptorOptional) throws XmlMergeException {
    Node parentDescriptorElem = mainDescriptorDom.selectSingleNode(parentDescriptorElementXPathQuery);
    List<MergeableDescriptor> descriptors = new ArrayList<>();
    if (parentDescriptorElem != null) {
        String parentDescriptorUrl = parentDescriptorElem.getText();
        Document parentDescriptorDom = getDescriptorDom(context, cachingOptions, parentDescriptorUrl);
        if (parentDescriptorDom != null) {
            DescriptorMergeStrategy parentMergeStrategy = mergeStrategyResolver.getStrategy(parentDescriptorUrl, parentDescriptorDom);
            if (parentMergeStrategy != null) {
                descriptors.addAll(parentMergeStrategy.getDescriptors(context, cachingOptions, parentDescriptorUrl, parentDescriptorDom, true));
            }
        } else {
            throw new XmlMergeException("No parent descriptor found at " + parentDescriptorUrl);
        }
    } else {
        throw new XmlMergeException("No parent descriptor element specified");
    }
    descriptors.add(new MergeableDescriptor(mainDescriptorUrl, mainDescriptorOptional));
    return descriptors;
}
Also used : DescriptorMergeStrategy(org.craftercms.core.xml.mergers.DescriptorMergeStrategy) Node(org.dom4j.Node) ArrayList(java.util.ArrayList) MergeableDescriptor(org.craftercms.core.xml.mergers.MergeableDescriptor) Document(org.dom4j.Document) XmlMergeException(org.craftercms.core.exception.XmlMergeException)

Example 4 with XmlMergeException

use of org.craftercms.core.exception.XmlMergeException in project core by craftercms.

the class MergeParentAndChildMergeCue method merge.

@Override
@SuppressWarnings("unchecked")
public Element merge(Element parent, Element child, Map<String, String> params) throws XmlMergeException {
    Element merged = DocumentHelper.createElement(child.getQName());
    org.craftercms.core.util.CollectionUtils.move(child.attributes(), merged.attributes());
    if (parent.isTextOnly() && child.isTextOnly()) {
        String parentText = parent.getText();
        String childText = child.getText();
        if (getMergeOrder(params).equalsIgnoreCase("after")) {
            merged.setText(parentText + childText);
        } else {
            merged.setText(childText + parentText);
        }
    } else {
        List<Element> parentElements = parent.elements();
        List<Element> childElements = child.elements();
        List<Element> mergedElements = merged.elements();
        if (CollectionUtils.isNotEmpty(parentElements) && CollectionUtils.isNotEmpty(childElements)) {
            for (Iterator<Element> i = parentElements.iterator(); i.hasNext(); ) {
                Element parentElement = i.next();
                boolean elementsMerged = false;
                for (Iterator<Element> j = childElements.iterator(); !elementsMerged && j.hasNext(); ) {
                    Element childElement = j.next();
                    if (elementMergeMatcher.matchForMerge(parentElement, childElement)) {
                        MergeCueContext context = mergeCueResolver.getMergeCue(parentElement, childElement);
                        if (context != null) {
                            i.remove();
                            j.remove();
                            Element mergedElement = context.doMerge();
                            mergedElements.add(mergedElement);
                            elementsMerged = true;
                        } else {
                            throw new XmlMergeException("No merge cue was resolved for matching elements " + parentElement + " (parent) and " + childElement + " (child)");
                        }
                    }
                }
            }
        }
        if (getMergeOrder(params).equalsIgnoreCase("after")) {
            org.craftercms.core.util.CollectionUtils.move(parentElements, mergedElements);
            org.craftercms.core.util.CollectionUtils.move(childElements, mergedElements);
        } else {
            org.craftercms.core.util.CollectionUtils.move(childElements, mergedElements);
            org.craftercms.core.util.CollectionUtils.move(parentElements, mergedElements);
        }
    }
    return merged;
}
Also used : MergeCueContext(org.craftercms.core.xml.mergers.impl.cues.MergeCueContext) Element(org.dom4j.Element) XmlMergeException(org.craftercms.core.exception.XmlMergeException)

Aggregations

XmlMergeException (org.craftercms.core.exception.XmlMergeException)4 ArrayList (java.util.ArrayList)3 DescriptorMergeStrategy (org.craftercms.core.xml.mergers.DescriptorMergeStrategy)3 MergeableDescriptor (org.craftercms.core.xml.mergers.MergeableDescriptor)3 Document (org.dom4j.Document)3 Item (org.craftercms.core.service.Item)1 ContentBundleUrl (org.craftercms.core.util.url.ContentBundleUrl)1 MergeCueContext (org.craftercms.core.xml.mergers.impl.cues.MergeCueContext)1 Element (org.dom4j.Element)1 Node (org.dom4j.Node)1