<commit_before>package org.springframework.roo.addon.web.flow;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.springframework.roo.addon.web.flow.XmlTemplate.DomElementCallback;
import org.springframework.roo.addon.web.mvc.controller.WebMvcOperations;
import org.springframework.roo.addon.web.mvc.jsp.JspOperations;
import org.springframework.roo.addon.web.mvc.jsp.menu.MenuOperations;
import org.springframework.roo.addon.web.mvc.jsp.tiles.TilesOperations;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.process.manager.FileManager;
import org.springframework.roo.project.Dependency;
import org.springframework.roo.project.Path;
import org.springframework.roo.project.ProjectOperations;
import org.springframework.roo.project.ProjectType;
import org.springframework.roo.project.Repository;
import org.springframework.roo.support.util.FileCopyUtils;
import org.springframework.roo.support.util.StringUtils;
import org.springframework.roo.support.util.TemplateUtils;
import org.springframework.roo.support.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Provides Web Flow configuration operations.
 * 
 * @author <NAME>
 * @author <NAME>
 * @since 1.0
 */
@Component
@Service
public class WebFlowOperationsImpl implements WebFlowOperations {
	@Reference private FileManager fileManager;
	@Reference private ProjectOperations projectOperations;
	@Reference private MenuOperations menuOperations;
	@Reference private WebMvcOperations webMvcOperations;
	@Reference private JspOperations jspOperations;
	@Reference private TilesOperations tilesOperations;

	public boolean isInstallWebFlowAvailable() {
		return projectOperations.isProjectAvailable();
	}

	public boolean isManageWebFlowAvailable() {
		return isInstallWebFlowAvailable() && fileManager.exists(projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/spring/webflow-config.xml"));
	}

	/**
	 * See {@link WebFlowOperations#installWebFlow(String)}.
	 */
	public void installWebFlow(String flowName) {
		installWebFlowConfiguration();

		final String flowId = getFlowId(flowName);
		String webRelativeFlowPath = "/WEB-INF/views/" + flowId;
		String resolvedFlowPath = projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, webRelativeFlowPath);
		String resolvedFlowDefinitionPath = resolvedFlowPath + "/flow.xml";

		if (fileManager.exists(resolvedFlowPath)) {
			throw new IllegalStateException("Flow directory already exists: " + resolvedFlowPath);
		}
		fileManager.createDirectory(resolvedFlowPath);

		copyTemplate("flow.xml", resolvedFlowPath);
		copyTemplate("view-state-1.jspx", resolvedFlowPath);
		copyTemplate("view-state-2.jspx", resolvedFlowPath);
		copyTemplate("end-state.jspx", resolvedFlowPath);

		new XmlTemplate(fileManager).update(resolvedFlowDefinitionPath, new DomElementCallback() {
			public boolean doWithElement(Document document, Element root) {
				List<Element> states = XmlUtils.findElements("/flow/view-state|end-state", root);
				for (Element state : states) {
					state.setAttribute("view", flowId + "/" + state.getAttribute("id"));
				}
				return true;
			}
		});

		JavaSymbolName flowMenuCategory = new JavaSymbolName("Flows");
		JavaSymbolName flowMenuName = new JavaSymbolName(flowId.replaceAll("/", "_"));
		menuOperations.addMenuItem(flowMenuCategory, flowMenuName, flowMenuName.getReadableSymbolName(), "webflow_menu_enter", "/" + flowId, null);

		tilesOperations.addViewDefinition(flowId, flowId + "/*", TilesOperations.DEFAULT_TEMPLATE, webRelativeFlowPath + "/{1}.jspx");

		updateConfiguration();
	}

