Package org.openntf.domino.nsfdata.impldxl

Source Code of org.openntf.domino.nsfdata.impldxl.DXLNote

package org.openntf.domino.nsfdata.impldxl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.openntf.domino.nsfdata.NSFItem;
import org.openntf.domino.nsfdata.NSFMimeData;
import org.openntf.domino.nsfdata.NSFNote;
import org.openntf.domino.nsfdata.NSFRichTextData;
import org.openntf.domino.nsfdata.impldxl.item.DXLItemComposite;
import org.openntf.domino.nsfdata.impldxl.item.DXLItemFactory;
import org.openntf.domino.nsfdata.structs.cd.CDFILEHEADER;
import org.openntf.domino.nsfdata.structs.cd.CDFILESEGMENT;
import org.openntf.domino.nsfdata.structs.cd.CDRecord;
import org.openntf.domino.nsfdata.structs.cd.CData;
import org.openntf.domino.utils.xml.XMLNode;

public class DXLNote implements NSFNote, Serializable {
  private static final long serialVersionUID = 1L;

  private static final boolean DEBUG = false;

  private final NoteClass noteClass_;
  private final int noteId_;
  private final String universalId_;
  private final boolean default_;
  private final int sequence_;

  private final List<NSFItem> items_ = new ArrayList<NSFItem>();
  private transient Map<String, List<NSFItem>> itemsByName_ = new TreeMap<String, List<NSFItem>>(String.CASE_INSENSITIVE_ORDER);

  public static DXLNote create(final XMLNode node) {
    return new DXLNote(node);
  }

  private DXLNote(final XMLNode node) {
    String noteClass = node.getAttribute("class");
    if ("replicationformula".equalsIgnoreCase(noteClass)) {
      noteClass = "replformula";
    }
    noteClass_ = NoteClass.valueOf(noteClass.toUpperCase());
    default_ = "true".equals(node.getAttribute("default"));

    XMLNode noteInfo = node.selectSingleNode("noteinfo");
    noteId_ = Integer.parseInt(noteInfo.getAttribute("noteid"), 16);
    universalId_ = noteInfo.getAttribute("unid");
    sequence_ = Integer.parseInt(noteInfo.getAttribute("sequence"), 10);

    if (DEBUG)
      System.out.println("\tUNID: " + universalId_);

    for (XMLNode itemNode : node.selectNodes("./item")) {
      if (DEBUG)
        System.out.println("\tItem: " + itemNode.getAttribute("name"));

      // Find out whether this is a duplicate item - solo items are all 0, while
      // dups are 1-based. I am aware that this is horrible.
      String name = itemNode.getAttribute("name");
      boolean duplicate = node.selectNodes("./item[@name='" + name + "']").size() > 1;
      int dupItemId = duplicate ? (getItems(name).size() + 1) : 0;

      NSFItem item = DXLItemFactory.create(itemNode, dupItemId);
      if (item != null) {
        items_.add(item);

        if (!itemsByName_.containsKey(name)) {
          itemsByName_.put(name, new ArrayList<NSFItem>());
        }
        itemsByName_.get(name).add(item);

        if (DEBUG) {
          System.out.print("\t\t[" + item.getType());
          System.out.print(", Class: " + item.getClass().getSimpleName());
          System.out.print(", Dup ID: " + item.getDupItemId());
          System.out.print(", Value: " + item.getValue());
          System.out.println("]");

          // Output composite data
          if (item instanceof DXLItemComposite) {
            CData cdata = ((DXLItemComposite) item).getValue();

            int breaker = 0;
            for (CDRecord record : cdata) {
              if (breaker++ > 1000) {
                System.out.println("we went too deep!");
                break;
              }
              System.out.print("\t\t\t[Signature: " + record.getSignature());
              System.out.print(", Length: " + record.getDataLength());
              System.out.print(", Value: " + record);
              System.out.println("]");

            }
          }
        }
      }
    }
  }

  @Override
  public NoteClass getNoteClass() {
    return noteClass_;
  }

  @Override
  public int getNoteId() {
    return noteId_;
  }

  @Override
  public String getUniversalId() {
    return universalId_;
  }

  @Override
  public boolean isDefault() {
    return default_;
  }

  @Override
  public int getSequence() {
    return sequence_;
  }

  @Override
  public Collection<NSFItem> getItems(final String itemName) {
    List<NSFItem> items = itemsByName_.get(itemName);
    if (items != null) {
      return items;
    } else {
      return Collections.emptyList();
    }
  }

  @Override
  public Collection<NSFItem> getItems() {
    return Collections.unmodifiableList(items_);
  }

  @Override
  public NSFMimeData getMimeData(final String itemName) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public NSFRichTextData getRichText(final String itemName) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public boolean hasItem(final String itemName) {
    return !getItems(itemName).isEmpty();
  }

  // TODO Make sure it works with multiple files
  @Override
  public void extractFileResource(final String itemName, final java.io.OutputStream os) {
    Collection<NSFItem> items = getItems(itemName);

    int segmentCount = 0;
    int totalSegments = 0;
    for (NSFItem item : items) {
      if (item instanceof DXLItemComposite) {
        CData cdata = ((DXLItemComposite) item).getValue();

        int breaker = 0;
        for (CDRecord record : cdata) {
          if (breaker++ > 1000) {
            System.out.println("we went too deep!");
            break;
          }

          if (record instanceof CDFILEHEADER) {
            CDFILEHEADER header = (CDFILEHEADER) record;
            totalSegments = header.getSegCount();
            segmentCount = 0;
          }
          if (record instanceof CDFILESEGMENT) {
            CDFILESEGMENT seg = (CDFILESEGMENT) record;
            ByteBuffer data = ByteBuffer.wrap(seg.getFileData());
            data.order(ByteOrder.LITTLE_ENDIAN);
            try {
              os.write(data.array(), data.position(), data.limit() - data.position());
            } catch (IOException e) {
              throw new RuntimeException(e);
            }
            if (++segmentCount >= totalSegments) {
              try {
                os.flush();
                return;
              } catch (IOException e) {
                throw new RuntimeException(e);
              }
            }
          }
        }

      }
    }
  }

  private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();

    itemsByName_ = new TreeMap<String, List<NSFItem>>(String.CASE_INSENSITIVE_ORDER);
    for (NSFItem item : items_) {
      String itemName = item.getName();
      if (!itemsByName_.containsKey(itemName)) {
        itemsByName_.put(itemName, new ArrayList<NSFItem>());
      }
      itemsByName_.get(itemName).add(item);
    }
  }
}
TOP

Related Classes of org.openntf.domino.nsfdata.impldxl.DXLNote

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.