/* * Freeplane - mind map editor * Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.freeplane.features.export.mindmapmode; import java.awt.image.RenderedImage; import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.Properties; import java.util.StringTokenizer; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.swing.ListModel; import javax.swing.filechooser.FileFilter; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.apache.commons.lang.StringUtils; import org.freeplane.core.resources.ResourceController; import org.freeplane.core.ui.ExampleFileFilter; import org.freeplane.core.ui.components.UITools; import org.freeplane.core.util.Compat; import org.freeplane.core.util.FileUtils; import org.freeplane.core.util.LogUtils; import org.freeplane.core.util.TextUtils; import org.freeplane.features.icon.UIIcon; import org.freeplane.features.map.MapModel; import org.freeplane.features.map.MapWriter.Mode; import org.freeplane.features.mode.Controller; import org.freeplane.features.mode.ModeController; import org.freeplane.features.url.UrlManager; /** * @author foltin To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class ExportWithXSLT extends AExportEngine { /** * @param map */ static void copyIconsToDirectory(final MapModel map, final String directoryName) { final ListModel icons = map.getIconRegistry().getIconsAsListModel(); for (int i = 0; i < icons.getSize(); i++) { final UIIcon icon = (UIIcon) icons.getElementAt(i); final String iconName = icon.getName(); final StringBuilder sb = new StringBuilder(directoryName); final int lastIndexOfSeparator = iconName.lastIndexOf('/'); if (lastIndexOfSeparator != -1) { sb.append(File.separatorChar); sb.append(iconName.substring(0, lastIndexOfSeparator)); } final File destinationDirectory = new File(sb.toString()); destinationDirectory.mkdirs(); FileUtils.copyFromURL(icon.getUrl(), destinationDirectory); } } /** * For test purposes. True=no error */ private boolean mTransformResultWithoutError = false; final private Properties properties; private String name; public ExportWithXSLT(final String name, final Properties properties) { this.name = name; this.properties = properties; } /** */ private void copyFilesFromResourcesToDirectory(final String directoryName, final String files, final String filePrefix) { final StringTokenizer tokenizer = new StringTokenizer(files, ","); final File destinationDirectory = new File(directoryName); while (tokenizer.hasMoreTokens()) { final String next = tokenizer.nextToken(); FileUtils.copyFromResource(filePrefix, next, destinationDirectory); } } /** * @param map */ private boolean copyIcons(final MapModel map, final String directoryName) { boolean success; final String iconDirectoryName = directoryName + File.separatorChar + "icons"; success = FileUtils.createDirectory(iconDirectoryName); if (success) { ExportWithXSLT.copyIconsToDirectory(map, iconDirectoryName); } return success; } private boolean copyMap(final MapModel map, final String pDirectoryName) { boolean success = true; try { final BufferedWriter fileout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream( pDirectoryName + File.separator + "map" + UrlManager.FREEPLANE_FILE_EXTENSION))); final Mode mode = Mode.valueOf(getProperty("copymode", Mode.EXPORT.name())); Controller.getCurrentModeController().getMapController().getFilteredXml(map, fileout, mode, Mode.EXPORT.equals(mode)); } catch (final IOException e) { success = false; } return success; } /** * @param map */ private boolean createImageFromMap(MapModel map, final String directoryName) { if (Controller.getCurrentController().getViewController().getMapView() == null) { return false; } final RenderedImage image = createBufferedImage(map); if(image == null){ return false; } try { final FileOutputStream out = new FileOutputStream(directoryName + File.separator + "image.png"); ImageIO.write(image, "png", out); out.close(); return true; } catch (final IOException e1) { LogUtils.severe(e1); return false; } } /** * @param create_image */ private String getAreaCode(final boolean create_image) { String areaCode = ""; if (create_image) { areaCode = Controller.getCurrentController().getMapViewManager().createHtmlMap(); } return areaCode; } /** * @param mode * @throws IOException */ private String getMapXml(final Mode mode) throws IOException { final StringWriter writer = new StringWriter(); final ModeController modeController = Controller.getCurrentModeController(); final Controller controller = modeController.getController(); final MapModel map = controller.getMap(); modeController.getMapController().getFilteredXml(map, writer, mode, Mode.EXPORT.equals(mode)); return writer.getBuffer().toString(); } String getProperty(final String key) { final String property = getProperty(key, null); if (property == null || !property.startsWith("$")) { return property; } return System.getProperty(property.substring(1), null); } String getProperty(final String key, final String value) { return properties.getProperty(key, value); } public boolean isTransformResultWithoutError() { return mTransformResultWithoutError; } /** * @param saveFile */ public void export(final MapModel map, final File saveFile) { try { mTransformResultWithoutError = true; final boolean create_image = StringUtils.equals(getProperty("create_html_linked_image"), "true"); final String areaCode = getAreaCode(create_image); final String xsltFileName = getProperty("xslt_file"); boolean success = transformMapWithXslt(xsltFileName, saveFile, areaCode); if (!success) { JOptionPane.showMessageDialog(UITools.getFrame(), getProperty("error_applying_template"), "Freeplane", JOptionPane.ERROR_MESSAGE); return; } if (success && StringUtils.equals(getProperty("create_dir"), "true")) { final String directoryName = saveFile.getAbsolutePath() + "_files"; success = FileUtils.createDirectory(directoryName); if (success) { final String files = getProperty("files_to_copy"); final String filePrefix = getProperty("file_prefix"); copyFilesFromResourcesToDirectory(directoryName, files, filePrefix); } if (success && StringUtils.equals(getProperty("copy_icons"), "true")) { success = copyIcons(map, directoryName); } if (success && StringUtils.equals(getProperty("copy_map"), "true")) { success = copyMap(map, directoryName); } if (success && create_image) { success = createImageFromMap(map, directoryName); } } if (!success) { JOptionPane.showMessageDialog(UITools.getFrame(), getProperty("error_creating_directory"), "Freeplane", JOptionPane.ERROR_MESSAGE); return; } if (StringUtils.equals(getProperty("load_file"), "true")) { Controller.getCurrentController().getViewController().openDocument(Compat.fileToUrl(saveFile)); } } catch (final Exception e) { LogUtils.severe(e); mTransformResultWithoutError = false; } } /** * @throws IOException */ private boolean transformMapWithXslt(final String xsltFileName, final File saveFile, final String areaCode) throws IOException { final Mode mode = Mode.valueOf(getProperty("mode", Mode.EXPORT.name())); final String map = getMapXml(mode); final StringReader reader = new StringReader(map); ResourceController resourceController = ResourceController.getResourceController(); final URL xsltUrl = resourceController.getResource(xsltFileName); if (xsltUrl == null) { LogUtils.severe("Can't find " + xsltFileName + " as resource."); throw new IllegalArgumentException("Can't find " + xsltFileName + " as resource."); } final InputStream xsltFile = new BufferedInputStream(xsltUrl.openStream()); final Source xsltSource = new StreamSource(xsltFile); final Result result = new StreamResult(saveFile); try { final TransformerFactory transFact = TransformerFactory.newInstance(); final Transformer trans = transFact.newTransformer(xsltSource); trans.setParameter("destination_dir", saveFile.getName() + "_files/"); trans.setParameter("area_code", areaCode); trans.setParameter("folding_type", resourceController.getProperty( "html_export_folding")); String[] parameters = getProperty("set_properties", "").split(",\\s*"); StringBuilder sb = new StringBuilder(); for(String p : parameters){ String value = resourceController.getProperty(p, null); if(value != null && ! value.equals(resourceController.getDefaultProperty(p))){ sb.append(p); sb.append('='); sb.append(value); sb.append("$$$"); } } trans.setParameter("propertyList", sb.toString()); trans.transform(new StreamSource(reader), result); } catch (final Exception e) { LogUtils.warn(e); return false; } finally { FileUtils.silentlyClose(xsltFile); } return true; } public FileFilter getFileFilter() { return new ExampleFileFilter(getProperty("file_type"), TextUtils.getText(name + ".text")); } }