package org.freeplane.plugin.workspace.features;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.freeplane.core.extension.IExtension;
import org.freeplane.core.io.IAttributeHandler;
import org.freeplane.core.io.IExtensionAttributeWriter;
import org.freeplane.core.io.ITreeWriter;
import org.freeplane.core.io.ReadManager;
import org.freeplane.features.map.MapController;
import org.freeplane.features.map.MapModel;
import org.freeplane.features.map.NodeModel;
import org.freeplane.features.mode.ModeController;
import org.freeplane.plugin.workspace.URIUtils;
import org.freeplane.plugin.workspace.WorkspaceController;
import org.freeplane.plugin.workspace.model.project.AWorkspaceProject;
public class WorkspaceModelExtensionWriterReader implements IExtensionAttributeWriter {
private static final String PROJECT_ID_XML_TAG = "project";
private static final String MAP_EXTENSION_XML_TAG = "map";
private static final String PROJECT_HOME_XML_TAG = "project_last_home";
private final Map<MapModel, TempProjectItem> tempProjectCache = new HashMap<MapModel, TempProjectItem>();
private WorkspaceModelExtensionWriterReader(MapController mapController) {
registerAttributeHandlers(mapController.getReadManager());
mapController.getWriteManager().addExtensionAttributeWriter(WorkspaceMapModelExtension.class, this);
}
private void registerAttributeHandlers(ReadManager reader) {
reader.addAttributeHandler(MAP_EXTENSION_XML_TAG, PROJECT_ID_XML_TAG, new IAttributeHandler() {
public void setAttribute(Object map, String value) {
final MapModel mapModel = (MapModel) map;
WorkspaceMapModelExtension wmme = WorkspaceController.getMapModelExtension(mapModel);
if(wmme.getProject() == null) {
updateProjectPathIndex(mapModel, value, null);
AWorkspaceProject prj = WorkspaceController.getCurrentModel().getProject(value);
if(prj == null) {
return;
}
wmme.setProject(prj);
}
}
});
reader.addAttributeHandler(MAP_EXTENSION_XML_TAG, PROJECT_HOME_XML_TAG, new IAttributeHandler() {
public void setAttribute(Object map, String value) {
final MapModel mapModel = (MapModel) map;
updateProjectPathIndex(mapModel, null, URIUtils.createURI(value));
}
});
}
private void updateProjectPathIndex(MapModel key, String id, URI path) {
synchronized (tempProjectCache) {
TempProjectItem item = tempProjectCache.get(key);
if(item == null) {
item = new TempProjectItem();
tempProjectCache.put(key, item);
}
if(id != null) {
item.projectID = id;
}
if(path != null) {
item.projectPath = path;
}
//index
if(item.isComplete()) {
WorkspaceMapModelExtension wmme = WorkspaceController.getMapModelExtension(key);
AWorkspaceProject project = WorkspaceController.getCachedProjectByID(item.projectID);
if(wmme.getProject() == null) {
if(project == null) {
project = AWorkspaceProject.create(item.projectID, item.projectPath);
}
WorkspaceController.addMapToProject(key, project);
WorkspaceController.indexProject(project);
}
else {
WorkspaceController.indexProject(wmme.getProject());
}
tempProjectCache.remove(key);
}
}
}
public void writeAttributes(ITreeWriter writer, Object userObject, IExtension extension) {
final WorkspaceMapModelExtension wmme = extension != null ? (WorkspaceMapModelExtension) extension : WorkspaceController.getMapModelExtension(((NodeModel) userObject).getMap());
AWorkspaceProject prj = wmme.getProject();
if(prj == null) {
return;
}
writer.addAttribute(PROJECT_ID_XML_TAG, prj.getProjectID());
writer.addAttribute(PROJECT_HOME_XML_TAG, prj.getProjectHome().toString());
}
public static void register(ModeController modeController) {
new WorkspaceModelExtensionWriterReader(modeController.getMapController());
}
static class TempProjectItem {
public String projectID = null;
public URI projectPath = null;
public boolean isComplete() {
return projectID != null && projectPath != null;
}
}
}