diff options
author | Michi Henning <michi@zeroc.com> | 2008-05-12 00:26:34 +1000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2008-05-12 00:26:34 +1000 |
commit | c4597d776f109d48a29031e01a99a4a8664b470c (patch) | |
tree | fad36531d09c263ba8428495649162b922584e89 | |
parent | Fixed incorrect file permissions. (diff) | |
download | ice-c4597d776f109d48a29031e01a99a4a8664b470c.tar.bz2 ice-c4597d776f109d48a29031e01a99a4a8664b470c.tar.xz ice-c4597d776f109d48a29031e01a99a4a8664b470c.zip |
Added map filesystem demo for Java.
Fixed a few bugs and style issues in C++ map filesystem demo.
47 files changed, 2766 insertions, 224 deletions
diff --git a/cpp/demo/book/evictor_filesystem/PersistentFilesystemI.cpp b/cpp/demo/book/evictor_filesystem/PersistentFilesystemI.cpp index 7dcda47a6b8..cc143cbb346 100644 --- a/cpp/demo/book/evictor_filesystem/PersistentFilesystemI.cpp +++ b/cpp/demo/book/evictor_filesystem/PersistentFilesystemI.cpp @@ -88,7 +88,7 @@ Filesystem::DirectoryI::destroy(const Ice::Current& c) { if(!parent) { - throw Filesystem::PermissionDenied("cannot destroy root directory"); + throw Filesystem::PermissionDenied("Cannot destroy root directory"); } NodeDict children; diff --git a/cpp/demo/book/evictor_filesystem/README b/cpp/demo/book/evictor_filesystem/README index 9f719fc6211..f6abb864764 100644 --- a/cpp/demo/book/evictor_filesystem/README +++ b/cpp/demo/book/evictor_filesystem/README @@ -9,3 +9,5 @@ $ server Then run the client in a separate window: $ client + +Type "help" at the client prompt to see a list of commands. diff --git a/cpp/demo/book/map_filesystem/FilesystemI.cpp b/cpp/demo/book/map_filesystem/FilesystemI.cpp index 77f46fe519e..6cf7f3dd386 100644 --- a/cpp/demo/book/map_filesystem/FilesystemI.cpp +++ b/cpp/demo/book/map_filesystem/FilesystemI.cpp @@ -140,9 +140,9 @@ FilesystemI::FileI::destroy(const Current& c) // FileI constructor -FilesystemI::FileI::FileI(const CommunicatorPtr& communicator, const Identity& id, +FilesystemI::FileI::FileI(const ObjectAdapterPtr& adapter, const Identity& id, const PersistentFilePtr& file, const DirectoryIPtr& parent) : - NodeI(communicator, id, parent), _file(file) + NodeI(adapter->getCommunicator(), id, parent), _file(file) { } @@ -204,10 +204,10 @@ FilesystemI::DirectoryI::find(const std::string& name, const Current& c) return i->second; } -// Slice Directory::createDirectory() operation +// Slice Directory::createFile() operation -DirectoryPrx -FilesystemI::DirectoryI::createDirectory(const std::string& name, const Current& c) +FilePrx +FilesystemI::DirectoryI::createFile(const std::string& name, const Current& c) { { IceUtil::Mutex::Lock lock(_m); @@ -227,32 +227,32 @@ FilesystemI::DirectoryI::createDirectory(const std::string& name, const Current& throw NameInUse(name); } - PersistentDirectoryPtr persistentDir = new PersistentDirectory; - persistentDir->name = name; + PersistentFilePtr persistentFile = new PersistentFile; + persistentFile->name = name; CommunicatorPtr communicator = c.adapter->getCommunicator(); - DirectoryIPtr dir = new DirectoryI(communicator, communicator->stringToIdentity(IceUtil::generateUUID()), - persistentDir, this); - assert(findNode(dir->_id) == 0); - _map.put(IdentityNodeMap::value_type(dir->_id, persistentDir)); + FileIPtr file = new FileI(c.adapter, communicator->stringToIdentity(IceUtil::generateUUID()), + persistentFile, this); + assert(findNode(file->id()) == 0); + _map.put(IdentityNodeMap::value_type(file->id(), persistentFile)); - DirectoryPrx proxy = DirectoryPrx::uncheckedCast(c.adapter->createProxy(dir->_id)); + FilePrx proxy = FilePrx::uncheckedCast(c.adapter->createProxy(file->id())); NodeDesc nd; nd.name = name; - nd.type = DirType; + nd.type = FileType; nd.proxy = proxy; _dir->nodes[name] = nd; _map.put(IdentityNodeMap::value_type(_id, _dir)); - dir->activate(c.adapter); + file->activate(c.adapter); return proxy; } -// Slice Directory::createFile() operation +// Slice Directory::createDirectory() operation -FilePrx -FilesystemI::DirectoryI::createFile(const std::string& name, const Current& c) +DirectoryPrx +FilesystemI::DirectoryI::createDirectory(const std::string& name, const Current& c) { { IceUtil::Mutex::Lock lock(_m); @@ -265,31 +265,31 @@ FilesystemI::DirectoryI::createFile(const std::string& name, const Current& c) IceUtil::StaticMutex::Lock lock(_lcMutex); + reap(); + if(name.empty() || _dir->nodes.find(name) != _dir->nodes.end()) { throw NameInUse(name); } - reap(); - - PersistentFilePtr persistentFile = new PersistentFile; - persistentFile->name = name; + PersistentDirectoryPtr persistentDir = new PersistentDirectory; + persistentDir->name = name; CommunicatorPtr communicator = c.adapter->getCommunicator(); - FileIPtr file = new FileI(communicator, communicator->stringToIdentity(IceUtil::generateUUID()), - persistentFile, this); - assert(findNode(file->id()) == 0); - _map.put(IdentityNodeMap::value_type(file->id(), persistentFile)); + DirectoryIPtr dir = new DirectoryI(c.adapter, communicator->stringToIdentity(IceUtil::generateUUID()), + persistentDir, this); + assert(findNode(dir->_id) == 0); + _map.put(IdentityNodeMap::value_type(dir->_id, persistentDir)); - FilePrx proxy = FilePrx::uncheckedCast(c.adapter->createProxy(file->id())); + DirectoryPrx proxy = DirectoryPrx::uncheckedCast(c.adapter->createProxy(dir->_id)); NodeDesc nd; nd.name = name; - nd.type = FileType; + nd.type = DirType; nd.proxy = proxy; _dir->nodes[name] = nd; _map.put(IdentityNodeMap::value_type(_id, _dir)); - file->activate(c.adapter); + dir->activate(c.adapter); return proxy; } @@ -301,7 +301,7 @@ FilesystemI::DirectoryI::destroy(const Current& c) { if(!_parent) { - throw Filesystem::PermissionDenied("cannot destroy root directory"); + throw Filesystem::PermissionDenied("Cannot destroy root directory"); } IceUtil::Mutex::Lock lock(_m); @@ -328,9 +328,9 @@ FilesystemI::DirectoryI::destroy(const Current& c) // DirectoryI constructor -FilesystemI::DirectoryI::DirectoryI(const CommunicatorPtr& communicator, const Identity& id, +FilesystemI::DirectoryI::DirectoryI(const ObjectAdapterPtr& adapter, const Identity& id, const PersistentDirectoryPtr& dir, const DirectoryIPtr& parent) - : NodeI(communicator, id, parent), _dir(dir) + : NodeI(adapter->getCommunicator(), id, parent), _dir(dir) { // // Instantiate the child nodes @@ -341,20 +341,22 @@ FilesystemI::DirectoryI::DirectoryI(const CommunicatorPtr& communicator, const I { Identity id = p->second.proxy->ice_getIdentity(); PersistentNodePtr node = findNode(id); + NodeIPtr servant; if(node) { if(p->second.type == DirType) { PersistentDirectoryPtr pDir = PersistentDirectoryPtr::dynamicCast(node); assert(pDir); - DirectoryIPtr d = new DirectoryI(communicator, id, pDir, this); + servant = new DirectoryI(adapter, id, pDir, this); } else { PersistentFilePtr pFile = PersistentFilePtr::dynamicCast(node); assert(pFile); - FileIPtr f = new FileI(communicator, id, pFile, this); + servant = new FileI(adapter, id, pFile, this); } + servant->activate(adapter); } else { diff --git a/cpp/demo/book/map_filesystem/FilesystemI.h b/cpp/demo/book/map_filesystem/FilesystemI.h index 83a8a0c087e..afca6869313 100644 --- a/cpp/demo/book/map_filesystem/FilesystemI.h +++ b/cpp/demo/book/map_filesystem/FilesystemI.h @@ -56,7 +56,7 @@ public: virtual void write(const Filesystem::Lines&, const Ice::Current&); virtual void destroy(const Ice::Current&); - FileI(const Ice::CommunicatorPtr&, const Ice::Identity&, + FileI(const Ice::ObjectAdapterPtr&, const Ice::Identity&, const Filesystem::PersistentFilePtr&, const DirectoryIPtr&); private: @@ -78,7 +78,7 @@ public: virtual Filesystem::DirectoryPrx createDirectory(const ::std::string&, const Ice::Current&); virtual void destroy(const Ice::Current&); - DirectoryI(const Ice::CommunicatorPtr&, const Ice::Identity&, + DirectoryI(const Ice::ObjectAdapterPtr&, const Ice::Identity&, const Filesystem::PersistentDirectoryPtr&, const DirectoryIPtr&); void addReapEntry(const std::string&); diff --git a/cpp/demo/book/map_filesystem/README b/cpp/demo/book/map_filesystem/README index 370331ef723..bb7408ec72e 100644 --- a/cpp/demo/book/map_filesystem/README +++ b/cpp/demo/book/map_filesystem/README @@ -9,3 +9,5 @@ $ server Then run the client in a separate window: $ client + +Type "help" at the client prompt to see a list of commands. diff --git a/cpp/demo/book/map_filesystem/Server.cpp b/cpp/demo/book/map_filesystem/Server.cpp index 03025e77d52..d2a35b13003 100644 --- a/cpp/demo/book/map_filesystem/Server.cpp +++ b/cpp/demo/book/map_filesystem/Server.cpp @@ -27,7 +27,7 @@ public: virtual int run(int, char*[]) { // - // Terminate cleanly on receipt of a signal + // Terminate cleanly on receipt of a signal. // shutdownOnInterrupt(); @@ -70,7 +70,7 @@ public: pRoot->name = "/"; persistentMap.insert(IdentityNodeMap::value_type(rootId, pRoot)); } - DirectoryIPtr dir = new DirectoryI(communicator(), rootId, pRoot, 0); + DirectoryIPtr dir = new DirectoryI(adapter, rootId, pRoot, 0); dir->activate(adapter); } diff --git a/java/allDemos.py b/java/allDemos.py index fbe050a51c4..ff6722e2a41 100755 --- a/java/allDemos.py +++ b/java/allDemos.py @@ -46,7 +46,8 @@ demos = [ "Freeze/library", "Freeze/transform", "Freeze/casino", - "book/freeze_filesystem", + "book/map_filesystem", + "book/evictor_filesystem", "book/simple_filesystem", "book/printer", "book/lifecycle", diff --git a/java/demo/book/README b/java/demo/book/README index bbace203f6d..5876d2c345e 100644 --- a/java/demo/book/README +++ b/java/demo/book/README @@ -3,8 +3,8 @@ Demos in this directory: - evictor This is the source code for the evictor implementation described in - the Ice Run Time chapter. You can copy and modify this code to - suit your needs. + the Ice Run Time chapter. You can copy and modify this code to suit + your needs. - printer @@ -20,7 +20,12 @@ Demos in this directory: An implementation of the file system that supports life cycle operations. -- freeze_filesystem +- map_filesystem An implementation of the persistent version of the file system - example described in the Freeze chapter. + based on Freeze maps as described in the Freeze chapter. + +- evictor_filesystem + + An implementation of the persistent version of the file system + based on a background-save evictor as described in the Freeze chapter. diff --git a/java/demo/book/build.xml b/java/demo/book/build.xml index aa71c1ae517..e44df524923 100644 --- a/java/demo/book/build.xml +++ b/java/demo/book/build.xml @@ -14,7 +14,8 @@ <target name="all"> <ant dir="printer"/> <ant dir="simple_filesystem"/> - <ant dir="freeze_filesystem"/> + <ant dir="map_filesystem"/> + <ant dir="evictor_filesystem"/> <ant dir="lifecycle"/> </target> @@ -22,8 +23,8 @@ <ant dir="printer" target="clean"/> <ant dir="simple_filesystem" target="clean"/> <ant dir="lifecycle" target="clean"/> - <ant dir="freeze_filesystem" target="clean"/> - <ant dir="lifecycle" target="clean"/> + <ant dir="map_filesystem" target="clean"/> + <ant dir="evictor_filesystem" target="clean"/> </target> </project> diff --git a/java/demo/book/freeze_filesystem/.gitignore b/java/demo/book/evictor_filesystem/.gitignore index 9c39416c539..9c39416c539 100644 --- a/java/demo/book/freeze_filesystem/.gitignore +++ b/java/demo/book/evictor_filesystem/.gitignore diff --git a/java/demo/book/evictor_filesystem/Client.java b/java/demo/book/evictor_filesystem/Client.java new file mode 100644 index 00000000000..8599d43e81d --- /dev/null +++ b/java/demo/book/evictor_filesystem/Client.java @@ -0,0 +1,56 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import Filesystem.*; + +public class Client extends Ice.Application +{ + public int + run(String[] args) + { + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // Create a proxy for the root directory + // + Ice.ObjectPrx base = communicator().stringToProxy("RootDir:default -p 10000"); + if(base == null) + { + throw new Error("Could not create proxy"); + } + + // Down-cast the proxy to a Directory proxy. + // + DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(base); + if(rootDir == null) + { + throw new Error("Invalid proxy"); + } + + Parser p = new Parser(rootDir); + return p.parse(); + } + + static public void + main(String[] args) + { + Client app = new Client(); + app.main("demo.book.lifecycle.Client", args); + } + + static private class Error extends RuntimeException + { + public Error(String msg) + { + super(msg); + } + } + +} diff --git a/java/demo/book/freeze_filesystem/DirectoryI.java b/java/demo/book/evictor_filesystem/DirectoryI.java index d8fe5a312a9..5da25ce6b0c 100644 --- a/java/demo/book/freeze_filesystem/DirectoryI.java +++ b/java/demo/book/evictor_filesystem/DirectoryI.java @@ -42,7 +42,7 @@ public final class DirectoryI extends PersistentDirectory { if(parent == null) { - throw new PermissionDenied("cannot remove root directory"); + throw new PermissionDenied("Cannot remove root directory"); } java.util.Map children = null; @@ -54,6 +54,11 @@ public final class DirectoryI extends PersistentDirectory throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); } + if(!nodes.isEmpty()) + { + throw new PermissionDenied("Cannot destroy non-empty directory"); + } + children = (java.util.Map)((java.util.HashMap)nodes).clone(); _destroyed = true; } diff --git a/java/demo/book/freeze_filesystem/FileI.java b/java/demo/book/evictor_filesystem/FileI.java index 09db1e60320..09db1e60320 100644 --- a/java/demo/book/freeze_filesystem/FileI.java +++ b/java/demo/book/evictor_filesystem/FileI.java diff --git a/java/demo/book/freeze_filesystem/Filesystem.ice b/java/demo/book/evictor_filesystem/Filesystem.ice index b8b5b38d351..b8b5b38d351 100644 --- a/java/demo/book/freeze_filesystem/Filesystem.ice +++ b/java/demo/book/evictor_filesystem/Filesystem.ice diff --git a/java/demo/book/evictor_filesystem/Grammar.java b/java/demo/book/evictor_filesystem/Grammar.java new file mode 100644 index 00000000000..92da79a56d0 --- /dev/null +++ b/java/demo/book/evictor_filesystem/Grammar.java @@ -0,0 +1,202 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Grammar +{ + Grammar(Parser p) + { + _parser = p; + _scanner = new Scanner(_parser); + } + + void + parse() + { + while(true) + { + try + { + _token = _scanner.nextToken(); + if(_token == null) + { + return; + } + else if(_token.type == Token.TOK_SEMI) + { + // Continue + } + else if(_token.type == Token.TOK_HELP) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.usage(); + } + else if(_token.type == Token.TOK_EXIT) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + return; + } + else if(_token.type == Token.TOK_LIST) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.list(false); + } + else if(_token.type == Token.TOK_LIST_RECURSIVE) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.list(true); + } + else if(_token.type == Token.TOK_CREATE_FILE) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: mkfile FILE [FILE...]"); + } + _parser.createFile(s); + } + else if(_token.type == Token.TOK_CREATE_DIR) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: mkdir DIR [DIR...]"); + } + _parser.createDir(s); + } + else if(_token.type == Token.TOK_PWD) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.pwd(); + } + else if(_token.type == Token.TOK_CD) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() > 1) + { + throw new ParseError("usage: cd [DIR]"); + } + else if(s.size() == 0) + { + _parser.cd("/"); + } + else + { + _parser.cd((String)s.get(0)); + } + } + else if(_token.type == Token.TOK_CAT) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() != 1) + { + throw new ParseError("usage: cat FILE"); + } + _parser.cat((String)s.get(0)); + } + else if(_token.type == Token.TOK_WRITE) + { + java.util.LinkedList<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: write FILE [STRING...]"); + } + _parser.write(s); + } + else if(_token.type == Token.TOK_RM) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: rm NAME [NAME...]"); + } + _parser.destroy(s); + } + else + { + _parser.error("parse error"); + } + } + catch(ParseError e) + { + _parser.error("Parse error: " + e.getMessage()); + } + } + } + + private java.util.LinkedList<String> + strings() + { + java.util.LinkedList<String> l = new java.util.LinkedList<String>(); + while(true) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_STRING) + { + return l; + } + l.add(_token.value); + } + } + + static private class ParseError extends RuntimeException + { + ParseError(String msg) + { + super(msg); + } + } + + private Parser _parser; + private Scanner _scanner; + private Token _token; +} diff --git a/java/demo/book/freeze_filesystem/NodeFactory.java b/java/demo/book/evictor_filesystem/NodeFactory.java index 74982387cac..74982387cac 100644 --- a/java/demo/book/freeze_filesystem/NodeFactory.java +++ b/java/demo/book/evictor_filesystem/NodeFactory.java diff --git a/java/demo/book/freeze_filesystem/NodeInitializer.java b/java/demo/book/evictor_filesystem/NodeInitializer.java index b1304afd16e..b1304afd16e 100644 --- a/java/demo/book/freeze_filesystem/NodeInitializer.java +++ b/java/demo/book/evictor_filesystem/NodeInitializer.java diff --git a/java/demo/book/evictor_filesystem/Parser.java b/java/demo/book/evictor_filesystem/Parser.java new file mode 100644 index 00000000000..94e4af53654 --- /dev/null +++ b/java/demo/book/evictor_filesystem/Parser.java @@ -0,0 +1,361 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import Filesystem.*; + +class Parser +{ + Parser(DirectoryPrx root) + { + _dirs = new java.util.LinkedList<DirectoryPrx>(); + _dirs.addFirst(root); + } + + void + usage() + { + System.err.print( + "help Print this message.\n" + + "pwd Print current directory (/ = root).\n" + + "cd [DIR] Change directory (/ or empty = root).\n" + + "ls List current directory.\n" + + "lr Recursively list current directory.\n" + + "mkdir DIR [DIR...] Create directories DIR in current directory.\n" + + "mkfile FILE [FILE...] Create files FILE in current directory.\n" + + "rm NAME [NAME...] Delete directory or file NAME (rm * to delete all).\n" + + "cat FILE List the contents of FILE.\n" + + "write FILE [STRING...] Write STRING to FILE.\n" + + "exit, quit Exit this program.\n"); + } + + void + list(boolean recursive) + { + try + { + list(_dirs.get(0), recursive, 0); + } + catch(Ice.LocalException ex) + { + error(ex.toString()); + } + } + + void + list(Filesystem.DirectoryPrx dir, boolean recursive, int depth) + { + StringBuffer b = new StringBuffer(); + for(int i = 0; i < depth; ++i) + { + b.append('\t'); + } + String indent = b.toString(); + + NodeDesc[] contents = dir.list(); + + for(int i = 0; i < contents.length; ++i) + { + DirectoryPrx d + = contents[i].type == NodeType.DirType + ? DirectoryPrxHelper.uncheckedCast(contents[i].proxy) + : null; + System.out.print(indent + contents[i].name + (d != null ? " (directory)" : " (file)")); + if(d != null && recursive) + { + System.out.println(":"); + list(d, true, ++depth); + } + else + { + System.out.println(); + } + } + } + + void + createFile(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("..")) + { + System.out.println("Cannot create a file named `..'"); + continue; + } + + try + { + dir.createFile(name); + } + catch(NameInUse ex) + { + System.out.println("`" + name + "' exists already"); + } + } + } + + void + createDir(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("..")) + { + System.out.println("Cannot create a directory named `..'"); + continue; + } + + try + { + dir.createDirectory(name); + } + catch(NameInUse ex) + { + System.out.println("`" + name + "' exists already"); + } + } + } + + void + pwd() + { + if(_dirs.size() == 1) + { + System.out.print("/"); + } + else + { + java.util.ListIterator<DirectoryPrx> i = _dirs.listIterator(_dirs.size()); + i.previous(); + while(i.hasPrevious()) + { + System.out.print("/" + i.previous().name()); + } + } + System.out.println(); + } + + void + cd(String name) + { + if(name.equals("/")) + { + while(_dirs.size() > 1) + { + _dirs.removeFirst(); + } + return; + } + + if(name.equals("..")) + { + if(_dirs.size() > 1) + { + _dirs.removeFirst(); + } + return; + } + + DirectoryPrx dir = _dirs.getFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such directory"); + return; + } + if(d.type == NodeType.FileType) + { + System.out.println("`" + name + "': not a directory"); + return; + } + _dirs.addFirst(DirectoryPrxHelper.uncheckedCast(d.proxy)); + } + + void + cat(String name) + { + DirectoryPrx dir = _dirs.getFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file"); + return; + } + if(d.type == NodeType.DirType) + { + System.out.println("`" + name + "': not a file"); + return; + } + FilePrx f = FilePrxHelper.uncheckedCast(d.proxy); + String[] l = f.read(); + for(int i = 0; i < l.length; ++i) + { + System.out.println(l[i]); + } + } + + void + write(java.util.LinkedList<String> args) + { + DirectoryPrx dir = _dirs.getFirst(); + String name = args.getFirst(); + args.removeFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file"); + return; + } + if(d.type == NodeType.DirType) + { + System.out.println("`" + name + "': not a file"); + return; + } + FilePrx f = FilePrxHelper.uncheckedCast(d.proxy); + + String[] l = new String[args.size()]; + java.util.Iterator<String> i = args.iterator(); + for(int j = 0; j < args.size(); ++j) + { + l[j] = i.next(); + } + try + { + f.write(l); + } + catch(GenericError ex) + { + System.out.println("`" + name + "': cannot write to file: " + ex.reason); + } + } + + void + destroy(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("*")) + { + NodeDesc[] nodes = dir.list(); + for(int j = 0; j < nodes.length; ++j) + { + try + { + nodes[j].proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + nodes[j].name + "': " + ex.reason); + } + } + return; + } + else + { + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file or directory"); + return; + } + try + { + d.proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + name + "': " + ex.reason); + } + } + } + + } + + void + error(String s) + { + System.err.println("error: " + s); + } + + void + warning(String s) + { + System.err.println("warning: " + s); + } + + String + getInput() + { + System.out.print("> "); + System.out.flush(); + + try + { + return _in.readLine(); + } + catch(java.io.IOException e) + { + return null; + } + } + + int + parse() + { + _in = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); + + Grammar g = new Grammar(this); + g.parse(); + + return 0; + } + + int + parse(java.io.BufferedReader in) + { + _in = in; + + Grammar g = new Grammar(this); + g.parse(); + + return 0; + } + + private java.util.LinkedList<DirectoryPrx> _dirs; + + private java.io.BufferedReader _in; +} diff --git a/java/demo/book/freeze_filesystem/PersistentFilesystem.ice b/java/demo/book/evictor_filesystem/PersistentFilesystem.ice index 2895d2f5d14..2895d2f5d14 100644 --- a/java/demo/book/freeze_filesystem/PersistentFilesystem.ice +++ b/java/demo/book/evictor_filesystem/PersistentFilesystem.ice diff --git a/java/demo/book/evictor_filesystem/README b/java/demo/book/evictor_filesystem/README new file mode 100644 index 00000000000..7abae01bca6 --- /dev/null +++ b/java/demo/book/evictor_filesystem/README @@ -0,0 +1,13 @@ +This demo presents an implementation of the filesystem +application based on a background-save evictor, as discussed in +the Freeze chapter of the Ice manual. + +To run it, start the server in a window: + +$ java Server + +Then run the client in a separate window: + +$ java Client + +Type "help" at the client prompt to see a list of commands. diff --git a/java/demo/book/evictor_filesystem/Scanner.java b/java/demo/book/evictor_filesystem/Scanner.java new file mode 100644 index 00000000000..d318ed291f0 --- /dev/null +++ b/java/demo/book/evictor_filesystem/Scanner.java @@ -0,0 +1,283 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Scanner +{ + Scanner(Parser p) + { + _parser = p; + } + + Token + nextToken() + { + String s = next(); + if(s == null) + { + return null; + } + + if(s.equals(";")) + { + return new Token(Token.TOK_SEMI); + } + else if(s.equals("help")) + { + return new Token(Token.TOK_HELP); + } + else if(s.equals("exit") || s.equals("quit")) + { + return new Token(Token.TOK_EXIT); + } + else if(s.equals("ls")) + { + return new Token(Token.TOK_LIST); + } + else if(s.equals("lr")) + { + return new Token(Token.TOK_LIST_RECURSIVE); + } + else if(s.equals("mkfile")) + { + return new Token(Token.TOK_CREATE_FILE); + } + else if(s.equals("mkdir")) + { + return new Token(Token.TOK_CREATE_DIR); + } + else if(s.equals("pwd")) + { + return new Token(Token.TOK_PWD); + } + else if(s.equals("cd")) + { + return new Token(Token.TOK_CD); + } + else if(s.equals("cat")) + { + return new Token(Token.TOK_CAT); + } + else if(s.equals("write")) + { + return new Token(Token.TOK_WRITE); + } + else if(s.equals("rm")) + { + return new Token(Token.TOK_RM); + } + else + { + return new Token(Token.TOK_STRING, s); + } + } + + static private class EndOfInput extends Exception + { + } + + private char + get() + throws EndOfInput + { + // + // If there is an character in the unget buffer, return it. + // + if(_unget) + { + _unget = false; + return _ungetChar; + } + + // + // No current buffer? + // + if(_buf == null) + { + _buf = _parser.getInput(); + _pos = 0; + if(_buf == null) + { + throw new EndOfInput(); + } + } + + // + // At the end-of-buffer? + // + while(_pos >= _buf.length()) + { + _buf = null; + _pos = 0; + return '\n'; + } + + return _buf.charAt(_pos++); + } + + // + // unget only works with one character. + // + private void + unget(char c) + { + assert(!_unget); + _unget = true; + _ungetChar = c; + } + + private String + next() + { + // + // Eat any whitespace. + // + char c; + try + { + do + { + c = get(); + } + while(Character.isWhitespace(c) && c != '\n'); + } + catch(EndOfInput ignore) + { + return null; + } + + StringBuffer buf = new StringBuffer(); + + if(c == ';' || c == '\n') + { + buf.append(';'); + } + else if(c == '\'') + { + try + { + while(true) + { + c = get(); + if(c == '\'') + { + break; + } + else + { + buf.append(c); + } + } + } + catch(EndOfInput e) + { + _parser.warning("EOF in string"); + } + } + else if(c == '\"') + { + try + { + while(true) + { + c = get(); + if(c == '\"') + { + break; + } + else if(c == '\\') + { + try + { + char next = get(); + switch(next) + { + case '\\': + case '"': + { + buf.append(next); + break; + } + + case 'n': + { + buf.append('\n'); + break; + } + + case 'r': + { + buf.append('\r'); + break; + } + + case 't': + { + buf.append('\t'); + break; + } + + case 'f': + { + buf.append('\f'); + break; + } + + default: + { + buf.append(c); + unget(next); + } + } + } + catch(EndOfInput e) + { + buf.append(c); + } + } + else + { + buf.append(c); + } + } + } + catch(EndOfInput e) + { + _parser.warning("EOF in string"); + } + } + else + { + // + // Otherwise it's a string. + // + try + { + do + { + buf.append(c); + c = get(); + } + while(!Character.isWhitespace(c) && c != ';' && c != '\n'); + + unget(c); + } + catch(EndOfInput ignore) + { + } + } + + return buf.toString(); + } + + private Parser _parser; + private boolean _unget = false; + private char _ungetChar; + private String _buf = null; + private int _pos; +} diff --git a/java/demo/book/freeze_filesystem/Server.java b/java/demo/book/evictor_filesystem/Server.java index 6e66f3ccb3f..6e66f3ccb3f 100644 --- a/java/demo/book/freeze_filesystem/Server.java +++ b/java/demo/book/evictor_filesystem/Server.java diff --git a/java/demo/book/evictor_filesystem/Token.java b/java/demo/book/evictor_filesystem/Token.java new file mode 100644 index 00000000000..7fe92e242e0 --- /dev/null +++ b/java/demo/book/evictor_filesystem/Token.java @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Token +{ + public static final int TOK_HELP = 0; + public static final int TOK_EXIT = 1; + public static final int TOK_SEMI = 2; + public static final int TOK_LIST = 3; + public static final int TOK_LIST_RECURSIVE = 4; + public static final int TOK_CREATE_FILE = 5; + public static final int TOK_CREATE_DIR = 6; + public static final int TOK_PWD = 7; + public static final int TOK_CD = 8; + public static final int TOK_CAT = 9; + public static final int TOK_WRITE = 10; + public static final int TOK_RM = 11; + public static final int TOK_STRING = 12; + + int type; + String value; + + Token(int t) + { + type = t; + value = null; + } + + Token(int t, String v) + { + type = t; + value = v; + } +} diff --git a/java/demo/book/freeze_filesystem/build.xml b/java/demo/book/evictor_filesystem/build.xml index b2c9993bb02..01d9c2a2a9e 100644 --- a/java/demo/book/freeze_filesystem/build.xml +++ b/java/demo/book/evictor_filesystem/build.xml @@ -9,7 +9,7 @@ ********************************************************************** --> -<project name="demo_book_freeze_filesystem" default="all" basedir="."> +<project name="demo_book_evictor_filesystem" default="all" basedir="."> <!-- set global properties for this build --> <property name="top.dir" value="../../.."/> diff --git a/java/demo/book/freeze_filesystem/config.client b/java/demo/book/evictor_filesystem/config.client index 6f0ba50b98f..6f0ba50b98f 100644 --- a/java/demo/book/freeze_filesystem/config.client +++ b/java/demo/book/evictor_filesystem/config.client diff --git a/java/demo/book/freeze_filesystem/config.server b/java/demo/book/evictor_filesystem/config.server index 8ee5723e944..8ee5723e944 100644 --- a/java/demo/book/freeze_filesystem/config.server +++ b/java/demo/book/evictor_filesystem/config.server diff --git a/java/demo/book/freeze_filesystem/db/.gitignore b/java/demo/book/evictor_filesystem/db/.gitignore index 39af5887579..39af5887579 100644 --- a/java/demo/book/freeze_filesystem/db/.gitignore +++ b/java/demo/book/evictor_filesystem/db/.gitignore diff --git a/java/demo/book/evictor_filesystem/expect.py b/java/demo/book/evictor_filesystem/expect.py new file mode 100755 index 00000000000..60d3c0c8e9d --- /dev/null +++ b/java/demo/book/evictor_filesystem/expect.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, os + +try: + import demoscript +except ImportError: + for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "demoscript")): + break + else: + raise "can't find toplevel directory!" + sys.path.append(os.path.join(toplevel)) + import demoscript + +import demoscript.Util +demoscript.Util.defaultLanguage = "Java" +import demoscript.book.evictor_filesystem + +print "cleaning databases...", +sys.stdout.flush() +demoscript.Util.cleanDbDir("db") +print "ok" + +server = demoscript.Util.spawn('java Server --Ice.PrintAdapterReady') +server.expect('.* ready') +client = demoscript.Util.spawn('java Client') + +demoscript.book.evictor_filesystem.run(client, server) diff --git a/java/demo/book/freeze_filesystem/Client.java b/java/demo/book/freeze_filesystem/Client.java deleted file mode 100644 index 01aac52f880..00000000000 --- a/java/demo/book/freeze_filesystem/Client.java +++ /dev/null @@ -1,164 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -import Filesystem.*; - -public class Client extends Ice.Application -{ - // Recursively print the contents of directory "dir" in tree fashion. - // For files, show the contents of each file. The "depth" - // parameter is the current nesting level (for indentation). - - static void - listRecursive(DirectoryPrx dir, int depth) - { - char[] indentCh = new char[++depth]; - java.util.Arrays.fill(indentCh, '\t'); - String indent = new String(indentCh); - - NodeDesc[] contents = dir.list(); - - for (int i = 0; i < contents.length; ++i) { - DirectoryPrx subdir = DirectoryPrxHelper.checkedCast(contents[i].proxy); - FilePrx file = FilePrxHelper.uncheckedCast(contents[i].proxy); - System.out.println(indent + contents[i].name + (subdir != null ? " (directory):" : " (file):")); - if (subdir != null) { - listRecursive(subdir, depth); - } else { - String[] text = file.read(); - for (int j = 0; j < text.length; ++j) - System.out.println(indent + "\t" + text[j]); - } - } - } - - class ShutdownHook extends Thread - { - public void - run() - { - try - { - communicator().destroy(); - } - catch(Ice.LocalException ex) - { - ex.printStackTrace(); - } - } - } - - public int - run(String[] args) - { - // - // Since this is an interactive demo we want to clear the - // Application installed interrupt callback and install our - // own shutdown hook. - // - setInterruptHook(new ShutdownHook()); - - // - // Create a proxy for the root directory. - // - DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(communicator().propertyToProxy("RootDir.Proxy")); - if(rootDir == null) - { - System.err.println("Client: invalid proxy"); - return 1; - } - - try - { - // - // Create a file called "README" in the root directory. - // - try - { - FilePrx readme = rootDir.createFile("README"); - String[] text = new String[1]; - text[0] = "This file system contains a collection of poetry."; - readme.write(text); - System.out.println("Created README."); - } - catch(NameInUse ex) - { - // - // Ignore - file already exists. - // - } - - // - // Create a directory called "Coleridge" in the root directory. - // - DirectoryPrx coleridge = null; - try - { - coleridge = rootDir.createDirectory("Coleridge"); - System.out.println("Created Coleridge."); - } - catch(NameInUse ex) - { - NodeDesc desc = rootDir.find("Coleridge"); - coleridge = DirectoryPrxHelper.checkedCast(desc.proxy); - assert(coleridge != null); - } - - // - // Create a file called "Kubla_Khan" in the Coleridge directory. - // - try - { - FilePrx file = coleridge.createFile("Kubla_Khan"); - String[] text = new String[5]; - text[0] = "In Xanadu did Kubla Khan"; - text[1] = "A stately pleasure-dome decree:"; - text[2] = "Where Alph, the sacred river, ran"; - text[3] = "Through caverns measureless to man"; - text[4] = "Down to a sunless sea."; - file.write(text); - System.out.println("Created Coleridge/Kubla_Khan."); - } - catch(NameInUse ex) - { - // - // Ignore - file already exists. - // - } - - System.out.println("Contents of filesystem:"); - listRecursive(rootDir, 0); - - // - // Destroy the filesystem. - // - NodeDesc[] contents = rootDir.list(); - for(int i = 0; i < contents.length; ++i) - { - NodeDesc d = contents[i]; - System.out.println("Destroying " + d.name); - d.proxy.destroy(); - } - } - catch(Ice.UserException ex) - { - ex.printStackTrace(); - } - - return 0; - } - - public static void - main(String[] args) - { - Client app = new Client(); - int status = app.main("Client", args, "config.client"); - System.exit(status); - } -} diff --git a/java/demo/book/freeze_filesystem/README b/java/demo/book/freeze_filesystem/README deleted file mode 100644 index 32f3381a068..00000000000 --- a/java/demo/book/freeze_filesystem/README +++ /dev/null @@ -1,10 +0,0 @@ -This demo presents an alternate implementation of the filesystem -application, as discussed in the Freeze chapter of the Ice manual. - -To run it, start the server in a window: - -$ java Server - -Then run the client in a separate window: - -$ java Client diff --git a/java/demo/book/map_filesystem/.gitignore b/java/demo/book/map_filesystem/.gitignore new file mode 100644 index 00000000000..9c39416c539 --- /dev/null +++ b/java/demo/book/map_filesystem/.gitignore @@ -0,0 +1 @@ +db/* diff --git a/java/demo/book/map_filesystem/Client.java b/java/demo/book/map_filesystem/Client.java new file mode 100644 index 00000000000..8599d43e81d --- /dev/null +++ b/java/demo/book/map_filesystem/Client.java @@ -0,0 +1,56 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import Filesystem.*; + +public class Client extends Ice.Application +{ + public int + run(String[] args) + { + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // Create a proxy for the root directory + // + Ice.ObjectPrx base = communicator().stringToProxy("RootDir:default -p 10000"); + if(base == null) + { + throw new Error("Could not create proxy"); + } + + // Down-cast the proxy to a Directory proxy. + // + DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(base); + if(rootDir == null) + { + throw new Error("Invalid proxy"); + } + + Parser p = new Parser(rootDir); + return p.parse(); + } + + static public void + main(String[] args) + { + Client app = new Client(); + app.main("demo.book.lifecycle.Client", args); + } + + static private class Error extends RuntimeException + { + public Error(String msg) + { + super(msg); + } + } + +} diff --git a/java/demo/book/map_filesystem/Filesystem.ice b/java/demo/book/map_filesystem/Filesystem.ice new file mode 100644 index 00000000000..fea080b38dd --- /dev/null +++ b/java/demo/book/map_filesystem/Filesystem.ice @@ -0,0 +1,69 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +module Filesystem +{ + exception GenericError + { + string reason; + }; + exception PermissionDenied extends GenericError {}; + exception NameInUse extends GenericError {}; + exception NoSuchName extends GenericError {}; + + interface Node + { + idempotent string name(); + void destroy() throws PermissionDenied; + }; + + sequence<string> Lines; + + interface File extends Node + { + idempotent Lines read(); + idempotent void write(Lines text) throws GenericError; + }; + + enum NodeType { DirType, FileType }; + + struct NodeDesc + { + string name; + NodeType type; + Node* proxy; + }; + + sequence<NodeDesc> NodeDescSeq; + + interface Directory extends Node + { + idempotent NodeDescSeq list(); + idempotent NodeDesc find(string name) throws NoSuchName; + File* createFile(string name) throws NameInUse; + Directory* createDirectory(string name) throws NameInUse; + }; + + class PersistentNode + { + string name; + }; + + class PersistentFile extends PersistentNode + { + Lines text; + }; + + dictionary<string, NodeDesc> NodeDict; + + class PersistentDirectory extends PersistentNode + { + NodeDict nodes; + }; +}; diff --git a/java/demo/book/map_filesystem/FilesystemI/DirectoryI.java b/java/demo/book/map_filesystem/FilesystemI/DirectoryI.java new file mode 100644 index 00000000000..90b298d64cf --- /dev/null +++ b/java/demo/book/map_filesystem/FilesystemI/DirectoryI.java @@ -0,0 +1,332 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package FilesystemI; + +import Ice.*; +import Filesystem.*; + +public class DirectoryI extends _DirectoryDisp implements NodeI, _DirectoryOperations +{ + + // Slice name() operation. + + public synchronized String + name(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + return _dir.name; + } + + // Return the object identity for this node. + + public Identity + id() + { + return _id; + } + + // Slice list() operation. + + public NodeDesc[] + list(Current c) + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + } + + synchronized(_lcMutex) + { + reap(); + + NodeDesc[] result = new NodeDesc[_dir.nodes.size()]; + java.util.Iterator<java.util.Map.Entry<String, NodeDesc> > pos = _dir.nodes.entrySet().iterator(); + for(int i = 0; i < _dir.nodes.size(); ++i) + { + java.util.Map.Entry<String, NodeDesc> e = pos.next(); + result[i] = e.getValue(); + } + return result; + } + } + + // Slice find() operation. + + public NodeDesc + find(String name, Current c) throws NoSuchName + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + } + + synchronized(_lcMutex) + { + reap(); + + NodeDesc nd = _dir.nodes.get(name); + if(nd == null) + { + throw new NoSuchName(name); + } + return nd; + } + } + + // Slice createFile() operation. + + public FilePrx + createFile(String name, Current c) throws NameInUse + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + } + + synchronized(_lcMutex) + { + reap(); + + if(name.length() == 0 || _dir.nodes.containsKey(name)) + { + throw new NameInUse(name); + } + + PersistentFile persistentFile = new PersistentFile(); + persistentFile.name = name; + Communicator communicator = c.adapter.getCommunicator(); + FileI file = new FileI(c.adapter, communicator.stringToIdentity(Util.generateUUID()), + persistentFile, this); + assert(_map.get(file.id()) == null); + _map.put(file.id(), persistentFile); + + FilePrx proxy = FilePrxHelper.uncheckedCast(c.adapter.createProxy(file.id())); + + NodeDesc nd = new NodeDesc(); + nd.name = name; + nd.type = NodeType.FileType; + nd.proxy = proxy; + _dir.nodes.put(name, nd); + _map.put(_id, _dir); + + file.activate(c.adapter); + + return proxy; + } + } + + // Slice createDirectory() operation. + + public DirectoryPrx + createDirectory(String name, Current c) throws NameInUse + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + } + + synchronized(_lcMutex) + { + reap(); + + if(name.length() == 0 || _dir.nodes.containsKey(name)) + { + throw new NameInUse(name); + } + + PersistentDirectory persistentDir = new PersistentDirectory(); + persistentDir.name = name; + persistentDir.nodes = new java.util.HashMap<String, NodeDesc>(); + Communicator communicator = c.adapter.getCommunicator(); + DirectoryI dir = new DirectoryI(c.adapter, communicator.stringToIdentity(Util.generateUUID()), + persistentDir, this); + assert(_map.get(dir.id()) == null); + _map.put(dir.id(), persistentDir); + + DirectoryPrx proxy = DirectoryPrxHelper.uncheckedCast(c.adapter.createProxy(dir.id())); + + NodeDesc nd = new NodeDesc(); + nd.name = name; + nd.type = NodeType.DirType; + nd.proxy = proxy; + _dir.nodes.put(name, nd); + _map.put(_id, _dir); + + dir.activate(c.adapter); + + return proxy; + } + } + + // Slice destroy() operation. + + public void + destroy(Current c) throws PermissionDenied + { + if(_parent == null) + { + throw new PermissionDenied("Cannot destroy root directory"); + } + + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + synchronized(_lcMutex) + { + reap(); + + if(_dir.nodes.size() != 0) + { + throw new PermissionDenied("Cannot destroy non-empty directory"); + } + + c.adapter.remove(id()); + _parent.addReapEntry(_dir.name); + _destroyed = true; + } + } + } + + // DirectoryI constructor. parent == null indicates root directory. + + public DirectoryI(ObjectAdapter adapter, Identity id, PersistentDirectory dir, DirectoryI parent) + { + Communicator communicator = adapter.getCommunicator(); + _connection = Freeze.Util.createConnection(communicator, _envName); + _map = new IdentityNodeMap(_connection, _dbName, false); + _id = id; + _dir = dir; + _parent = parent; + _destroyed = false; + + java.util.Vector<String> staleEntries = new java.util.Vector<String>(); + + java.util.Iterator<java.util.Map.Entry<String, NodeDesc> > p = dir.nodes.entrySet().iterator(); + while(p.hasNext()) + { + java.util.Map.Entry<String, NodeDesc> e = (java.util.Map.Entry)p.next(); + NodeDesc nd = e.getValue(); + Identity ident = nd.proxy.ice_getIdentity(); + PersistentNode node = (PersistentNode)_map.get(ident); + NodeI servant; + if(node != null) + { + if(nd.type == NodeType.DirType) + { + PersistentDirectory pDir = (PersistentDirectory)node; + servant = new DirectoryI(adapter, ident, pDir, this); + } + else + { + PersistentFile pFile = (PersistentFile)node; + servant = new FileI(adapter, ident, pFile, this); + } + servant.activate(adapter); + } + else + { + staleEntries.add(e.getKey()); + } + } + + java.util.Iterator<String> i = staleEntries.iterator(); + while(i.hasNext()) + { + dir.nodes.remove(i.next()); + } + if(!staleEntries.isEmpty()) + { + _map.put(id, dir); + } + } + + + // Add servant to ASM and to parent's _contents map. + + public DirectoryPrx + activate(ObjectAdapter a) + { + return DirectoryPrxHelper.uncheckedCast(a.add(this, _id)); + } + + // Add this directory and the name of a deleted entry to the reap map. + + public void + addReapEntry(String name) + { + java.util.List<String> l = _reapMap.get(this); + if(l != null) + { + l.add(name); + } + else + { + l = new java.util.ArrayList<String>(); + l.add(name); + _reapMap.put(this, l); + } + } + + // Remove all names in the reap map from the corresponding directory contents. + + private static void + reap() + { + java.util.Iterator<java.util.Map.Entry<DirectoryI, java.util.List<String> > > i = + _reapMap.entrySet().iterator(); + while(i.hasNext()) + { + java.util.Map.Entry<DirectoryI, java.util.List<String> > e = i.next(); + DirectoryI dir = e.getKey(); + java.util.List<String> l = e.getValue(); + java.util.Iterator<String> j = l.iterator(); + while(j.hasNext()) + { + dir._dir.nodes.remove(j.next()); + } + } + _reapMap.clear(); + } + + public static java.lang.Object _lcMutex = new java.lang.Object(); + + public static String _envName; + public static String _dbName; + + private DirectoryI _parent; + private boolean _destroyed; + private Identity _id; + private Freeze.Connection _connection; + private IdentityNodeMap _map; + private PersistentDirectory _dir; + + private static java.util.Map<DirectoryI, java.util.List<String> > _reapMap = + new java.util.HashMap<DirectoryI, java.util.List<String> >(); + +} diff --git a/java/demo/book/map_filesystem/FilesystemI/FileI.java b/java/demo/book/map_filesystem/FilesystemI/FileI.java new file mode 100644 index 00000000000..8014c9fa5cf --- /dev/null +++ b/java/demo/book/map_filesystem/FilesystemI/FileI.java @@ -0,0 +1,102 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package FilesystemI; + +import Ice.*; +import Filesystem.*; +import FilesystemI.*; + +public class FileI extends _FileDisp implements NodeI, _FileOperations +{ + public synchronized String + name(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + return _file.name; + } + + public Identity + id() + { + return _id; + } + + public synchronized String[] + read(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + return _file.text; + } + + public synchronized void + write(String[] text, Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + _file.text = (String[])text.clone(); + _map.put(_id, _file); + } + + public void + destroy(Current c) + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + _destroyed = true; + } + + synchronized(_parent._lcMutex) + { + c.adapter.remove(c.id); + _parent.addReapEntry(_file.name); + _map.remove(c.id); + } + } + + public FileI(ObjectAdapter adapter, Ice.Identity id, PersistentFile file, DirectoryI parent) + { + _connection = Freeze.Util.createConnection(adapter.getCommunicator(), _envName); + _map = new IdentityNodeMap(_connection, _dbName, false); + _id = id; + _file = file; + _parent = parent; + _destroyed = false; + } + + public FilePrx + activate(Ice.ObjectAdapter a) + { + return FilePrxHelper.uncheckedCast(a.add(this, _id)); + } + + public static String _envName; + public static String _dbName; + + private DirectoryI _parent; + private boolean _destroyed; + private Identity _id; + private Freeze.Connection _connection; + private IdentityNodeMap _map; + private PersistentFile _file; +} diff --git a/java/demo/book/map_filesystem/FilesystemI/NodeI.java b/java/demo/book/map_filesystem/FilesystemI/NodeI.java new file mode 100644 index 00000000000..52162b64b85 --- /dev/null +++ b/java/demo/book/map_filesystem/FilesystemI/NodeI.java @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package FilesystemI; + +public interface NodeI +{ + Ice.Identity id(); + Ice.ObjectPrx activate(Ice.ObjectAdapter a); +} diff --git a/java/demo/book/map_filesystem/Grammar.java b/java/demo/book/map_filesystem/Grammar.java new file mode 100644 index 00000000000..92da79a56d0 --- /dev/null +++ b/java/demo/book/map_filesystem/Grammar.java @@ -0,0 +1,202 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Grammar +{ + Grammar(Parser p) + { + _parser = p; + _scanner = new Scanner(_parser); + } + + void + parse() + { + while(true) + { + try + { + _token = _scanner.nextToken(); + if(_token == null) + { + return; + } + else if(_token.type == Token.TOK_SEMI) + { + // Continue + } + else if(_token.type == Token.TOK_HELP) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.usage(); + } + else if(_token.type == Token.TOK_EXIT) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + return; + } + else if(_token.type == Token.TOK_LIST) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.list(false); + } + else if(_token.type == Token.TOK_LIST_RECURSIVE) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.list(true); + } + else if(_token.type == Token.TOK_CREATE_FILE) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: mkfile FILE [FILE...]"); + } + _parser.createFile(s); + } + else if(_token.type == Token.TOK_CREATE_DIR) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: mkdir DIR [DIR...]"); + } + _parser.createDir(s); + } + else if(_token.type == Token.TOK_PWD) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + _parser.pwd(); + } + else if(_token.type == Token.TOK_CD) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() > 1) + { + throw new ParseError("usage: cd [DIR]"); + } + else if(s.size() == 0) + { + _parser.cd("/"); + } + else + { + _parser.cd((String)s.get(0)); + } + } + else if(_token.type == Token.TOK_CAT) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() != 1) + { + throw new ParseError("usage: cat FILE"); + } + _parser.cat((String)s.get(0)); + } + else if(_token.type == Token.TOK_WRITE) + { + java.util.LinkedList<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: write FILE [STRING...]"); + } + _parser.write(s); + } + else if(_token.type == Token.TOK_RM) + { + java.util.List<String> s = strings(); + if(_token.type != Token.TOK_SEMI) + { + throw new ParseError("Expected ';'"); + } + if(s.size() == 0) + { + throw new ParseError("usage: rm NAME [NAME...]"); + } + _parser.destroy(s); + } + else + { + _parser.error("parse error"); + } + } + catch(ParseError e) + { + _parser.error("Parse error: " + e.getMessage()); + } + } + } + + private java.util.LinkedList<String> + strings() + { + java.util.LinkedList<String> l = new java.util.LinkedList<String>(); + while(true) + { + _token = _scanner.nextToken(); + if(_token.type != Token.TOK_STRING) + { + return l; + } + l.add(_token.value); + } + } + + static private class ParseError extends RuntimeException + { + ParseError(String msg) + { + super(msg); + } + } + + private Parser _parser; + private Scanner _scanner; + private Token _token; +} diff --git a/java/demo/book/map_filesystem/Parser.java b/java/demo/book/map_filesystem/Parser.java new file mode 100644 index 00000000000..94e4af53654 --- /dev/null +++ b/java/demo/book/map_filesystem/Parser.java @@ -0,0 +1,361 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import Filesystem.*; + +class Parser +{ + Parser(DirectoryPrx root) + { + _dirs = new java.util.LinkedList<DirectoryPrx>(); + _dirs.addFirst(root); + } + + void + usage() + { + System.err.print( + "help Print this message.\n" + + "pwd Print current directory (/ = root).\n" + + "cd [DIR] Change directory (/ or empty = root).\n" + + "ls List current directory.\n" + + "lr Recursively list current directory.\n" + + "mkdir DIR [DIR...] Create directories DIR in current directory.\n" + + "mkfile FILE [FILE...] Create files FILE in current directory.\n" + + "rm NAME [NAME...] Delete directory or file NAME (rm * to delete all).\n" + + "cat FILE List the contents of FILE.\n" + + "write FILE [STRING...] Write STRING to FILE.\n" + + "exit, quit Exit this program.\n"); + } + + void + list(boolean recursive) + { + try + { + list(_dirs.get(0), recursive, 0); + } + catch(Ice.LocalException ex) + { + error(ex.toString()); + } + } + + void + list(Filesystem.DirectoryPrx dir, boolean recursive, int depth) + { + StringBuffer b = new StringBuffer(); + for(int i = 0; i < depth; ++i) + { + b.append('\t'); + } + String indent = b.toString(); + + NodeDesc[] contents = dir.list(); + + for(int i = 0; i < contents.length; ++i) + { + DirectoryPrx d + = contents[i].type == NodeType.DirType + ? DirectoryPrxHelper.uncheckedCast(contents[i].proxy) + : null; + System.out.print(indent + contents[i].name + (d != null ? " (directory)" : " (file)")); + if(d != null && recursive) + { + System.out.println(":"); + list(d, true, ++depth); + } + else + { + System.out.println(); + } + } + } + + void + createFile(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("..")) + { + System.out.println("Cannot create a file named `..'"); + continue; + } + + try + { + dir.createFile(name); + } + catch(NameInUse ex) + { + System.out.println("`" + name + "' exists already"); + } + } + } + + void + createDir(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("..")) + { + System.out.println("Cannot create a directory named `..'"); + continue; + } + + try + { + dir.createDirectory(name); + } + catch(NameInUse ex) + { + System.out.println("`" + name + "' exists already"); + } + } + } + + void + pwd() + { + if(_dirs.size() == 1) + { + System.out.print("/"); + } + else + { + java.util.ListIterator<DirectoryPrx> i = _dirs.listIterator(_dirs.size()); + i.previous(); + while(i.hasPrevious()) + { + System.out.print("/" + i.previous().name()); + } + } + System.out.println(); + } + + void + cd(String name) + { + if(name.equals("/")) + { + while(_dirs.size() > 1) + { + _dirs.removeFirst(); + } + return; + } + + if(name.equals("..")) + { + if(_dirs.size() > 1) + { + _dirs.removeFirst(); + } + return; + } + + DirectoryPrx dir = _dirs.getFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such directory"); + return; + } + if(d.type == NodeType.FileType) + { + System.out.println("`" + name + "': not a directory"); + return; + } + _dirs.addFirst(DirectoryPrxHelper.uncheckedCast(d.proxy)); + } + + void + cat(String name) + { + DirectoryPrx dir = _dirs.getFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file"); + return; + } + if(d.type == NodeType.DirType) + { + System.out.println("`" + name + "': not a file"); + return; + } + FilePrx f = FilePrxHelper.uncheckedCast(d.proxy); + String[] l = f.read(); + for(int i = 0; i < l.length; ++i) + { + System.out.println(l[i]); + } + } + + void + write(java.util.LinkedList<String> args) + { + DirectoryPrx dir = _dirs.getFirst(); + String name = args.getFirst(); + args.removeFirst(); + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file"); + return; + } + if(d.type == NodeType.DirType) + { + System.out.println("`" + name + "': not a file"); + return; + } + FilePrx f = FilePrxHelper.uncheckedCast(d.proxy); + + String[] l = new String[args.size()]; + java.util.Iterator<String> i = args.iterator(); + for(int j = 0; j < args.size(); ++j) + { + l[j] = i.next(); + } + try + { + f.write(l); + } + catch(GenericError ex) + { + System.out.println("`" + name + "': cannot write to file: " + ex.reason); + } + } + + void + destroy(java.util.List<String> names) + { + DirectoryPrx dir = _dirs.getFirst(); + + java.util.Iterator<String> i = names.iterator(); + while(i.hasNext()) + { + String name = i.next(); + if(name.equals("*")) + { + NodeDesc[] nodes = dir.list(); + for(int j = 0; j < nodes.length; ++j) + { + try + { + nodes[j].proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + nodes[j].name + "': " + ex.reason); + } + } + return; + } + else + { + NodeDesc d; + try + { + d = dir.find(name); + } + catch(NoSuchName ex) + { + System.out.println("`" + name + "': no such file or directory"); + return; + } + try + { + d.proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + name + "': " + ex.reason); + } + } + } + + } + + void + error(String s) + { + System.err.println("error: " + s); + } + + void + warning(String s) + { + System.err.println("warning: " + s); + } + + String + getInput() + { + System.out.print("> "); + System.out.flush(); + + try + { + return _in.readLine(); + } + catch(java.io.IOException e) + { + return null; + } + } + + int + parse() + { + _in = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); + + Grammar g = new Grammar(this); + g.parse(); + + return 0; + } + + int + parse(java.io.BufferedReader in) + { + _in = in; + + Grammar g = new Grammar(this); + g.parse(); + + return 0; + } + + private java.util.LinkedList<DirectoryPrx> _dirs; + + private java.io.BufferedReader _in; +} diff --git a/java/demo/book/map_filesystem/README b/java/demo/book/map_filesystem/README new file mode 100644 index 00000000000..b0e8d943879 --- /dev/null +++ b/java/demo/book/map_filesystem/README @@ -0,0 +1,13 @@ +This demo presents an implementation of the filesystem +application based on a Freeze map, as discussed in +the Freeze chapter of the Ice manual. + +To run it, start the server in a window: + +$ java Server + +Then run the client in a separate window: + +$ java Client + +Type "help" at the client prompt to see a list of commands. diff --git a/java/demo/book/map_filesystem/Scanner.java b/java/demo/book/map_filesystem/Scanner.java new file mode 100644 index 00000000000..d318ed291f0 --- /dev/null +++ b/java/demo/book/map_filesystem/Scanner.java @@ -0,0 +1,283 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Scanner +{ + Scanner(Parser p) + { + _parser = p; + } + + Token + nextToken() + { + String s = next(); + if(s == null) + { + return null; + } + + if(s.equals(";")) + { + return new Token(Token.TOK_SEMI); + } + else if(s.equals("help")) + { + return new Token(Token.TOK_HELP); + } + else if(s.equals("exit") || s.equals("quit")) + { + return new Token(Token.TOK_EXIT); + } + else if(s.equals("ls")) + { + return new Token(Token.TOK_LIST); + } + else if(s.equals("lr")) + { + return new Token(Token.TOK_LIST_RECURSIVE); + } + else if(s.equals("mkfile")) + { + return new Token(Token.TOK_CREATE_FILE); + } + else if(s.equals("mkdir")) + { + return new Token(Token.TOK_CREATE_DIR); + } + else if(s.equals("pwd")) + { + return new Token(Token.TOK_PWD); + } + else if(s.equals("cd")) + { + return new Token(Token.TOK_CD); + } + else if(s.equals("cat")) + { + return new Token(Token.TOK_CAT); + } + else if(s.equals("write")) + { + return new Token(Token.TOK_WRITE); + } + else if(s.equals("rm")) + { + return new Token(Token.TOK_RM); + } + else + { + return new Token(Token.TOK_STRING, s); + } + } + + static private class EndOfInput extends Exception + { + } + + private char + get() + throws EndOfInput + { + // + // If there is an character in the unget buffer, return it. + // + if(_unget) + { + _unget = false; + return _ungetChar; + } + + // + // No current buffer? + // + if(_buf == null) + { + _buf = _parser.getInput(); + _pos = 0; + if(_buf == null) + { + throw new EndOfInput(); + } + } + + // + // At the end-of-buffer? + // + while(_pos >= _buf.length()) + { + _buf = null; + _pos = 0; + return '\n'; + } + + return _buf.charAt(_pos++); + } + + // + // unget only works with one character. + // + private void + unget(char c) + { + assert(!_unget); + _unget = true; + _ungetChar = c; + } + + private String + next() + { + // + // Eat any whitespace. + // + char c; + try + { + do + { + c = get(); + } + while(Character.isWhitespace(c) && c != '\n'); + } + catch(EndOfInput ignore) + { + return null; + } + + StringBuffer buf = new StringBuffer(); + + if(c == ';' || c == '\n') + { + buf.append(';'); + } + else if(c == '\'') + { + try + { + while(true) + { + c = get(); + if(c == '\'') + { + break; + } + else + { + buf.append(c); + } + } + } + catch(EndOfInput e) + { + _parser.warning("EOF in string"); + } + } + else if(c == '\"') + { + try + { + while(true) + { + c = get(); + if(c == '\"') + { + break; + } + else if(c == '\\') + { + try + { + char next = get(); + switch(next) + { + case '\\': + case '"': + { + buf.append(next); + break; + } + + case 'n': + { + buf.append('\n'); + break; + } + + case 'r': + { + buf.append('\r'); + break; + } + + case 't': + { + buf.append('\t'); + break; + } + + case 'f': + { + buf.append('\f'); + break; + } + + default: + { + buf.append(c); + unget(next); + } + } + } + catch(EndOfInput e) + { + buf.append(c); + } + } + else + { + buf.append(c); + } + } + } + catch(EndOfInput e) + { + _parser.warning("EOF in string"); + } + } + else + { + // + // Otherwise it's a string. + // + try + { + do + { + buf.append(c); + c = get(); + } + while(!Character.isWhitespace(c) && c != ';' && c != '\n'); + + unget(c); + } + catch(EndOfInput ignore) + { + } + } + + return buf.toString(); + } + + private Parser _parser; + private boolean _unget = false; + private char _ungetChar; + private String _buf = null; + private int _pos; +} diff --git a/java/demo/book/map_filesystem/Server.java b/java/demo/book/map_filesystem/Server.java new file mode 100644 index 00000000000..b9666633b71 --- /dev/null +++ b/java/demo/book/map_filesystem/Server.java @@ -0,0 +1,87 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import Filesystem.*; +import FilesystemI.*; + +public class Server extends Ice.Application +{ + public + Server(String envName) + { + _envName = envName; + } + + public int + run(String[] args) + { + // + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // + // Install object factories. + // + communicator().addObjectFactory(PersistentFile.ice_factory(), PersistentFile.ice_staticId()); + communicator().addObjectFactory(PersistentDirectory.ice_factory(), PersistentDirectory.ice_staticId()); + + // + // Create an object adapter. + // + Ice.ObjectAdapter adapter = + communicator().createObjectAdapterWithEndpoints("MapFilesystem", "default -p 10000"); + + DirectoryI._envName = _envName; + DirectoryI._dbName = "mapfs"; + FileI._envName = _envName; + FileI._dbName = "mapfs"; + + // + // Find the persistent node for the root directory, + // or create it if not found. + // + Freeze.Connection connection = Freeze.Util.createConnection(communicator(), _envName); + IdentityNodeMap persistentMap = new IdentityNodeMap(connection, FileI._dbName, true); + + Ice.Identity rootId = communicator().stringToIdentity("RootDir"); + PersistentDirectory pRoot = (PersistentDirectory)persistentMap.get(rootId); + if(pRoot == null) + { + pRoot = new PersistentDirectory(); + pRoot.name ="/"; + pRoot.nodes = new java.util.HashMap<java.lang.String, NodeDesc>(); + persistentMap.put(rootId, pRoot); + } + DirectoryI dir = new DirectoryI(adapter, rootId, pRoot, null); + dir.activate(adapter); + + // + // Ready to accept requests now. + // + adapter.activate(); + + // + // Wait until we are done. + // + communicator().waitForShutdown(); + + return 0; + } + + public static void + main(String[] args) + { + Server app = new Server("db"); + int status = app.main("Server", args, "config.server"); + System.exit(status); + } + + private String _envName; +} diff --git a/java/demo/book/map_filesystem/Token.java b/java/demo/book/map_filesystem/Token.java new file mode 100644 index 00000000000..7fe92e242e0 --- /dev/null +++ b/java/demo/book/map_filesystem/Token.java @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +class Token +{ + public static final int TOK_HELP = 0; + public static final int TOK_EXIT = 1; + public static final int TOK_SEMI = 2; + public static final int TOK_LIST = 3; + public static final int TOK_LIST_RECURSIVE = 4; + public static final int TOK_CREATE_FILE = 5; + public static final int TOK_CREATE_DIR = 6; + public static final int TOK_PWD = 7; + public static final int TOK_CD = 8; + public static final int TOK_CAT = 9; + public static final int TOK_WRITE = 10; + public static final int TOK_RM = 11; + public static final int TOK_STRING = 12; + + int type; + String value; + + Token(int t) + { + type = t; + value = null; + } + + Token(int t, String v) + { + type = t; + value = v; + } +} diff --git a/java/demo/book/map_filesystem/build.xml b/java/demo/book/map_filesystem/build.xml new file mode 100644 index 00000000000..8799fe2a2e4 --- /dev/null +++ b/java/demo/book/map_filesystem/build.xml @@ -0,0 +1,65 @@ +<!-- + ********************************************************************** + + Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. + + This copy of Ice is licensed to you under the terms described in the + ICE_LICENSE file included in this distribution. + + ********************************************************************** +--> + +<project name="demo_book_lifecycle" default="all" basedir="."> + + <!-- set global properties for this build --> + <property name="top.dir" value="../../.."/> + + <!-- import common definitions --> + <import file="${top.dir}/config/common.xml"/> + + <target name="generate" depends="init"> + <!-- Create the output directory for generated code --> + <mkdir dir="${generated.dir}"/> + <slice2java outputdir="${generated.dir}"> + <meta value="${java2metadata}"/> + <includepath> + <pathelement path="${slice.dir}" /> + </includepath> + <fileset dir="." includes="Filesystem.ice"/> + </slice2java> + <slice2freezej ice="on" outputdir="${generated.dir}"> + <includepath> + <pathelement path="${slice.dir}" /> + </includepath> + <fileset dir="."> + <include name="Filesystem.ice"/> + </fileset> + <fileset dir="${slice.dir}/Ice"> + <include name="Identity.ice"/> + </fileset> + <dict name="Filesystem.IdentityNodeMap" key="Ice::Identity" value="Filesystem::PersistentNode"/> + </slice2freezej> + </target> + + <target name="compile" depends="generate"> + <mkdir dir="${class.dir}"/> + <javac srcdir="${generated.dir}" destdir="${class.dir}" + debug="${debug}"> + <classpath refid="ice.classpath"/> + <compilerarg value="${javac.lint}"/> + </javac> + <javac srcdir="." destdir="${class.dir}" + excludes="generated/**" debug="${debug}"> + <classpath refid="ice.classpath"/> + <compilerarg value="${javac.lint}"/> + </javac> + </target> + + <target name="all" depends="compile"/> + + <target name="clean"> + <delete dir="${generated.dir}"/> + <delete dir="${class.dir}"/> + </target> + +</project> diff --git a/java/demo/book/map_filesystem/config.client b/java/demo/book/map_filesystem/config.client new file mode 100644 index 00000000000..6f0ba50b98f --- /dev/null +++ b/java/demo/book/map_filesystem/config.client @@ -0,0 +1,28 @@ +# +# The client reads this property to create the reference to the root +# "directory" object in the server. +# +RootDir.Proxy=RootDir:default -p 10000 + +# +# Warn about connection exceptions +# +Ice.Warn.Connections=1 + +# +# Network Tracing +# +# 0 = no network tracing +# 1 = trace connection establishment and closure +# 2 = like 1, but more detailed +# 3 = like 2, but also trace data transfer +# +#Ice.Trace.Network=1 + +# +# Protocol Tracing +# +# 0 = no protocol tracing +# 1 = trace protocol messages +# +#Ice.Trace.Protocol=1 diff --git a/java/demo/book/map_filesystem/config.server b/java/demo/book/map_filesystem/config.server new file mode 100644 index 00000000000..8ee5723e944 --- /dev/null +++ b/java/demo/book/map_filesystem/config.server @@ -0,0 +1,49 @@ +# +# Configure the server endpoints. +# +FreezeFilesystem.Endpoints=default -p 10000 + +# +# Freeze Map Tracing. +# +# 0 = No map activity trace (default). +# 1 = Trace database open and close. +# 2 = Also trace iterator and transaction operations, and reference +# counting of the underlying database. +# +Freeze.Trace.Map=1 + +# +# Freeze Evictor Tracing. +# +# 0 = No evictor activity trace (default). +# 1 = Trace Ice object and facet creation and destruction, facet +# streaming time, facet saving time, object eviction (every 50 +# objects) and evictor deactivation. +# 2 = Also trace object lookups, and all object evictions. +# 3 = Also trace object retrieval from the database. +# +Freeze.Trace.Evictor=2 + +# +# Warn about connection exceptions +# +Ice.Warn.Connections=1 + +# +# Network Tracing +# +# 0 = no network tracing +# 1 = trace connection establishment and closure +# 2 = like 1, but more detailed +# 3 = like 2, but also trace data transfer +# +#Ice.Trace.Network=1 + +# +# Protocol Tracing +# +# 0 = no protocol tracing +# 1 = trace protocol messages +# +#Ice.Trace.Protocol=1 diff --git a/java/demo/book/map_filesystem/db/.gitignore b/java/demo/book/map_filesystem/db/.gitignore new file mode 100644 index 00000000000..39af5887579 --- /dev/null +++ b/java/demo/book/map_filesystem/db/.gitignore @@ -0,0 +1 @@ +# Dummy file, so that git retains this otherwise empty directory. diff --git a/java/demo/book/freeze_filesystem/expect.py b/java/demo/book/map_filesystem/expect.py index 555fc67854a..3504eff9099 100755 --- a/java/demo/book/freeze_filesystem/expect.py +++ b/java/demo/book/map_filesystem/expect.py @@ -24,7 +24,7 @@ except ImportError: import demoscript.Util demoscript.Util.defaultLanguage = "Java" -import demoscript.book.freeze_filesystem +import demoscript.book.map_filesystem print "cleaning databases...", sys.stdout.flush() @@ -35,4 +35,4 @@ server = demoscript.Util.spawn('java Server --Ice.PrintAdapterReady') server.expect('.* ready') client = demoscript.Util.spawn('java Client') -demoscript.book.freeze_filesystem.run(client, server) +demoscript.book.map_filesystem.run(client, server) |