REM This sample implements a file explorer to demonstrate the client
REM filesystem methods
REM USE declarations for Java classes
USE java.io.ByteArrayInputStream
USE java.io.ByteArrayOutputStream
USE java.io.FileInputStream
USE java.io.FileOutputStream
USE java.io.InputStream
USE java.io.OutputStream
USE java.lang.Object
USE java.lang.String
USE java.lang.System
USE java.util.Date
USE java.util.HashMap
USE java.util.Iterator
USE java.util.Properties
USE java.util.TreeMap
REM DECLARE statements for type checking
DECLARE BBjAPI myAPI!
DECLARE BBjSysGui mySysGui!
DECLARE BBjWindow myWindow!
DECLARE BBjTree myExplorer!
DECLARE BBjButton myHomeButton!
DECLARE BBjButton myCreateButton!
DECLARE BBjButton myDeleteButton!
DECLARE BBjButton myRenameButton!
DECLARE BBjButton myMkdirButton!
DECLARE BBjButton myReadOnlyButton!
DECLARE BBjButton myLoadConfigButton!
DECLARE BBjButton mySaveConfigButton!
DECLARE BBjStandardGrid myProperties!
DECLARE FileUtil myFileUtil!
DECLARE BBjClientFileSystem myClientFS!
DECLARE BBjClientFile myFile!
DECLARE BBjVector roots!
DECLARE BBjTreeNodeExpandedEvent myExpandEv!
DECLARE BBjTreeMouseDownEvent mySelectEv!
DECLARE BBjTreeNodeEditStoppedEvent myEditStoppedEv!
DECLARE BBjInt ROOT_NODE%
REM Open SYSGUI channel for display
sysgui = UNT
OPEN(sysgui)"X0"
REM Get BBjAPI and BBjSysGui objects
myAPI! = BBJAPI()
mySysGui! = myAPI!.getSysGui()
REM Create explorer window
myWindow! = mySysGui!.addWindow(100, 100, 400, 500, "Explorer", $00010092$)
REM Create explorer tree
myExplorer! = myWindow!.addTree(101, 0, 0, 200, 500)
ROOT_NODE% = 1
myExplorer!.setRoot(ROOT_NODE%, $$)
myExplorer!.setRootVisible(0)
REM Label for grid
myWindow!.addStaticText(102, 200, 0, 200, 25, "Properties", $4000$)
REM Grid for properties display
rows = 6
cols = 2
myProperties! = myWindow!.addGrid(103, 200, 25, 200, 225, $0010$, rows, cols)
myProperties!.setColumnWidth(0, 100)
myProperties!.setColumnWidth(1, 100)
myProperties!.setVisible(1)
myProperties!.setColumnAlignment(0, myProperties!.LEFT_ALIGNMENT)
myProperties!.setColumnAlignment(1, myProperties!.LEFT_ALIGNMENT)
REM Buttons for different example actions
myHomeButton! = myWindow!.addButton(104, 200, 250, 100, 25, "Home")
myCreateButton! = myWindow!.addButton(105, 300, 250, 100, 25, "Create File")
myDeleteButton! = myWindow!.addButton(106, 200, 275, 100, 25, "Delete")
myRenameButton! = myWindow!.addButton(107, 300, 275, 100, 25, "Rename")
myMkdirButton! = myWindow!.addButton(108, 200, 300, 100, 25, "Mkdir")
myReadOnlyButton! = myWindow!.addButton(109, 300, 300, 100, 25, "Set Read Only")
myLoadConfigButton! = myWindow!.addButton(110, 200, 325, 100, 25, "Load Config")
mySaveConfigButton! = myWindow!.addButton(111, 300, 325, 100, 25, "Save Config")
REM The BBjClientFilesystem object used to obtain client side file references
myClientFS! = myAPI!.getThinClient().getClientFileSystem()
REM A Custom Object to hold the data
myFileUtil! = new FileUtil(myClientFS!, myExplorer!)
REM Add filesystem roots to tree
roots! = myClientFS!.getRoots()
FOR i = 0 TO roots!.size() - 1
myFile! = CAST(BBjClientFile, roots!.get(i))
myFileUtil!.addFile(myFile!, ROOT_NODE%)
NEXT i
REM Setup callbacks
myWindow!.setCallback(myWindow!.ON_CLOSE, "DO_CLOSE")
myExplorer!.setCallback(myExplorer!.ON_TREE_EXPAND, "EXPAND")
myExplorer!.setCallback(myExplorer!.ON_TREE_MOUSE_DOWN, "SELECTED")
myExplorer!.setCallback(myExplorer!.ON_TREE_EDIT_STOP, "EDIT_STOPPED")
myHomeButton!.setCallback(myHomeButton!.ON_BUTTON_PUSH, "HOME_ACTION")
myCreateButton!.setCallback(myCreateButton!.ON_BUTTON_PUSH, "CREATE_ACTION")
myDeleteButton!.setCallback(myDeleteButton!.ON_BUTTON_PUSH, "DELETE_ACTION")
myRenameButton!.setCallback(myRenameButton!.ON_BUTTON_PUSH, "RENAME_ACTION")
myMkdirButton!.setCallback(myMkdirButton!.ON_BUTTON_PUSH, "MKDIR_ACTION")
myReadOnlyButton!.setCallback(myReadOnlyButton!.ON_BUTTON_PUSH, "READONLY_ACTION")
myLoadConfigButton!.setCallback(myLoadConfigButton!.ON_BUTTON_PUSH, "LOADCONFIG_ACTION")
mySaveConfigButton!.setCallback(mySaveConfigButton!.ON_BUTTON_PUSH, "SAVECONFIG_ACTION")
REM Once everything is done, set window visible
myWindow!.setVisible(1)
PROCESS_EVENTS
REM Callback for ON_TREE_EXPAND
EXPAND:
myExpandEv! = CAST(BBjTreeNodeExpandedEvent, myAPI!.getLastEvent())
currentID% = myExpandEv!.getNodeID()
myFileUtil!.populateChildren(currentID%)
RETURN
REM Callback for ON_TREE_MOUSE_DOWN
SELECTED:
mySelectEv! = CAST(BBjTreeMouseDownEvent, myAPI!.getLastEvent())
currentID% = mySelectEv!.getNodeID()
myExplorer!.selectNode(currentID%)
myFile! = myFileUtil!.getFile(currentID%)
IF (myFile! = NULL())
PRINT "Selected node " + STR(currentID%) + " was NULL()"
PRINT "Text: " + myExplorer!.getNodeText(currentID%)
ELSE
myFileUtil!.setProperties(myFile!, myProperties!)
ENDIF
RETURN
REM Callback when a previously started edit is finished
EDIT_STOPPED:
myEditStoppedEv! = CAST(BBjTreeNodeEditStoppedEvent, myAPI!.getLastEvent())
currentID% = myEditStoppedEv!.getNodeID()
myExplorer!.setNodeEditable(currentID%, 0)
myExplorer!.setTreeEditable(0)
name$ = myEditStoppedEv!.getNewText()
myFileUtil!.createOrRenameFile(currentID%, name$)
RETURN
REM Callback for window close box
DO_CLOSE:
RELEASE
REM Callback for "Home" button
HOME_ACTION:
myFileUtil!.showHomeDirectory()
RETURN
REM Callback for "Create File" button
CREATE_ACTION:
myFileUtil!.createFile()
RETURN
REM Callback for "Delete" button
DELETE_ACTION:
myFileUtil!.deleteFile()
RETURN
REM Callback for "Rename" button
RENAME_ACTION:
node% = myExplorer!.getSelectedNode()
IF (node% > 0)
myExplorer!.setNodeText(node%, myFileUtil!.getFile(node%).getName())
myExplorer!.setTreeEditable(1)
myExplorer!.setNodeEditable(node%, 1)
myExplorer!.editNode(node%)
ENDIF
RETURN
REM Callback for "Mkdir" button
MKDIR_ACTION:
myFileUtil!.mkdir()
RETURN
REM Callback for "Set Readonly " button
READONLY_ACTION:
node% = myExplorer!.getSelectedNode()
IF (node% > 0)
myFile! = myFileUtil!.getFile(node%)
myFile!.setReadOnly()
myFileUtil!.setProperties(myFile!, myProperties!)
ENDIF
RETURN
REM Callback for "Load Config" button
LOADCONFIG_ACTION:
myFileUtil!.loadConfig()
RETURN
REM Callback for "Save Config" button
SAVECONFIG_ACTION:
myFileUtil!.saveConfig()
RETURN
REM Utility class to store all the associated state for the tree and the files
CLASS PUBLIC FileUtil
REM Map from tree node numbers to files
FIELD PRIVATE HashMap NodeToFileMap! = new HashMap()
REM Map from files to tree node numbers
FIELD PRIVATE HashMap FileToNodeMap! = new HashMap()
REM explorer tree control
FIELD PRIVATE BBjTree Explorer!
REM Client filesystem
FIELD PRIVATE BBjClientFileSystem ClientFS!
REM Node number used for new tree nodes
FIELD PRIVATE BBjInt NodeNum% = 2
REM Configured directory color
FIELD PRIVATE BBjString DirColor$ = "#0000ff"
REM Configured color for non-files
FIELD PRIVATE BBjString NonFileColor$ = "#ff0000"
REM Configuration whether config is stored in memory or on disk
FIELD PRIVATE BBjInt MemoryConfig%
REM Local configuration file, if used
FIELD PRIVATE BBjString LocalConfig$
REM Last modification time of remote config file
FIELD PRIVATE BBjNumber LastModified
REM Constants for the configuration properties file
FIELD PUBLIC STATIC BBjString DIR_COLOR$ = "configfs.dirColor"
FIELD PUBLIC STATIC BBjString NON_FILE_COLOR$ = "configfs.nonFileColor"
FIELD PUBLIC STATIC BBjString MEMORY_CONFIG$ = "configfs.memoryConfig"
METHOD PUBLIC FileUtil(BBjClientFileSystem p_clientFS!, BBjTree p_explorer!)
REM Set the values for the fields
#Explorer! = p_explorer!
#ClientFS! = p_clientFS!
REM Load the config from the client, if it exists
#loadConfig()
METHODEND
REM Adds a file to the tree below the node specified by p_parent%
METHOD PUBLIC VOID addFile(BBjClientFile p_clientFile!, BBjInt p_parent%)
DECLARE BBjString text$
DECLARE BBjInt node%
REM If we already have the file, reuse it.
IF (#FileToNodeMap!.containsKey(p_clientFile!))
node% = #getNode(p_clientFile!)
REM Otherwise, make a new node
ELSE
node% = #NodeNum%
#NodeNum% = INT(#NodeNum% + 1)
ENDIF
REM Get the html formatted text for the file
text$ = #getFileNameText(p_clientFile!)
REM Add the file, using the folder icons for directories, and normal icons for others.
IF (p_clientFile!.isDirectory())
#Explorer!.addExpandableNode(node%, p_parent%, text$)
ELSE
#Explorer!.addNode(node%, p_parent%, text$)
ENDIF
REM Add the tree node number and file to the maps for other operations
#NodeToFileMap!.put(node%, p_clientFile!)
#FileToNodeMap!.put(p_clientFile!, node%)
METHODEND
REM Returns an HTML-formatted string for the given client file based on
REM its properties
METHOD PUBLIC BBjString getFileNameText(BBjClientFile p_clientFile!)
DECLARE BBjString text$
text$ = p_clientFile!.getName()
styled = 0
REM If it's a directory, use the saved directory color.
IF (p_clientFile!.isDirectory())
text$ = "<font color=""" + #DirColor$ + """>" + text$ + "/</font>"
styled = 1
ELSE
REM otherwise, if it's not a regular file, use the non-file color
IF (! p_clientFile!.isFile())
text$ = "<font color=""" + #NonFileColor$ + """>" + text$ + "</font>"
styled = 1
ENDIF
ENDIF
REM If it's a hidden file, make it italicized
IF (p_clientFile!.isHidden())
text$ = "<i>" + text$ + "</i>"
styled = 1
ENDIF
REM If it's been styled in anyway, add html tags
IF styled
text$ = "<html>" + text$ + "</html>"
ENDIF
REM Return the text
METHODRET text$
METHODEND
REM Return the file associated with the provided node number
METHOD PUBLIC BBjClientFile getFile(BBjInt p_nodeNum%)
DECLARE BBjClientFile ret!
ret! = CAST(BBjClientFile, #NodeToFileMap!.get(p_nodeNum%))
METHODRET ret!
METHODEND
REM Return the node number associated with the provided file
METHOD PUBLIC BBjInt getNode(BBjClientFile p_file!)
DECLARE BBjInt ret%
IF (#FileToNodeMap!.get(p_file!) <> NULL()) THEN
ret% = CAST(BBjInt, #FileToNodeMap!.get(p_file!))
METHODRET ret%
else
METHODRET 2
ENDIF
METHODEND
METHOD PUBLIC VOID populateChildren(BBjInt p_nodeNum%)
DECLARE BBjClientFile myCurrentFile!
DECLARE BBjClientFile child!
DECLARE BBjVector children!
DECLARE TreeMap sorter!
DECLARE Iterator iter!
DECLARE BBjString name$
DECLARE Object key!
REM Get the file associated with p_nodeNum%
myCurrentFile! = #getFile(p_nodeNum%)
REM If it exists, then populate the children of the directory
IF (myCurrentFile! <> NULL())
REM If it has children, remove all the descendents, and repopulate the list
IF (#Explorer!.getNumChildren(p_nodeNum%))
#removeDescendents(p_nodeNum%)
ENDIF
REM If it's a directory, add all the files below it.
IF (myCurrentFile!.isDirectory())
children! = myCurrentFile!.listFiles()
IF (children!.size() > 0)
REM TreeMap used for sorting the file names
sorter! = new TreeMap()
FOR i = 0 TO children!.size() - 1
child! = CAST(BBjClientFile, children!.get(i))
name$ = child!.getName()
REM Sort directories before files
IF (child!.isDirectory())
name$ = $00$ + name$
ENDIF
sorter!.put(name$, child!)
NEXT i
REM Iterating through the TreeMap will add the files in sorted order
iter! = sorter!.keySet().iterator()
WHILE iter!.hasNext()
key! = iter!.next()
child! = CAST(BBjClientFile, sorter!.get(key!))
#addFile(child!, p_nodeNum%)
WEND
ENDIF
ENDIF
ENDIF
METHODEND
REM Sets the properties of the given file in the grid
METHOD PUBLIC VOID setProperties(BBjClientFile p_file!, BBjStandardGrid p_properties!)
DECLARE BBjVector data!
data! = BBJAPI().makeVector()
REM Populate each line of the grid with the appropriate data.
data!.addItem("Name"); data!.addItem(p_file!.getName())
data!.addItem("Canonical"); data!.addItem(p_file!.getCanonicalFile().getPath())
data!.addItem("Contained in"); IF (p_file!.getParent() = NULL()) THEN data!.addItem("<root>") ELSE data!.addItem(p_file!.getParent().getPath()) FI
data!.addItem("Readable"); data!.addItem(String.valueOf(p_file!.canRead()))
data!.addItem("Writeable"); data!.addItem(String.valueOf(p_file!.canWrite()))
data!.addItem("Modified Date"); data!.addItem(new Date(p_file!.lastModified()).toString())
REM Set the data in the grid
p_properties!.setCellText(0, 0, data!)
METHODEND
METHOD PUBLIC VOID showHomeDirectory()
DECLARE BBjVector path!
DECLARE BBjVector files!
DECLARE BBjClientFile file!
DECLARE BBjClientFile parent!
DECLARE Iterator iter!
DECLARE BBjInt node%
DECLARE Object node!
REM We have to populate the tree down to the home directory,
REM if it's never been done
file! = #ClientFS!.getHomeDirectory()
path! = BBJAPI().makeVector()
parent! = file!
WHILE (parent! <> NULL() AND (! #FileToNodeMap!.containsKey(parent!)))
path!.add(0, parent!)
parent! = parent!.getParent()
WEND
REM The vector has all the directories, from closest to the root to
REM furthest from the root. Iterate and populate until we're home
IF (parent! <> NULL())
node% = #getNode(parent!)
#populateChildren(node%)
iter! = path!.iterator()
WHILE (iter!.hasNext())
file! = CAST(BBjClientFile, iter!.next())
node% = #getNode(file!)
#populateChildren(node%)
WEND
REM Once we're home, show that node
#Explorer!.expandNode(node%)
#Explorer!.setNodeVisible(node%)
#Explorer!.selectNode(node%)
ELSE
REM Should never happen
PRINT "parent = NULL()"
ENDIF
METHODEND
REM Remove a specific node and all its children from the tree and the maps
METHOD PRIVATE VOID remove(BBjInt p_node%)
DECLARE BBjClientFile file!
DECLARE BBjInt children%
REM First iterate through any children and recursively call remove()
children% = #Explorer!.getNumChildren(p_node%)
IF (children% > 0)
REM Go backwards, so the index remains consistent
FOR i = children% - 1 TO 0 STEP -1
REM recursive call
#remove(#Explorer!.getChildAt(p_node%, i))
NEXT i
ENDIF
REM Finally, remove the node itself and the associated file
file! = #getFile(p_node%)
#NodeToFileMap!.remove(p_node%)
#FileToNodeMap!.remove(file!)
#Explorer!.removeNode(p_node%)
METHODEND
REM Remove all the children of a specific node from the tree and the maps
METHOD PRIVATE VOID removeDescendents(BBjInt p_node%)
DECLARE BBjInt children%
DECLARE BBjInt child%
DECLARE BBjClientFile file!
REM call remove() on all the children
children% = #Explorer!.getNumChildren(p_node%)
IF (children% > 0)
FOR i = children% - 1 TO 0 STEP -1
child% = #Explorer!.getChildAt(p_node%, i)
#remove(child%)
NEXT i
ENDIF
METHODEND
REM Get ready to create a new file
METHOD PUBLIC VOID createFile()
DECLARE BBjInt node%
DECLARE BBjInt newNode%
DECLARE BBjNumber dummy
DECLARE BBjClientFile file!
REM Only do it if there's a selected node.
node% = #Explorer!.getSelectedNode()
IF (node% <> -1)
file! = #getFile(node%)
REM If the selected node is a directory, create the file in the directory
IF (file!.isDirectory())
#populateChildren(node%)
REM Otherwise, get the parent of the specified file and use that.
ELSE
file! = file!.getParent()
node% = #getNode(file!)
ENDIF
REM If we can write to the directory, add a new node, and
REM immediately begin editing the node.
IF (file!.canWrite())
newNode% = #NodeNum%
#NodeNum% = INT(#NodeNum% + 1)
#Explorer!.addNode(newNode%, node%, "New File")
#Explorer!.setTreeEditable(1)
#Explorer!.setNodeEditable(newNode%, 1)
#Explorer!.setNodeVisible(newNode%)
#Explorer!.editNode(newNode%)
REM When the edit finishes, we'll get an event and create the file then
REM If we can't, tell the user
ELSE
dummy = MSGBOX("Cannot write to this directory")
ENDIF
ENDIF
METHODEND
REM delete the selected node
METHOD PUBLIC VOID deleteFile()
DECLARE BBjInt node%
DECLARE BBjClientFile file!
DECLARE BBjNumber dummy
REM Determine what file is selected
node% = #Explorer!.getSelectedNode()
file! = CAST(BBjClientFile, #NodeToFileMap!.get(node%))
REM If the file may not be deleted, tell the user
IF (! file!.delete())
dummy = MSGBOX("Delete failed")
REM Otherwise, delete it from all the maps.
ELSE
#FileToNodeMap!.remove(file!)
#NodeToFileMap!.remove(node%)
#Explorer!.removeNode(node%)
ENDIF
METHODEND
REM Make a directory
METHOD PUBLIC VOID mkdir()
DECLARE BBjInt parentNode%
DECLARE BBjInt newNode%
DECLARE BBjNumber dummy
DECLARE BBjClientFile parent!
DECLARE BBjClientFile newDir!
REM Get the selected node to create a directory in
parentNode% = #Explorer!.getSelectedNode()
IF (parentNode% <> -1)
REM Get the directory containing the file if it's not a directory
parent! = #getFile(parentNode%)
IF (parent!.isDirectory())
#populateChildren(parentNode%)
ELSE
parent! = parent!.getParent()
parentNode% = #getNode(parent!)
ENDIF
REM If we can write to the directory, create a new folder
IF (parent!.canWrite())
newDir! = #ClientFS!.getClientFile(parent!, "New Folder")
REM If we can create the folder, start editing the name.
IF (newDir!.mkdir())
#addFile(newDir!, parentNode%)
newNode% = #getNode(newDir!)
#Explorer!.setNodeText(newNode%, newDir!.getName())
#Explorer!.setTreeEditable(1)
#Explorer!.setNodeEditable(newNode%, 1)
#Explorer!.setNodeVisible(newNode%)
#Explorer!.editNode(newNode%)
REM Respond to the event as though it were a rename event
REM Otherwise, tell the user
ELSE
dummy = MSGBOX("mkdir failed")
ENDIF
REM Otherwise, tell the user
ELSE
dummy = MSGBOX("Cannot write to this directory")
ENDIF
ENDIF
METHODEND
REM This method is called in response to an editstopped event.
METHOD PUBLIC VOID createOrRenameFile(BBjInt p_node%, BBjString p_string$)
DECLARE BBjClientFile file!
DECLARE BBjClientFile newFile!
DECLARE BBjClientFile parentFile!
DECLARE BBjInt parent%
DECLARE BBjInt node%
file! = CAST(BBjClientFile, #NodeToFileMap!.get(p_node%))
REM If the file does not exist, we're creating a new file
IF (file! = NULL())
REM Remove the existing node
parent% = #Explorer!.getParentNode(p_node%)
parentFile! = CAST(BBjClientFile, #NodeToFileMap!.get(parent%))
#Explorer!.removeNode(p_node%)
REM Use the new text p_string$ as the new file name
newFile! = #ClientFS!.getClientFile(parentFile!, p_string$)
newFile!.createNewFile()
REM Otherwise, the file does exist, and we're renaming it
ELSE
REM Get the file representing the new name
parentFile! = file!.getParent()
parent% = #getNode(parentFile!)
newFile! = #ClientFS!.getClientFile(parentFile!, p_string$)
REM Rename the old file to the new file name.
file!.renameTo(newFile!)
REM Remove the old file, we'll add the new one afterwards
#NodeToFileMap!.remove(p_node%)
#FileToNodeMap!.remove(file!)
#Explorer!.removeNode(p_node%)
ENDIF
REM Add the new file, and reselect it
#addFile(newFile!, parent%)
node% = #getNode(newFile!)
#Explorer!.selectNode(node%)
#Explorer!.setNodeVisible(node%)
METHODEND
REM Load the configuration from the client
METHOD PUBLIC VOID loadConfig()
DECLARE BBjClientFile userConfigFile!
DECLARE BBjClientFile userHome!
DECLARE BBjString localFile$
DECLARE Properties props!
DECLARE InputStream input!
DECLARE BBjInt tmpMemoryConfig%
REM Get the home directory
userHome! = #ClientFS!.getHomeDirectory()
REM This is the file name used for the config file
userConfigFile! = #ClientFS!.getClientFile(userHome!.getPath() + "/.clientfs/config/config.properties")
REM If it exists and we can read it, get the file contents
IF (userConfigFile!.exists() AND userConfigFile!.canRead())
props! = new Properties()
REM If we're using an in-memory config, read the bytes directly
IF (#MemoryConfig%)
contents$ = userConfigFile!.getContents()
input! = new ByteArrayInputStream(contents$)
REM Otherwise, write to a local file and read it that way
ELSE
#LocalConfig$ = userConfigFile!.copyFromClient()
input! = new FileInputStream(#LocalConfig$)
ENDIF
REM Load the properties from the InputStream
props!.load(input!)
REM Set the fields based on each property.
IF (props!.getProperty(#DIR_COLOR$) <> NULL())
#DirColor$ = props!.getProperty(#DIR_COLOR$)
ENDIF
IF (props!.getProperty(#NON_FILE_COLOR$) <> NULL())
#NonFileColor$ = props!.getProperty(#NON_FILE_COLOR$)
ENDIF
IF (props!.getProperty(#MEMORY_CONFIG$) <> NULL())
tmpMemoryConfig% = INT(NUM(props!.getProperty(#MEMORY_CONFIG$), ERR=*NEXT))
#MemoryConfig% = tmpMemoryConfig%
ENDIF
REM Remember the last time we read the file by setting the last modified time
#LastModified = System.currentTimeMillis()
userConfigFile!.setLastModified(#LastModified)
ENDIF
METHODEND
REM Save the configuration properties file
METHOD PUBLIC VOID saveConfig()
DECLARE BBjClientFile userConfigFile!
DECLARE BBjClientFile userConfigDir!
DECLARE BBjClientFile userHome!
DECLARE ByteArrayOutputStream byteOutput!
DECLARE FileOutputStream fileOutput!
DECLARE Properties props!
DECLARE BBjString contents$
DECLARE BBjInt msgResult%
REM Get the home directory and the subdirectory containing the configuration.
userHome! = #ClientFS!.getHomeDirectory()
userConfigDir! = #ClientFS!.getClientFile(userHome!.getPath() + "/.clientfs/config")
REM Get the file object representing the directory.
userConfigFile! = #ClientFS!.getClientFile(userConfigDir!, "config.properties")
REM Create the directory if it's never existed.
IF (! userConfigDir!.exists())
IF (! userConfigDir!.mkdirs())
dummy = MSGBOX("Cannot create config dir")
METHODRET
ENDIF
ENDIF
REM IF the file exists, check to make sure we're not overwriting changes
IF (userConfigFile!.exists())
IF (userConfigFile!.lastModified() > #LastModified)
msgResult% = MSGBOX("Config file modified since last load. Overwrite changes?", 1)
IF (msgResult% <> 1)
METHODRET
ENDIF
ENDIF
ENDIF
REM Set the properties from this object
props! = new Properties()
props!.setProperty(#DIR_COLOR$, #DirColor$)
props!.setProperty(#NON_FILE_COLOR$, #NonFileColor$)
props!.setProperty(#MEMORY_CONFIG$, "1")
REM If using an in-memory config, store the contents to a string.
IF (#MemoryConfig%)
byteOutput! = new ByteArrayOutputStream()
props!.store(byteOutput!, "Client FS Sample Config File")
byteOutput!.close()
REM Assign the bytes to a string variable
bytes$ = byteOutput!.toByteArray()
REM Set those contents across the wire
userConfigFile!.setContents(bytes$)
REM Otherwise, use a local file and then copy contents over.
ELSE
REM If we don't have a local config file make one
IF (#LocalConfig$ = $$)
IF (! userConfigFile!.exists())
userConfigFile!.createNewFile()
ENDIF
#LocalConfig$ = userConfigFile!.copyFromClient()
ENDIF
REM Write the properties to a local file.
fileOutput! = new FileOutputStream(#LocalConfig$)
props!.store(fileOutput!, "Client FS Sample Config File")
fileOutput!.close()
REM Copy the file to the client
userConfigFile!.copyToClient(#LocalConfig$)
ENDIF
REM Update the last modified time
#LastModified = userConfigFile!.lastModified()
METHODEND
CLASSEND
|