package org.docear.plugin.core.workspace.compatible; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; import org.apache.commons.io.IOExceptionWithCause; import org.docear.plugin.core.workspace.controller.DocearConversionDescriptor; import org.docear.plugin.core.workspace.creator.FolderTypeLibraryCreator; import org.docear.plugin.core.workspace.creator.FolderTypeLiteratureRepositoryCreator; import org.docear.plugin.core.workspace.creator.LinkTypeIncomingCreator; import org.docear.plugin.core.workspace.creator.LinkTypeLiteratureAnnotationsCreator; import org.docear.plugin.core.workspace.creator.LinkTypeMyPublicationsCreator; import org.docear.plugin.core.workspace.creator.LinkTypeReferencesCreator; import org.docear.plugin.core.workspace.model.DocearWorkspaceProject; import org.docear.plugin.core.workspace.node.FolderTypeLibraryNode; import org.docear.plugin.core.workspace.node.FolderTypeLiteratureRepositoryNode; import org.docear.plugin.core.workspace.node.LinkTypeIncomingNode; import org.docear.plugin.core.workspace.node.LinkTypeLiteratureAnnotationsNode; import org.docear.plugin.core.workspace.node.LinkTypeMyPublicationsNode; import org.docear.plugin.core.workspace.node.LinkTypeReferencesNode; import org.docear.plugin.core.workspace.node.LiteratureRepositoryPathNode; import org.freeplane.core.io.ReadManager; import org.freeplane.core.io.xml.TreeXmlReader; import org.freeplane.core.util.LogUtils; import org.freeplane.n3.nanoxml.XMLElement; import org.freeplane.n3.nanoxml.XMLException; import org.freeplane.plugin.workspace.URIUtils; import org.freeplane.plugin.workspace.creator.ActionCreator; import org.freeplane.plugin.workspace.creator.FolderCreator; import org.freeplane.plugin.workspace.creator.FolderTypePhysicalCreator; import org.freeplane.plugin.workspace.creator.FolderTypeVirtualCreator; import org.freeplane.plugin.workspace.creator.LinkCreator; import org.freeplane.plugin.workspace.creator.LinkTypeFileCreator; import org.freeplane.plugin.workspace.model.AWorkspaceNodeCreator; import org.freeplane.plugin.workspace.model.AWorkspaceTreeNode; import org.freeplane.plugin.workspace.model.IResultProcessor; import org.freeplane.plugin.workspace.model.project.AWorkspaceProject; import org.freeplane.plugin.workspace.model.project.IWorkspaceProjectExtension; import org.freeplane.plugin.workspace.nodes.FolderLinkNode; import org.freeplane.plugin.workspace.nodes.LinkTypeFileNode; import org.freeplane.plugin.workspace.nodes.ProjectRootNode; public class DocearWorkspaceToProjectConverter { private static Object lock = new Object(); private final ReadManager readManager; public final static int WSNODE_FOLDER = 1; public final static int WSNODE_LINK = 2; public final static int WSNODE_ACTION = 4; private FolderCreator folderCreator = null; private LinkCreator linkCreator = null; private ActionCreator actionCreator = null; private AWorkspaceNodeCreator projectRootCreator = null; private FolderTypeLibraryCreator folderTypeLibraryCreator; private AWorkspaceNodeCreator folderTypeLiteratureRepositoryCreator; private LinkTypeIncomingCreator linkTypeIncomingCreator; private LinkTypeLiteratureAnnotationsCreator linkTypeLiteratureAnnotationsCreator; private LinkTypeMyPublicationsCreator linkTypeMyPublicationsCreator; private LinkTypeReferencesCreator linkTypeReferencesCreator; private IResultProcessor resultProcessor; public DocearWorkspaceToProjectConverter() { this.readManager = new ReadManager(); initReadManager(); } /*********************************************************************************** * CONSTRUCTORS **********************************************************************************/ /*********************************************************************************** * METHODS **********************************************************************************/ private void initReadManager() { readManager.addElementHandler("workspace", getProjectRootCreator()); readManager.addElementHandler("folder", getFolderCreator()); readManager.addElementHandler("link", getLinkCreator()); //readManager.addElementHandler("action", getActionCreator()); registerTypeCreator(WSNODE_FOLDER, "virtual", new FolderTypeVirtualCreator()); registerTypeCreator(WSNODE_FOLDER, "physical", new FolderTypePhysicalCreator()); registerTypeCreator(WSNODE_LINK, "file", new LinkTypeFileCreator()); registerTypeCreator(WSNODE_FOLDER, FolderTypeLibraryCreator.FOLDER_TYPE_LIBRARY, getFolderTypeLibraryCreator()); registerTypeCreator(WSNODE_FOLDER, FolderTypeLiteratureRepositoryCreator.FOLDER_TYPE_LITERATUREREPOSITORY, getFolderTypeLiteratureRepositoryCreator()); registerTypeCreator(WSNODE_LINK, LinkTypeIncomingCreator.LINK_TYPE_INCOMING, getLinkTypeIncomingCreator()); registerTypeCreator(WSNODE_LINK, LinkTypeLiteratureAnnotationsCreator.LINK_TYPE_LITERATUREANNOTATIONS, getLinkTypeLiteratureAnnotationsCreator()); registerTypeCreator(WSNODE_LINK, LinkTypeMyPublicationsCreator.LINK_TYPE_MYPUBLICATIONS, getLinkTypeMyPublicationsCreator()); registerTypeCreator(WSNODE_LINK, LinkTypeReferencesCreator.LINK_TYPE_REFERENCES, getLinkTypeReferencesCreator()); } private AWorkspaceNodeCreator getProjectRootCreator() { if (this.projectRootCreator == null) { this.projectRootCreator = new AWorkspaceNodeCreator() { public AWorkspaceTreeNode getNode(XMLElement data) { ProjectRootNode node = new ProjectRootNode(); String name = data.getAttribute("name", "project"); String id = data.getAttribute("id", null); String version = DocearWorkspaceProject.CURRENT_PROJECT_VERSION.getVersionString(); node.setName(name.replace("(Workspace)", "").trim()); node.setProjectID(id); node.setVersion(version); return node; } }; this.projectRootCreator.setResultProcessor(getDefaultResultProcessor()); } return this.projectRootCreator; } private FolderCreator getFolderCreator() { if (this.folderCreator == null) { this.folderCreator = new FolderCreator(); this.folderCreator.setResultProcessor(getDefaultResultProcessor()); } return this.folderCreator; } private ActionCreator getActionCreator() { if (this.actionCreator == null) { this.actionCreator = new ActionCreator(); this.actionCreator.setResultProcessor(getDefaultResultProcessor()); } return this.actionCreator; } private LinkCreator getLinkCreator() { if (this.linkCreator == null) { this.linkCreator = new LinkCreator(); this.linkCreator.setResultProcessor(getDefaultResultProcessor()); } return this.linkCreator; } private FolderTypeLibraryCreator getFolderTypeLibraryCreator() { if (folderTypeLibraryCreator == null) { folderTypeLibraryCreator = new FolderTypeLibraryCreator(); } return folderTypeLibraryCreator; } private AWorkspaceNodeCreator getFolderTypeLiteratureRepositoryCreator() { if (folderTypeLiteratureRepositoryCreator == null) { folderTypeLiteratureRepositoryCreator = new AWorkspaceNodeCreator() { @Override public AWorkspaceTreeNode getNode(XMLElement data) { String type = data.getAttribute("type", FolderTypeLiteratureRepositoryNode.TYPE); FolderTypeLiteratureRepositoryNode node = new FolderTypeLiteratureRepositoryNode(type); String path = data.getAttribute("path", null); boolean descending = Boolean.parseBoolean(data.getAttribute("orderDescending", "false")); node.orderDescending(descending); if (path != null && path.length() != 0) { LiteratureRepositoryPathNode pathNode = new LiteratureRepositoryPathNode(); pathNode.setPath(URIUtils.createURI(path)); node.addChildNode(pathNode); } return node; } public void endElement(final Object parent, final String tag, final Object node, final XMLElement lastBuiltElement) { super.endElement(parent, tag, node, lastBuiltElement); try { ((AWorkspaceTreeNode) node).refresh(); } catch(Exception e) { LogUtils.warn("Exception in org.docear.plugin.core.workspace.compatible.DocearWorkspaceToProjectConverter.getFolderTypeLiteratureRepositoryCreator().new AWorkspaceNodeCreator() {...}.endElement(parent, tag, node, lastBuiltElement): "+e.getMessage()); } } }; } return folderTypeLiteratureRepositoryCreator; } private LinkTypeIncomingCreator getLinkTypeIncomingCreator() { if (linkTypeIncomingCreator == null) { linkTypeIncomingCreator = new LinkTypeIncomingCreator(); } return linkTypeIncomingCreator; } private LinkTypeLiteratureAnnotationsCreator getLinkTypeLiteratureAnnotationsCreator() { if (linkTypeLiteratureAnnotationsCreator == null) { linkTypeLiteratureAnnotationsCreator = new LinkTypeLiteratureAnnotationsCreator(); } return linkTypeLiteratureAnnotationsCreator; } private LinkTypeMyPublicationsCreator getLinkTypeMyPublicationsCreator() { if (linkTypeMyPublicationsCreator == null) { linkTypeMyPublicationsCreator = new LinkTypeMyPublicationsCreator(); } return linkTypeMyPublicationsCreator; } private LinkTypeReferencesCreator getLinkTypeReferencesCreator() { if (linkTypeReferencesCreator == null) { linkTypeReferencesCreator = new LinkTypeReferencesCreator(); } return linkTypeReferencesCreator; } private void registerTypeCreator(final int nodeType, final String typeName, final AWorkspaceNodeCreator creator) { if (typeName == null || typeName.trim().length() <= 0) return; switch (nodeType) { case WSNODE_FOLDER: { getFolderCreator().addTypeCreator(typeName, creator); break; } case WSNODE_LINK: { getLinkCreator().addTypeCreator(typeName, creator); break; } case WSNODE_ACTION: { getActionCreator().addTypeCreator(typeName, creator); break; } default: { throw new IllegalArgumentException("not allowed argument for nodeType. Use only WorkspaceConfiguration.WSNODE_ACTION, WorkspaceConfiguration.WSNODE_FOLDER or WorkspaceConfiguration.WSNODE_LINK."); } } if(creator.getResultProcessor() == null) { creator.setResultProcessor(getDefaultResultProcessor()); } } private void load(final URI xmlFile) throws MalformedURLException, XMLException, IOException { final TreeXmlReader reader = new TreeXmlReader(readManager); InputStream stream = xmlFile.toURL().openStream(); try { reader.load(new InputStreamReader(new BufferedInputStream(stream))); } finally { try { stream.close(); } catch (IOException e) { } } } private IResultProcessor getDefaultResultProcessor() { if(this.resultProcessor == null) { this.resultProcessor = new ConverterResultProcessor(); } return this.resultProcessor; } public static void convert(DocearConversionDescriptor descriptor) throws IOException { synchronized (lock ) { try { DocearWorkspaceToProjectConverter converter = new DocearWorkspaceToProjectConverter(); DocearWorkspaceProject project = descriptor.getTargetProject(); File profileHome = descriptor.getSelectedProfileHome(); File workspaceSettings = new File(profileHome,"workspace.xml"); if(workspaceSettings.exists()) { DocearConversionURLHandler.setTargetProject(project); converter.getDefaultResultProcessor().setProject(project); converter.load(workspaceSettings.toURI()); } //delete old workspace settings, if selected if(descriptor.deleteOldSettings()) { if(!workspaceSettings.delete()) { LogUtils.info("could not delete: "+workspaceSettings); } } } catch (Exception e) { throw new IOExceptionWithCause(e); } } } private void convertNodeLink(AWorkspaceTreeNode node, AWorkspaceProject project) { if(node instanceof LinkTypeIncomingNode) { ((LinkTypeIncomingNode) node).setLinkPath(getReplacementURI(((LinkTypeIncomingNode) node).getLinkURI(), project)); } else if(node instanceof LinkTypeReferencesNode) { ((LinkTypeReferencesNode) node).setLinkURI(getReplacementURI(((LinkTypeReferencesNode) node).getLinkURI(), project)); } else if(node instanceof LinkTypeMyPublicationsNode) { ((LinkTypeMyPublicationsNode) node).setLinkPath(getReplacementURI(((LinkTypeMyPublicationsNode) node).getLinkURI(), project)); } else if(node instanceof LinkTypeLiteratureAnnotationsNode) { ((LinkTypeLiteratureAnnotationsNode) node).setLinkPath(getReplacementURI(((LinkTypeLiteratureAnnotationsNode) node).getLinkURI(), project)); } else if(node instanceof FolderTypeLiteratureRepositoryNode && node.getChildCount() > 0) { ((LiteratureRepositoryPathNode) node.getChildAt(0)).setPath(getReplacementURI(((LiteratureRepositoryPathNode) node.getChildAt(0)).getPath(), project)); } else if(node instanceof LinkTypeFileNode) { ((LinkTypeFileNode) node).setLinkURI(getReplacementURI(((LinkTypeFileNode) node).getLinkURI(), project)); } else if(node instanceof FolderLinkNode) { ((FolderLinkNode) node).setPath(getReplacementURI(((FolderLinkNode) node).getPath(), project)); } } private URI getReplacementURI(URI uri, AWorkspaceProject project) { URI replacement = project.getRelativeURI(URIUtils.getAbsoluteURI(uri)); if(replacement == null) { replacement = uri; LogUtils.info("could not convert URI: "+uri); } return replacement; } private class ConverterResultProcessor implements IResultProcessor { private AWorkspaceProject project; public AWorkspaceProject getProject() { return project; } public void setProject(AWorkspaceProject project) { this.project = project; } public void process(AWorkspaceTreeNode parent, AWorkspaceTreeNode node) { if(getProject() == null) { LogUtils.warn("Missing project container! cannot add node to a model."); return; } if(node instanceof ProjectRootNode) { getProject().getModel().setRoot(node); if(((ProjectRootNode) node).getProjectID() == null) { ((ProjectRootNode) node).setProjectID(getProject().getProjectID()); } } else { convertNodeLink(node, getProject()); if(parent == null) { if (!getProject().getModel().containsNode(node.getKey())) { getProject().getModel().addNodeTo(node, parent); } } else { if (!parent.getModel().containsNode(node.getKey())) { parent.getModel().addNodeTo(node, parent); } } //add myFiles after a certain node type if(node instanceof LinkTypeReferencesNode) { ((ProjectRootNode) parent.getModel().getRoot()).initiateMyFile(getProject()); } else if(node instanceof FolderTypeLiteratureRepositoryNode) { project.addExtension(FolderTypeLiteratureRepositoryNode.class, (IWorkspaceProjectExtension) node); node.getChildAt(0).refresh(); } else if(node instanceof FolderTypeLibraryNode) { //WorkspaceController.getCurrentModeExtension().getView().expandPath(node.getTreePath()); } } } } /*********************************************************************************** * REQUIRED METHODS FOR INTERFACES **********************************************************************************/ }