/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.util.ant; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.dom4j.Document; import org.dom4j.Node; import org.xml.sax.InputSource; /** * Ant task for synchronizing local directory into a manifest xml file.<p> * * @since 8.0.0 */ public class CmsAntTaskEnsureDirManifest extends Task { /** base directory. */ private String m_base; // required /** source directory. */ private String m_directory; // required /** absolute path to the xml file. */ private String m_xmlFile; // required /** * Default constructor.<p> */ public CmsAntTaskEnsureDirManifest() { super(); } /** * Test case.<p> * * @param args not used */ public static void main(String[] args) { CmsAntTaskEnsureDirManifest task = new CmsAntTaskEnsureDirManifest(); task.setBase("C:\\dev\\workspace\\OpenCms\\modules\\org.opencms.ade\\resources"); task.setDirectory("C:\\dev\\workspace\\OpenCms\\modules\\org.opencms.ade\\resources\\system\\modules\\org.opencms.ade\\sitemap"); task.setXmlFile("C:\\dev\\workspace\\OpenCms\\modules\\org.opencms.ade\\resources\\manifest.xml"); task.execute(); } /** * Run the task.<p> * * Sets the given property to <code>__ABORT__</code> if canceled, or to a list of selected * modules if not.<p> * * @throws BuildException if something goes wrong * * @see org.apache.tools.ant.Task#execute() */ @SuppressWarnings("unchecked") @Override public void execute() throws BuildException { try { // read xml Document doc; BufferedInputStream in = new BufferedInputStream(new FileInputStream(getXmlFile())); try { doc = CmsXmlUtils.unmarshalHelper(new InputSource(in), null); } finally { in.close(); } // get directory content String directory = getDirectory(); String[] files = new File(directory).list(); for (int i = 0; i < files.length; i++) { File file = new File(directory, files[i]); if (!file.isDirectory()) { continue; } // prepare new file array String[] children = file.list(); String[] newFiles = new String[files.length + children.length]; System.arraycopy(files, 0, newFiles, 0, i + 1); for (int j = 0; j < children.length; j++) { newFiles[j + i + 1] = files[i] + '/' + children[j]; } if (i + 1 < files.length) { System.arraycopy(files, i + 1, newFiles, i + 1 + children.length, files.length - (i + 1)); } files = newFiles; } // delete superfluous entries String prefix = new File(directory).getAbsolutePath().substring( new File(getBase()).getAbsolutePath().length() + 1).replace('\\', '/'); List<Node> xmlFiles = doc.selectNodes("export/files/file/destination[starts-with(.,'" + prefix + "/')]"); for (Node xmlFile : xmlFiles) { String path = xmlFile.getText(); File file = new File(getBase() + "/" + path); if (!file.exists()) { CmsSetupXmlHelper.setValue(doc, getFileXpath(path), null); } } // create missing entries for (int i = 0; i < files.length; i++) { String destination = prefix + '/' + files[i]; if (destination.endsWith("/CVS") || destination.contains("/CVS/")) { // ignore cvs data continue; } String xpath = getFileXpath(destination); if (CmsSetupXmlHelper.getValue(doc, xpath) != null) { // entry already present continue; } // create entry String prevDest = prefix + (i == 0 ? "" : '/' + files[i - 1]); createEntry(doc, prevDest, destination); } // write xml BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(getXmlFile())); try { CmsXmlUtils.marshal(doc, out, "UTF-8"); } finally { out.close(); } } catch (Exception e) { throw new BuildException(e.getLocalizedMessage(), e); } } /** * Returns the required base path.<p> * * @return the required base path */ public String getBase() { return m_base; } /** * Returns the required directory path.<p> * * @return the required directory path */ public String getDirectory() { return m_directory; } /** * Returns the xmlFile absolute path.<p> * * @return the xmlFile absolute path */ public String getXmlFile() { return m_xmlFile; } /** * Sets the required base path.<p> * * @param base the required base path to set */ public void setBase(String base) { m_base = base; } /** * Sets the required directory path.<p> * * @param directory the required directory path to set */ public void setDirectory(String directory) { m_directory = directory; } /** * Sets the xmlFile absolute path.<p> * * @param xmlFile the xmlFile absolute path to set */ public void setXmlFile(String xmlFile) { m_xmlFile = xmlFile; } /** * Creates a new XML entry for the given destination path.<p> * * The node will be created just after the given previous destination path.<p> * * @param doc the xml document to modify * @param destination the destination path */ private void createEntry(Document doc, String prevDest, String destination) { String xpath = getFileXpath(destination); String type = getType(destination); if (!type.equals("folder")) { xpath = "export/files/file[source[text()='" + destination + "']]"; } CmsSetupXmlHelper.setValue(doc, getFileXpath(prevDest), null, xpath.substring("export/files/".length())); if (!type.equals("folder")) { CmsSetupXmlHelper.setValue(doc, xpath + "/destination", destination); } CmsSetupXmlHelper.setValue(doc, xpath + "/type", type); CmsSetupXmlHelper.setValue(doc, xpath + "/uuidstructure", new CmsUUID().toString()); CmsSetupXmlHelper.setValue(doc, xpath + "/uuidresource", new CmsUUID().toString()); CmsSetupXmlHelper.setValue( doc, xpath + "/datelastmodified", CmsDateUtil.getHeaderDate(System.currentTimeMillis())); CmsSetupXmlHelper.setValue(doc, xpath + "/userlastmodified", "Admin"); CmsSetupXmlHelper.setValue(doc, xpath + "/datecreated", CmsDateUtil.getHeaderDate(System.currentTimeMillis())); CmsSetupXmlHelper.setValue(doc, xpath + "/usercreated", "Admin"); CmsSetupXmlHelper.setValue(doc, xpath + "/flags", "0"); CmsSetupXmlHelper.setValue(doc, xpath + "/properties", ""); CmsSetupXmlHelper.setValue(doc, xpath + "/relations", ""); CmsSetupXmlHelper.setValue(doc, xpath + "/accesscontrol", ""); } /** * Retrieves the xpath for the given destination path.<p> * * @param destination the destination path * * @return the xpath for the given destination path */ private String getFileXpath(String destination) { return "export/files/file[destination[text()='" + destination + "']]"; } /** * Retrieves the type for the given destination path.<p> * * @param destination the destination path * * @return the type for the given destination path */ private String getType(String destination) { if (destination.endsWith(".jpg") || destination.endsWith(".gif") || destination.endsWith(".png")) { return "image"; } if (destination.endsWith(".jar") || destination.endsWith(".class")) { return "binary"; } if (destination.endsWith(".jsp")) { return "jsp"; } if (destination.endsWith(".properties") || destination.endsWith(".xsd") || destination.endsWith(".txt") || destination.endsWith(".java") || destination.endsWith(".html") || destination.endsWith(".js") || destination.endsWith(".xml") || destination.endsWith(".rpc") || destination.endsWith(".css")) { return "plain"; } return "folder"; } }