	private void installWebFlowConfiguration() {
		String resolvedSpringConfigPath = projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/spring");
		if (fileManager.exists(resolvedSpringConfigPath + "/webflow-config.xml")) {
			return;
		}

		copyTemplate("webflow-config.xml", resolvedSpringConfigPath);

		String webMvcConfigPath = resolvedSpringConfigPath + "/webmvc-config.xml";
		if (!fileManager.exists(webMvcConfigPath)) {
			webMvcOperations.installAllWebMvcArtifacts();
			jspOperations.installCommonViewArtefacts();
		}

		new XmlTemplate(fileManager).update(webMvcConfigPath, new DomElementCallback() {
			public boolean doWithElement(Document document, Element root) {
				if (XmlUtils.findFirstElement("/beans/bean[@id='conversionService']", root) == null) {
					Element conversionServiceBean = document.createElement("bean");
					conversionServiceBean.setAttribute("id", "conversionService");
					conversionServiceBean.setAttribute("class", "org.springframework.format.support.FormattingConversionServiceFactoryBean");
					root.appendChild(conversionServiceBean);
					return true;
				}
				return false;
			}
		});

		new XmlTemplate(fileManager).update(webMvcConfigPath, new DomElementCallback() {
			public boolean doWithElement(Document document, Element root) {
				if (XmlUtils.findFirstElement("/beans/import[@resource='webflow-config.xml']", root) == null) {
					Element importSWF = document.createElement("import");
					importSWF.setAttribute("resource", "webflow-config.xml");
					root.appendChild(importSWF);
					return true;
				}
				return false;
			}
		});
	}

