[e-cvs] cvs commit: e/src/esrc/scripts eDesk.e intro.updoc
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Sat, 27 Oct 2001 13:34:08 -0400
markm 01/10/27 13:34:08
Added: src/esrc/com/skyhunter/e/awt/dnd dragDropKit.emaker
src/esrc/com/skyhunter/e/net moreRecentVowFuncMaker.emaker
src/esrc/com/skyhunter/e/util stackTraceFunc.emaker
src/esrc/com/skyhunter/eDesk
navPanelControllerMakerAuthor.emaker
serverDescVowAuthor.emaker testConfigurator.updoc
testNavPanel.e testNavPanel.updoc
src/esrc/com/skyhunter/eDesk/icons folder.gif
src/esrc/scripts eDesk.e intro.updoc
Log:
New eDesk files, for the new eDesk, some of whose files were committed
in the previous 'cvs commit'
Revision Changes Path
1.1 e/src/esrc/com/skyhunter/e/awt/dnd/dragDropKit.emaker
Index: dragDropKit.emaker
===================================================================
//Copyright (C) 2001 Combex. All Rights Reserved.
def dragDropKitAuthor(awt__uriGetter, traceln) :near {
def dragDropKit {
#uses class java.awt.dnd.DropTargetEvent in specifying
#dataflavor only so there is a concrete class for the
#dataflavor (java.lang.Object does not work!)
#Users of the E dnd system must specify a reactor
# to mimeType := DataFlavor javaJVMLocalObjectMimeType() +
# "; class=java.awt.dnd.DropTargetEvent"
#to transfer eobjects
to makeTransferableLocalEObject(eObject) :near {
def DataFlavor := <awt:datatransfer.DataFlavor>
def mimeType := DataFlavor javaJVMLocalObjectMimeType() +
"; class=java.awt.dnd.DropTargetEvent"
def transferable {
to getTransferData(flavor) :near {
eObject
}
to getTransferDataFlavors() :any {
traceln("getting transfer flavors")
def flavors := [DataFlavor new(mimeType)]
traceln("transfer flavors: " + flavors)
flavors
}
to isDataFlavorSupported(flavor) :boolean {
flavor isMimeTypeEqual(mimeType)
}
match [verb, args] {
traceln("BAD: transfer got surprise message: " + verb)
}
}
}
to setupLocalDragSource(component, localEObjectFunc) {
def dragSourceListener {
to dragDropEnd(blah1) {traceln("drag source sees dragdropend")}
to dragEnter(blah2) {traceln("drag source sees dragenter")}
to dragExit(blah3) {traceln("drag source sees dragexit")}
to dragOver (blah4) {
#traceln("drag source sees dragover")
}
to dropActionChanged(blah) {traceln("dropactionchanged")}
match [verb,args] {traceln("dragsource says: " + verb)}
}
def dragGestureListener {
to dragGestureRecognized(dragEvent) {
def eObject := localEObjectFunc()
def objCarrier := dragDropKit makeTransferableLocalEObject(eObject)
traceln("dragging object: " + eObject)
traceln("dragEvent: " + dragEvent)
traceln ("sourcel: " + dragSourceListener)
def cursor := <awt:dnd.DragSource> DefaultMoveDrop()
traceln("cursor: " + cursor)
try {
dragEvent startDrag(
cursor,
objCarrier,
dragSourceListener)
} catch err {traceln("dragevent err: " + err)}
traceln ("started drag")
}
match [verb,args] {traceln("gesturer heard: " + verb)}
}
def dragSource := <awt:dnd.DragSource> getDefaultDragSource()
dragSource createDefaultDragGestureRecognizer(
component,
<awt:dnd.DnDConstants> ACTION_COPY_OR_MOVE(),
dragGestureListener)
}
}
}
1.1 e/src/esrc/com/skyhunter/e/net/moreRecentVowFuncMaker.emaker
Index: moreRecentVowFuncMaker.emaker
===================================================================
class moreRecentVowFuncMaker() :near {
def obsoleteError := "Obsolete Data"
var mostRecentlyFulfilledIndex := 0
var nextPromiseIndex := 1
def moreRecentVow(nextPromise) :any {
def [onlyMoreRecentPromise,resolver] := PromiseMaker()
def thisPromiseIndex := nextPromiseIndex
nextPromiseIndex += 1
when (nextPromise) -> done(resolution) {
if (thisPromiseIndex > mostRecentlyFulfilledIndex) {
resolver resolve(resolution)
mostRecentlyFulfilledIndex := thisPromiseIndex
} else { resolver smash(obsoleteError) }
} catch e {
if (thisPromiseIndex > mostRecentlyFulfilledIndex) {
mostRecentlyFulfilledIndex := thisPromiseIndex
resolver smash(e)
} else { resolver smash(obsoleteError) }
}
onlyMoreRecentPromise
}
}
1.1 e/src/esrc/com/skyhunter/e/util/stackTraceFunc.emaker
Index: stackTraceFunc.emaker
===================================================================
//Copyright (C) 2001 Combex. All Rights Reserved.
def stackTraceFunc(err) :pbc {
err eStack() + "\n\n" +
err leaf() javaStack()
}
1.1 e/src/esrc/com/skyhunter/eDesk/navPanelControllerMakerAuthor.emaker
Index: navPanelControllerMakerAuthor.emaker
===================================================================
#!/usr/local/bin/e
//License Agreement:
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
// http://www.skyhunter.com/marcs/securit-Edesk-license.html
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights and
// limitations under the License.
//The Original Code is The Securit-Edesk Configurator Program.
//The Initial Developer of the Original Code is Marc Stiegler. Portions created by
// Marc Stiegler are Copyright (C) Marc Stiegler. All Rights Reserved.
//**********
def navPanelControllerMakerAuthor(unsafe__uriGetter, awt__uriGetter, swing__uriGetter, traceln) :any {
def JPanel__quasiParser := <import:org.erights.ex.swing.JPanelQParserMaker> new(awt__uriGetter, swing__uriGetter)
def promiseAllResolved := <import:com.skyhunter.e.net.promiseAllResolved>
def uiKit := <import:com.skyhunter.ex.swing.uiKitAuthor>(awt__uriGetter,
swing__uriGetter)
def dirIcon := <swing:ImageIcon> new(<resource:com/skyhunter/eDesk/icons/folder.gif>)
def moreRecentVowFuncMaker := <import:com.skyhunter.e.net.moreRecentVowFuncMaker>
def diskNavStub {
to dupNavigator() :near {diskNavStub}
to getStorageName() :String {""}
to versionNumber() :pbc {0}
to getCurrentPath() :String {""}
to getParentPath() :String {""}
to listCurrentSubdirectoriesAndFiles() :pbc {[[],[]]}
match [verb, args] {}
}
def unAssociatedIcon := <swing:ImageIcon> new(<resource:com/skyhunter/eDesk/icons/stranger.gif>)
def cellRenderer {
to getListCellRendererComponent(listPanel, cell,
index, isSelected, cellHasFocus) :near {
def component := cell composeComponent()
def label := cell getLabel()
if (isSelected) {
label setBackground(<awt:Color> cyan())
} else {
label setBackground(<awt:Color> white())
}
component
}
}
def dirNameFromPath(path) :pbc {
traceln("path: " + path)
def parts := path split("/")
if (parts size() >= 2) {
parts[parts size() - 2] + "/"
} else {""}
}
def computeSuffix(name) :near {
def parts := name split(".")
def size := parts size()
if (size == 1) {
""
} else {
parts[size - 1]
}
}
class cellMaker(var name, isDir) :near {
var component := null
var label := null
var icon := null
var iconPane := null
def cell {
to composeComponent() :near {
if (component != null) {
component
} else {
icon := if (isDir) {dirIcon} else {unAssociatedIcon}
iconPane := <swing:JLabel> new(icon)
iconPane setIcon(icon)
label := <swing:JTextField> new(name)
label setBorder(<swing:BorderFactory> createEmptyBorder(0,0,0,0))
label setEditable(false)
component := JPanel`$iconPane $label.X`
}
}
to rename(newName) {
name := newName
component := null
}
to isDir() :pbc {isDir}
to getLabel() :near {label}
to getIconPane() :near {iconPane}
}
}
def composeCellArray(dirsFiles) :pbc {
def list := [] diverge()
for each in dirsFiles[0] {
list push(cellMaker new(each, true))
}
for each in dirsFiles[1] {
list push(cellMaker new(each, false))
}
list snapshot()
}
class navPanelControllerMaker(optHigherDirControllerVow, optLowerDirControllerVow, suffixMapper, windowController) :near {
def localReactor
var diskNavRcvr := diskNavStub
def recentPathVow := moreRecentVowFuncMaker new()
def recentFilesListVow := moreRecentVowFuncMaker new()
def listPanel := <swing:JList> new()
listPanel setCellRenderer(cellRenderer)
def listScroller := <swing:JScrollPane> new(listPanel)
def locationLabel := <swing:JLabel> new()
def refreshButton := uiKit newToolButton(<resource:com/skyhunter/eDesk/icons/refresh.gif>,
"Refresh", def act(){localReactor reload()})
def mainPanel := JPanel`$refreshButton $locationLabel.X
$listScroller.Y > `
def navPanelController
def listPaneListener{
to mouseClicked(theEvent) {
#traceln("into mouseClicked")
def clickLocation := <unsafe:java.awt.Point> new(theEvent getX(), theEvent getY())
def selectionIndex := listPanel locationToIndex(clickLocation)
if (!(listPanel isSelectedIndex(selectionIndex))) {
listPanel setSelectedIndex(selectionIndex)
}
if (theEvent getClickCount() > 1) {
def cell := listPanel getSelectedValue()
if (cell isDir()) {
traceln("double clicked on dir")
navPanelController openDir()
} else {
#dialogVowMaker new("DoubleClick TBD",
# "<html>Double click default open not yet available",
# null, ["OK"])
}
} else if (theEvent isPopupTrigger() ||
<unsafe:javax.swing.SwingUtilities> isRightMouseButton(theEvent)) {
traceln("into is popup")
windowController showFilePopup(navPanelController, theEvent getX(),
theEvent getY())
}
}
match _ {}
}
listPanel addMouseListener(listPaneListener)
def bind localReactor {
to reload() {
windowController setStatus("Refreshing Listing")
def currentPathVow := recentPathVow (diskNavRcvr <- getCurrentPath())
def dirsVow := recentFilesListVow (diskNavRcvr <- listCurrentSubdirectoriesAndFiles())
when (dirsVow, currentPathVow) -> done(dirsFilesTuple, currentPath) {
locationLabel setText(dirNameFromPath(currentPath))
listPanel setListData(composeCellArray(dirsFilesTuple))
windowController setStatus("Refresh done.")
} catch err {
#connectionWarning("Screen Refresh Failed\n" + err)
traceln("err in reload: " + err)
#windowController setStatus("Refresh failed")
}
}
}
def navReactors := [] asMap() diverge()
def listSelectionListener {
to valueChanged(event) {
def onlyOne := listPanel getSelectedValues() size() == 1
def selection := listPanel getSelectedValue()
def isDir := selection != null && selection isDir()
if (onlyOne && isDir) {
for each => stub in navReactors {
each selectedDir(navPanelController)
}
}
}
}
listPanel addListSelectionListener(listSelectionListener)
def dragDropKit := <import:com.skyhunter.e.awt.dnd.dragDropKit> (awt__uriGetter, traceln)
def getFileRcvrs() :any {navPanelController getSelectedFileRcvrs() }
dragDropKit setupLocalDragSource(listPanel , getFileRcvrs )
def clear() {
for each => stub in navReactors {each cleared(navPanelController)}
diskNavRcvr := diskNavStub
localReactor reload()
}
def lowerPaneReactor {
to openingDir(controller) {
traceln("opening dir reached in lower listener")
def nextNavRcvr := controller dupDiskNavRcvr()
for each => stub in navReactors {each lowerDirOpening(navPanelController)}
diskNavRcvr := nextNavRcvr
localReactor reload()
for each => stub in navReactors {each openedDir(navPanelController)}
}
to lowerDirOpening(controller) {
lowerPaneReactor openingDir(controller)
}
match [verb, args] {}
}
when (optLowerDirControllerVow) -> doneLower(lowerController) {
if (lowerController != null) {
lowerController <- addNavReactor(lowerPaneReactor)
}
} catch prob {traceln("disaster with lowerController: " + prob)}
def upperPaneReactor {
to goingUp(controller) {
for each => stub in navReactors {each goingUp(navPanelController)}
diskNavRcvr := controller dupDiskNavRcvr()
localReactor reload()
for each => stub in navReactors {each wentUp(navPanelController)}
}
to lowerDirOpening(controller) {}
to wentUp(controller) {}
to jumped(controller) {clear()}
to cleared(controller) {clear()}
to openingDir(controller) {clear()}
to openedDir(controller) {}
to selectedDir(controller) {
def newSelection := (controller getSelectedNames())[0]
diskNavRcvr := controller dupDiskNavRcvr()
diskNavRcvr <- changeToSubdirectory(newSelection)
localReactor reload()
for each => stub in navReactors {each jumped(navPanelController)}
}
to deletionsMade(controller) {
when (diskNavRcvr <- currentDirExists()) -> done(exists) {
if (!exists) {clear()}
} catch prob {traceln("deletionsmade prob: " + prob)}
}
match [verb, args] {traceln("Got verb in upperPaneReactor: " + verb)}
}
when (optHigherDirControllerVow) -> doneHigher(higherController) {
if (higherController != null) {
higherController <- addNavReactor(upperPaneReactor)
}
} catch prob {traceln("disaster with higherController: " + prob)}
def bind navPanelController {
to setDiskNavRcvr(newNavRcvr) {
diskNavRcvr := newNavRcvr
localReactor reload()
}
to getDiskNavRcvr() :any {diskNavRcvr }
to dupDiskNavRcvr() :any {
if (diskNavRcvr == null) {
null
} else {diskNavRcvr <- dupNavigator()}
}
to addNavReactor(reactor) {navReactors[reactor] := null}
to removeNavReactor(reactor) {navReactors removeKey(reactor)}
to goto(path) {
diskNavRcvr <-changeToDirectory(path)
localReactor reload()
for each => stub in navReactors {each jumped(navPanelController)}
}
to gotoHome() {
diskNavRcvr <- gotoHome()
localReactor reload()
for each => stub in navReactors {each jumped(navPanelController)}
}
to reload() {localReactor reload()}
to deletionsMade() {
localReactor reload()
for each => stub in navReactors {each deletionsMade(navPanelController)}
}
to getCellRenderer() :near {cellRenderer}
to getMainPanel() :near {mainPanel}
to getListPanel() :near {listPanel}
to goUp() {
for each => stub in navReactors { each goingUp(navPanelController)}
diskNavRcvr <- goUp()
localReactor reload()
for each => stub in navReactors { each wentUp(navPanelController)}
}
to openDir() {
traceln("into open dir")
def newDirName := (navPanelController getSelectedNames() )[0]
traceln("newDir: " + newDirName)
for each => stub in navReactors { each openingDir(navPanelController)}
traceln("told reactors opening")
diskNavRcvr <- changeToSubdirectory(newDirName)
#listPanel clearSelection()
traceln("about to change dir: " + diskNavRcvr)
localReactor reload()
traceln("about to tell reactors opened")
for each => stub in navReactors { each openedDir(navPanelController)}
}
to getSelectedNames() :pbc {
def names := [] diverge()
def cells := listPanel getSelectedValues()
for each in cells {
names push(each getLabel() getText())
}
names snapshot()
}
to getSelectedFileRcvrs() :pbc {
def fileRcvrs := [] diverge()
for each in navPanelController getSelectedNames() {
fileRcvrs push(diskNavRcvr <- getFileNamed(each))
}
fileRcvrs snapshot()
}
}
}
}
1.1 e/src/esrc/com/skyhunter/eDesk/serverDescVowAuthor.emaker
Index: serverDescVowAuthor.emaker
===================================================================
#!/usr/local/bin/e
//License Agreement:
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
// http://www.skyhunter.com/marcs/securit-Edesk-license.html
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights and
// limitations under the License.
//The Original Code is The Securit-Edesk Configurator Program.
//The Initial Developer of the Original Code is Marc Stiegler. Portions created by
// Marc Stiegler are Copyright (C) Marc Stiegler. All Rights Reserved.
//**********
def serverDescVowAuthor(unsafe__uriGetter, awt__uriGetter, swing__uriGetter, frameMaker, traceln) :any {
def JPanel__quasiParser := <import:org.erights.ex.swing.JPanelQParserMaker> new(awt__uriGetter, swing__uriGetter)
def promiseAllResolved := <import:com.skyhunter.e.net.promiseAllResolved>
#def uriTools := <import:com.skyhunter.e.net.uriToolsAuthor>(introducer,
# sturdyRef)
def uiSet := <import:com.skyhunter.ex.swing.uiKitAuthor>(awt__uriGetter,
swing__uriGetter)
def dialogVowMaker := <import:com.skyhunter.ex.swing.dialogVowMakerAuthor>(
awt__uriGetter,
swing__uriGetter,
JPanel__quasiParser,
frameMaker)
#integer string converter
def toInt(numString) :near {(<unsafe:java.lang.Integer> new(numString)) intValue()}
#****** Configurator Specific Code ***********
def mainFrame := frameMaker new()
def [configVow, configSolver] := PromiseMaker()
def configReady
def windowTitleField := <swing:JTextField> new("My eDesk Server")
def rootPathField := <swing:JTextField> new()
def homePathField := <swing:JTextField> new("c:\\windows\\desktop")
def capFileField := <swing:JTextField> new("edeskServer.eds")
def serverOnlyBox := <swing:JCheckBox> new()
serverOnlyBox setText("Server Only")
serverOnlyBox setSelected(false)
def isReadOnlyBox := <swing:JCheckBox> new()
isReadOnlyBox setText("Read Only")
isReadOnlyBox setSelected(true)
def okButton := uiSet newButton("OK",configReady)
def l(text) :near {<swing:JLabel> new(text)}
def formPane :=
JPanel`${l("Browser-Window Title")} $windowTitleField.X
${l("Home Path")} $homePathField.X
$serverOnlyBox >
${l(" Write Capability To")} $capFileField.X
${l(" ")} >
${l(" Security Configuration")} >
$isReadOnlyBox >
${l("Top Accessible Directory")} $rootPathField.X
$okButton > `
traceln("config form about to make window")
#create form window
def mainPane := mainFrame getContentPane()
mainFrame setDefaultCloseOperation(<swing:WindowConstants> DISPOSE_ON_CLOSE())
mainPane add(formPane)
mainFrame setTitle("Configure Edesk")
mainFrame pack()
#mainFrame setSize(400,200)
mainFrame show()
def bind configReady() {
#traceln("made it")
configSolver resolve (`
<serverDesc>
<windowTitle>${windowTitleField getText()}</windowTitle>
<home>${homePathField getText()}</home>
<serverOnly>${if (serverOnlyBox isSelected()) { "true"} else {"false"}}</serverOnly>
<capabilityFile>${capFileField getText()}</capabilityFile>
<isReadOnly>${if (isReadOnlyBox isSelected()) {"true"} else {"false"}}<isReadOnly>
<virtualRoot>${rootPathField getText()}</virtualRoot>
</serverDesc>
`)
mainFrame dispose()
}
configVow
}
1.1 e/src/esrc/com/skyhunter/eDesk/testConfigurator.updoc
Index: testConfigurator.updoc
===================================================================
? def frameMaker := <swing:JFrame>
# value: <unsafe:javax.swing.JFrame>
? def traceln := println
# value: <println>
?
? def configurator := <import:com.skyhunter.eDesk.serverDescVowAuthor> (unsafe__uriGetter, awt__uriGetter,
> swing__uriGetter, frameMaker, traceln)
config form about to make window
# value: <Eventual ref>
? when (configurator) -> done(serverDesc) {
> println("server desc: ")
> println(serverDesc)
> } catch prob {println("prob with desc: " + prob)}
# value: <Eventual ref>
?
server desc:
<serverDesc>
<windowTitle>My eDesk Server</windowTitle>
<home>c:\windows\desktop</home>
<serverOnly>false</serverOnly>
<capabilityFile>edeskServer.eds</capabilityFile>
<isReadOnly>true<isReadOnly>
<virtualRoot></virtualRoot>
</serverDesc>
?
server desc:
<serverDesc>
<windowTitle>My eDesk Server</windowTitle>
<home>c:\windows\desktop</home>
<serverOnly>false</serverOnly>
<capabilityFile>edeskServer.eds</capabilityFile>
<isReadOnly>true<isReadOnly>
<virtualRoot></virtualRoot>
</serverDesc>
?
1.1 e/src/esrc/com/skyhunter/eDesk/testNavPanel.e
Index: testNavPanel.e
===================================================================
def testNavigator {
to listCurrentSubdirectoriesAndFiles() :pbc {[["dir1", "dir2"],["file1","f2"]]}
to getCurrentPath() :pbc {"path1/path2"}
}
# value: <testNavigator>
def traceln := println
def frame := <swing:JFrame> new("test nav panel")
def navMaker := <import:com.skyhunter.eDesk.navPanelControllerMakerAuthor> (
unsafe__uriGetter, awt__uriGetter, swing__uriGetter, println)
# value: <navPanelControllerMaker>
def winController {match [verb, args] {traceln("winController requested to: " + verb)}}
def navPanel := navMaker new(null, null, null, winController)
# value: <navPanelController>
navPanel setDiskNavRcvr(testNavigator)
frame setContentPane(navPanel getMainPanel())
frame show()
1.1 e/src/esrc/com/skyhunter/eDesk/testNavPanel.updoc
Index: testNavPanel.updoc
===================================================================
? def testNavigator {
> to listCurrentSubdirectoriesAndFiles() :pbc {[["dir1", "dir2"],["file1","f2"]]}
> to getCurrentPath() :pbc {"path1/path2"}
> }
# value: <testNavigator>
? def frame := <swing:JFrame> new("test nav panel")
# value: javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,resizable,title=test nav panel,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=1538,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
? def navMaker := <import:com.skyhunter.eDesk.navPanelControllerMakerAuthor> (
> unsafe__uriGetter, awt__uriGetter, swing__uriGetter, println)
# value: <navPanelControllerMaker>
? def navPanel := navMaker new(null, null, null)
# value: <navPanelController>
? navPanel setDiskNavRcvr(testNavigator)
about to reloadPane<testNavigator>
? frame setContentPane(navPanel getMainPanel())
? frame show()
?
1.1 e/src/esrc/com/skyhunter/eDesk/icons/folder.gif
Index: folder.gif
===================================================================
GIF89a
0j1S HJ*ëX
1.1 e/src/esrc/scripts/eDesk.e
Index: eDesk.e
===================================================================
//License Agreement:
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
// http://www.skyhunter.com/marcs/securit-Edesk-license.html
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights and
// limitations under the License.
//The Original Code is The Securit-Edesk Program.
//The Initial Developer of the Original Code is Marc Stiegler. Portions created by
// Marc Stiegler are Copyright (C) Marc Stiegler. All Rights Reserved.
//**********
# set up tracing; stub out all the printing for operational version
def traceln(str) { println(str) }
traceln("started")
def versionNumber := "0.7"
def io__uriGetter := <unsafe:java.io.*>
def ser__uriGetter := <unsafe:org.erights.e.elib.serial.*>
def SerializerMaker := <ser:Serializer>
def UnserializerMaker := <ser:Unserializer>
def byte := <unsafe:java.lang.Byte> TYPE()
def makeErr(text) :near {<unsafe:java.lang.Exception> new(text)}
class frameMakerMaker(iconURL) :near {
def image := <swing:ImageIcon> new(iconURL) getImage()
def frameMaker {
to new(title) :near {
def frame := <swing:JFrame> new(title)
frame setIconImage(image)
frame
}
to new() :near {
frameMaker new("")
}
}
}
traceln("compiled maker maker")
def eFrameMaker := frameMakerMaker new(
<resource:org/erights/e/icons/green-e-on-white-16.gif>)
def strangerFrameMaker := frameMakerMaker new(
<resource:com/skyhunter/eDesk/icons/stranger.gif>)
def superFrameMaker := frameMakerMaker new(
<resource:com/skyhunter/eDesk/icons/super.gif>)
traceln("got frame makers")
def promiseAllResolved := <import:com.skyhunter.e.net.promiseAllResolved>
def uriTools := <import:com.skyhunter.e.net.uriToolsAuthor>(introducer,
sturdyRef)
def uiTools := <import:com.skyhunter.ex.swing.uiToolsAuthor>(awt__uriGetter,
swing__uriGetter)
def dialogVowMaker := <import:com.skyhunter.ex.swing.dialogVowMakerAuthor>(
awt__uriGetter,
swing__uriGetter,
JPanel__quasiParser,
superFrameMaker)
def sendValveMaker := <import:com.skyhunter.e.net.sendValveMaker>
def standardWindow := <import:com.skyhunter.ex.swing.standardWindowMakerAuthor>(interp, superFrameMaker)
traceln("got standardWindow")
def progressWindowMaker := <import:com.skyhunter.eDesk.progressWindowMakerAuthor>(
swing__uriGetter, standardWindow)
class vowsMonitorMaker(): any {
def [bundlePromise,resolver] := PromiseMaker()
def bundle := [] diverge()
def vowsMonitor {
to add (thePromise) {bundle push(thePromise)}
to finishAll() {resolver resolve(promiseAllResolved(bundle))}
to promiseFinish() : any {bundlePromise}
}
}
traceln("about to def installer")
def installer := <import:com.skyhunter.installer.persistentInstallerAuthor> run(
unsafe__uriGetter,
file__uriGetter,
interp,
introducer,
interp getProps(),
traceln,
stdout)
traceln("about to build appsManager")
def edeskHomePath := "~/eDeskPrivate/"
//XXX use these dir and file text strings from resources ubiquitously
def appsDirPath := edeskHomePath +
<resource:com/skyhunter/eDesk/strings/installedAppsDir.txt> getText() trim()
traceln("appsDirPath: " + appsDirPath)
def appsDir := <file: appsDirPath>
if (!(appsDir exists())) {appsDir mkdirs()}
def appsDescPath := appsDirPath + <resource:com/skyhunter/eDesk/strings/appsDescFile.txt> getText() trim()
traceln("appsDescPath: " + appsDescPath)
def appsDescFile := <file: appsDescPath>
if (!(appsDescFile exists())) {appsDescFile setText("<installed></installed>" )}
def installedAppsManager := <import:com.skyhunter.eDesk.installedAppsManagerMaker> new(
appsDescFile, traceln )
traceln("did appsManager: " + installedAppsManager)
def connectionWarning(description) {
dialogVowMaker new("Connection apparently lost",
`<html><b>Lost Connection</b><p><pre>$description</pre>`,
null, ["OK"])
}
class forwarderMaker(target) : any {
def forwarder {
match [verb,args] {E send(target,verb,args)}
}
}
def makeWriteFile {
to run(fileName) : any {<file: fileName>}
to label() : any {""}
}
def makeReadFile {
to run(fileName) : any { (<file: fileName>) transReadOnly()}
to label(): any {"(Read Only)"}
}
def fileHash(file, numBytesToHash) : any {
def MDMaker := <unsafe:java.security.MessageDigest>
var blockSize := 100000
var hashedBytes := 0
def openFile(file) : any {
E call(<io:FileInputStream>, "new(File)", [file])
}
def sha := MDMaker getInstance("SHA")
def inStream := openFile(file)
var result := []
if (numBytesToHash <= file length()) {
while (hashedBytes < numBytesToHash) {
if (numBytesToHash - hashedBytes < blockSize) {blockSize := numBytesToHash - hashedBytes}
def buf := byte[blockSize]
def count := inStream read(buf)
sha update(buf, 0, count)
hashedBytes := hashedBytes + blockSize
}
result := sha digest()
}
inStream close()
traceln("hashed: " + result)
result
}
class readOnlyToFileCopierMaker(myFile) : any {
def fileCopier {
to copyEventually(a,farProgressObserver,c,d) : any {
farProgressObserver <- copyFailed()
def [dead,resolver] := PromiseMaker()
resolver smash(makeErr("readOnlyFile"))
dead
}
match _ { }
}
}
class writeableToFileCopierMaker(myFile) : any {
var myOutputStream := null
var myTempFile := null
var myRemoteProgressObserver := null
def [copyPromise,resolver] := PromiseMaker()
def fileCopier {
to copyEventually(farFile, farProgressObserver,
farLastResortForwarderToSelf, farLastResortForwarderToFarFile) : any {
traceln("into copy eventually" + farProgressObserver)
myTempFile := <file: ((myFile getAbsolutePath()) + ".tmp")>
traceln("did temp file creation")
def sendBytesRequest(fromCopier,toCopier) : any {
var fileVow := null
if (myTempFile exists()) {
traceln("temp file exists")
def hash := fileHash(myTempFile, myTempFile length())
fileVow := fromCopier <- sendToPartialFile(toCopier, myTempFile length(), hash)
} else if (myFile exists()) {
traceln("about to hash in file copier")
def hash := fileHash(myFile, myFile length())
fileVow := fromCopier <- sendToExistingFile(toCopier, myFile length(), hash)
} else {
fileVow := fromCopier <- sendByteBlocks(toCopier)
}
fileVow
}
def fp := sendBytesRequest(farFile, fileCopier)
traceln("fp: " + fp)
when (fp) -> done(connection) {
Ref whenBroken(farFile, def breaker(err){
resolver smash(makeErr ("lost file copy connection: " + err))
farProgressObserver copyFailed()
})
} catch err {
sendBytesRequest (farLastResortForwarderToFarFile, farLastResortForwarderToSelf)
traceln("using forwarders to copy file")
Ref whenBroken(farLastResortForwarderToFarFile, def breaker(p2) {
resolver smash(makeErr ("lost forwarded file copy connection" + p2))
farProgressObserver copyFailed()
})
}
myRemoteProgressObserver := farProgressObserver
copyPromise
}
to amountBeingSent(amount) {myRemoteProgressObserver <-setFileSize(amount)}
to receiveByteBlock(count,bytes) {
if (myOutputStream == null) {
myOutputStream := E call(<io:FileOutputStream>, "new(String)", [(myTempFile getAbsolutePath())])
traceln("receiveBytes made stream")
}
traceln("receiving bytes")
myOutputStream write(bytes,0,count)
try {myOutputStream flush()} catch e{}
myRemoteProgressObserver <- updateCount(count)
}
to existingFileIsFine() {
myRemoteProgressObserver <- completed()
resolver resolve(true)
}
to partialFileIsFine() {
traceln("in partialIsFine")
myOutputStream := E call(<io:RandomAccessFile>, "new(File, String)",[myTempFile,"rw"])
myOutputStream skipBytes(myTempFile length())
traceln("should have skipped by now")
}
to allBytesSent() {
#if output stream does not exist, file transferred was 0 length
if (myOutputStream != null) {
myOutputStream close()
} else if (!(myTempFile exists())) {myTempFile setText("")}
if (myFile exists()) {myFile delete()}
myTempFile renameTo(myFile)
myRemoteProgressObserver <- completed()
resolver resolve(true)
}
}
}
traceln ("about to compile toFileCopierMaker")
var toFileCopierMaker := writeableToFileCopierMaker
class fromFileCopierMaker (myFile) : any {
def fileCopier {
to sendByteBlocks(farRecipient, startIndex) {
traceln("send bytes recipient:" + farRecipient)
farRecipient <- amountBeingSent(myFile length() - startIndex)
def inStream := E call(<io:FileInputStream>, "new(String)", [(myFile getAbsolutePath())])
inStream skip (startIndex)
var blockSize := 50000
var bytes := byte[blockSize]
def sendRemainingBlocks() {
def bytesAvailable := inStream available()
if (bytesAvailable > 0) {
if (bytesAvailable < blockSize) {
blockSize := bytesAvailable
bytes := byte[blockSize]
}
//def bytes := byte[blockSize]
def count := inStream read(bytes)
traceln("about to send receiveByteBlock for" + (myFile getAbsolutePath()))
def sentPromise := farRecipient <- receiveByteBlock(count,bytes)
when (sentPromise) -> done(sent) {
sendRemainingBlocks()
} catch err {traceln("lost connection transferrring file: " + err)}
} else {
inStream close()
farRecipient <- allBytesSent()
}
}
sendRemainingBlocks ()
}
to sendByteBlocks(farRecipient) {fileCopier sendByteBlocks(farRecipient, 0)}
to sendToExistingFile(farRecipient, farSize, farHash) {
if (myFile length() == farSize && fileHash(myFile, myFile length()) == farHash ) {
traceln("copy file is duplicate")
farRecipient <- existingFileIsFine()
} else {
traceln("copy file is not duplicate")
fileCopier sendByteBlocks(farRecipient)
}
}
to sendToPartialFile(farRecipient, farSize, farHash) {
if (myFile length() >= farSize && fileHash(myFile, farSize) == farHash ) {
traceln("partial file is good:" + farSize + "my size" +myFile length())
farRecipient <- partialFileIsFine()
fileCopier sendByteBlocks(farRecipient, farSize)
} else {
traceln("partial file is not duplicate")
fileCopier sendByteBlocks(farRecipient)
}
}
}
}
//FileModel
class fileModelMaker(myFile) :any {
def fileModel {
to getFromCopier() : any {fromFileCopierMaker new(myFile) }
to getToCopier() : any {toFileCopierMaker new(myFile)}
delegate {myFile}
}
}
class fileProgressObserverMaker(title, farFile) : any {
def myWindow := progressWindowMaker new(title)
var bytesSent := 0
def localFailed() {myWindow closeWindow()}
Ref whenBroken(farFile, def breaker(p) {
localFailed()
})
def fileProgressObserver {
to completed() {
traceln("completed file transfer!")
myWindow closeWindow()
}
to setFileSize(theSize) {myWindow setFileSize(theSize)}
to updateCount(countIncrement) {
bytesSent := bytesSent + countIncrement
myWindow setProgress(bytesSent)
}
to copyFailed() {
localFailed()
}
}
}
def fileProgressObserverStub {
match _ {}
}
def quickEditMaker := <import:com.skyhunter.eDesk.quickEditMakerAuthor>(traceln, awt__uriGetter,
swing__uriGetter, connectionWarning,
standardWindow, dialogVowMaker )
traceln("about to compile navigatorWindowMaker")
//NavigatorWindow
class navigatorWindowMaker(myFtController, myDiskNavigator) : any {
def navigatorWindow
def myStorageName := myDiskNavigator <- getStorageName()
def navFrame := standardWindow("", navigatorWindow)
when (myStorageName) -> done(name) {
navFrame setTitle(name)
} catch err{}
def mainPane := navFrame getContentPane()
#make the menus
def menuReactor {
to doNewWindow(){navigatorWindow dupWindow() }
to doOpenRemote() {navigatorWindow openRemote() }
to doAbouteDesk() {
def html := <resource:com/skyhunter/eDesk/strings/about.txt> getText()
dialogVowMaker new("About eDesk", html, null, ["OK"])
}
to doQuickHelp() {
def html := <resource:com/skyhunter/eDesk/strings/help.txt> getText()
dialogVowMaker new("Quick Help", html, null, ["OK"])
}
match [verb,args] {traceln("menu hit for " + verb)}
}
def mm := <import:com.skyhunter.ex.swing.menuMakerAuthor> (
swing__uriGetter,
<unsafe:org.erights.e.ui.jed.EAction>,
menuReactor)
def menuBar := mm menuBar([
mm menu("&Windows", [
mm action("&New Window", "Ctrl+N"),
mm action("Open Remote...", "Ctrl+O")
]),
mm menu("&Help", [
mm action("&Quick Help"),
"--"
mm action("&About eDesk")
])
])
navFrame setJMenuBar(menuBar)
def statusPanel := <swing:JLabel> new()
def setStatus(status) {statusPanel setText(status)}
def navPanelServer
def navPanelControllerMaker := <import:com.skyhunter.eDesk.navPanelControllerMakerAuthor> (
unsafe__uriGetter, awt__uriGetter, swing__uriGetter, println)
def navPanelController1
def navPanelController2
def navPanelController3
def bind navPanelController1 := navPanelControllerMaker new(null, navPanelController2, installedAppsManager , navPanelServer )
def bind navPanelController2 := navPanelControllerMaker new(navPanelController1, navPanelController3, installedAppsManager , navPanelServer )
def bind navPanelController3 := navPanelControllerMaker new(navPanelController2, null, installedAppsManager, navPanelServer )
class navWinActionMaker(actionName) :near {
def action() {E call(navigatorWindow, actionName, [])}
}
def gotoButton := uiTools newToolButton(
<resource:com/skyhunter/eDesk/icons/goto.gif>,
"Goto", navWinActionMaker new("gotoFieldName"))
def upButton := uiTools newToolButton(
<resource:com/skyhunter/eDesk/icons/up.gif>,
"Up", navWinActionMaker new("goUp"))
def homeButton := uiTools newToolButton(
<resource:com/skyhunter/eDesk/icons/home.gif>,
"Home", navWinActionMaker new("goHome"))
def fullPathTextField := <swing:JTextField> new()
def enterKeyListener{
to keyPressed(theEvent) {
if (theEvent getKeyCode() == <unsafe:java.awt.event.KeyEvent> VK_ENTER()) {
navigatorWindow gotoFieldName()
}
}
match _ {}
}
fullPathTextField addKeyListener(enterKeyListener)
def refreshLocal() {
navPanelController1 reload()
navPanelController2 reload()
navPanelController3 reload()
traceln("BAD: RefreshLocal!")
}
def newFile(navPanelController) {
def newName := <swing:JOptionPane> showInputDialog(navFrame, "Name for New File: ", "New File", <swing:JOptionPane> QUESTION_MESSAGE())
if (newName != null && newName size() >0) {
navPanelController getDiskNavRcvr() <- newFile(newName)
}
navPanelController reload()
}
def newDir(navPanelController) {
def newName := <swing:JOptionPane> showInputDialog(navFrame, "Name for New Folder: ", "New Folder", <swing:JOptionPane> QUESTION_MESSAGE())
traceln("Dir Name: " + newName)
if (newName != null && newName size() >0) {
navPanelController getDiskNavRcvr() <- makeDir(newName)
}
navPanelController reload()
}
def openDir(navPanelController) {
navPanelController openDir()
}
def openEDesk(navPanelController) {
def fileNames := navPanelController getSelectedNames()
def navRcvr := navPanelController dupDiskNavRcvr()
if (fileNames != null && fileNames size() >0) {
for each in fileNames {
myFtController openEdesk(navRcvr <- getFileNamed(each))
}
}
}
def propertiesList(navPanelController) {
def fileRcvrList := navPanelController getSelectedFileRcvrs()
if (fileRcvrList != null) {
setStatus("Showing files properties")
for each in fileRcvrList {
traceln("a file properties")
def path := each <- getPath()
def canonical := each <- getCanonicalPath()
def fileSize := each <- length()
def lastModified := each <- lastModified()
traceln("requested properties")
when (path, canonical, fileSize,lastModified) -> done(p,c,f,l) {
traceln("all resolved")
def modDate := E call(<unsafe:java.util.Date>, "new(long)",[lastModified])
def display :=
`<html><table><tr>
<td><b>Full Path:</b></td><td>$path</td>
</tr><tr>
<td><b>Canonical Path:</b></td><td>$canonical</td>
</tr><tr>
<td><b>Size:</b></td><td>$fileSize</td>
</tr><tr>
<td><b>Last Modified:</b></td><td>$modDate</td>
</tr></table></html>`
dialogVowMaker new("Properties For " + each, display, null, ["OK"])
setStatus("")
} catch e { connectionWarning(e)}
}
}
}
def renameList(navPanelController) {
def theList := navPanelController getSelectedNames()
def diskNavRcvr := navPanelController dupDiskNavRcvr()
setStatus("Renaming files")
for each in theList {
def newName := <swing:JOptionPane> showInputDialog (null, "New Name for: " + each , "Rename" , <swing:JOptionPane> QUESTION_MESSAGE(), null, null, each)
if (newName != null && newName size() >0) {
diskNavRcvr <- rename(each, newName)
}
}
navPanelController reload()
}
def deleteList(navPanelController){
def theList := navPanelController getSelectedNames()
def navRcvr := navPanelController dupDiskNavRcvr()
def deletionVows := [] diverge()
setStatus("Deleting files")
for each in theList {
deletionVows push(navRcvr <- deleteFileObject(each))
}
when (promiseAllResolved(deletionVows)) -> done(deletions) {
navPanelController <- deletionsMade()
} catch prob {traceln("deletions incomplete: " + prob)}
}
def copyList(navPanelController) {
def fileRcvrs := navPanelController getSelectedFileRcvrs()
def localNavigator := navPanelController dupDiskNavRcvr()
myFtController copyFrom (fileRcvrs, localNavigator)
}
def pasteFromPanel(navPanelController) {
setStatus("Paste/Copying files")
myFtController paste(navPanelController dupDiskNavRcvr(), navigatorWindow)
}
def installCaplet(navPanelController) {
def sourceFileVow := (navPanelController getSelectedFileRcvrs())[0]
when (sourceFileVow) -> done(sourceFile) {
installer install(sourceFile, installedAppsManager )
} catch prob {traceln("prob in install catch" + prob)}
}
def runCaplet{
to run(navPanelController) {
def sourceFileVow := (navPanelController getSelectedFileRcvrs())[0]
when (sourceFileVow) -> done(sourceFile) {
runCaplet(sourceFile,[])
} catch prob {traceln("sourcefile prob in runcaplet: " + prob)}
}
to run(sourceFile, docRcvrs) {
def powerboxControllerMaker := <import:com.skyhunter.e.security.powerboxControllerMakerAuthor> run(
unsafe__uriGetter, file__uriGetter, interp, traceln, stdout)
traceln("made powerboxMaker")
def appDesc := installedAppsManager getAppBySourcePath(sourceFile getCanonicalPath())
traceln("got appDesc: " + appDesc)
def findImage() :near {
var image := null
if (appDesc maps("Icon")) {
def path := appDesc["Icon"]
traceln("appDesc maps Icon: " + path )
var iconfile := (sourceFile getParentFile())[path]
if (!(iconfile exists())) {
iconfile := <file: appDesc["Icon"]>
}
if (iconfile exists()) {
image := <swing:ImageIcon> new(iconfile getCanonicalPath()) getImage()
}
}
traceln("returning image: " + image)
image
}
def powerboxController := powerboxControllerMaker new(
appDesc get("Name", sourceFile getCanonicalPath()),
findImage(), <file: appDesc["RunPath"]> getText())
def box := powerboxController getPowerbox()
powerboxController setCap(box DOC_SUFFIX(), appDesc get("Suffix", null))
powerboxController setCap(box INITIAL_DOC_RCVRS(), docRcvrs)
traceln("about to launch file")
powerboxController launchFile(sourceFile)
traceln("launch initiated")
}
}
def bind navPanelServer {
to setStatus(text) {setStatus(text)}
to showFilePopup(navPanelController, showX, showY) {
def myNavigatorRcvr := navPanelController dupDiskNavRcvr()
def selectedFileNames := navPanelController getSelectedNames()
def selectedCells := navPanelController getListPanel() getSelectedValues()
traceln("got selected names: " + selectedFileNames)
def appReactor {
match[verb, args] {
def docRcvrs := [] diverge()
def appMap := installedAppsManager optAppByPetName(verb)
def sourceFile := <file: appMap["SourcePath"]>
for each in selectedFileNames {
docRcvrs push(myNavigatorRcvr <- getFileNamed(each))
}
runCaplet(sourceFile, docRcvrs)
}
}
class appActionMaker(appPetName) :near {
def action(){E call(appReactor, appPetName,[])}
}
def appsMenu := <swing:JMenu> new("Open With")
for each in installedAppsManager getAppPetNames() {
uiTools addMenuItem(appsMenu, each, appActionMaker new(each))
}
var suffix := ""
if (selectedFileNames size() > 0) {
def sections := selectedFileNames[0] split(".")
if (sections size() > 1) {suffix := sections[sections size() - 1]}
}
class actionMaker(func) :near {
def action(){E send(func, "run", [navPanelController])}
}
traceln("about to make popup frame")
def popup := <swing:JPopupMenu> new("File Ops")
def popWithUniversalChoices() {
traceln("into pop universal choices")
uiTools addMenuItem(popup,"Paste", actionMaker new(pasteFromPanel))
uiTools addMenuItem(popup,"New File", actionMaker new(newFile))
uiTools addMenuItem(popup,"New Folder", actionMaker new(newDir))
popup show(navPanelController getListPanel(), showX, showY)
}
def popWithDirChoices() {
uiTools addMenuItem(popup, "Open Folder", actionMaker new(openDir))
uiTools addMenuItem(popup,"Copy", actionMaker new(copyList))
uiTools addMenuItem(popup, "Delete", actionMaker new(deleteList))
uiTools addMenuItem(popup, "Rename", actionMaker new(renameList))
popWithUniversalChoices()
}
def popWithAllDocChoices() {
E call(popup, "add(JMenuItem)", [appsMenu])
uiTools addMenuItem(popup,"Copy", actionMaker new(copyList))
uiTools addMenuItem(popup, "Delete", actionMaker new(deleteList))
uiTools addMenuItem(popup, "Rename", actionMaker new(renameList))
uiTools addMenuItem(popup,"Properties", actionMaker new(propertiesList))
popWithUniversalChoices()
}
if (selectedFileNames size() > 0) {
if (selectedCells[0] isDir()) {
traceln("is dir")
popWithDirChoices()
} else if (suffix == "edesk-cap") {
uiTools addMenuItem(popup,"Open Edesk", actionMaker new(openEDesk))
popWithAllDocChoices()
} else if (suffix == "caplet") {
uiTools addMenuItem(popup,"Install", actionMaker new(installCaplet))
def pathVow := myNavigatorRcvr <- getFileNamed(selectedFileNames[0]) <- getCanonicalPath()
when (pathVow) -> done(path) {
if (installedAppsManager optAppBySourcePath(path) != null) {
uiTools addMenuItem(popup,"Run", actionMaker new(runCaplet))
}
popWithAllDocChoices()
} catch prob {traceln("popup caplet path prob: " + prob)}
} else {popWithAllDocChoices() }
} else {
popWithUniversalChoices()
}
}
}
def toolbarPane :=
JPanel`$upButton $homeButton $gotoButton $fullPathTextField.X `
def navPanelsPane := uiTools makeGridRow([navPanelController1 getMainPanel(), navPanelController2 getMainPanel(), navPanelController3 getMainPanel()])
def realPane := JPanel`$toolbarPane
$navPanelsPane.Y
$statusPanel`
mainPane add(realPane)
#refreshLocal()
navFrame pack()
navFrame show()
def resetPathField() {
when (navPanelController1 getDiskNavRcvr() <- getCurrentPath()) -> done(path) {
fullPathTextField setText(path)
} catch prob {traceln("prob getting path" + prob)}
}
def navReactorForPathField {
to wentUp(c) {resetPathField()}
to jumped(c) {resetPathField()}
to openedDir(c) {resetPathField()}
match [verb, args] {}
}
navPanelController1 addNavReactor(navReactorForPathField)
navPanelController1 setDiskNavRcvr(myDiskNavigator)
resetPathField()
def bind navigatorWindow {
#to getDiskNavigator(): any {diskNav1()}
to dupWindow() {
navigatorWindowMaker new(myFtController, navPanelController1 <- dupDiskNavRcvr())
}
to gotoFieldName() {
navPanelController1 goto(fullPathTextField getText())
}
to getStorageName(): any {myStorageName}
to refresh() {refreshLocal()}
to windowClosing() {navFrame dispose()}
to goUp() {
#myDiskNavigator <- goUp()
#navigatorWindow refresh()
navPanelController1 goUp()
}
to goHome() {
#myDiskNavigator <- gotoHome()
#navigatorWindow refresh()
navPanelController1 gotoHome()
}
to openRemote() {myFtController openRemote()}
to openEdesk() {
def fileNames := navPanelController1 getSelectedNames()
if (fileNames != null && fileNames size() >0) {
for each in fileNames {
myFtController openEdesk(myDiskNavigator <- getFileNamed(each))
}
}
}
}
}
//DiskNavigator
class diskNavigatorMaker (var myHomeDirectoryPath, myStorageName, var myRootDirPath, makeFileFunction) : any {
#traceln("into making disk navigator")
var myCurrentDir := makeFileFunction(myHomeDirectoryPath)
//file: myHomeDirectoryPath
def dirPathString (path) : any {
//makes sure a dir separator is at end
def sep := <io:File> separator()
var answerPath := path
def lastCharString := path(path size() - 1, path size() )
if (lastCharString == sep || lastCharString == "/") {
answerPath := path
} else {
answerPath := path + sep
}
answerPath
}
def dirPath (theDir) : any { dirPathString(theDir getPath())}
def isInRootTree(theDir) : any {
var answer := true
if (myRootDirPath != null) {
answer := dirPathString(theDir getCanonicalPath()) startsWith(myRootDirPath)
}
answer
}
def setCurrentDir(theDir) {
if (theDir exists() && isInRootTree(theDir)) {myCurrentDir := theDir}
}
if (myRootDirPath != null) {
myRootDirPath := dirPathString((makeFileFunction(myRootDirPath)) getCanonicalPath())
if (isInRootTree(myCurrentDir)) {
traceln("home is part of the root tree")
} else {
println("Home path not part of root tree! Changing")
myCurrentDir := makeFileFunction( myRootDirPath)
myHomeDirectoryPath := myRootDirPath
}
}
#traceln("making navigator")
def diskNavigator {
//offers MakeAnotherNavigator(homeDirname) returns the navigator uri
to dupNavigator(): any {
traceln("into dupnavigator")
def newNav := diskNavigatorMaker new(myHomeDirectoryPath, myStorageName, myRootDirPath, makeFileFunction)
newNav changeToDirectory (myCurrentDir getAbsolutePath())
newNav
}
to getStorageName(): any {myStorageName + makeFileFunction label()}
to versionNumber(): any {versionNumber}
to currentDirExists() :boolean {myCurrentDir exists()}
to getCurrentPath (): any {
if (! (myCurrentDir exists())) {diskNavigator gotoHome()}
myCurrentDir getAbsolutePath()
}
to getParentPath(): any {myCurrentDir getParent()}
to newFile(name) {
def theFile := makeFileFunction( (dirPath(myCurrentDir) + name))
if (! (theFile exists())) {
theFile setText("")
}
}
to makeDir(dirName) {
def fullName := dirPath(myCurrentDir) + dirName
(makeFileFunction( fullName)) mkdir()
}
to gotoHome() {
myCurrentDir := makeFileFunction( myHomeDirectoryPath)
}
to changeToDirectory(fullPathName) {
#traceln("change to directory: " + fullPathName)
setCurrentDir(makeFileFunction( fullPathName))
}
to changeToSubdirectory(name) {
setCurrentDir(makeFileFunction( (dirPath(myCurrentDir) + name)))
traceln("diskNav changed to subdir: " +dirPath(myCurrentDir))
}
to goUp() {setCurrentDir(makeFileFunction( (myCurrentDir getParent())))}
to listCurrentSubdirectoriesAndFiles(): any {
if (! (myCurrentDir exists())) {diskNavigator gotoHome()}
def fileobjNames := myCurrentDir list()
def dirTuple := [] diverge()
def fileTuple := [] diverge()
#traceln("into list subs, count:" + fileobjNames size())
for next in fileobjNames {
if ((makeFileFunction( (dirPath(myCurrentDir) + next))) isDirectory()) {
dirTuple push(next)
} else {
fileTuple push(next)
}
}
[dirTuple sort() snapshot(), fileTuple sort() snapshot()]
}
to getFileNamed(name) : any {
fileModelMaker new(makeFileFunction( (dirPath(myCurrentDir) + name)))
}
to rename(fileName,newName) {
(makeFileFunction (dirPath(myCurrentDir) + fileName)) renameTo(makeFileFunction (dirPath(myCurrentDir) + newName))
}
to deleteFileObject(fileName) {
def fileObj := diskNavigator getFileNamed(fileName)
try {fileObj delete()} catch e1 {}
if (fileObj exists() && fileObj isDirectory()) {
traceln("found undeleted dir")
for each in fileObj {
if (each isFile()) {
try {each delete()} catch e2{traceln("no file delete" + e2)}
} else {
def subNavigator := diskNavigator dupNavigator()
traceln("got sub navigator for delete")
subNavigator changeToSubdirectory (fileName)
traceln("about to del dir "+ each getName())
subNavigator deleteFileObject(each getName())
}
}
try {fileObj delete()} catch e3 { traceln("delete folder try 2 failed" + e3)}
}
}
}
}
class revokableConnectionMaker (myFtController) : any {
def revokableConnection {
to getANavigator(): any {
myFtController getANavigator()
}
to versionNumber(): any {versionNumber}
}
}
// farOverwriteAnswerer uses state pattern
// with different functions for different behaviors
// it select the right function with lazy evaluation:
// if there's never a preexisting file to consider overwriting,
// no overwriting policy request ever goes to the user
class overwriteAnswererMaker (): any {
def alwaysOverwrite(fileName) : any {true}
def neverOverwrite(fileName) : any {false}
def askOverwrite(fileName) : any {
def [answerPromise, resolver] := PromiseMaker()
def answerDialog := dialogVowMaker new("Overwrite?", "Overwrite file " + fileName + "?", null, ["Yes","No"])
when (answerDialog) -> done(answer) {
resolver resolve (answerDialog getClickedButton() == "Yes")
} catch err {}
answerPromise
}
var answerFunctionSelectionAlreadyStarted := false
def [answerFunction,functionResolver] := PromiseMaker()
def determineOverwritePlan() {
answerFunctionSelectionAlreadyStarted := true
def planDialogPromise := dialogVowMaker new("OverwritePolicy", "When should files be overwritten?", null, ["Always","Never","After Confirmation"])
when (planDialogPromise) -> done(planDialog) {
def button := planDialog getClickedButton()
if (button == "Always") {
functionResolver resolve(alwaysOverwrite)
}else if (button == "Never") {
functionResolver resolve(neverOverwrite)
}else {functionResolver resolve(askOverwrite)}
} catch err {}
}
def overwriteAnswerer {
to promiseOverwriteAnswer(fileName) :any {
if (!answerFunctionSelectionAlreadyStarted) {determineOverwritePlan()}
answerFunction <- run(fileName)
}
}
overwriteAnswerer
}
traceln("about to compile copyAction")
def copyAction(farFromFile,farToFile,fileName ) : any {
def vow
def firstvow := farToFile <- getToCopier() <- copyEventually(farFromFile <- getFromCopier(),
fileProgressObserverMaker new("Copying " + fileName, farToFile),
forwarderMaker new(farToFile), forwarderMaker new(farFromFile))
when (firstvow) -> done(result) {
traceln("copyaction success: " + result)
def bind vow := result
} catch prob {
traceln("copyaction failure: " + prob + prob eStack())
traceln("now trying backup strategy")
def bind vow := farToFile <- getToCopier() <- copyEventually(forwarderMaker new(farFromFile),
fileProgressObserverMaker new("Copying " + fileName, farToFile),
forwarderMaker new(farToFile), forwarderMaker new(farFromFile))
}
when (vow) -> donevow(finished) {
traceln("vow resolved nicely")
} catch vowprob {traceln ("copyaction vow failed finally completely")}
vow
}
//Sequencer of file copies to limit the number of progress windows and the number
// of big fromFile copy buffers in existence at any one time
def copySequencer := sendValveMaker new(5)
def copyFiles(fromNavigator, toNavigator, overwriteAnswerer) : any {
traceln("into copyFiles" + fromNavigator+toNavigator + overwriteAnswerer)
def copyVows := vowsMonitorMaker new()
def copyBase(farFromFile, farToFile, fileName) {
copyVows add(copySequencer makeActionVow([copyAction, "run", [farFromFile, farToFile, fileName]]))
}
def filesDirsPromise := fromNavigator <- listCurrentSubdirectoriesAndFiles()
when (filesDirsPromise) -> done(filesDirs) {
def fileNames := filesDirs[1]
for each in fileNames {
def nextFromFile := fromNavigator <- getFileNamed(each)
def nextToFile := toNavigator <- getFileNamed(each)
when (nextToFile <- exists()) -> doneNext(doesExist) {
if ( doesExist) {
def shouldCopy := overwriteAnswerer promiseOverwriteAnswer(each)
when (shouldCopy) -> doneCopy(copyFulfilled) {
if (shouldCopy) {
copyBase(nextFromFile, nextToFile, each)
}
} catch err {}
} else {
copyBase(nextFromFile, nextToFile, each)
}
} catch err{}
}
copyVows finishAll()
} catch err {traceln("error not caught in old version getting filesDirs: " + err)}
copyVows promiseFinish()
}
class marshalledDirPromiser(farOuterNavigator, farDir) : any {
traceln("make marshall" + farOuterNavigator + farDir)
def [marshalledDirPromise, resolver] := PromiseMaker()
var farDirNavigator := null
var dirExists := farDir <- exists()
def dirName := farDir <- getName()
def dirCanonicalPath := farDir <- getCanonicalPath()
def dirPath := farDir <- getPath()
def fillWhenDirExists() {
farDirNavigator := farOuterNavigator <- dupNavigator()
farDirNavigator <- changeToSubdirectory (dirName)
dirExists := true
}
def marshalledDir := {
when (dirPath) -> done(dirPathR) {
if (dirExists) {fillWhenDirExists()}
resolver resolve(marshalledDir)
traceln("dir paths: " + dirCanonicalPath + " :" + dirPath)
} catch err {
resolver smash(makeErr ("dead dir: "+ err))
}
def marshalledDir {
to getDir() : any {farDir}
to getOuterNavigator() :any {farOuterNavigator}
to getDirNavigator() :any {farDirNavigator}
to exists() : any {dirExists}
to getName() : any {dirName}
to promiseMarshalledSubDir(subName) : any {
def farSubdir := farDirNavigator <- getFileNamed(subName)
marshalledDirPromiser new(farDirNavigator,farSubdir)
}
to makeSelf() : any {
var makePromise := null
if (!dirExists) {
makePromise := farDir <-mkdir()
fillWhenDirExists()
}
makePromise
}
to isProperSubDir() : any {dirCanonicalPath toLowerCase() == dirPath toLowerCase()}
to getCanonicalPath() :any {dirCanonicalPath}
to getPath() : any {dirPath}
}
}
marshalledDirPromise
}
traceln("got up to paster")
//paster
def paster {
to paste(farFromFiles, fromDiskNavigator, initialToDiskNavigator, toNavigatorWindow) {
traceln("into paster paste:" + farFromFiles + fromDiskNavigator + toNavigatorWindow)
def toDiskNavigator := initialToDiskNavigator <- dupNavigator()
def allDone := vowsMonitorMaker new()
def myOverwriter := overwriteAnswererMaker new()
for each in farFromFiles {
traceln("got each file" + each)
def isDir := each <- isDirectory()
def [nextCopyPromise, nextResolver] := PromiseMaker()
allDone add(nextCopyPromise)
when (isDir) -> done(isDirR) {
if (isDirR) {
def nextPromise := paster copyDirBegin(each,
fromDiskNavigator, toDiskNavigator, myOverwriter)
nextResolver resolve(nextPromise)
}else{
def nextPromise := paster pasteFile(each,
toDiskNavigator)
nextResolver resolve(nextPromise)
}
} catch err {}
}
allDone finishAll()
when (allDone promiseFinish()) -> done(p) {
traceln("about to refresh after pasting files")
toNavigatorWindow refresh()
} catch err {
toNavigatorWindow refresh()
connectionWarning("Some files may not have been copy/pasted.\n" + err)
}
}
to pasteFile(fromFilePromise, toDiskNavigator) : any {
traceln("into pasteFile")
def [finishPromise,resolver] := PromiseMaker()
def startCopyTo(target,fromName) {
traceln("about to copy in pastefile")
def finalPromise := copySequencer makeActionVow(
[copyAction, "run", [fromFilePromise, target, fromName]])
traceln("about to start resolver in pastefile")
when (finalPromise) -> done(p) {
traceln("about to resolve in pastefile: " + p)
resolver resolve(p)
} catch err{traceln("err in pasteFile finalpromise: " + err)}
}
def fromNamePromise := fromFilePromise <- getName()
when (fromNamePromise) -> done(fromName) {
traceln("paste is getting target " + fromName)
var target := toDiskNavigator <- getFileNamed(fromName)
traceln("paste target eventually requested")
when (target <- exists()) -> done2(fileExists) {
traceln("resolved target exists")
if (fileExists) {
traceln("file exists: " + fromName)
def result := <swing:JOptionPane> showInputDialog (null,
"Confirm or change name, or cancel",
"File " + fromName + " already exists",
<swing:JOptionPane> QUESTION_MESSAGE(), null, null, fromName + "")
if (result != null) {
if (result != fromName) {
target := toDiskNavigator <- getFileNamed(result)
}
startCopyTo(target,fromName)
} else {
resolver resolve("user canceled")
}
} else {
traceln("about to copyeventually")
startCopyTo(target,fromName)
}
} catch err2 {
traceln("err getting fileExists " + err2)
}
} catch err {connectionWarning(err)}
finishPromise
}
to copyDirCautiously(marshalledFromDir, marshalledToDir, createdDirPaths, overwriteAnswerer) : any {
traceln("in copyDirCautiously" + marshalledFromDir + " :" +marshalledToDir)
//only continue copying if the fromDir is not something we just
// created as a todir(indicating we are copying a dir into its own subdir)
//and if the fromdir is not a symlink running off to someplace odd)
traceln("is proper subdir " + (marshalledFromDir isProperSubDir()))
def copyVows := vowsMonitorMaker new()
if ((! (createdDirPaths contains(marshalledFromDir getCanonicalPath()))) && marshalledFromDir isProperSubDir()) {
traceln("continuing copying in cautiously")
if (! (marshalledToDir exists())) {
marshalledToDir makeSelf()
traceln("made dir")
createdDirPaths push(marshalledToDir getCanonicalPath())
}
copyVows add(copyFiles(marshalledFromDir getDirNavigator(), marshalledToDir getDirNavigator(),overwriteAnswerer))
def filesDirsPromise := marshalledFromDir getDirNavigator() <- listCurrentSubdirectoriesAndFiles()
when (filesDirsPromise) -> done(filesDirs) {
def dirs := filesDirs[0]
for each in dirs {
traceln("copying dir: " + each)
def [subDirPromise,subDirResolver] := PromiseMaker()
copyVows add(subDirPromise)
def fromSubNavigator := marshalledFromDir getDirNavigator()
def marshalledFromSubDir := marshalledDirPromiser new(fromSubNavigator, fromSubNavigator <- getFileNamed(each))
def toSubNavigator := marshalledToDir getDirNavigator()
def marshalledToSubDir := marshalledDirPromiser new(toSubNavigator, toSubNavigator <- getFileNamed(each))
def dirsReadyVow := promiseAllResolved([marshalledToSubDir, marshalledFromSubDir])
when (dirsReadyVow) -> done2(dirsReady) {
subDirResolver resolve(paster copyDirCautiously (marshalledFromSubDir, marshalledToSubDir, createdDirPaths, overwriteAnswerer))
} catch e {
connectionWarning(e)
subDirResolver smash(makeErr ("Couldn't connect to directory: " + e))
}
}
copyVows finishAll()
} catch err {}
} else {copyVows finishAll()}
copyVows promiseFinish()
}
to copyDirBegin(farFromDir, farFromDisk, toDiskNavigator, overwriteAnswerer) : any {
def farToDisk := toDiskNavigator <- dupNavigator()
def fromDir := marshalledDirPromiser new(farFromDisk,farFromDir)
def createdDirPaths := [] diverge()
def [dirCopyCompletePromise, dirCopyCompleteResolver] := PromiseMaker()
when (fromDir) -> done(fromDirR) {
def farToDir := farToDisk <- getFileNamed(fromDir getName())
def toDir := marshalledDirPromiser new(farToDisk, farToDir)
when (toDir) -> done2(toDirR) {
def copyPromise := paster copyDirCautiously (fromDir, toDir, createdDirPaths, overwriteAnswerer)
dirCopyCompleteResolver resolve(copyPromise)
}catch err2 {
dirCopyCompleteResolver smash(makeErr ("Lost connection: " +err2))
connectionWarning(err2)
}
} catch err {}
dirCopyCompletePromise
}
}
def makeDefaultConfigMap() :near {
def map := [] asKeys() diverge()
map["windowTitle"] := "My eDesk"
map["home"] := if (<file:~/Desktop> exists()) {"~/Desktop"} else {"~/"}
map["serverOnly"] := false
map["capabilityFile"] := null
map["makeFileFunction"] := makeWriteFile
map["virtualRoot"] := null
map
}
#assumes it is getting a default config, modifying from there
def setConfigFromCommandLine(configMap) {
def commandArgs := interp getArgs()
configMap["windowTitle"] := commandArgs[0]
configMap["serverOnly"] := commandArgs[1] != "gui"
configMap["home"] := commandArgs[2]
if (commandArgs size() > 3) {configMap["capabilityFile"] := commandArgs[3]}
if (commandArgs size() >4) {configMap["virtualRoot"] := commandArgs[4]}
if (commandArgs size() > 5 && commandArgs[5] != "write") {
traceln("Read Only File System")
configMap["makeFileFunction"] := makeReadFile
#diddling rather global variable
toFileCopierMaker := readOnlyToFileCopierMaker
}
}
traceln("about to compile setconfig from file")
#assumes it is getting a default config, modifying from there
def setConfigFromFile(configFile,configMap) {
if (configFile exists()) {
for each in configFile {
if (each =~ `@keyword=@value${"\n"}`) {
if (keyword == "isReadOnly" && value=="true") {
configMap["makeFileFunction"]:=makeReadFile
} else if (keyword == "serverOnly") {
configMap[keyword] := value == "true"
} else {configMap[keyword] := value }
}
}
}
}
traceln("about to compile ftControllerMaker")
//ftController
class ftControllerMaker(): any {
def ftController
var copyBuffer := null
var copyBufferDiskNavigator := null
var configMap := makeDefaultConfigMap()
def commandArgs := interp getArgs()
traceln("command arguments" + commandArgs)
if (commandArgs size() > 1) {setConfigFromCommandLine(configMap)}
if (commandArgs size() < 1) {setConfigFromFile(<file:edesk.conf>, configMap)}
if (commandArgs size() == 1) {setConfigFromFile(<file: commandArgs[0]>, configMap)}
def myHomeNavigator := diskNavigatorMaker new(configMap["home"],
configMap["windowTitle"], configMap["virtualRoot"], configMap["makeFileFunction"])
if (configMap["serverOnly"]) {
def identityFilePath := edeskHomePath + configMap["windowTitle"] + ".edesk-private"
def identityFile := <file: identityFilePath>
def conn := revokableConnectionMaker new(ftController)
def sturdyConn
traceln("server only")
if (!(identityFile exists())) {
traceln("first incarnation")
def keyPair := introducer newVatIdentity()
introducer onTheAir()
def netConfig := introducer getNetConfig()
def [bind sturdyConn, swissBase] :=
sturdyRef incarnate(conn)
SerializerMaker recordFile(identityFile, [netConfig, keyPair, swissBase])
} else {
traceln("reincarnation")
def [netConfig, keyPair, swissBase] := UnserializerMaker playFile(identityFile)
introducer setNetConfig(netConfig)
introducer setVatIdentity(keyPair)
introducer onTheAir()
def bind sturdyConn := sturdyRef reincarnate(conn, swissBase)
}
def capFile := <file: configMap["capabilityFile"]>
def cap := introducer sturdyToURI(sturdyConn)
traceln("made cap: " + cap)
capFile setText(cap)
println("Disk Navigator Operational")
} else {
navigatorWindowMaker new(ftController, myHomeNavigator)
introducer onTheAir()
}
def getRemoteConnectionURI(): any {
var uri := null
def blah := eFrameMaker new("")
def dialog := <awt:FileDialog> new(blah, "Select an Edesk erights file")
dialog show()
var path := dialog getFile()
if (path != null) {
path := dialog getDirectory() + path
uri := (<file: path>) getText()
traceln("connection is:" + uri)
}
uri
}
def buildNavWindow(uri) {
traceln("in buildnavwin, uri:" + uri)
def connector:= uriTools promiseObject(uri)
traceln("connector is" + connector)
def navigator := connector <- getANavigator()
def versionPromise := connector <-versionNumber()
when (versionPromise) -> done(version) {
traceln("ha! resolved promise")
if (version == versionNumber) {
navigatorWindowMaker new(ftController, navigator)
} else {
connectionWarning("Wrong Version")
}
} catch err {
connectionWarning("Remote Navigator Not Acquired\n" + err)
traceln("connection failure" + err)
}
}
def bind ftController {
to copyFrom(fromFilePromises,fromDiskNavigator) {
copyBuffer := fromFilePromises
copyBufferDiskNavigator := fromDiskNavigator <- dupNavigator()
traceln("copyFrom: " + fromFilePromises + copyBufferDiskNavigator)
}
to paste(toDiskNavigator, navigatorWindow) {
traceln("paste started with: " + copyBuffer + copyBufferDiskNavigator)
paster paste(copyBuffer, copyBufferDiskNavigator, toDiskNavigator, navigatorWindow)
}
to getANavigator(): any {
diskNavigatorMaker new(configMap["home"], configMap["windowTitle"],
configMap["virtualRoot"], configMap["makeFileFunction"])
}
to openRemote() {
def uri := getRemoteConnectionURI()
if (uri != null) {
buildNavWindow(uri)
}
}
to openEdesk(filePromise) {
def uri := filePromise <- getText()
when (uri) -> done(uriR) {
buildNavWindow(uri)
} catch err {
connectionWarning("No Edesk server")
}
}
}
}
traceln("about to make controller")
def baseController := ftControllerMaker new()
interp blockAtTop()
1.1 e/src/esrc/scripts/intro.updoc
Index: intro.updoc
===================================================================
Elmer is a simple text editor that also executes embedded
command line examples. Try hitting enter below
? 2 + 3