package org.springframework.roo.addon.tailor.config.xml; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.springframework.roo.addon.tailor.actions.ActionConfig; import org.springframework.roo.addon.tailor.config.CommandConfiguration; import org.springframework.roo.addon.tailor.config.TailorConfiguration; import org.springframework.roo.support.logging.HandlerUtils; import org.springframework.roo.support.util.XmlUtils; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; public class TailorParser { private static final Logger LOGGER = HandlerUtils.getLogger(TailorParser.class); /** * Maps the XML file contents to a TailorConfiguration object. It is * possible to have multiple configurations in tailor.xml * * @param root * @return list of tailor configurations */ public static List<TailorConfiguration> mapXmlToTailorConfiguration(final Element root) { final List<Element> elTailors = XmlUtils.findElements("/tailorconfiguration/tailor", root); if (elTailors.isEmpty()) { logTailorXMLInvalid("no <tailor> definitions found in <tailorconfiguration> root element"); return null; } final List<TailorConfiguration> configs = new ArrayList<TailorConfiguration>(); for (final Element eTailor : elTailors) { final TailorConfiguration config = parseTailorConfiguration(eTailor); if (config != null) { configs.add(config); } } return configs; } /** * Maps the single XML tailor configuration to a TailorConfiguration object. * * @param tailor element * @return tailor configurations */ public static TailorConfiguration parseTailorConfiguration(final Element elTailor) { if (StringUtils.isBlank(elTailor.getAttribute("name"))) { logTailorXMLInvalid("<tailor> must have a name attribute"); return null; } final TailorConfiguration result = new TailorConfiguration(elTailor.getAttribute("name"), elTailor.getAttribute("description")); final String activeAttribute = elTailor.getAttribute("activate"); if (StringUtils.isNotBlank(activeAttribute)) { final boolean isActive = "true".equalsIgnoreCase(activeAttribute) || "yes".equalsIgnoreCase(activeAttribute); result.setActive(isActive); } final List<Element> elConfigs = XmlUtils.findElements("config", elTailor); if (elConfigs.isEmpty()) { logTailorXMLInvalid("<tailor> must have <config> child elements"); return null; } for (final Element elConfig : elConfigs) { final String command = elConfig.getAttribute("command"); if (StringUtils.isBlank(command)) { logTailorXMLInvalid("found <config> without command attribute"); return null; } final CommandConfiguration newCmdConfig = new CommandConfiguration(); newCmdConfig.setCommandName(command); final List<Element> elActions = XmlUtils.findElements("action", elConfig); for (final Element elAction : elActions) { // Determine the action type if (StringUtils.isBlank(elAction.getAttribute("type"))) { logTailorXMLInvalid("found <action> without type attribute"); return null; } final ActionConfig newAction = new ActionConfig(elAction.getAttribute("type")); final NamedNodeMap attributes = elAction.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { final Node item = attributes.item(i); final String attributeKey = item.getNodeName(); if (!"type".equals(attributeKey)) { newAction.setAttribute(attributeKey, item.getNodeValue()); } } newCmdConfig.addAction(newAction); } result.addCommandConfig(newCmdConfig); } return result; } private static void logTailorXMLInvalid(final String msg) { LOGGER .warning("Invalid tailor.xml - please correct and restart the shell to use this configuration (" + msg + ")"); } }