package org.docear.plugin.core.workspace.model; import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Vector; import org.docear.plugin.core.IBibtexDatabase; import org.docear.plugin.core.ILibraryRepository; import org.docear.plugin.core.event.DocearEventType; import org.docear.plugin.core.workspace.AVirtualDirectory; import org.docear.plugin.core.workspace.node.FolderTypeLibraryNode; import org.docear.plugin.core.workspace.node.FolderTypeLiteratureRepositoryNode; import org.docear.plugin.core.workspace.node.LiteratureRepositoryPathNode; import org.freeplane.core.util.Compat; import org.freeplane.core.util.UniqueIDCreator; import org.freeplane.features.link.LinkController; import org.freeplane.plugin.workspace.URIUtils; import org.freeplane.plugin.workspace.WorkspaceController; import org.freeplane.plugin.workspace.model.WorkspaceModelEvent; import org.freeplane.plugin.workspace.model.project.AWorkspaceProject; import org.freeplane.plugin.workspace.model.project.IProjectModelListener; import org.freeplane.plugin.workspace.model.project.ProjectVersion; import org.freeplane.plugin.workspace.nodes.ProjectRootNode; public class DocearWorkspaceProject extends AWorkspaceProject { public static final String REPOSITORY_PATH_ADDED = "__added_repository_path__"; public static final ProjectVersion CURRENT_PROJECT_VERSION = new ProjectVersion("docear 1.0"); //WORKSPACE - should docear-project ids have a prefix like "dcr_"? private String id; private URI home; private FolderTypeLiteratureRepositoryNode literatureRepository = null; private ILibraryRepository library = null; //WORKSPACE - Docear: add bibTexDatabase to observers private final Vector<IBibtexDatabase> referencesIndex = new Vector<IBibtexDatabase>(); private List<IDocearProjectListener> listeners = new ArrayList<IDocearProjectListener>(); public DocearWorkspaceProject(final URI projectHome) { this(null, projectHome); } public DocearWorkspaceProject(final String projectID, final URI projectHome) { this.id = projectID; this.home = projectHome; this.getModel().addProjectModelListener(new IProjectModelListener() { public void treeStructureChanged(WorkspaceModelEvent event) { } public void treeNodesRemoved(WorkspaceModelEvent event) { } @Override public void treeNodesInserted(WorkspaceModelEvent event) { if(DocearWorkspaceProject.this.equals(event.getProject())) { if(event.getChildren()[0] instanceof FolderTypeLiteratureRepositoryNode) { literatureRepository = (FolderTypeLiteratureRepositoryNode) event.getChildren()[0]; } else if(event.getChildren()[0] instanceof FolderTypeLibraryNode) { library = (ILibraryRepository) event.getChildren()[0]; } else if(event.getChildren()[0] instanceof IBibtexDatabase) { addReferenceToIndex((IBibtexDatabase) event.getChildren()[0]); } } } @Override public void treeNodesChanged(WorkspaceModelEvent event) { } }); } public URI getProjectLibraryPath() { File home = URIUtils.getAbsoluteFile(getProjectDataPath()); home = new File(home, "default_files"); return home.toURI(); } public Collection<URI> getLibraryMaps() { if(library == null) { return Collections.emptyList(); } return library.getMaps(); } protected void addReferenceToIndex(IBibtexDatabase ref) { synchronized (referencesIndex) { referencesIndex.clear(); if(ref == null) { return; } referencesIndex.add(ref); } DocearProjectChangedEvent event = new DocearProjectChangedEvent(this, ref, DocearEventType.LIBRARY_CHANGED); //new DocearEvent(this, (DocearWorkspaceProject) WorkspaceController.getCurrentModel().getProject(getModel()), DocearEventType.LIBRARY_CHANGED, ref); fireProjectChanged(event); } public URI getBibtexDatabase() { synchronized (referencesIndex) { if(referencesIndex.size() > 0) { return referencesIndex.get(0).getUri(); } } return null; } public void changeBibtexURI(URI path) { if(path == null) { return; } IBibtexDatabase ref = null; synchronized (referencesIndex) { if(referencesIndex.size() > 0) { URI oldUri = referencesIndex.get(0).getUri(); if(!path.equals(oldUri)) { ref = referencesIndex.get(0); ref.setUri(path); } } } if(ref != null) { DocearProjectChangedEvent event = new DocearProjectChangedEvent(this, ref, DocearEventType.LIBRARY_CHANGED); //new DocearEvent(this, (DocearWorkspaceProject) WorkspaceController.getCurrentModel().getProject(getModel()), DocearEventType.LIBRARY_CHANGED, ref); fireProjectChanged(event); } } public URI getRelativeLibraryPath() { return getRelativeURI(getProjectLibraryPath()); } public AVirtualDirectory getProjectLiteratureRepository() { if(this.literatureRepository == null) { return null; } return (AVirtualDirectory) this.literatureRepository.getFile(); } public void addToProjectLiteratureRepository(URI uri) { if(uri == null || this.literatureRepository == null) { return; } LiteratureRepositoryPathNode pathNode = new LiteratureRepositoryPathNode(); pathNode.setPath(uri); this.literatureRepository.getModel().addNodeTo(pathNode, this.literatureRepository); DocearProjectChangedEvent event = new DocearProjectChangedEvent(this, this.literatureRepository, REPOSITORY_PATH_ADDED); fireProjectChanged(event); } public void addProjectListener(IDocearProjectListener listener) { if(listener == null) { return; } synchronized (listeners) { if(listeners.contains(listener)) { return; } listeners.add(listener); } } public void removeProjectListener(IDocearProjectListener listener) { if(listener == null) { return; } synchronized (listeners) { listeners.remove(listener); } } private void fireProjectChanged(DocearProjectChangedEvent event) { if(event == null) { return; } synchronized (listeners) { for (IDocearProjectListener listener : listeners) { listener.changed(event); } } } @Override public URI getProjectHome() { return home; } @Override public String getProjectName() { if(getModel().getRoot() == null) { return this.getProjectID(); } return getModel().getRoot().getName().trim(); } @Override public String getProjectID() { if(this.id == null) { this.id = UniqueIDCreator.getCreator().uniqueID(); } return this.id; } @Override public URI getProjectDataPath() { File home = URIUtils.getAbsoluteFile(getProjectHome()); home = new File(home, "_data"); home = new File(home, getProjectID()); return home.toURI(); } @Override public URI getRelativeURI(URI uri) { try { URI relativeUri = LinkController.getController().createRelativeURI(new File(getProjectHome()), new File(uri), LinkController.LINK_RELATIVE_TO_MINDMAP); if(Compat.isWindowsOS() && relativeUri.getRawPath().contains(":")) { return uri; } return LinkController.createURI(WorkspaceController.PROJECT_RESOURCE_URL_PROTOCOL + "://"+ getProjectID() +"/"+relativeUri.getRawPath()); } catch (Exception ignore) { } return null; } @Override public ProjectVersion getVersion() { ProjectVersion version = null; if(getModel().getRoot() == null || ((ProjectRootNode)getModel().getRoot()).getVersion() == null) { version = CURRENT_PROJECT_VERSION; } else { version = new ProjectVersion(((ProjectRootNode)getModel().getRoot()).getVersion()); } return version; } public void unload() { super.unload(); literatureRepository = null; library = null; } public static boolean isCompatible(AWorkspaceProject project) { if(project == null || project.getVersion() == null) { return false; } //DOCEAR - todo: implement more differentiated version compare method return CURRENT_PROJECT_VERSION.getVersionString().equals(project.getVersion().getVersionString()); } public String toString() { return this.getClass().getSimpleName()+"[name="+getProjectName()+";id="+getProjectID()+";home="+getProjectHome()+"]"; } @Override public int hashCode() { return getProjectID().hashCode(); } }