/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.maven.tools; import org.eclipse.che.commons.xml.Element; import org.eclipse.che.commons.xml.ElementMapper; import org.eclipse.che.commons.xml.NewElement; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static org.eclipse.che.commons.xml.NewElement.createElement; import static org.eclipse.che.commons.xml.XMLTreeLocation.after; import static org.eclipse.che.commons.xml.XMLTreeLocation.afterAnyOf; import static org.eclipse.che.commons.xml.XMLTreeLocation.before; import static org.eclipse.che.commons.xml.XMLTreeLocation.inTheBegin; import static org.eclipse.che.commons.xml.XMLTreeLocation.inTheEnd; import static java.lang.Boolean.parseBoolean; import static java.util.Collections.emptyList; /** * Describes <i>/project/build/resources/resource</i>, which contains information * about where associated with project files should be included. * <p/> * Supports next data: * <ul> * <li>targetPath</li> * <li>filtering</li> * <li>directory</li> * <li>includes</li> * <li>excludes</li> * </ul> * * @author Eugene Voevodin */ public class Resource { private static final ElementMapper<String> TEXT_MAPPER = new ElementTextMapper(); private String targetPath; private String directory; private boolean filtering; private List<String> includes; private List<String> excludes; Element resourceElement; public Resource() { } Resource(Element resourceElement) { this.resourceElement = resourceElement; targetPath = resourceElement.getChildText("targetPath"); directory = resourceElement.getChildText("directory"); filtering = parseBoolean(resourceElement.getChildText("filtering")); if (resourceElement.hasSingleChild("includes")) { includes = resourceElement.getSingleChild("includes").getChildren(TEXT_MAPPER); } if (resourceElement.hasSingleChild("excludes")) { excludes = resourceElement.getSingleChild("excludes").getChildren(TEXT_MAPPER); } } /** * Returns directory structure to place the set of resources from a build */ public String getTargetPath() { return targetPath; } /** * Specifies the directory structure to place the set of resources from a build */ public Resource setTargetPath(String targetPath) { this.targetPath = targetPath; if (!isNew()) { if (targetPath == null) { resourceElement.removeChild("targetPath"); } else if (resourceElement.hasChild("targetPath")) { resourceElement.getSingleChild("targetPath").setText(targetPath); } else { resourceElement.insertChild(createElement("targetPath", targetPath), inTheBegin()); } } return this; } /** * Returns directory where the resources are to be found */ public String getDirectory() { return directory; } /** * Specifies directory where the resource are to be found */ public Resource setDirectory(String directory) { this.directory = directory; if (!isNew()) { if (directory == null) { resourceElement.removeChild("directory"); } else if (resourceElement.hasSingleChild("directory")) { resourceElement.getSingleChild("directory").setText(directory); } else { resourceElement.insertChild(createElement("directory", directory), afterAnyOf("targetPath", "filtering").or(inTheBegin())); } } return this; } /** * Returns {@code true} if filtering is enabled for this resource, otherwise returns {@code false} */ public boolean isFiltering() { return filtering; } public Resource setFiltering(boolean filtering) { this.filtering = filtering; if (!isNew()) { if (resourceElement.hasSingleChild("filtering")) { resourceElement.getSingleChild("filtering").setText(Boolean.toString(filtering)); } else { resourceElement.insertChild(createElement("filtering", Boolean.toString(filtering)), after("targetPath").or(inTheBegin())); } } return this; } /** * Returns list of file patterns which specifies the files * to include into specified directory. */ public List<String> getIncludes() { if (includes == null) { return emptyList(); } return new ArrayList<>(includes); } /** * Specifies list of file patterns which specifies the files * to include into specified directory */ public Resource setIncludes(Collection<String> includes) { if (includes == null || includes.isEmpty()) { removeIncludes(); } else { setIncludes0(includes); } return this; } /** * Returns list of file patterns which specifies the files to exclude * from specified directory */ public List<String> getExcludes() { if (excludes == null) { return emptyList(); } return new ArrayList<>(excludes); } /** * Specifies list of file patterns which specifies the files * to exclude from specified directory */ public Resource setExcludes(Collection<String> excludes) { if (excludes == null || excludes.isEmpty()) { removeExcludes(); } else { setExcludes0(excludes); } return this; } NewElement asXMLElement() { final NewElement resource = createElement("resource"); if (targetPath != null) { resource.appendChild(createElement("targetPath", targetPath)); } if (filtering) { resource.appendChild(createElement("filtering", "true")); } if (directory != null) { resource.appendChild(createElement("directory", directory)); } if (includes != null && !includes.isEmpty()) { resource.appendChild(newXMLElement(includes, "includes", "include")); } if (excludes != null && !excludes.isEmpty()) { resource.appendChild(newXMLElement(excludes, "excludes", "exclude")); } return resource; } private void setIncludes0(Collection<String> includes) { this.includes = new ArrayList<>(includes); if (isNew()) return; //if includes element exists we should replace it children //with new set of includes, otherwise create element for it if (resourceElement.hasSingleChild("includes")) { final Element includesElement = resourceElement.getSingleChild("includes"); //remove all includes from element for (Element inclusion : includesElement.getChildren()) { inclusion.remove(); } //append each new inclusion to "includes" element for (String inclusion : includes) { includesElement.appendChild(createElement("include", inclusion)); } } else { resourceElement.insertChild(newXMLElement(this.includes, "includes", "include"), before("excludes").or(inTheEnd())); } } private void removeIncludes() { if (!isNew()) { resourceElement.removeChild("includes"); } includes = null; } private void removeExcludes() { if (!isNew()) { resourceElement.removeChild("excludes"); } excludes = null; } private void setExcludes0(Collection<String> excludes) { this.excludes = new ArrayList<>(excludes); if (isNew()) return; //if excludes element exists we should replace it children //with new set of excludes, otherwise create element for it if (resourceElement.hasSingleChild("excludes")) { final Element excludesElement = resourceElement.getSingleChild("excludes"); //remove all exclusions from element for (Element exclusion : excludesElement.getChildren()) { exclusion.remove(); } //append each new exclusion to "excludes" element for (String exclusion : excludes) { excludesElement.appendChild(createElement("exclude", exclusion)); } } else { resourceElement.appendChild(newXMLElement(this.excludes, "excludes", "exclude")); } } private boolean isNew() { return resourceElement == null; } private NewElement newXMLElement(List<String> text, String parentName, String childName) { final NewElement element = createElement(parentName); for (String line : text) { element.appendChild(createElement(childName, line)); } return element; } private static class ElementTextMapper implements ElementMapper<String> { @Override public String map(Element element) { return element.getText(); } } }