diff options
29 files changed, 1776 insertions, 2 deletions
diff --git a/cpp/demo/book/Makefile b/cpp/demo/book/Makefile index 569470347c6..9468eac283d 100644 --- a/cpp/demo/book/Makefile +++ b/cpp/demo/book/Makefile @@ -12,7 +12,8 @@ top_srcdir = ../.. include $(top_srcdir)/config/Make.rules SUBDIRS = printer \ - simple_filesystem + simple_filesystem \ + freeze_filesystem $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/demo/book/Makefile.mak b/cpp/demo/book/Makefile.mak index 6b31ee4401d..a4185d20fd1 100644 --- a/cpp/demo/book/Makefile.mak +++ b/cpp/demo/book/Makefile.mak @@ -11,7 +11,7 @@ top_srcdir = ..\.. !include $(top_srcdir)\config\Make.rules.mak -SUBDIRS = printer simple_filesystem +SUBDIRS = printer simple_filesystem freeze_filesystem $(EVERYTHING):: @for %i in ( $(SUBDIRS) ) do \ diff --git a/cpp/demo/book/README b/cpp/demo/book/README index 07162207955..6c7ad26e4fe 100644 --- a/cpp/demo/book/README +++ b/cpp/demo/book/README @@ -15,3 +15,8 @@ Demos in this directory: An implementation of the simple (non-persistent, non-life-cycle) version of the filesystem example. + +- freeze_filesystem + + An implementation of the persistent version of the filesystem + example described in the Freeze chapter. diff --git a/cpp/demo/book/freeze_filesystem/.depend b/cpp/demo/book/freeze_filesystem/.depend new file mode 100644 index 00000000000..29c6f5218d0 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/.depend @@ -0,0 +1,9 @@ +Filesystem$(OBJEXT): Filesystem.cpp ./Filesystem.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Config.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/IceUtil/Shared.h ../../../include/Ice/Proxy.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/GCShared.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/InstanceF.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/LocalException.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/ObjectFactory.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/ScopedArray.h +Client$(OBJEXT): Client.cpp ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Config.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/IceUtil/Shared.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/InstanceF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StreamF.h ../../../include/Ice/StatsF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/Proxy.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/Object.h ../../../include/Ice/GCShared.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/RecMutex.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/Direct.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/FacetMap.h ../../../include/Ice/Locator.h ../../../include/Ice/ProcessF.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/IceUtil/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ./Filesystem.h +PersistentFilesystem$(OBJEXT): PersistentFilesystem.cpp ./PersistentFilesystem.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Config.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/IceUtil/Shared.h ../../../include/Ice/Proxy.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/GCShared.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/InstanceF.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ./Filesystem.h ../../../include/Ice/LocalException.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/ObjectFactory.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/ScopedArray.h +PersistentFilesystemI$(OBJEXT): PersistentFilesystemI.cpp ./PersistentFilesystemI.h ./PersistentFilesystem.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Config.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/IceUtil/Shared.h ../../../include/Ice/Proxy.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/GCShared.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/InstanceF.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ./Filesystem.h ../../../include/IceUtil/IceUtil.h ../../../include/IceUtil/AbstractMutex.h ../../../include/IceUtil/Algorithm.h ../../../include/IceUtil/ArgVector.h ../../../include/IceUtil/Base64.h ../../../include/IceUtil/Cache.h ../../../include/IceUtil/CountDownLatch.h ../../../include/IceUtil/CtrlCHandler.h ../../../include/IceUtil/Functional.h ../../../include/IceUtil/InputUtil.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/MD5.h ../../../include/IceUtil/Options.h ../../../include/IceUtil/RecMutex.h ../../../include/IceUtil/OutputUtil.h ../../../include/IceUtil/RWRecMutex.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Random.h ../../../include/IceUtil/ScopedArray.h ../../../include/IceUtil/StringUtil.h ../../../include/IceUtil/UUID.h ../../../include/Freeze/Freeze.h ../../../include/Freeze/Initialize.h ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/OutgoingAsync.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/FacetMap.h ../../../include/Ice/Locator.h ../../../include/Ice/ProcessF.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Freeze/EvictorF.h ../../../include/Freeze/ConnectionF.h ../../../include/Freeze/Index.h ../../../include/Freeze/DB.h ../../../include/Freeze/Transaction.h ../../../include/Freeze/Evictor.h ../../../include/Freeze/Exception.h ../../../include/Freeze/Map.h ../../../include/Freeze/Connection.h ../../../include/Freeze/TransactionHolder.h +Server$(OBJEXT): Server.cpp ./PersistentFilesystemI.h ./PersistentFilesystem.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Config.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/IceUtil/Shared.h ../../../include/Ice/Proxy.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/GCShared.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/InstanceF.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ./Filesystem.h ../../../include/IceUtil/IceUtil.h ../../../include/IceUtil/AbstractMutex.h ../../../include/IceUtil/Algorithm.h ../../../include/IceUtil/ArgVector.h ../../../include/IceUtil/Base64.h ../../../include/IceUtil/Cache.h ../../../include/IceUtil/CountDownLatch.h ../../../include/IceUtil/CtrlCHandler.h ../../../include/IceUtil/Functional.h ../../../include/IceUtil/InputUtil.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/MD5.h ../../../include/IceUtil/Options.h ../../../include/IceUtil/RecMutex.h ../../../include/IceUtil/OutputUtil.h ../../../include/IceUtil/RWRecMutex.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Random.h ../../../include/IceUtil/ScopedArray.h ../../../include/IceUtil/StringUtil.h ../../../include/IceUtil/UUID.h ../../../include/Freeze/Freeze.h ../../../include/Freeze/Initialize.h ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/OutgoingAsync.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/FacetMap.h ../../../include/Ice/Locator.h ../../../include/Ice/ProcessF.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Freeze/EvictorF.h ../../../include/Freeze/ConnectionF.h ../../../include/Freeze/Index.h ../../../include/Freeze/DB.h ../../../include/Freeze/Transaction.h ../../../include/Freeze/Evictor.h ../../../include/Freeze/Exception.h ../../../include/Freeze/Map.h ../../../include/Freeze/Connection.h ../../../include/Freeze/TransactionHolder.h +Filesystem.cpp: Filesystem.ice +PersistentFilesystem.cpp: PersistentFilesystem.ice Filesystem.ice +Filesystem.ice: $(SLICE2CPP) $(SLICEPARSERLIB) +PersistentFilesystem.ice: $(SLICE2CPP) $(SLICEPARSERLIB) diff --git a/cpp/demo/book/freeze_filesystem/Client.cpp b/cpp/demo/book/freeze_filesystem/Client.cpp new file mode 100644 index 00000000000..96886b1228b --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/Client.cpp @@ -0,0 +1,151 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <Filesystem.h> + +using namespace std; +using namespace Filesystem; + +class FilesystemClient : public Ice::Application +{ + virtual int run(int argc, char* argv[]); + virtual void interruptCallback(int); +}; + +int +main(int argc, char* argv[]) +{ + FilesystemClient app; + return app.main(argc, argv, "config.client"); +} + +int +FilesystemClient::run(int argc, char* argv[]) +{ + // + // Since this is an interactive demo we want the custom interrupt + // callback to be called when the process is interrupted. + // + callbackOnInterrupt(); + + // + // Create a proxy for the root directory. + // + DirectoryPrx rootDir = DirectoryPrx::checkedCast(communicator()->propertyToProxy("RootDir.Proxy")); + if(!rootDir) + { + cerr << argv[0] << ": invalid proxy" << endl; + return EXIT_FAILURE; + } + + // + // Create a file called "README" in the root directory. + // + try + { + FilePrx readme = rootDir->createFile("README"); + Lines text; + text.push_back("This file system contains a collection of poetry."); + readme->write(text); + cout << "Created README." << endl; + } + catch(const NameInUse&) + { + // + // Ignore - file already exists. + // + } + + // + // Create a directory called "Coleridge" in the root directory. + // + DirectoryPrx coleridge; + try + { + coleridge = rootDir->createDirectory("Coleridge"); + cout << "Created Coleridge." << endl; + } + catch(const NameInUse&) + { + NodeDesc desc = rootDir->resolve("Coleridge"); + coleridge = DirectoryPrx::checkedCast(desc.proxy); + assert(coleridge); + } + + // + // Create a file called "Kubla_Khan" in the Coleridge directory. + // + try + { + FilePrx file = coleridge->createFile("Kubla_Khan"); + Lines text; + text.push_back("In Xanadu did Kubla Khan"); + text.push_back("A stately pleasure-dome decree:"); + text.push_back("Where Alph, the sacred river, ran"); + text.push_back("Through caverns measureless to man"); + text.push_back("Down to a sunless sea."); + file->write(text); + cout << "Created Coleridge/Kubla_Khan." << endl; + } + catch(const NameInUse&) + { + // + // Ignore - file already exists. + // + } + + cout << "Contents of filesystem:" << endl; + NodeDict contents = rootDir->list(RecursiveList); + NodeDict::iterator p; + for(p = contents.begin(); p != contents.end(); ++p) + { + cout << " " << p->first << endl; + } + + NodeDesc desc = rootDir->resolve("Coleridge/Kubla_Khan"); + FilePrx file = FilePrx::checkedCast(desc.proxy); + assert(file); + Lines text = file->read(); + cout << "Contents of file Coleridge/Kubla_Khan:" << endl; + for(Lines::iterator i = text.begin(); i != text.end(); ++i) + { + cout << " " << *i << endl; + } + + // + // Destroy the filesystem. + // + contents = rootDir->list(NormalList); + for(p = contents.begin(); p != contents.end(); ++p) + { + cout << "Destroying " << p->first << "..." << endl; + p->second.proxy->destroy(); + } + + return EXIT_SUCCESS; +} + +void +FilesystemClient::interruptCallback(int) +{ + try + { + communicator()->destroy(); + } + catch(const IceUtil::Exception& ex) + { + cerr << appName() << ": " << ex << endl; + } + catch(...) + { + cerr << appName() << ": unknown exception" << endl; + } + exit(EXIT_SUCCESS); +} diff --git a/cpp/demo/book/freeze_filesystem/Filesystem.ice b/cpp/demo/book/freeze_filesystem/Filesystem.ice new file mode 100644 index 00000000000..61917b1e888 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/Filesystem.ice @@ -0,0 +1,69 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 IllegalName extends GenericError {}; + exception NoSuchName extends GenericError {}; + + interface Node + { + idempotent string name(); + + ["freeze:write"] + void destroy() + throws PermissionDenied; + }; + + sequence<string> Lines; + + interface File extends Node + { + idempotent Lines read(); + + ["freeze:write"] + idempotent void write(Lines text) + throws GenericError; + }; + + enum NodeType { DirType, FileType }; + + struct NodeDesc + { + string name; + NodeType type; + Node* proxy; + }; + + dictionary<string, NodeDesc> NodeDict; + + enum ListMode { NormalList, RecursiveList }; + + interface Directory extends Node + { + idempotent NodeDict list(ListMode mode); + + idempotent NodeDesc resolve(string path) + throws NoSuchName; + + ["freeze:write"] + File* createFile(string name) + throws NameInUse, IllegalName; + + ["freeze:write"] + Directory* createDirectory(string name) + throws NameInUse, IllegalName; + }; +}; diff --git a/cpp/demo/book/freeze_filesystem/Makefile b/cpp/demo/book/freeze_filesystem/Makefile new file mode 100644 index 00000000000..880cf9f4e12 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/Makefile @@ -0,0 +1,49 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client +SERVER = server + +TARGETS = $(CLIENT) $(SERVER) + +OBJS = Filesystem.o + +COBJS = Client.o + +SOBJS = PersistentFilesystem.o \ + PersistentFilesystemI.o \ + Server.o + +SRCS = $(OBJS:.o=.cpp) \ + $(COBJS:.o=.cpp) \ + $(SOBJS:.o=.cpp) \ + $(COLOBJS:.o=.cpp) + +SLICE_SRCS = Filesystem.ice PersistentFilesystem.ice + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. $(READLINE_FLAGS) $(CPPFLAGS) +SLICE2CPPFLAGS := -I. $(SLICE2CPPFLAGS) + +$(CLIENT): $(OBJS) $(COBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(COBJS) $(LIBS) $(READLINE_LIBS) + +$(SERVER): $(OBJS) $(SOBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SOBJS) $(DB_RPATH_LINK) -lFreeze $(LIBS) + +clean:: + rm -f Grammar.cpp Grammar.h + rm -f Scanner.cpp + +include .depend diff --git a/cpp/demo/book/freeze_filesystem/Makefile.mak b/cpp/demo/book/freeze_filesystem/Makefile.mak new file mode 100644 index 00000000000..fb5130dd3d2 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/Makefile.mak @@ -0,0 +1,54 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ..\..\.. + +CLIENT = client.exe +SERVER = server.exe + +TARGETS = $(CLIENT) $(SERVER) + +OBJS = Library.obj + +COBJS = Client.obj + +SOBJS = PersistentFilesystem.obj \ + PersistentFilesystemI.obj \ + Server.obj + +SRCS = $(OBJS:.obj=.cpp) \ + $(COBJS:.obj=.cpp) \ + $(SOBJS:.obj=.cpp) \ + $(COLOBJS:.obj=.cpp) + +!include $(top_srcdir)/config/Make.rules.mak + +CPPFLAGS = -I. -Idummyinclude $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN +SLICE2CPPFLAGS = -I. $(SLICE2CPPFLAGS) + +!if "$(CPP_COMPILER)" != "BCC2006" & "$(OPTIMIZE)" != "yes" +CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb) +SPDBFLAGS = /pdb:$(SERVER:.exe=.pdb) +!endif + +$(CLIENT): $(OBJS) $(COBJS) + $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(OBJS) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +$(SERVER): $(OBJS) $(SOBJS) + $(LINK) $(LD_EXEFLAGS) $(SPDBFLAGS) $(SETARGV) $(OBJS) $(SOBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) freeze$(LIBSUFFIX).lib + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +clean:: + del /q Filesystem.cpp Filesystem.h + del /q PersistentFilesystem.cpp PersistentFilesystem.h + +!include .depend diff --git a/cpp/demo/book/freeze_filesystem/PersistentFilesystem.ice b/cpp/demo/book/freeze_filesystem/PersistentFilesystem.ice new file mode 100644 index 00000000000..174ba7aec3d --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/PersistentFilesystem.ice @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#include <Filesystem.ice> + +module Filesystem +{ + class PersistentDirectory; + + class PersistentNode implements Node + { + string nodeName; + PersistentDirectory* parent; + }; + + class PersistentFile extends PersistentNode implements File + { + Lines text; + }; + + class PersistentDirectory extends PersistentNode implements Directory + { + ["freeze:write"] + void removeNode(string name); + + NodeDict nodes; + }; +}; diff --git a/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.cpp b/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.cpp new file mode 100644 index 00000000000..af6f5a853ab --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.cpp @@ -0,0 +1,331 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#include <PersistentFilesystemI.h> + +using namespace std; + +// +// Filesystem::NodeI +// +Ice::ObjectAdapterPtr Filesystem::NodeI::_adapter; +Freeze::EvictorPtr Filesystem::NodeI::_evictor; + +Filesystem::NodeI::NodeI() +{ +} + +Filesystem::NodeI::NodeI(const Ice::Identity& id) + : _ID(id) +{ +} + +// +// Filesystem::FileI +// +string +Filesystem::FileI::name(const Ice::Current&) +{ + return nodeName; +} + +void +Filesystem::FileI::destroy(const Ice::Current&) +{ + parent->removeNode(nodeName); + _evictor->remove(_ID); +} + +Filesystem::Lines +Filesystem::FileI::read(const Ice::Current&) +{ + IceUtil::Mutex::Lock lock(*this); + return text; +} + +void +Filesystem::FileI::write(const Filesystem::Lines& text, const Ice::Current&) +{ + IceUtil::Mutex::Lock lock(*this); + this->text = text; +} + +Filesystem::FileI::FileI() +{ +} + +Filesystem::FileI::FileI(const Ice::Identity& id) + : NodeI(id) +{ +} + +// +// Filesystem::DirectoryI +// +string +Filesystem::DirectoryI::name(const Ice::Current& current) +{ + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + return nodeName; +} + +void +Filesystem::DirectoryI::destroy(const Ice::Current& current) +{ + if(!parent) + { + throw Filesystem::PermissionDenied("cannot remove root directory"); + } + + NodeDict children; + + { + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + children = nodes; + _destroyed = true; + } + + // + // We must iterate over the children outside of synchronization. + // + for(NodeDict::iterator p = children.begin(); p != children.end(); ++p) + { + p->second.proxy->destroy(); + } + + assert(nodes.empty()); + + parent->removeNode(nodeName); + _evictor->remove(_ID); +} + +Filesystem::NodeDict +Filesystem::DirectoryI::list(Filesystem::ListMode mode, const Ice::Current& current) +{ + NodeDict result; + { + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + result = nodes; + } + + if(mode == RecursiveList) + { + for(NodeDict::iterator p = result.begin(); p != result.end(); ++p) + { + if(p->second.type == DirType) + { + DirectoryPrx dir = DirectoryPrx::uncheckedCast(p->second.proxy); + NodeDict d = dir->list(mode); + for(NodeDict::iterator q = d.begin(); q != d.end(); ++q) + { + result[p->second.name + "/" + q->second.name] = q->second; + } + } + } + } + + return result; +} + +Filesystem::NodeDesc +Filesystem::DirectoryI::resolve(const string& path, const Ice::Current& current) +{ + string::size_type pos = path.find('/'); + string child, remainder; + if(pos == string::npos) + { + child = path; + } + else + { + child = path.substr(0, pos); + pos = path.find_first_not_of("/", pos); + if(pos != string::npos) + { + remainder = path.substr(pos); + } + } + + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + NodeDict::iterator p = nodes.find(child); + if(p == nodes.end()) + { + throw NoSuchName("no node exists with name `" + child + "'"); + } + + if(remainder.empty()) + { + return p->second; + } + else + { + if(p->second.type != DirType) + { + throw NoSuchName("node `" + child + "' is not a directory"); + } + DirectoryPrx dir = DirectoryPrx::checkedCast(p->second.proxy); + assert(dir); + return dir->resolve(remainder); + } +} + +Filesystem::DirectoryPrx +Filesystem::DirectoryI::createDirectory(const string& name, const Ice::Current& current) +{ + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + checkName(name); + + Ice::Identity id = current.adapter->getCommunicator()->stringToIdentity(IceUtil::generateUUID()); + PersistentDirectoryPtr dir = new DirectoryI(id); + dir->nodeName = name; + dir->parent = PersistentDirectoryPrx::uncheckedCast(current.adapter->createProxy(current.id)); + DirectoryPrx proxy = DirectoryPrx::uncheckedCast(_evictor->add(dir, id)); + + NodeDesc nd; + nd.name = name; + nd.type = DirType; + nd.proxy = proxy; + nodes[name] = nd; + + return proxy; +} + +Filesystem::FilePrx +Filesystem::DirectoryI::createFile(const string& name, const Ice::Current& current) +{ + IceUtil::Mutex::Lock lock(*this); + + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + checkName(name); + + Ice::Identity id = current.adapter->getCommunicator()->stringToIdentity(IceUtil::generateUUID()); + PersistentFilePtr file = new FileI(id); + file->nodeName = name; + file->parent = PersistentDirectoryPrx::uncheckedCast(current.adapter->createProxy(current.id)); + FilePrx proxy = FilePrx::uncheckedCast(_evictor->add(file, id)); + + NodeDesc nd; + nd.name = name; + nd.type = FileType; + nd.proxy = proxy; + nodes[name] = nd; + + return proxy; +} + +void +Filesystem::DirectoryI::removeNode(const string& name, const Ice::Current&) +{ + IceUtil::Mutex::Lock lock(*this); + + NodeDict::iterator p = nodes.find(name); + assert(p != nodes.end()); + nodes.erase(p); +} + +Filesystem::DirectoryI::DirectoryI() : + _destroyed(false) +{ +} + +Filesystem::DirectoryI::DirectoryI(const Ice::Identity& id) : + NodeI(id), _destroyed(false) +{ +} + +void +Filesystem::DirectoryI::checkName(const string& name) const +{ + if(name.empty() || name.find('/') != string::npos) + { + IllegalName e; + e.reason = "illegal name `" + name + "'"; + throw e; + } + + NodeDict::const_iterator p = nodes.find(name); + if(p != nodes.end()) + { + throw NameInUse("name `" + name + "' is already in use"); + } +} + +// +// Filesystem::NodeFactory +// +Ice::ObjectPtr +Filesystem::NodeFactory::create(const string& type) +{ + if(type == "::Filesystem::PersistentFile") + { + return new FileI; + } + else if(type == "::Filesystem::PersistentDirectory") + { + return new DirectoryI; + } + else + { + assert(false); + return 0; + } +} + +void +Filesystem::NodeFactory::destroy() +{ +} + +// +// Filesystem::NodeInitializer +// +void +Filesystem::NodeInitializer::initialize(const Ice::ObjectAdapterPtr&, + const Ice::Identity& id, + const string& facet, + const Ice::ObjectPtr& obj) +{ + NodeIPtr node = NodeIPtr::dynamicCast(obj); + assert(node); + const_cast<Ice::Identity&>(node->_ID) = id; +} diff --git a/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.h b/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.h new file mode 100644 index 00000000000..6114fc02210 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/PersistentFilesystemI.h @@ -0,0 +1,98 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef PERSISTENT_FILESYSTEM_I_H +#define PERSISTENT_FILESYSTEM_I_H + +#include <PersistentFilesystem.h> +#include <IceUtil/IceUtil.h> +#include <Freeze/Freeze.h> + +namespace Filesystem +{ + +class NodeI : virtual public PersistentNode, + public IceUtil::AbstractMutexI<IceUtil::Mutex> +{ +public: + + static Ice::ObjectAdapterPtr _adapter; + static Freeze::EvictorPtr _evictor; + +protected: + + NodeI(); + NodeI(const Ice::Identity&); + +public: + + const Ice::Identity _ID; +}; +typedef IceUtil::Handle<NodeI> NodeIPtr; + +class FileI : virtual public PersistentFile, + virtual public NodeI +{ +public: + + virtual std::string name(const Ice::Current&); + virtual void destroy(const Ice::Current&); + + virtual Lines read(const Ice::Current&); + virtual void write(const Lines&, const Ice::Current&); + + FileI(); + FileI(const Ice::Identity&); +}; + +class DirectoryI : virtual public PersistentDirectory, + virtual public NodeI +{ +public: + + virtual std::string name(const Ice::Current&); + virtual void destroy(const Ice::Current&); + + virtual NodeDict list(ListMode, const Ice::Current&); + virtual NodeDesc resolve(const std::string&, const Ice::Current&); + virtual DirectoryPrx createDirectory(const std::string&, const Ice::Current&); + virtual FilePrx createFile(const std::string&, const Ice::Current&); + virtual void removeNode(const std::string&, const Ice::Current&); + + DirectoryI(); + DirectoryI(const Ice::Identity&); + +private: + + void checkName(const std::string&) const; + + bool _destroyed; +}; + +class NodeFactory : virtual public Ice::ObjectFactory +{ +public: + + virtual Ice::ObjectPtr create(const std::string&); + virtual void destroy(); +}; + +class NodeInitializer : virtual public Freeze::ServantInitializer +{ +public: + + virtual void initialize(const Ice::ObjectAdapterPtr&, + const Ice::Identity&, + const std::string&, + const Ice::ObjectPtr&); +}; + +} + +#endif diff --git a/cpp/demo/book/freeze_filesystem/Server.cpp b/cpp/demo/book/freeze_filesystem/Server.cpp new file mode 100644 index 00000000000..79dfb9365cc --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/Server.cpp @@ -0,0 +1,84 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#include <PersistentFilesystemI.h> + +using namespace std; +using namespace Filesystem; + +class FilesystemApp : virtual public Ice::Application +{ +public: + + FilesystemApp(const string& envName) : + _envName(envName) + { + } + + virtual int run(int, char*[]) + { + // + // Install object factories. + // + Ice::ObjectFactoryPtr factory = new NodeFactory; + communicator()->addObjectFactory(factory, PersistentFile::ice_staticId()); + communicator()->addObjectFactory(factory, PersistentDirectory::ice_staticId()); + + // + // Create an object adapter (stored in the NodeI::_adapter static member). + // + NodeI::_adapter = communicator()->createObjectAdapterWithEndpoints("FreezeFilesystem", "default -p 10000"); + + // + // Create the Freeze evictor (stored in the NodeI::_evictor static member). + // + Freeze::ServantInitializerPtr init = new NodeInitializer; + NodeI::_evictor = Freeze::createEvictor(NodeI::_adapter, _envName, "evictorfs", init); + + NodeI::_adapter->addServantLocator(NodeI::_evictor, ""); + + // + // Create the root node if it doesn't exist. + // + Ice::Identity rootId = communicator()->stringToIdentity("RootDir"); + if(!NodeI::_evictor->hasObject(rootId)) + { + PersistentDirectoryPtr root = new DirectoryI(rootId); + root->nodeName = "/"; + NodeI::_evictor->add(root, rootId); + } + + // + // Ready to accept requests now. + // + NodeI::_adapter->activate(); + + // + // Wait until we are done. + // + communicator()->waitForShutdown(); + if(interrupted()) + { + cerr << appName() << ": received signal, shutting down" << endl; + } + + return 0; + } + +private: + + string _envName; +}; + +int +main(int argc, char* argv[]) +{ + FilesystemApp app("db"); + return app.main(argc, argv, "config.server"); +} diff --git a/cpp/demo/book/freeze_filesystem/config.client b/cpp/demo/book/freeze_filesystem/config.client new file mode 100644 index 00000000000..4bd7574216d --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/config.client @@ -0,0 +1,28 @@ +# +# The client reads this property to create the reference to the +# "library" 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/cpp/demo/book/freeze_filesystem/config.server b/cpp/demo/book/freeze_filesystem/config.server new file mode 100644 index 00000000000..2370acc99a5 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/config.server @@ -0,0 +1,27 @@ +FreezeFilesystem.Endpoints=default -p 10000 + +Freeze.Trace.Map=1 +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/cpp/demo/book/freeze_filesystem/db/.dummy b/cpp/demo/book/freeze_filesystem/db/.dummy new file mode 100644 index 00000000000..029d4b7cff2 --- /dev/null +++ b/cpp/demo/book/freeze_filesystem/db/.dummy @@ -0,0 +1 @@ +Dummy file, so that `cvs export' creates this otherwise empty directory. diff --git a/java/demo/book/README b/java/demo/book/README index c269a7ead90..9bc5e919521 100644 --- a/java/demo/book/README +++ b/java/demo/book/README @@ -15,3 +15,8 @@ Demos in this directory: An implementation of the simple (non-persistent, non-life-cycle) version of the filesystem example. + +- freeze_filesystem + + An implementation of the persistent version of the filesystem + example described in the Freeze chapter. diff --git a/java/demo/book/build.xml b/java/demo/book/build.xml index 232a77ab9b2..f67c27bccac 100644 --- a/java/demo/book/build.xml +++ b/java/demo/book/build.xml @@ -14,11 +14,13 @@ <target name="all"> <ant dir="printer"/> <ant dir="simple_filesystem"/> + <ant dir="freeze_filesystem"/> </target> <target name="clean"> <ant dir="printer" target="clean"/> <ant dir="simple_filesystem" target="clean"/> + <ant dir="freeze_filesystem" target="clean"/> </target> </project> diff --git a/java/demo/book/freeze_filesystem/Client.java b/java/demo/book/freeze_filesystem/Client.java new file mode 100644 index 00000000000..10f58722fb7 --- /dev/null +++ b/java/demo/book/freeze_filesystem/Client.java @@ -0,0 +1,154 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 +{ + 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.resolve("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:"); + java.util.Map contents = rootDir.list(ListMode.RecursiveList); + java.util.Iterator p = contents.keySet().iterator(); + while(p.hasNext()) + { + System.out.println(" " + (String)p.next()); + } + + NodeDesc desc = rootDir.resolve("Coleridge/Kubla_Khan"); + FilePrx file = FilePrxHelper.checkedCast(desc.proxy); + assert(file != null); + String[] text = file.read(); + System.out.println("Contents of file Coleridge/Kubla_Khan:"); + for(int i = 0; i < text.length; ++i) + { + System.out.println(" " + text[i]); + } + + // + // Destroy the filesystem. + // + contents = rootDir.list(ListMode.NormalList); + p = contents.entrySet().iterator(); + while(p.hasNext()) + { + java.util.Map.Entry e = (java.util.Map.Entry)p.next(); + NodeDesc d = (NodeDesc)e.getValue(); + System.out.println("Destroying " + (String)e.getKey() + "..."); + 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/DirectoryI.java b/java/demo/book/freeze_filesystem/DirectoryI.java new file mode 100644 index 00000000000..6e63d6edf27 --- /dev/null +++ b/java/demo/book/freeze_filesystem/DirectoryI.java @@ -0,0 +1,258 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 final class DirectoryI extends PersistentDirectory +{ + public + DirectoryI() + { + _destroyed = false; + } + + public + DirectoryI(Ice.Identity id) + { + _ID = id; + nodes = new java.util.HashMap(); + _destroyed = false; + } + + public synchronized String + name(Ice.Current current) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + return nodeName; + } + + public void + destroy(Ice.Current current) + throws PermissionDenied + { + if(parent == null) + { + throw new PermissionDenied("cannot remove root directory"); + } + + java.util.Map children = null; + + synchronized(this) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + children = (java.util.Map)((java.util.HashMap)nodes).clone(); + _destroyed = true; + } + + // + // For consistency with C++, we iterate over the children outside of synchronization. + // + java.util.Iterator p = children.values().iterator(); + while(p.hasNext()) + { + NodeDesc desc = (NodeDesc)p.next(); + desc.proxy.destroy(); + } + + assert(nodes.isEmpty()); + + parent.removeNode(nodeName); + _evictor.remove(_ID); + } + + public java.util.Map + list(ListMode mode, Ice.Current current) + { + java.util.Map result = null; + synchronized(this) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + result = (java.util.Map)((java.util.HashMap)nodes).clone(); + } + + if(mode == ListMode.RecursiveList) + { + java.util.Map children = new java.util.HashMap(); + java.util.Iterator p = result.entrySet().iterator(); + while(p.hasNext()) + { + java.util.Map.Entry e = (java.util.Map.Entry)p.next(); + NodeDesc desc = (NodeDesc)e.getValue(); + if(desc.type == NodeType.DirType) + { + DirectoryPrx dir = DirectoryPrxHelper.uncheckedCast(desc.proxy); + try + { + java.util.Map d = dir.list(mode); + java.util.Iterator q = d.entrySet().iterator(); + while(q.hasNext()) + { + java.util.Map.Entry e2 = (java.util.Map.Entry)q.next(); + NodeDesc desc2 = (NodeDesc)e2.getValue(); + children.put(desc.name + "/" + desc2.name, desc2); + } + } + catch(Ice.ObjectNotExistException ex) + { + // This node may have been destroyed, so skip it. + } + } + } + result.putAll(children); + } + + return result; + } + + public NodeDesc + resolve(String path, Ice.Current current) + throws NoSuchName + { + int pos = path.indexOf('/'); + String child, remainder = null; + if(pos == -1) + { + child = path; + } + else + { + child = path.substring(0, pos); + while(pos < path.length() && path.charAt(pos) == '/') + { + ++pos; + } + if(pos < path.length()) + { + remainder = path.substring(pos); + } + } + + synchronized(this) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + if(!nodes.containsKey(child)) + { + throw new NoSuchName("no node exists with name `" + child + "'"); + } + + NodeDesc desc = (NodeDesc)nodes.get(child); + if(remainder == null) + { + return desc; + } + else + { + if(desc.type != NodeType.DirType) + { + throw new NoSuchName("node `" + child + "' is not a directory"); + } + DirectoryPrx dir = DirectoryPrxHelper.checkedCast(desc.proxy); + assert(dir != null); + return dir.resolve(remainder); + } + } + } + + public synchronized DirectoryPrx + createDirectory(String name, Ice.Current current) + throws IllegalName, + NameInUse + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + checkName(name); + + Ice.Identity id = current.adapter.getCommunicator().stringToIdentity(Ice.Util.generateUUID()); + PersistentDirectory dir = new DirectoryI(id); + dir.nodeName = name; + dir.parent = PersistentDirectoryPrxHelper.uncheckedCast(current.adapter.createProxy(current.id)); + DirectoryPrx proxy = DirectoryPrxHelper.uncheckedCast(_evictor.add(dir, id)); + + NodeDesc nd = new NodeDesc(); + nd.name = name; + nd.type = NodeType.DirType; + nd.proxy = proxy; + nodes.put(name, nd); + + return proxy; + } + + public synchronized FilePrx + createFile(String name, Ice.Current current) + throws IllegalName, + NameInUse + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + checkName(name); + + Ice.Identity id = current.adapter.getCommunicator().stringToIdentity(Ice.Util.generateUUID()); + PersistentFile file = new FileI(id); + file.nodeName = name; + file.parent = PersistentDirectoryPrxHelper.uncheckedCast(current.adapter.createProxy(current.id)); + FilePrx proxy = FilePrxHelper.uncheckedCast(_evictor.add(file, id)); + + NodeDesc nd = new NodeDesc(); + nd.name = name; + nd.type = NodeType.FileType; + nd.proxy = proxy; + nodes.put(name, nd); + + return proxy; + } + + public synchronized void + removeNode(String name, Ice.Current current) + { + assert(nodes.containsKey(name)); + nodes.remove(name); + } + + private + void checkName(String name) + throws IllegalName, NameInUse + { + if(name.length() == 0 || name.indexOf('/') >= 0) + { + throw new IllegalName("illegal name `" + name + "'"); + } + + if(nodes.containsKey(name)) + { + throw new NameInUse("name `" + name + "' is already in use"); + } + } + + public static Ice.ObjectAdapter _adapter; + public static Freeze.Evictor _evictor; + public Ice.Identity _ID; + private boolean _destroyed; +} diff --git a/java/demo/book/freeze_filesystem/FileI.java b/java/demo/book/freeze_filesystem/FileI.java new file mode 100644 index 00000000000..6a59838ec2c --- /dev/null +++ b/java/demo/book/freeze_filesystem/FileI.java @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 final class FileI extends PersistentFile +{ + public + FileI() + { + } + + public + FileI(Ice.Identity id) + { + _ID = id; + } + + public String + name(Ice.Current current) + { + return nodeName; + } + + public void + destroy(Ice.Current current) + throws PermissionDenied + { + parent.removeNode(nodeName); + _evictor.remove(_ID); + } + + public synchronized String[] + read(Ice.Current current) + { + return (String[])text.clone(); + } + + public synchronized void + write(String[] text, Ice.Current current) + throws GenericError + { + this.text = text; + } + + public static Ice.ObjectAdapter _adapter; + public static Freeze.Evictor _evictor; + public Ice.Identity _ID; +} diff --git a/java/demo/book/freeze_filesystem/Filesystem.ice b/java/demo/book/freeze_filesystem/Filesystem.ice new file mode 100644 index 00000000000..61917b1e888 --- /dev/null +++ b/java/demo/book/freeze_filesystem/Filesystem.ice @@ -0,0 +1,69 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 IllegalName extends GenericError {}; + exception NoSuchName extends GenericError {}; + + interface Node + { + idempotent string name(); + + ["freeze:write"] + void destroy() + throws PermissionDenied; + }; + + sequence<string> Lines; + + interface File extends Node + { + idempotent Lines read(); + + ["freeze:write"] + idempotent void write(Lines text) + throws GenericError; + }; + + enum NodeType { DirType, FileType }; + + struct NodeDesc + { + string name; + NodeType type; + Node* proxy; + }; + + dictionary<string, NodeDesc> NodeDict; + + enum ListMode { NormalList, RecursiveList }; + + interface Directory extends Node + { + idempotent NodeDict list(ListMode mode); + + idempotent NodeDesc resolve(string path) + throws NoSuchName; + + ["freeze:write"] + File* createFile(string name) + throws NameInUse, IllegalName; + + ["freeze:write"] + Directory* createDirectory(string name) + throws NameInUse, IllegalName; + }; +}; diff --git a/java/demo/book/freeze_filesystem/NodeFactory.java b/java/demo/book/freeze_filesystem/NodeFactory.java new file mode 100644 index 00000000000..5711943a9fe --- /dev/null +++ b/java/demo/book/freeze_filesystem/NodeFactory.java @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 NodeFactory extends Ice.LocalObjectImpl implements Ice.ObjectFactory +{ + public Ice.Object + create(String type) + { + if(type.equals("::Filesystem::PersistentFile")) + { + return new FileI(); + } + else if(type.equals("::Filesystem::PersistentDirectory")) + { + return new DirectoryI(); + } + else + { + assert(false); + return null; + } + } + + public void + destroy() + { + } +} diff --git a/java/demo/book/freeze_filesystem/NodeInitializer.java b/java/demo/book/freeze_filesystem/NodeInitializer.java new file mode 100644 index 00000000000..c246f6e2b09 --- /dev/null +++ b/java/demo/book/freeze_filesystem/NodeInitializer.java @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 NodeInitializer extends Ice.LocalObjectImpl implements Freeze.ServantInitializer +{ + public void + initialize(Ice.ObjectAdapter adapter, Ice.Identity id, String facet, Ice.Object obj) + { + if(obj instanceof FileI) + { + ((FileI)obj)._ID = id; + } + else if(obj instanceof DirectoryI) + { + ((DirectoryI)obj)._ID = id; + } + } +} diff --git a/java/demo/book/freeze_filesystem/PersistentFilesystem.ice b/java/demo/book/freeze_filesystem/PersistentFilesystem.ice new file mode 100644 index 00000000000..174ba7aec3d --- /dev/null +++ b/java/demo/book/freeze_filesystem/PersistentFilesystem.ice @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#include <Filesystem.ice> + +module Filesystem +{ + class PersistentDirectory; + + class PersistentNode implements Node + { + string nodeName; + PersistentDirectory* parent; + }; + + class PersistentFile extends PersistentNode implements File + { + Lines text; + }; + + class PersistentDirectory extends PersistentNode implements Directory + { + ["freeze:write"] + void removeNode(string name); + + NodeDict nodes; + }; +}; diff --git a/java/demo/book/freeze_filesystem/Server.java b/java/demo/book/freeze_filesystem/Server.java new file mode 100644 index 00000000000..d0a21c6caa4 --- /dev/null +++ b/java/demo/book/freeze_filesystem/Server.java @@ -0,0 +1,84 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 Server extends Ice.Application +{ + public + Server(String envName) + { + _envName = envName; + } + + public int + run(String[] args) + { + // + // Install object factories. + // + Ice.ObjectFactory factory = new NodeFactory(); + communicator().addObjectFactory(factory, PersistentFile.ice_staticId()); + communicator().addObjectFactory(factory, PersistentDirectory.ice_staticId()); + + // + // Create an object adapter (stored in the _adapter + // static member). + // + Ice.ObjectAdapter adapter = + communicator().createObjectAdapterWithEndpoints("FreezeFilesystem", "default -p 10000"); + DirectoryI._adapter = adapter; + FileI._adapter = adapter; + + // + // Create the Freeze evictor (stored in the _evictor + // static member). + // + Freeze.ServantInitializer init = new NodeInitializer(); + Freeze.Evictor evictor = Freeze.Util.createEvictor(adapter, _envName, "evictorfs", init, null, true); + DirectoryI._evictor = evictor; + FileI._evictor = evictor; + + adapter.addServantLocator(evictor, ""); + + // + // Create the root node if it doesn't exist. + // + Ice.Identity rootId = Ice.Util.stringToIdentity("RootDir"); + if(!evictor.hasObject(rootId)) + { + PersistentDirectory root = new DirectoryI(rootId); + root.nodeName = "/"; + root.nodes = new java.util.HashMap(); + evictor.add(root, rootId); + } + + // + // 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/freeze_filesystem/build.xml b/java/demo/book/freeze_filesystem/build.xml new file mode 100644 index 00000000000..9882a3bde40 --- /dev/null +++ b/java/demo/book/freeze_filesystem/build.xml @@ -0,0 +1,55 @@ +<!-- + ********************************************************************** + + Copyright (c) 2003-2007 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_freeze_filesystem" 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="." /> + </includepath> + <fileset dir="." includes="Filesystem.ice"/> + <fileset dir="." includes="PersistentFilesystem.ice"/> + </slice2java> + </target> + + <target name="compile" depends="generate"> + <mkdir dir="${class.dir}"/> + <javac srcdir="${generated.dir}" destdir="${class.dir}" + source="${jdk.version}" debug="${debug}"> + <classpath refid="ice.classpath"/> + <compilerarg value="${javac.lint}" compiler="${javac.lint.compiler}"/> + </javac> + <javac srcdir="." destdir="${class.dir}" source="${jdk.version}" + excludes="generated/**" debug="${debug}"> + <classpath refid="ice.classpath"/> + <compilerarg value="${javac.lint}" compiler="${javac.lint.compiler}"/> + </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/freeze_filesystem/config.client b/java/demo/book/freeze_filesystem/config.client new file mode 100644 index 00000000000..4bd7574216d --- /dev/null +++ b/java/demo/book/freeze_filesystem/config.client @@ -0,0 +1,28 @@ +# +# The client reads this property to create the reference to the +# "library" 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/freeze_filesystem/config.server b/java/demo/book/freeze_filesystem/config.server new file mode 100644 index 00000000000..2370acc99a5 --- /dev/null +++ b/java/demo/book/freeze_filesystem/config.server @@ -0,0 +1,27 @@ +FreezeFilesystem.Endpoints=default -p 10000 + +Freeze.Trace.Map=1 +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/freeze_filesystem/db/.dummy b/java/demo/book/freeze_filesystem/db/.dummy new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/java/demo/book/freeze_filesystem/db/.dummy |