categories
groovy
merge
System Administrator
Jahia 7.3
Jahia 8
How to merge 2 categories
Question
What is the way to merge 2 categories?
Answer
Imagine that we have 2 categories catA
and catB
If you want to merge catA
with catB
, then you simply need to get the list of nodes with a reference to catA
, then remove this reference and set it to catB
Here could be a script to handle it from the groovy console. Before running it, you need to set the categoryFrom
and the categoryTo
variables with the current category path you want to work with.
Also set the doIt
to true
to apply the changes.
import org.jahia.api.Constants
import org.jahia.services.content.*
import javax.jcr.NodeIterator
import javax.jcr.PathNotFoundException
import javax.jcr.RepositoryException
import javax.jcr.query.Query
def logger = log;
String categoryFrom = "/sites/systemsite/categories/category-a";
String categoryTo = "/sites/systemsite/categories/category-b";
boolean doIt = false;
Set<String> nodesToAutoPublish = new HashSet<String>();
Set<String> nodesToManuallyPublish = new HashSet<String>();
JCRTemplate.getInstance().doExecuteWithSystemSession(null, Constants.EDIT_WORKSPACE, null, new JCRCallback() {
@Override
Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
JCRNodeWrapper fromCategoryNode = null;
try {
fromCategoryNode = session.getNode(categoryFrom);
} catch (javax.jcr.PathNotFoundException e) {
}
JCRNodeWrapper toCategoryNode = null;
try {
toCategoryNode = session.getNode(categoryTo);
} catch (javax.jcr.PathNotFoundException e) {
}
if (fromCategoryNode != null && toCategoryNode != null) {
String categoryFromUUID = fromCategoryNode.getIdentifier();
String categoryToUUID = toCategoryNode.getIdentifier();
def q = "SELECT * FROM [jmix:categorized] where [j:defaultCategory]='" + categoryFromUUID + "'";
NodeIterator iterator = session.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2).execute().getNodes();
while (iterator.hasNext()) {
final JCRNodeWrapper node = (JCRNodeWrapper) iterator.nextNode();
logger.info("Found category (" + fromCategoryNode.getDisplayableName() + ") on node " + node.getPath());
boolean toCategoryAlreadySet = false;
try {
if (! hasPendingModification(node)) {
nodesToAutoPublish.add(node.getIdentifier());
} else {
nodesToManuallyPublish.add(node.getIdentifier());
}
JCRPropertyWrapper categoryProp = node.getProperty("j:defaultCategory");
JCRValueWrapper valueToRemove = null;
JCRValueWrapper[] categoryValues = categoryProp.getValues()
for (JCRValueWrapper categoryValue : categoryValues) {
if (categoryValue.getString().equals(categoryToUUID)) {
toCategoryAlreadySet = true;
}
if (categoryValue.getString().equals(categoryFromUUID)) {
valueToRemove = categoryValue;
}
}
try {
categoryProp.removeValue(valueToRemove);
logger.info(" Remove category " + valueToRemove.getString() + " (" + fromCategoryNode.getDisplayableName() + ") on " + node.getPath());
} catch (javax.jcr.ValueFormatException e) {
logger.info(" Error when trying to rempve category " + categoryFromUUID + " (" + fromCategoryNode.getDisplayableName() + ") on " + node.getPath() + " " + e.getMessage());
}
if (! toCategoryAlreadySet ) {
try {
categoryProp.addValue(toCategoryNode);
logger.info(" Set category " + categoryToUUID + " (" + toCategoryNode.getDisplayableName() + ") on " + node.getPath());
} catch (javax.jcr.ValueFormatException e) {
logger.info(" Error when trying to set category " + categoryToUUID + " (" + toCategoryNode.getDisplayableName() + ") on " + node.getPath() + " " + e.getMessage());
}
}
node.setProperty("j:defaultCategory", categoryProp.getValues());
if (doIt) {
node.saveSession();
}
} catch (PathNotFoundException e) {
}
}
}
if (CollectionUtils.isNotEmpty(nodesToAutoPublish)) {
if (doIt) {
JCRPublicationService.getInstance().publish(nodesToAutoPublish.asList(), Constants.EDIT_WORKSPACE, Constants.LIVE_WORKSPACE, null);
};
logger.info("");
logger.info("Nodes which where republished:")
for (String identifier : nodesToAutoPublish) {
logger.warn(" " + session.getNodeByIdentifier(identifier).getPath());
}
}
if (CollectionUtils.isNotEmpty(nodesToManuallyPublish)) {
logger.info("");
logger.info("Nodes to publish manually:")
for (String identifier : nodesToManuallyPublish) {
logger.warn(" " + session.getNodeByIdentifier(identifier).getPath());
}
}
if (doIt) {
session.save();
}
return null;
}
});
private boolean hasPendingModifications(JCRNodeWrapper node) {
if (!node.hasProperty("j:lastPublished")) return true
if (!node.hasProperty("j:published") || !node.getProperty("j:published").getBoolean()) return true
java.util.Calendar lastModified = node.getProperty("jcr:lastModified").getDate()
java.util.Calendar lastPublished = node.getProperty("j:lastPublished").getDate()
return lastModified > lastPublished
}