package org.docear.plugin.pdfutilities.features; import java.io.IOException; import org.docear.plugin.core.features.DocearMapModelController; import org.docear.plugin.core.features.DocearMapModelExtension; import org.docear.plugin.core.features.DocearRequiredConversionController; import org.docear.plugin.pdfutilities.features.IAnnotation.AnnotationType; import org.docear.plugin.pdfutilities.map.AnnotationController; import org.freeplane.core.extension.IExtension; import org.freeplane.core.io.IAttributeHandler; import org.freeplane.core.io.IElementDOMHandler; 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.util.LogUtils; import org.freeplane.features.map.MapModel; import org.freeplane.features.map.NodeModel; import org.freeplane.n3.nanoxml.XMLElement; import org.freeplane.plugin.workspace.URIUtils; public class AnnotationXmlBuilder implements IElementDOMHandler, IExtensionElementWriter { private static final String ANNOTATION_PAGE_XML_TAG = "page"; //$NON-NLS-1$ private static final String ANNOTATION_TYPE_XML_TAG = "type"; //$NON-NLS-1$ private static final String ANNOTATION_HIGHLIGHT_TYPE_XML_TAG = "highlight_type"; //$NON-NLS-1$ private static final String ANNOTATION_OBJECT_NUMBER_XML_TAG = "object_number"; //$NON-NLS-1$ private static final String ANNOTATION_OBJECT_ID_XML_TAG = "object_id"; //$NON-NLS-1$ private static final String DOCUMENT_HASH_XML_TAG = "document_hash"; //$NON-NLS-1$ private static final String PDF_ANNOTATION_XML_TAG = "pdf_annotation"; //$NON-NLS-1$ private static final String PDF_TITLE_XML_TAG = "pdf_title"; public AnnotationXmlBuilder(){ } public void registerBy(final ReadManager reader, final WriteManager writer) { reader.addElementHandler(PDF_ANNOTATION_XML_TAG, this); //DOCEAR - just read the title elements to prevent freeplane from handling it as unknown reader.addElementHandler(PDF_TITLE_XML_TAG, new IElementDOMHandler() { public Object createElement(Object parent, String tag, XMLElement attributes) { return null; } public void endElement(Object parent, String tag, Object element, XMLElement dom) { } }); registerAttributeHandlers(reader); writer.addExtensionElementWriter(AnnotationModel.class, this); } private void registerAttributeHandlers(ReadManager reader) { reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, ANNOTATION_TYPE_XML_TAG, new IAttributeHandler() { public void setAttribute(Object node, String value) { final AnnotationModel annotation = (AnnotationModel) node; if(annotation.getAnnotationType() == null || !annotation.getAnnotationType().equals(AnnotationType.TRUE_HIGHLIGHTED_TEXT)){ annotation.setAnnotationType(AnnotationModel.AnnotationType.valueOf(value)); } } }); reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, ANNOTATION_PAGE_XML_TAG, new IAttributeHandler() { public void setAttribute(Object node, String value) { final AnnotationModel annotation = (AnnotationModel) node; try{ annotation.setPage(Integer.parseInt(value)); } catch(NumberFormatException e){ LogUtils.warn("Could not Parse Pdf Annotation Page Number."); //$NON-NLS-1$ } } }); reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, ANNOTATION_OBJECT_NUMBER_XML_TAG, new IAttributeHandler() { public void setAttribute(Object node, String value) { final AnnotationModel annotation = (AnnotationModel) node; try{ annotation.setOldObjectNumber(Integer.parseInt(value)); } catch(NumberFormatException e){ LogUtils.warn("Could not Parse Pdf Annotation Object Number."); //$NON-NLS-1$ } } }); reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, ANNOTATION_HIGHLIGHT_TYPE_XML_TAG, new IAttributeHandler() { public void setAttribute(Object node, String value) { final AnnotationModel annotation = (AnnotationModel) node; annotation.setAnnotationType(AnnotationModel.AnnotationType.valueOf(value)); } }); // reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, ANNOTATION_GENERATION_NUMBER_XML_TAG, new IAttributeHandler() { // // public void setAttribute(Object node, String value) { // final AnnotationModel annotation = (AnnotationModel) node; // try{ // annotation.setGenerationNumber(Integer.parseInt(value)); // } catch(NumberFormatException e){ // LogUtils.warn("Could not Parse Pdf Annotation Generation Number."); //$NON-NLS-1$ // } // } // // }); reader.addAttributeHandler(PDF_ANNOTATION_XML_TAG, DOCUMENT_HASH_XML_TAG, new IAttributeHandler() { public void setAttribute(Object node, String value) { final AnnotationModel annotation = (AnnotationModel) node; try { AnnotationController.registerDocumentHash(annotation.getSource(), value); } catch (Throwable e) { LogUtils.info("Error ("+e.getMessage()+") for: "+annotation.getSource()); } } }); } public Object createElement(Object parent, String tag, XMLElement attributes) { if(attributes == null) { return null; } if (tag.equals(PDF_ANNOTATION_XML_TAG)) { final AnnotationModel oldAnnotationModel = AnnotationController.getModel((NodeModel) parent, false); if(oldAnnotationModel != null){ return oldAnnotationModel; } else{ AnnotationModel model = new AnnotationModel(-1); try{ MapModel map = ((NodeModel)parent).getMap(); DocearMapModelExtension mapExt = DocearMapModelController.getModel(map); if(mapExt != null && mapExt.getVersion().compareTo(DocearMapModelController.CURRENT_MAP_VERSION) < 0) { DocearRequiredConversionController.setRequiredConversion(new ConvertAnnotationsExtension(), map); } String obj_id = attributes.getAttribute(ANNOTATION_OBJECT_ID_XML_TAG, null); model = new AnnotationModel(Long.parseLong(obj_id)); } catch(NumberFormatException e){ //LogUtils.warn("Could not Parse Pdf Annotation Object ID."); } try { model.setSource(URIUtils.getAbsoluteURI((NodeModel) parent)); return model; } catch (Exception e) { LogUtils.warn(e); } } } return null; } public void endElement(final Object parent, final String tag, final Object userObject, final XMLElement dom) { if (parent instanceof NodeModel) { final NodeModel node = (NodeModel) parent; if (userObject instanceof AnnotationModel) { final AnnotationModel annotation = (AnnotationModel) userObject; if(AnnotationType.PDF_FILE.equals(annotation.getAnnotationType())) { AnnotationController.setModel(node, AnnotationConverter.cloneAnnotation(0, annotation)); } else { AnnotationController.setModel(node, annotation); } } } } public void writeContent(ITreeWriter writer, Object element, IExtension extension) throws IOException { writeContentImpl(writer, null, extension); } public void writeContentImpl(final ITreeWriter writer, final NodeModel node, final IExtension extension) throws IOException { final AnnotationModel model = extension != null ? (AnnotationModel) extension : AnnotationController.getModel(node, false); if (model == null) { return; } final XMLElement pdfAnnotation = new XMLElement(); pdfAnnotation.setName(PDF_ANNOTATION_XML_TAG); final AnnotationType annotationType = model.getAnnotationType(); if (annotationType != null) { if(annotationType.equals(AnnotationType.TRUE_HIGHLIGHTED_TEXT)){ pdfAnnotation.setAttribute(ANNOTATION_HIGHLIGHT_TYPE_XML_TAG, annotationType.toString()); pdfAnnotation.setAttribute(ANNOTATION_TYPE_XML_TAG, AnnotationType.HIGHLIGHTED_TEXT.toString()); } else{ pdfAnnotation.setAttribute(ANNOTATION_TYPE_XML_TAG, annotationType.toString()); } } final Integer page = model.getPage(); if (page != null) { pdfAnnotation.setAttribute(ANNOTATION_PAGE_XML_TAG, "" + page); //$NON-NLS-1$ } final long objectID = model.getObjectID(); if(objectID >= 0) { pdfAnnotation.setAttribute(ANNOTATION_OBJECT_ID_XML_TAG, "" + objectID); //$NON-NLS-1$ } final int objectNumber = model.getOldObjectNumber(); if(objectNumber >= 0) { pdfAnnotation.setAttribute(ANNOTATION_OBJECT_NUMBER_XML_TAG, "" + objectNumber); //$NON-NLS-1$ } final String documentHash = model.getDocumentHash(); if(documentHash != null && documentHash.length() > 0){ pdfAnnotation.setAttribute(DOCUMENT_HASH_XML_TAG, "" + documentHash); final String documentTitle = AnnotationController.getDocumentTitle(model.getSource()); if(documentTitle != null) { final XMLElement pdftitle = new XMLElement(); pdftitle.setName(PDF_TITLE_XML_TAG); pdftitle.setContent(documentTitle); pdfAnnotation.addChild(pdftitle); } } writer.addElement(model, pdfAnnotation); } }