package org.openntf.domino.nsfdata.impldxl; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.xml.parsers.ParserConfigurationException; import org.openntf.domino.nsfdata.NSFDatabase; import org.openntf.domino.nsfdata.NSFNote; import org.openntf.domino.utils.xml.XMLDocument; import org.xml.sax.SAXException; public class DXLDatabase implements Serializable, NSFDatabase { private static final long serialVersionUID = 1L; private static final boolean DEBUG = false; private Set<NSFNote> notes_ = new LinkedHashSet<NSFNote>(); private transient Map<Integer, NSFNote> notesByNoteId_ = new TreeMap<Integer, NSFNote>(); private transient Map<String, NSFNote> notesByUniversalId_ = new TreeMap<String, NSFNote>(); public DXLDatabase(final InputStream is) throws IOException, SAXException, ParserConfigurationException { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); boolean inNote = false; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (reader.ready()) { String aLine = reader.readLine(); // Assume that we don't have multiple notes per line, but one may end and another may start int startIndex = aLine.indexOf("<note "); int endIndex = aLine.indexOf("</note>"); // We may be in a note if (inNote) { String remainder = aLine.substring(startIndex > -1 ? startIndex : 0, endIndex > -1 ? (endIndex + 7) : aLine.length()); bos.write(remainder.getBytes()); } // See if we ended if (endIndex > -1) { ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); XMLDocument xml = new XMLDocument(); xml.loadInputStream(bis); if (DEBUG) System.out.println("want to add note of class " + xml.getDocumentElement().getAttribute("class")); DXLNote note = DXLNote.create(xml.getDocumentElement()); notes_.add(note); notesByNoteId_.put(note.getNoteId(), note); notesByUniversalId_.put(note.getUniversalId(), note); inNote = false; } if (startIndex > -1) { String outputLine = aLine.substring(startIndex, endIndex > -1 ? (endIndex + 7) : aLine.length()); bos.reset(); bos.write(outputLine.getBytes()); inNote = true; } } } /* (non-Javadoc) * @see org.openntf.domino.nsfdata.impldxl.NSFDatabase#getNotes() */ @Override public Set<NSFNote> getNotes() { return Collections.unmodifiableSet(notes_); } /* (non-Javadoc) * @see org.openntf.domino.nsfdata.impldxl.NSFDatabase#getNoteById(int) */ @Override public NSFNote getNoteById(final int noteId) { return notesByNoteId_.get(noteId); } /* (non-Javadoc) * @see org.openntf.domino.nsfdata.impldxl.NSFDatabase#getNoteByUniversalId(java.lang.String) */ @Override public NSFNote getNoteByUniversalId(final String universalId) { return notesByUniversalId_.get(universalId); } /* * Reconstruct the ID views for fast access */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); notesByNoteId_ = new TreeMap<Integer, NSFNote>(); notesByUniversalId_ = new TreeMap<String, NSFNote>(); for (NSFNote note : notes_) { notesByNoteId_.put(note.getNoteId(), note); notesByUniversalId_.put(note.getUniversalId(), note); } } }