Package org.freeplane.features.text

Source Code of org.freeplane.features.text.NodeTextBuilder

/*
*  Freeplane - mind map editor
*  Copyright (C) 2008 Dimitry Polivaev
*
*  This file author is 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.text;

import java.io.IOException;

import org.freeplane.core.extension.IExtension;
import org.freeplane.core.io.IAttributeHandler;
import org.freeplane.core.io.IAttributeWriter;
import org.freeplane.core.io.IElementContentHandler;
import org.freeplane.core.io.IElementWriter;
import org.freeplane.core.io.IExtensionAttributeWriter;
import org.freeplane.core.io.IExtensionElementWriter;
import org.freeplane.core.io.ITreeWriter;
import org.freeplane.core.io.ReadManager;
import org.freeplane.core.io.WriteManager;
import org.freeplane.core.resources.NamedObject;
import org.freeplane.core.util.HtmlUtils;
import org.freeplane.core.util.LogUtils;
import org.freeplane.core.util.TypeReference;
import org.freeplane.features.format.IFormattedObject;
import org.freeplane.features.map.MapWriter;
import org.freeplane.features.map.NodeBuilder;
import org.freeplane.features.map.NodeModel;
import org.freeplane.features.map.NodeWriter;
import org.freeplane.features.styles.StyleFactory;
import org.freeplane.features.styles.StyleNamedObject;
import org.freeplane.features.styles.StyleString;
import org.freeplane.n3.nanoxml.XMLElement;

public class NodeTextBuilder implements IElementContentHandler, IElementWriter, IAttributeWriter, IExtensionElementWriter, IExtensionAttributeWriter {
  public static final String XML_NODE_TEXT = "TEXT";
  public static final String XML_NODE_LOCALIZED_TEXT = "LOCALIZED_TEXT";
  public static final String XML_NODE_XHTML_CONTENT_TAG = "richcontent";
  public static final String XML_NODE_XHTML_TYPE_NODE = "NODE";
  public static final String XML_NODE_XHTML_TYPE_NOTE = "NOTE";
  public static final String XML_NODE_XHTML_TYPE_DETAILS = "DETAILS";
  public static final String XML_NODE_XHTML_TYPE_TAG = "TYPE";
  public static final String XML_NODE_OBJECT = "OBJECT";
  private static final String XML_NODE_TEXT_SHORTENED = "TEXT_SHORTENED";

  public Object createElement(final Object parent, final String tag, final XMLElement attributes) {
    if (attributes == null) {
      return null;
    }
    final Object typeAttribute = attributes.getAttribute(NodeTextBuilder.XML_NODE_XHTML_TYPE_TAG, null);
    if (NodeTextBuilder.XML_NODE_XHTML_TYPE_NODE.equals(typeAttribute)
         || NodeTextBuilder.XML_NODE_XHTML_TYPE_DETAILS.equals(typeAttribute)) {
      return parent;
    }
    return null;
  }

  public void endElement(final Object parent, final String tag, final Object obj, final XMLElement attributes,
                         final String content) {
    assert tag.equals("richcontent");
    final String xmlText = content.trim();
    final Object typeAttribute = attributes.getAttribute(NodeTextBuilder.XML_NODE_XHTML_TYPE_TAG, null);
    final NodeModel nodeModel = (NodeModel) obj;
    if (NodeTextBuilder.XML_NODE_XHTML_TYPE_NODE.equals(typeAttribute)) {
      nodeModel.setXmlText(xmlText);
    }
    else if (NodeTextBuilder.XML_NODE_XHTML_TYPE_DETAILS.equals(typeAttribute)) {
      final DetailTextModel note = new DetailTextModel("true".equals(attributes.getAttribute("HIDDEN", "false")));
      note.setXml(xmlText);
      nodeModel.addExtension(note);
    }
  }

  private void registerAttributeHandlers(final ReadManager reader) {
    reader.addAttributeHandler(NodeBuilder.XML_NODE, NodeTextBuilder.XML_NODE_TEXT, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        final Object nodeContent = node.getUserObject();
        if(nodeContent == null || nodeContent.equals("")){
          node.setText(value);
        }
      }
    });
    reader.addAttributeHandler(NodeBuilder.XML_NODE, NodeTextBuilder.XML_NODE_OBJECT, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        final Object newInstance = TypeReference.create(value);
        // work around for old maps :
        // actually we do not need IFormattedObject as user objects
        // because formatting is saved as an extra attribute
        if(newInstance instanceof IFormattedObject)
          node.setUserObject(((IFormattedObject) newInstance).getObject());
        else
          node.setUserObject(newInstance);
      }
    });
    reader.addAttributeHandler(NodeBuilder.XML_NODE, NodeTextBuilder.XML_NODE_TEXT_SHORTENED, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        try {
          if(Boolean.valueOf(value)){
            node.addExtension(new ShortenedTextModel());
          }
        }
        catch (Exception e) {
          LogUtils.warn(e);
        }
      }
    });
    reader.addAttributeHandler(NodeBuilder.XML_STYLENODE, NodeTextBuilder.XML_NODE_TEXT, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        node.setUserObject(StyleFactory.create(value));
      }
    });
    reader.addAttributeHandler(NodeBuilder.XML_NODE, NodeTextBuilder.XML_NODE_LOCALIZED_TEXT, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        node.setUserObject(StyleFactory.create(NamedObject.format(value)));
      }
    });
    reader.addAttributeHandler(NodeBuilder.XML_STYLENODE, NodeTextBuilder.XML_NODE_LOCALIZED_TEXT, new IAttributeHandler() {
      public void setAttribute(final Object userObject, final String value) {
        final NodeModel node = ((NodeModel) userObject);
        node.setUserObject(StyleFactory.create(NamedObject.format(value)));
      }
    });
  }

  /**
   * @param writeManager
   */
  public void registerBy(final ReadManager reader, final WriteManager writeManager) {
    registerAttributeHandlers(reader);
    reader.addElementHandler("richcontent", this);
    writeManager.addElementWriter(NodeBuilder.XML_NODE, this);
    writeManager.addElementWriter(NodeBuilder.XML_STYLENODE, this);
    writeManager.addAttributeWriter(NodeBuilder.XML_NODE, this);
    writeManager.addAttributeWriter(NodeBuilder.XML_STYLENODE, this);
  }

  private static class TransformedXMLExtension implements IExtension{
    final String xml;

    public TransformedXMLExtension(String html) {
          super();
          this.xml = HtmlUtils.toXhtml(html);
        }
  }
  public void writeAttributes(final ITreeWriter writer, final Object userObject, final String tag) {
    if(! NodeWriter.shouldWriteSharedContent(writer))
      return;
    final NodeModel node = (NodeModel) userObject;
    final Object data = node.getUserObject();
    if(data == null)
      return;
    final Class<? extends Object> dataClass = data.getClass();
    if (dataClass.equals(StyleNamedObject.class)) {
      writer.addAttribute(NodeTextBuilder.XML_NODE_LOCALIZED_TEXT, ((StyleNamedObject) data).getObject().toString());
      return;
    }
    if (dataClass.equals(NamedObject.class)) {
      writer.addAttribute(NodeTextBuilder.XML_NODE_LOCALIZED_TEXT, ((NamedObject) data).getObject().toString());
      return;
    }
    final boolean forceFormatting = Boolean.TRUE.equals(writer.getHint(MapWriter.WriterHint.FORCE_FORMATTING));
    if (forceFormatting) {
      final String text = TextController.getController().getTransformedTextNoThrow(data, node, data);
      if (!HtmlUtils.isHtmlNode(text)) {
        writer.addAttribute(NodeTextBuilder.XML_NODE_TEXT, text.replace('\0', ' '));
      }
      else{
        node.addExtension(new TransformedXMLExtension(text));
      }
    }
    else{
      final String text =  data.toString();
      if (node.getXmlText() == null) {
        writer.addAttribute(NodeTextBuilder.XML_NODE_TEXT, text.replace('\0', ' '));
      }
      if(! (data instanceof String || data instanceof StyleString)){
        writer.addAttribute(XML_NODE_OBJECT, TypeReference.toSpec(data));
      }
    }
  }

  public void writeContent(final ITreeWriter writer, final Object element, final String tag) throws IOException {
    if(! NodeWriter.shouldWriteSharedContent(writer))
      return;
    final NodeModel node = (NodeModel) element;
    final TransformedXMLExtension transformedXML = node.getExtension(TransformedXMLExtension.class);
    if (transformedXML != null || node.getXmlText() != null) {
      final XMLElement htmlElement = new XMLElement();
      htmlElement.setName(NodeTextBuilder.XML_NODE_XHTML_CONTENT_TAG);
      htmlElement.setAttribute(NodeTextBuilder.XML_NODE_XHTML_TYPE_TAG, NodeTextBuilder.XML_NODE_XHTML_TYPE_NODE);
      final String xmlText;
      if (transformedXML != null){
        xmlText = transformedXML.xml;
        node.removeExtension(transformedXML);
      }
      else
        xmlText = node.getXmlText();
      final String content = xmlText.replace('\0', ' ');
      writer.addElement('\n' + content + '\n', htmlElement);
    }
  }
  /*
   * (non-Javadoc)
   * @see freeplane.io.INodeWriter#saveContent(freeplane.io.ITreeWriter,
   * java.lang.Object, java.lang.String)
   */
  public void writeContent(final ITreeWriter writer, final Object element, final IExtension note) throws IOException {
    DetailTextModel model = (DetailTextModel) note;
    if (model.getXml() != null) {
      final XMLElement htmlElement = new XMLElement();
      htmlElement.setName(NodeTextBuilder.XML_NODE_XHTML_CONTENT_TAG);
      htmlElement.setAttribute(NodeTextBuilder.XML_NODE_XHTML_TYPE_TAG, NodeTextBuilder.XML_NODE_XHTML_TYPE_DETAILS);
      if(model.isHidden()){
        htmlElement.setAttribute("HIDDEN", "true");
      }
      final String content = model.getXml().replace('\0', ' ');
      writer.addElement('\n' + content + '\n', htmlElement);
    }
    return;
  }

  public void writeAttributes(ITreeWriter writer, Object userObject, IExtension extension) {
    writer.addAttribute(XML_NODE_TEXT_SHORTENED, Boolean.TRUE.toString());
    }
}
TOP

Related Classes of org.freeplane.features.text.NodeTextBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.