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;
}
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;
}
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;
}
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;
}
Aggregations