package org.concord.otrunk.view; import java.awt.Component; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Vector; import org.concord.framework.otrunk.OTID; import org.concord.framework.otrunk.OTObjectMap; import org.concord.framework.otrunk.OTObjectService; import org.concord.framework.otrunk.OTUser; import org.concord.framework.otrunk.OTrunk; import org.concord.otrunk.OTStateRoot; import org.concord.otrunk.OTrunkImpl; import org.concord.otrunk.datamodel.OTDataObject; import org.concord.otrunk.datamodel.OTDatabase; import org.concord.otrunk.user.OTReferenceMap; import org.concord.otrunk.user.OTUserObject; import org.concord.otrunk.xml.ExporterJDOM; import org.concord.otrunk.xml.XMLDatabase; import org.concord.swing.MostRecentFileDialog; import org.doomdark.uuid.UUID; public class OTMLUserSession implements OTUserSession { File currentUserFile; URL currentUserUrl; XMLDatabase userDataDB; protected URL contextURL; String userName; Component dialogParent; private OTrunkImpl otrunk; OTReferenceMap refMap; protected String workgroupName; public OTMLUserSession() { } public OTMLUserSession(File dbFile, String name) { this.currentUserFile = dbFile; this.userName = name; } public OTMLUserSession(URL dbUrl, String name) { this.currentUserUrl = dbUrl; this.userName = name; } public OTMLUserSession(XMLDatabase db, String name) { this.userDataDB = db; this.userName = name; } public void setOTrunk(OTrunk otrunk) { this.otrunk = (OTrunkImpl)otrunk; } public void load() throws Exception { // This will be the case if we were initialized with a file if(currentUserFile != null && currentUserUrl == null && userDataDB == null){ load(currentUserFile); return; } // This will be the case if we were initialized with a url if(currentUserUrl != null && userDataDB == null){ load(currentUserUrl); return; } if(userDataDB != null){ load(userDataDB); } else { newLayer(); if(userName != null){ getUserObject().setName(userName); } } } protected void load(URL url) throws Exception { currentUserUrl = url; userDataDB = new XMLDatabase(currentUserUrl); userDataDB.loadObjects(); load(userDataDB); } protected void load(File file) throws Exception { currentUserFile = file; URL fileUrl = file.toURL(); load(fileUrl); if(userName == null){ OTUserObject userObject = getUserObject(); if(userObject.getName() == null){ userObject.setName(currentUserFile.getName()); } } } protected void load(XMLDatabase db) throws Exception { initUserDb(db); // Set the username OTUser user = refMap.getUser(); OTUserObject aUser = (OTUserObject)user; if(userName != null){ aUser.setName(userName); } otrunk.registerReferenceMap(getReferenceMap()); // just loading the database shouldn't cause it to have changes that need // saving. If the user name was set that would be change. userDataDB.setDirty(false); } public boolean allowNewLayer() { return true; } public boolean allowOpen() { return true; } public boolean allowSaveAs() { return true; } public boolean allowSave() { return true; } public String getLabel() { // we might not always have a current User file so this might need to return something else. if(currentUserFile != null){ return currentUserFile.toString(); } else { return null; } } public OTReferenceMap getReferenceMap() { return refMap; } public OTUserObject getUserObject() { return refMap.getUser(); } public boolean hasUnsavedChanges() { if(userDataDB == null){ return false; } return userDataDB.isDirty(); } public void ignoreCurrentUnsavedChanges() { userDataDB.setDirty(false); } public void newLayer() throws Exception { // need to make a brand new stateDB userDataDB = new XMLDatabase(); otrunk.addDatabase(userDataDB); // System.out.println("otrunk: " + otrunk + " userDatabase: " + // userDataDB); OTObjectService objService = otrunk.createObjectService(userDataDB); OTStateRoot stateRoot = objService.createObject(OTStateRoot.class); userDataDB.setRoot(stateRoot.getGlobalId()); stateRoot.setFormatVersionString("1.0"); OTUserObject userObject = objService.createObject(OTUserObject.class); OTID userId = userObject.getUserId(); OTObjectMap userStateMapMap = stateRoot.getUserMap(); refMap = objService.createObject(OTReferenceMap.class); userStateMapMap.putObject(userId.toExternalForm(), refMap); refMap.setUser(userObject); otrunk.registerReferenceMap(refMap); userDataDB.setDirty(false); currentUserFile = null; } public boolean open() { MostRecentFileDialog mrfd = new MostRecentFileDialog("org.concord.otviewer.openotml"); mrfd.setFilenameFilter("otml"); int retval = mrfd.showOpenDialog(getDialogParent()); File file = null; if (retval == MostRecentFileDialog.APPROVE_OPTION) { file = mrfd.getSelectedFile(); } if (file == null || !file.exists()){ return false; } // CHECKME it isn't clear if the userName should be cleared here or not try { load(file); return true; } catch (MalformedURLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return false; } public void save() { if (currentUserFile == null || !currentUserFile.exists()) { saveAs(); return; } if (currentUserFile.exists()) { try { ExporterJDOM.export(currentUserFile, userDataDB.getRoot(), userDataDB); userDataDB.setDirty(false); } catch (Exception e) { e.printStackTrace(); } } } public void saveAs() { MostRecentFileDialog mrfd = new MostRecentFileDialog("org.concord.otviewer.saveotml"); mrfd.setFilenameFilter("otml"); if (currentUserFile != null) { mrfd.setCurrentDirectory(currentUserFile.getParentFile()); mrfd.setSelectedFile(currentUserFile); } int retval = mrfd.showSaveDialog(getDialogParent()); File file = null; if (retval == MostRecentFileDialog.APPROVE_OPTION) { file = mrfd.getSelectedFile(); String fileName = file.getPath(); currentUserFile = file; if (!fileName.toLowerCase().endsWith(".otml")) { currentUserFile = new File(currentUserFile.getAbsolutePath() + ".otml"); } try { ExporterJDOM.export(currentUserFile, userDataDB.getRoot(), userDataDB); userDataDB.setDirty(false); } catch (Exception e) { e.printStackTrace(); } } } public Component getDialogParent() { return dialogParent; } public void setDialogParent(Component dialogParent) { this.dialogParent = dialogParent; } public OTDatabase getUserDataDb() { return userDataDB; } protected void initUserDb(XMLDatabase userDataDb) throws Exception { this.userDataDB = userDataDb; otrunk.addDatabase(userDataDB); OTObjectService objService = otrunk.createObjectService(userDataDb); OTDataObject rootDO = userDataDb.getRoot(); OTStateRoot stateRoot = (OTStateRoot)objService.getOTObject(rootDO.getGlobalId()); OTObjectMap userMap = stateRoot.getUserMap(); // find the user from this database. // this currently is the first user in the userMap Vector<String> keys = userMap.getObjectKeys(); refMap = (OTReferenceMap)userMap.getObject(keys.get(0)); } public boolean isInitialized() { // This implementation is always initialized. Because it will // just create a new database. return true; } public void saveAndClose() { // allow subclasses to do things like shut down timers before the final save. preSaveAndClose(); if(hasUnsavedChanges()){ save(); } close(); } public void close() { // there is nothing to do on close } public void setWorkgroup(String workgroupName, String workgroupToken, UUID workgroupId) { this.workgroupName = workgroupName; } /** * This method can be overriden if something needs to be done before * a final save. */ protected void preSaveAndClose() { } public void setContextURL(URL url) { this.contextURL = url; } public URL getContextURL() { return this.contextURL; } }