	private void updateConfiguration() {
		Element configuration = XmlUtils.getConfiguration(getClass());

		List<Dependency> dependencies = new ArrayList<Dependency>();
		List<Element> webFlowDependencies = XmlUtils.findElements("/configuration/springWebFlow/dependencies/dependency", configuration);
		for (Element d : webFlowDependencies) {
			dependencies.add(new Dependency(d));
		}
		projectOperations.addDependencies(dependencies);
		
		List<Element> repositories = XmlUtils.findElements("/configuration/springWebFlow/repositories/repository", configuration);
		for (Element r : repositories) {
			projectOperations.addRepository(new Repository(r));
		}
		projectOperations.updateProjectType(ProjectType.WAR);<commit_msg>Revert "ROO-2368: Overriding method results in Method '*' already defined in target type - added deactivate method to follow pattern of other md providers"<commit_after>package org.springframework.roo.addon.web.flow;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.springframework.roo.addon.web.flow.XmlTemplate.DomElementCallback;
import org.springframework.roo.addon.web.mvc.controller.WebMvcOperations;
import org.springframework.roo.addon.web.mvc.jsp.JspOperations;
import org.springframework.roo.addon.web.mvc.jsp.menu.MenuOperations;
import org.springframework.roo.addon.web.mvc.jsp.tiles.TilesOperations;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.process.manager.FileManager;
import org.springframework.roo.project.Dependency;
import org.springframework.roo.project.Path;
import org.springframework.roo.project.ProjectOperations;
import org.springframework.roo.project.ProjectType;
import org.springframework.roo.project.Repository;
import org.springframework.roo.support.util.FileCopyUtils;
import org.springframework.roo.support.util.StringUtils;
import org.springframework.roo.support.util.TemplateUtils;
import org.springframework.roo.support.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Provides Web Flow configuration operations.
 * 
 * @author <NAME>
 * @author <NAME>
 * @since 1.0
 */
@Component
@Service
public class WebFlowOperationsImpl implements WebFlowOperations {
	@Reference private FileManager fileManager;
	@Reference private ProjectOperations projectOperations;
	@Reference private MenuOperations menuOperations;
	@Reference private WebMvcOperations webMvcOperations;
	@Reference private JspOperations jspOperations;
	@Reference private TilesOperations tilesOperations;

	public boolean isInstallWebFlowAvailable() {
		return projectOperations.isProjectAvailable();
	}

	public boolean isManageWebFlowAvailable() {
		return isInstallWebFlowAvailable() && fileManager.exists(projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/spring/webflow-config.xml"));
	}

	/**
	 * See {@link WebFlowOperations#installWebFlow(String)}.
	 */
	public void installWebFlow(String flowName) {
		installWebFlowConfiguration();

		final String flowId = getFlowId(flowName);
		String webRelativeFlowPath = "/WEB-INF/views/" + flowId;
		String resolvedFlowPath = projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, webRelativeFlowPath);
		String resolvedFlowDefinitionPath = resolvedFlowPath + "/flow.xml";

		if (fileManager.exists(resolvedFlowPath)) {
			throw new IllegalStateException("Flow directory already exists: " + resolvedFlowPath);
		}
		fileManager.createDirectory(resolvedFlowPath);

		copyTemplate("flow.xml", resolvedFlowPath);
		copyTemplate("view-state-1.jspx", resolvedFlowPath);
		copyTemplate("view-state-2.jspx", resolvedFlowPath);
		copyTemplate("end-state.jspx", resolvedFlowPath);

		new XmlTemplate(fileManager).update(resolvedFlowDefinitionPath, new DomElementCallback() {
			public boolean doWithElement(Document document, Element root) {
				List<Element> states = XmlUtils.findElements("/flow/view-state|end-state", root);
				for (Element state : states) {
					state.setAttribute("view", flowId + "/" + state.getAttribute("id"));
				}
				return true;
			}
		});

		JavaSymbolName flowMenuCategory = new JavaSymbolName("Flows");
		JavaSymbolName flowMenuName = new JavaSymbolName(flowId.replaceAll("/", "_"));
		menuOperations.addMenuItem(flowMenuCategory, flowMenuName, flowMenuName.getReadableSymbolName(), "webflow_menu_enter", "/" + flowId, null);

		tilesOperations.addViewDefinition(flowId, flowId + "/*", TilesOperations.DEFAULT_TEMPLATE, webRelativeFlowPath + "/{1}.jspx");

		updateConfiguration();
	}

	private void installWebFlowConfiguration() {
		String resolvedSpringConfigPath = projectOperations.getPathResolver().getIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/spring");
		if (fileManager.exists(resolvedSpringConfigPath + "/webflow-config.xml")) {
			return;
		}

		copyTemplate("webflow-config.xml", resolvedSpringConfigPath);

		String webMvcConfigPath = resolvedSpringConfigPath + "/webmvc-config.xml";
		if (!fileManager.exists(webMvcConfigPath)) {
			webMvcOperations.installAllWebMvcArtifacts();
			jspOperations.installCommonViewArtefacts();
		}

		new XmlTemplate(fileManager).update(webMvcConfigPath, new DomElementCallback() {
			public boolean doWithElement(Document document, Element root) {
				if (null == XmlUtils.findFirstElement("/beans/import[@resource='webflow-config.xml']", root)) {
					Element importSWF = document.createElement("import");
					importSWF.setAttribute("resource", "webflow-config.xml");
					root.appendChild(importSWF);
					return true;
				}
				return false;
			}
		});
	}

	private void updateConfiguration() {
		Element configuration = XmlUtils.getConfiguration(getClass());

		List<Dependency> dependencies = new ArrayList<Dependency>();
		List<Element> webFlowDependencies = XmlUtils.findElements("/configuration/springWebFlow/dependencies/dependency", configuration);
		for (Element d : webFlowDependencies) {
			dependencies.add(new Dependency(d));
		}
		projectOperations.addDependencies(dependencies);
		
		List<Element> repositories = XmlUtils.findElements("/configuration/springWebFlow/repositories/repository", configuration);
		for (Element r : repositories) {
			projectOperations.addRepository(new Repository(r));
		}
		projectOperations.updateProjectType(ProjectType.WAR);
{'fraction_non_alphanumeric': 0.1136, 'fraction_numerical': 0.0015157894736842106, 'mean_word_length': 6.128451380552221, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7665258', 'n_tokens_mistral': 3603, 'n_tokens_neox': 3363, 'n_words': 578}