diff options
author | Jose <jose@zeroc.com> | 2014-11-07 21:28:00 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2014-11-07 21:28:00 +0100 |
commit | f99742d525f519996a6d321afb323a67fd9be4f9 (patch) | |
tree | f7b4454611d64d1a28bf9609aa64234fe78d3f53 /java/demo/Manual | |
parent | Some IceJS linting fixes (diff) | |
download | ice-f99742d525f519996a6d321afb323a67fd9be4f9.tar.bz2 ice-f99742d525f519996a6d321afb323a67fd9be4f9.tar.xz ice-f99742d525f519996a6d321afb323a67fd9be4f9.zip |
Fix for (ICE-5832) Versioning of Jar files
Renaming JAR files
Diffstat (limited to 'java/demo/Manual')
72 files changed, 6118 insertions, 0 deletions
diff --git a/java/demo/Manual/README b/java/demo/Manual/README new file mode 100644 index 00000000000..6dbc708834e --- /dev/null +++ b/java/demo/Manual/README @@ -0,0 +1,31 @@ +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. + +- evictor_filesystem + + An implementation of the persistent version of the file system + example described in the Freeze chapter using a Freeze evictor. + +- map_filesystem + + An implementation of the persistent version of the file system + example described in the Freeze chapter using a Freeze map. + +- lifecycle + + An implementation of the file system that supports life cycle operations. + +- printer + + An implementation of the simple printer example at the beginning of + the manual. + +- simple_filesystem + + An implementation of the simple (non-persistent, non-life-cycle) + version of the file system example. diff --git a/java/demo/Manual/build.gradle b/java/demo/Manual/build.gradle new file mode 100644 index 00000000000..32a101b37b9 --- /dev/null +++ b/java/demo/Manual/build.gradle @@ -0,0 +1,98 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +['evictor_filesystem', 'lifecycle', 'printer', 'simple_filesystem'].each { + // abc_def -> AbcDef + def name = it.split('_').collect { it.capitalize() }.join() + project(":demoManual${name}") { + slice { + java { + include = ["${projectDir}", "${sliceDir}"] + srcDir = '.' + } + } + + sourceSets { + main { + java { + srcDir '.' + output.classesDir "${buildDir}/classes" + } + } + } + + if (useMavenJars) { + dependencies { + compile "com.zeroc:ice:${iceVersion}" + } + } else if (distJarDir != null) { + dependencies { + compile files("${distJarDir}/Ice${versionSuffix}.jar") + } + } else { + dependencies { + compile project(':Ice') + } + } + + if(name == "EvictorFilesystem") { + if (distJarDir == null) { + dependencies { + compile project(':Freeze') + } + } else { + dependencies { + compile files("${distJarDir}/Freeze${versionSuffix}.jar") + compile 'com.sleepycat:db:5.3.28' + } + } + } + + // Create a jar for the client & server which includes everything in the demo. + task clientJar(type: Jar) { + baseName = "client" + from(sourceSets.main.output) { + include "**" + } + } + + task serverJar(type: Jar) { + baseName = "server" + from(sourceSets.main.output) { + include "**" + } + } + + clientJar { + manifest { + attributes("Main-Class": "Client") + attributes("Class-Path": configurations.compile.resolve().collect { it.toURI() }.join(' ')) + } + } + + serverJar { + manifest { + attributes("Main-Class": "Server") + attributes("Class-Path": configurations.compile.resolve().collect { it.toURI() }.join(' ')) + } + } + + artifacts { + archives clientJar, serverJar; + } + + // Don't create the default jar. + jar.enabled = false + + idea.module { + excludeDirs -= file(buildDir) + buildDir.listFiles({d, f ->f != 'generated-src'} as FilenameFilter).each { excludeDirs += it } + } + } +} diff --git a/java/demo/Manual/evictor/EvictorBase.java b/java/demo/Manual/evictor/EvictorBase.java new file mode 100644 index 00000000000..c309bd2866a --- /dev/null +++ b/java/demo/Manual/evictor/EvictorBase.java @@ -0,0 +1,124 @@ +package Evictor; + +public abstract class EvictorBase implements Ice.ServantLocator +{ + public + EvictorBase() + { + _size = 1000; + } + + public + EvictorBase(int size) + { + _size = size < 0 ? 1000 : size; + } + + public abstract Ice.Object + add(Ice.Current c, Ice.LocalObjectHolder cookie); + + public abstract void + evict(Ice.Object servant, java.lang.Object cookie); + + synchronized public final Ice.Object + locate(Ice.Current c, Ice.LocalObjectHolder cookie) + { + // + // Check if we have a servant in the map already. + // + EvictorEntry entry = _map.get(c.id); + if(entry != null) + { + // + // Got an entry already, dequeue the entry from its current position. + // + entry.queuePos.remove(); + } + else + { + // + // We do not have entry. Ask the derived class to + // instantiate a servant and add a new entry to the map. + // + entry = new EvictorEntry(); + Ice.LocalObjectHolder cookieHolder = new Ice.LocalObjectHolder(); + entry.servant = add(c, cookieHolder); // Down-call + if(entry.servant == null) + { + return null; + } + entry.userCookie = cookieHolder.value; + entry.useCount = 0; + _map.put(c.id, entry); + } + + // + // Increment the use count of the servant and enqueue + // the entry at the front, so we get LRU order. + // + ++(entry.useCount); + _queue.addFirst(c.id); + entry.queuePos = _queue.iterator(); + entry.queuePos.next(); // Position the iterator on the element. + + cookie.value = entry; + + return entry.servant; + } + + synchronized public final void + finished(Ice.Current c, Ice.Object o, java.lang.Object cookie) + { + EvictorEntry entry = (EvictorEntry)cookie; + + // + // Decrement use count and check if + // there is something to evict. + // + --(entry.useCount); + evictServants(); + } + + synchronized public final void + deactivate(String category) + { + _size = 0; + evictServants(); + } + + private class EvictorEntry + { + Ice.Object servant; + java.lang.Object userCookie; + java.util.Iterator<Ice.Identity> queuePos; + int useCount; + } + + private void evictServants() + { + // + // If the evictor queue has grown larger than the limit, + // look at the excess elements to see whether any of them + // can be evicted. + // + java.util.Iterator<Ice.Identity> p = _queue.riterator(); + int excessEntries = _map.size() - _size; + for(int i = 0; i < excessEntries; ++i) + { + Ice.Identity id = p.next(); + EvictorEntry e = _map.get(id); + if(e.useCount == 0) + { + evict(e.servant, e.userCookie); // Down-call + e.queuePos.remove(); + _map.remove(id); + } + } + } + + private java.util.Map<Ice.Identity, EvictorEntry> _map = + new java.util.HashMap<Ice.Identity, EvictorEntry>(); + private Evictor.LinkedList<Ice.Identity> _queue = + new Evictor.LinkedList<Ice.Identity>(); + private int _size; +} diff --git a/java/demo/Manual/evictor/LinkedList.java b/java/demo/Manual/evictor/LinkedList.java new file mode 100644 index 00000000000..5270142e6a9 --- /dev/null +++ b/java/demo/Manual/evictor/LinkedList.java @@ -0,0 +1,225 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 Evictor; + +// +// Stripped down LinkedList implementation for use in the Evictor. The +// API is similar to java.util.LinkedList. +// +// Major differences: +// * listIterator() is not implemented. +// * Operation riterator() returns a reverse iterator. +// * This implementation also has the property that an Iterator can be +// retained over structural changes to the list itself (similar to an +// STL list). +// +public class LinkedList<T> +{ + public + LinkedList() + { + _header.next = _header.previous = _header; + } + + public T + getFirst() + { + if(_size == 0) + { + throw new java.util.NoSuchElementException(); + } + + return _header.next.element; + } + + public void + addFirst(T o) + { + addBefore(o, _header.next); + } + + public boolean + isEmpty() + { + return _size == 0; + } + + public int + size() + { + return _size; + } + + public java.util.Iterator<T> + iterator() + { + return new ForwardIterator(); + } + + public java.util.Iterator<T> + riterator() + { + return new ReverseIterator(); + } + + private class ForwardIterator implements java.util.Iterator<T> + { + public boolean + hasNext() + { + return _next != null; + } + + public T + next() + { + if(_next == null) + { + throw new java.util.NoSuchElementException(); + } + + _current = _next; + + if(_next.next != _header) + { + _next = _next.next; + } + else + { + _next = null; + } + return _current.element; + } + + public void + remove() + { + if(_current == null) + { + throw new IllegalStateException(); + } + LinkedList.this.remove(_current); + _current = null; + } + + ForwardIterator() + { + if(_header.next == _header) + { + _next = null; + } + else + { + _next = _header.next; + } + _current = null; + } + + private Entry<T> _current; + private Entry<T> _next; + } + + private class ReverseIterator implements java.util.Iterator<T> + { + public boolean + hasNext() + { + return _next != null; + } + + public T + next() + { + if(_next == null) + { + throw new java.util.NoSuchElementException(); + } + + _current = _next; + + if(_next.previous != _header) + { + _next = _next.previous; + } + else + { + _next = null; + } + return _current.element; + } + + public void + remove() + { + if(_current == null) + { + throw new IllegalStateException(); + } + LinkedList.this.remove(_current); + _current = null; + } + + ReverseIterator() + { + if(_header.next == _header) + { + _next = null; + } + else + { + _next = _header.previous; + } + _current = null; + } + + private Entry<T> _current; + private Entry<T> _next; + } + + private static class Entry<T> + { + T element; + Entry<T> next; + Entry<T> previous; + + Entry(T element, Entry<T> next, Entry<T> previous) + { + this.element = element; + this.next = next; + this.previous = previous; + } + } + + private Entry<T> + addBefore(T o, Entry<T> e) + { + Entry<T> newEntry = new Entry<T>(o, e, e.previous); + newEntry.previous.next = newEntry; + newEntry.next.previous = newEntry; + _size++; + return newEntry; + } + + private void + remove(Entry<T> e) + { + if(e == _header) + { + throw new java.util.NoSuchElementException(); + } + + e.previous.next = e.next; + e.next.previous = e.previous; + _size--; + } + + private Entry<T> _header = new Entry<T>(null, null, null); + private int _size = 0; +} diff --git a/java/demo/Manual/evictor/README b/java/demo/Manual/evictor/README new file mode 100644 index 00000000000..cc6b56f5d65 --- /dev/null +++ b/java/demo/Manual/evictor/README @@ -0,0 +1,15 @@ +The source code provided here implements a Java evictor base class. To +use it, you must derive a class from EvictorBase and implement the +abstract add() and evict() methods. + +add() is called when the evictor needs to instantiate a servant, and +evict() is called when the evictor has decided to evict a servant. +Note that you can pass information from add() to the corresponding +call to evict() via the cookie argument. + +The evictor implementation relies on a linked list that allows items +to be added and removed without invalidating iterators. Such an +implementation is provided in LinkedList.java. + +For more details on this evictor, see the section "Server +Implementation Techniques" in the Ice documentation. diff --git a/java/demo/Manual/evictor_filesystem/.externalToolBuilders/book.demo.evictor_filesystem.slice.launch b/java/demo/Manual/evictor_filesystem/.externalToolBuilders/book.demo.evictor_filesystem.slice.launch new file mode 100644 index 00000000000..0ce604434d2 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/.externalToolBuilders/book.demo.evictor_filesystem.slice.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="generate,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="generate,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${container}"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="demo.book.evictor_filesystem"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/demo.book.evictor_filesystem/Filesystem.ice" type="1"/> <item path="/demo.book.evictor_filesystem/PersistentFilesystem.ice" type="1"/> </resources>}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/demo.book.evictor_filesystem/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="incremental,auto,clean"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> diff --git a/java/demo/Manual/evictor_filesystem/.gitignore b/java/demo/Manual/evictor_filesystem/.gitignore new file mode 100644 index 00000000000..9c39416c539 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/.gitignore @@ -0,0 +1 @@ +db/* diff --git a/java/demo/Manual/evictor_filesystem/Client.java b/java/demo/Manual/evictor_filesystem/Client.java new file mode 100644 index 00000000000..93a48deb2b5 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Client.java @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 +{ + @Override + public int + run(String[] args) + { + // + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // + // Create a proxy for the root directory + // + DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(communicator().propertyToProxy("RootDir.Proxy")); + if(rootDir == null) + { + throw new Error("Client: invalid proxy"); + } + + Parser p = new Parser(rootDir); + return p.parse(); + } + + static public void + main(String[] args) + { + Client app = new Client(); + app.main("demo.book.evictor_filesystem.Client", args, "config.client"); + } + + static private class Error extends RuntimeException + { + public Error(String msg) + { + super(msg); + } + } +} diff --git a/java/demo/Manual/evictor_filesystem/DirectoryI.java b/java/demo/Manual/evictor_filesystem/DirectoryI.java new file mode 100644 index 00000000000..73074c8b5ec --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/DirectoryI.java @@ -0,0 +1,170 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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; + nodes = new java.util.HashMap<java.lang.String, NodeDesc>(); + } + + @Override + public synchronized String + name(Ice.Current current) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + return nodeName; + } + + @Override + public void + destroy(Ice.Current current) + throws PermissionDenied + { + if(parent == null) + { + throw new PermissionDenied("Cannot destroy root directory"); + } + + synchronized(this) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + if(!nodes.isEmpty()) + { + throw new PermissionDenied("Cannot destroy non-empty directory"); + } + _destroyed = true; + } + + // + // Because we use a transactional evictor, these updates are guaranteed to be atomic. + // + parent.removeNode(nodeName); + _evictor.remove(current.id); + } + + @Override + public synchronized NodeDesc[] + list(Ice.Current current) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + NodeDesc[] result = new NodeDesc[nodes.size()]; + int i = 0; + java.util.Iterator<NodeDesc> p = nodes.values().iterator(); + while(p.hasNext()) + { + result[i++] = p.next(); + } + return result; + } + + @Override + public synchronized NodeDesc + find(String name, Ice.Current current) + throws NoSuchName + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + if(!nodes.containsKey(name)) + { + throw new NoSuchName(name); + } + + return nodes.get(name); + } + + @Override + public synchronized DirectoryPrx + createDirectory(String name, Ice.Current current) + throws NameInUse + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + if(name.length() == 0 || nodes.containsKey(name)) + { + throw new NameInUse(name); + } + + Ice.Identity id = current.adapter.getCommunicator().stringToIdentity(java.util.UUID.randomUUID().toString()); + PersistentDirectory dir = new DirectoryI(); + 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; + } + + @Override + public synchronized FilePrx + createFile(String name, Ice.Current current) + throws NameInUse + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + if(name.length() == 0 || nodes.containsKey(name)) + { + throw new NameInUse(name); + } + + Ice.Identity id = current.adapter.getCommunicator().stringToIdentity(java.util.UUID.randomUUID().toString()); + PersistentFile file = new FileI(); + 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; + } + + @Override + public synchronized void + removeNode(String name, Ice.Current current) + { + assert(nodes.containsKey(name)); + nodes.remove(name); + } + + public static Freeze.Evictor _evictor; + private boolean _destroyed; +} diff --git a/java/demo/Manual/evictor_filesystem/FileI.java b/java/demo/Manual/evictor_filesystem/FileI.java new file mode 100644 index 00000000000..f8904d52490 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/FileI.java @@ -0,0 +1,80 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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() + { + _destroyed = false; + } + + @Override + public synchronized String + name(Ice.Current current) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + return nodeName; + } + + @Override + public void + destroy(Ice.Current current) + throws PermissionDenied + { + synchronized(this) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + _destroyed = true; + } + + // + // Because we use a transactional evictor, these updates are guaranteed to be atomic. + // + parent.removeNode(nodeName); + _evictor.remove(current.id); + } + + @Override + public synchronized String[] + read(Ice.Current current) + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + return text.clone(); + } + + @Override + public synchronized void + write(String[] text, Ice.Current current) + throws GenericError + { + if(_destroyed) + { + throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation); + } + + this.text = text; + } + + public static Freeze.Evictor _evictor; + private boolean _destroyed; +} diff --git a/java/demo/Manual/evictor_filesystem/Filesystem.ice b/java/demo/Manual/evictor_filesystem/Filesystem.ice new file mode 100644 index 00000000000..bb84720f462 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Filesystem.ice @@ -0,0 +1,63 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +module Filesystem +{ + exception GenericError + { + string reason; + }; + exception PermissionDenied extends GenericError {}; + exception NameInUse 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; + }; + + sequence<NodeDesc> NodeDescSeq; + + interface Directory extends Node + { + idempotent NodeDescSeq list(); + + idempotent NodeDesc find(string name) throws NoSuchName; + + ["freeze:write"] + File* createFile(string name) throws NameInUse; + + ["freeze:write"] + Directory* createDirectory(string name) throws NameInUse; + }; +}; diff --git a/java/demo/Manual/evictor_filesystem/Grammar.java b/java/demo/Manual/evictor_filesystem/Grammar.java new file mode 100644 index 00000000000..16234c61ea5 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Grammar.java @@ -0,0 +1,202 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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(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(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/Manual/evictor_filesystem/NodeFactory.java b/java/demo/Manual/evictor_filesystem/NodeFactory.java new file mode 100644 index 00000000000..80669a9bde2 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/NodeFactory.java @@ -0,0 +1,38 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 implements Ice.ObjectFactory +{ + @Override + public Ice.Object + create(String type) + { + if(type.equals(PersistentFile.ice_staticId())) + { + return new FileI(); + } + else if(type.equals(PersistentDirectory.ice_staticId())) + { + return new DirectoryI(); + } + else + { + assert(false); + return null; + } + } + + @Override + public void + destroy() + { + } +} diff --git a/java/demo/Manual/evictor_filesystem/Parser.java b/java/demo/Manual/evictor_filesystem/Parser.java new file mode 100644 index 00000000000..8e89bed9a13 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Parser.java @@ -0,0 +1,349 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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) + { + StringBuilder b = new StringBuilder(); + 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(); + + for(String name : names) + { + 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(); + + for(String name : names) + { + 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 = args.toArray(new String[0]); + 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(); + + for(String name : names) + { + if(name.equals("*")) + { + NodeDesc[] nodes = dir.list(); + for(NodeDesc node : nodes) + { + try + { + node.proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + node.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/Manual/evictor_filesystem/PersistentFilesystem.ice b/java/demo/Manual/evictor_filesystem/PersistentFilesystem.ice new file mode 100644 index 00000000000..07b7d43c382 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/PersistentFilesystem.ice @@ -0,0 +1,38 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +#include <Filesystem.ice> + +module Filesystem +{ + class PersistentDirectory; + + class PersistentNode implements Node + { + string nodeName; + PersistentDirectory* parent; + }; + + class PersistentFile extends PersistentNode implements File + { + Lines text; + }; + + dictionary<string, NodeDesc> NodeDict; + + class PersistentDirectory extends PersistentNode implements Directory + { + ["freeze:write"] + void removeNode(string name); + + NodeDict nodes; + }; +}; diff --git a/java/demo/Manual/evictor_filesystem/README b/java/demo/Manual/evictor_filesystem/README new file mode 100644 index 00000000000..73ff1f9f14d --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/README @@ -0,0 +1,11 @@ +This demo presents an alternate implementation of the filesystem +application using a Freeze evictor, as discussed in the Freeze chapter +of the Ice manual. + +To run it, start the server in a window: + +$ java -jar build/libs/server.jar + +Then run the client in a separate window: + +$ java -jar build/libs/client.jar diff --git a/java/demo/Manual/evictor_filesystem/Scanner.java b/java/demo/Manual/evictor_filesystem/Scanner.java new file mode 100644 index 00000000000..2b81fcfd450 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Scanner.java @@ -0,0 +1,283 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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; + } + + StringBuilder buf = new StringBuilder(128); + + 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/Manual/evictor_filesystem/Server.java b/java/demo/Manual/evictor_filesystem/Server.java new file mode 100644 index 00000000000..93449bf215c --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Server.java @@ -0,0 +1,82 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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; + } + + @Override + 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. + // + Ice.ObjectAdapter adapter = communicator().createObjectAdapter("EvictorFilesystem"); + + // + // Create the Freeze evictor (stored in the _evictor + // static member). + // + Freeze.Evictor evictor = Freeze.Util.createTransactionalEvictor(adapter, _envName, "evictorfs", + null, null, null, true); + DirectoryI._evictor = evictor; + FileI._evictor = evictor; + + adapter.addServantLocator(evictor, ""); + + // + // Create the root node if it doesn't exist. + // + Ice.Identity rootId = new Ice.Identity(); + rootId.name = "RootDir"; + if(!evictor.hasObject(rootId)) + { + PersistentDirectory root = new DirectoryI(); + root.nodeName = "/"; + root.nodes = new java.util.HashMap<java.lang.String, NodeDesc>(); + 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("demo.book.evictor_filesystem.Server", args, "config.server"); + System.exit(status); + } + + private String _envName; +} diff --git a/java/demo/Manual/evictor_filesystem/Token.java b/java/demo/Manual/evictor_filesystem/Token.java new file mode 100644 index 00000000000..7a538343d6c --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/Token.java @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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/Manual/evictor_filesystem/config.client b/java/demo/Manual/evictor_filesystem/config.client new file mode 100644 index 00000000000..640cfade4f1 --- /dev/null +++ b/java/demo/Manual/evictor_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 -h localhost -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/Manual/evictor_filesystem/config.server b/java/demo/Manual/evictor_filesystem/config.server new file mode 100644 index 00000000000..69e536ab202 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/config.server @@ -0,0 +1,49 @@ +# +# Configure the server endpoints. +# +EvictorFilesystem.Endpoints=default -h localhost -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/Manual/evictor_filesystem/demo_manual_evictor_filesystem.iml b/java/demo/Manual/evictor_filesystem/demo_manual_evictor_filesystem.iml new file mode 100644 index 00000000000..e32f5e3b556 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/demo_manual_evictor_filesystem.iml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="java" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/build/classes" /> + <output-test url="file://$MODULE_DIR$/build/classes/test" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/build/generated-src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="Ice" exported="" /> + <orderEntry type="module" module-name="Freeze" exported="" /> + </component> +</module> + diff --git a/java/demo/Manual/evictor_filesystem/expect.py b/java/demo/Manual/evictor_filesystem/expect.py new file mode 100755 index 00000000000..bcd9eb26f47 --- /dev/null +++ b/java/demo/Manual/evictor_filesystem/expect.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2014 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 + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "demoscript")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(path[0]) + +from demoscript import Util +from demoscript.manual import evictor_filesystem + +sys.stdout.write("cleaning databases... ") +sys.stdout.flush() +Util.cleanDbDir("db") +print("ok") + +server = Util.spawn('java -jar build/libs/server.jar --Ice.PrintAdapterReady') +server.expect('.* ready') +client = Util.spawn('java -jar build/libs/client.jar') + +evictor_filesystem.run(client, server) diff --git a/java/demo/Manual/lifecycle/.externalToolBuilders/demo.book.lifecycle.slice.launch b/java/demo/Manual/lifecycle/.externalToolBuilders/demo.book.lifecycle.slice.launch new file mode 100644 index 00000000000..f4da860e3df --- /dev/null +++ b/java/demo/Manual/lifecycle/.externalToolBuilders/demo.book.lifecycle.slice.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="generate,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="generate,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="demo.book.lifecycle"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/demo.book.lifecycle/Filesystem.ice" type="1"/> </resources>}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/demo.book.lifecycle/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="incremental,auto,clean"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> diff --git a/java/demo/Manual/lifecycle/Client.java b/java/demo/Manual/lifecycle/Client.java new file mode 100644 index 00000000000..aac2733bc58 --- /dev/null +++ b/java/demo/Manual/lifecycle/Client.java @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 +{ + @Override + 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 -h localhost -p 10000"); + + // + // 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/Manual/lifecycle/Filesystem.ice b/java/demo/Manual/lifecycle/Filesystem.ice new file mode 100644 index 00000000000..a62086add45 --- /dev/null +++ b/java/demo/Manual/lifecycle/Filesystem.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +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; + }; +}; diff --git a/java/demo/Manual/lifecycle/FilesystemI/DirectoryI.java b/java/demo/Manual/lifecycle/FilesystemI/DirectoryI.java new file mode 100644 index 00000000000..005871ed897 --- /dev/null +++ b/java/demo/Manual/lifecycle/FilesystemI/DirectoryI.java @@ -0,0 +1,189 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 +{ + + // Slice name() operation. + + public synchronized String + name(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + return _name; + } + + // Return the object identity for this node. + + public Identity + id() + { + return _id; + } + + // Slice list() operation. + + public synchronized NodeDesc[] + list(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + NodeDesc[] ret = new NodeDesc[_contents.size()]; + java.util.Iterator<java.util.Map.Entry<String, NodeI> > pos = _contents.entrySet().iterator(); + for(int i = 0; i < _contents.size(); ++i) + { + java.util.Map.Entry<String, NodeI> e = pos.next(); + NodeI p = e.getValue(); + ret[i] = new NodeDesc(); + ret[i].name = e.getKey(); + ret[i].type = p instanceof FileI ? NodeType.FileType : NodeType.DirType; + ret[i].proxy = NodePrxHelper.uncheckedCast(c.adapter.createProxy(p.id())); + } + return ret; + } + + // Slice find() operation. + + public synchronized NodeDesc + find(String name, Current c) throws NoSuchName + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + NodeI p = _contents.get(name); + if(p == null) + { + throw new NoSuchName(name); + } + + NodeDesc d = new NodeDesc(); + d.name = name; + d.type = p instanceof FileI ? NodeType.FileType : NodeType.DirType; + d.proxy = NodePrxHelper.uncheckedCast(c.adapter.createProxy(p.id())); + return d; + } + + // Slice createFile() operation. + + public synchronized FilePrx + createFile(String name, Current c) throws NameInUse + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + if(name.length() == 0 || _contents.containsKey(name)) + { + throw new NameInUse(name); + } + + FileI f = new FileI(name, this); + ObjectPrx node = c.adapter.add(f, f.id()); + _contents.put(name, f); + return FilePrxHelper.uncheckedCast(node); + } + + // Slice createDirectory() operation. + + public synchronized DirectoryPrx + createDirectory(String name, Current c) throws NameInUse + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + if(name.length() == 0 || _contents.containsKey(name)) + { + throw new NameInUse(name); + } + + DirectoryI d = new DirectoryI(name, this); + ObjectPrx node = c.adapter.add(d, d.id()); + _contents.put(name, d); + return DirectoryPrxHelper.uncheckedCast(node); + } + + // 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(); + } + + if(_contents.size() != 0) + { + throw new PermissionDenied("Cannot destroy non-empty directory"); + } + + c.adapter.remove(id()); + _destroyed = true; + } + + _parent.removeEntry(_name); + } + + // DirectoryI constructor for root directory. + + public DirectoryI() + { + this("/", null); + } + + // DirectoryI constructor. parent == null indicates root directory. + + public DirectoryI(String name, DirectoryI parent) + { + _name = name; + _parent = parent; + _id = new Identity(); + _destroyed = false; + _contents = new java.util.HashMap<String, NodeI>(); + + _id.name = parent == null ? "RootDir" : java.util.UUID.randomUUID().toString(); + } + + // Remove the entry from the _contents map. + + public synchronized void + removeEntry(String name) + { + _contents.remove(name); + } + + private String _name; // Immutable + private DirectoryI _parent; // Immutable + private Identity _id; // Immutable + private boolean _destroyed; + private java.util.Map<String, NodeI> _contents; +} diff --git a/java/demo/Manual/lifecycle/FilesystemI/FileI.java b/java/demo/Manual/lifecycle/FilesystemI/FileI.java new file mode 100644 index 00000000000..7912d4bc83e --- /dev/null +++ b/java/demo/Manual/lifecycle/FilesystemI/FileI.java @@ -0,0 +1,86 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 FileI extends _FileDisp implements NodeI +{ + public synchronized String + name(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + return _name; + } + + public Identity + id() + { + return _id; + } + + public synchronized String[] + read(Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + return _lines; + } + + public synchronized void + write(String[] text, Current c) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + _lines = (String[])text.clone(); + } + + public void + destroy(Current c) + { + synchronized(this) + { + if(_destroyed) + { + throw new ObjectNotExistException(); + } + + c.adapter.remove(id()); + _destroyed = true; + } + + _parent.removeEntry(_name); + } + + public FileI(String name, DirectoryI parent) + { + _name = name; + _parent = parent; + _destroyed = false; + _id = new Identity(); + _id.name = java.util.UUID.randomUUID().toString(); + } + + private String _name; + private DirectoryI _parent; + private boolean _destroyed; + private Identity _id; + private String[] _lines; +} diff --git a/java/demo/Manual/lifecycle/FilesystemI/NodeI.java b/java/demo/Manual/lifecycle/FilesystemI/NodeI.java new file mode 100644 index 00000000000..33786ce60f6 --- /dev/null +++ b/java/demo/Manual/lifecycle/FilesystemI/NodeI.java @@ -0,0 +1,15 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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(); +} diff --git a/java/demo/Manual/lifecycle/Grammar.java b/java/demo/Manual/lifecycle/Grammar.java new file mode 100644 index 00000000000..16234c61ea5 --- /dev/null +++ b/java/demo/Manual/lifecycle/Grammar.java @@ -0,0 +1,202 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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(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(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/Manual/lifecycle/Parser.java b/java/demo/Manual/lifecycle/Parser.java new file mode 100644 index 00000000000..8e89bed9a13 --- /dev/null +++ b/java/demo/Manual/lifecycle/Parser.java @@ -0,0 +1,349 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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) + { + StringBuilder b = new StringBuilder(); + 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(); + + for(String name : names) + { + 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(); + + for(String name : names) + { + 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 = args.toArray(new String[0]); + 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(); + + for(String name : names) + { + if(name.equals("*")) + { + NodeDesc[] nodes = dir.list(); + for(NodeDesc node : nodes) + { + try + { + node.proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + node.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/Manual/lifecycle/README b/java/demo/Manual/lifecycle/README new file mode 100644 index 00000000000..ea985301bfd --- /dev/null +++ b/java/demo/Manual/lifecycle/README @@ -0,0 +1,11 @@ +This demo implements the file system with life cycle support. + +To run it, start the server in a window: + +$ java -jar build/libs/server.jar + +Then run the client in a separate window: + +$ java -jar build/libs/client.jar + +Type "help" at the client prompt to see a list of commands. diff --git a/java/demo/Manual/lifecycle/Scanner.java b/java/demo/Manual/lifecycle/Scanner.java new file mode 100644 index 00000000000..2b81fcfd450 --- /dev/null +++ b/java/demo/Manual/lifecycle/Scanner.java @@ -0,0 +1,283 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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; + } + + StringBuilder buf = new StringBuilder(128); + + 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/Manual/lifecycle/Server.java b/java/demo/Manual/lifecycle/Server.java new file mode 100644 index 00000000000..2a5fe5d103a --- /dev/null +++ b/java/demo/Manual/lifecycle/Server.java @@ -0,0 +1,60 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 FilesystemI.*; + +class Server extends Ice.Application +{ + @Override + public int + run(String[] args) + { + // + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // + // Create an object adapter + // + Ice.ObjectAdapter adapter = communicator().createObjectAdapterWithEndpoints( + "LifecycleFilesystem", "default -h localhost -p 10000"); + + // + // Create the root directory. + // + DirectoryI root = new DirectoryI(); + Ice.Identity id = new Ice.Identity(); + id.name = "RootDir"; + adapter.add(root, id); + + // + // All objects are created, allow client requests now. + // + adapter.activate(); + + // + // Wait until we are done. + // + communicator().waitForShutdown(); + if(interrupted()) + { + System.err.println(appName() + ": received signal, shutting down"); + } + + return 0; + } + + static public void + main(String[] args) + { + Server app = new Server(); + app.main("demo.book.lifecycle.Server", args); + } +} diff --git a/java/demo/Manual/lifecycle/Token.java b/java/demo/Manual/lifecycle/Token.java new file mode 100644 index 00000000000..7a538343d6c --- /dev/null +++ b/java/demo/Manual/lifecycle/Token.java @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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/Manual/lifecycle/demo_manual_lifecycle.iml b/java/demo/Manual/lifecycle/demo_manual_lifecycle.iml new file mode 100644 index 00000000000..b6dce281ba2 --- /dev/null +++ b/java/demo/Manual/lifecycle/demo_manual_lifecycle.iml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="java" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/build/classes" /> + <output-test url="file://$MODULE_DIR$/build/classes/test" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/build/generated-src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="Ice" exported="" /> + </component> +</module> + diff --git a/java/demo/Manual/lifecycle/expect.py b/java/demo/Manual/lifecycle/expect.py new file mode 100755 index 00000000000..ef248a53559 --- /dev/null +++ b/java/demo/Manual/lifecycle/expect.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2014 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 + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "demoscript")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(path[0]) + +from demoscript import Util +from demoscript.manual import lifecycle + +server = Util.spawn('java -jar build/libs/server.jar --Ice.PrintAdapterReady') +server.expect('.* ready') +client = Util.spawn('java -jar build/libs/client.jar') + +lifecycle.run(client, server) diff --git a/java/demo/Manual/map_filesystem/.externalToolBuilders/demo.book.map_filesystem.launch b/java/demo/Manual/map_filesystem/.externalToolBuilders/demo.book.map_filesystem.launch new file mode 100644 index 00000000000..abe7897ac17 --- /dev/null +++ b/java/demo/Manual/map_filesystem/.externalToolBuilders/demo.book.map_filesystem.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="generate,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="generate,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="demo.book.map_filesystem"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/demo.book.map_filesystem/Filesystem.ice" type="1"/> <item path="/demo.book.map_filesystem/FilesystemDB.ice" type="1"/> </resources>}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/demo.book.map_filesystem/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="incremental,auto,clean"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> diff --git a/java/demo/Manual/map_filesystem/.gitignore b/java/demo/Manual/map_filesystem/.gitignore new file mode 100644 index 00000000000..9c39416c539 --- /dev/null +++ b/java/demo/Manual/map_filesystem/.gitignore @@ -0,0 +1 @@ +db/* diff --git a/java/demo/Manual/map_filesystem/Client.java b/java/demo/Manual/map_filesystem/Client.java new file mode 100644 index 00000000000..2309f6a3b23 --- /dev/null +++ b/java/demo/Manual/map_filesystem/Client.java @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 +{ + @Override + public int + run(String[] args) + { + // + // Terminate cleanly on receipt of a signal. + // + shutdownOnInterrupt(); + + // + // Create a proxy for the root directory + // + DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(communicator().propertyToProxy("RootDir.Proxy")); + if(rootDir == null) + { + throw new Error("Client: invalid proxy"); + } + + Parser p = new Parser(rootDir); + return p.parse(); + } + + static public void + main(String[] args) + { + Client app = new Client(); + app.main("demo.book.map_filesystem.Client", args, "config.client"); + } + + static private class Error extends RuntimeException + { + public Error(String msg) + { + super(msg); + } + } +} diff --git a/java/demo/Manual/map_filesystem/DirectoryI.java b/java/demo/Manual/map_filesystem/DirectoryI.java new file mode 100644 index 00000000000..226814d5981 --- /dev/null +++ b/java/demo/Manual/map_filesystem/DirectoryI.java @@ -0,0 +1,407 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 FilesystemDB.*; + +public class DirectoryI extends _DirectoryDisp +{ + public + DirectoryI(Ice.Communicator communicator, String envName) + { + _communicator = communicator; + _envName = envName; + + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + // + // Create the record for the root directory if necessary. + // + for(;;) + { + try + { + Ice.Identity rootId = new Ice.Identity("RootDir", ""); + DirectoryEntry entry = dirDB.get(rootId); + if(entry == null) + { + dirDB.put(rootId, new DirectoryEntry("/", new Ice.Identity("", ""), null)); + } + break; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public String + name(Ice.Current c) + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + try + { + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + return entry.name; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public NodeDesc[] + list(Ice.Current c) + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + try + { + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + NodeDesc[] result = new NodeDesc[entry.nodes.size()]; + java.util.Iterator<NodeDesc> p = entry.nodes.values().iterator(); + for(int i = 0; i < entry.nodes.size(); ++i) + { + result[i] = p.next(); + } + return result; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public NodeDesc + find(String name, Ice.Current c) + throws NoSuchName + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + try + { + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + NodeDesc nd = entry.nodes.get(name); + if(nd == null) + { + throw new NoSuchName(name); + } + return nd; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public FilePrx + createFile(String name, Ice.Current c) + throws NameInUse + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityFileEntryMap fileDB = new IdentityFileEntryMap(connection, FileI.filesDB()); + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + // + // The transaction is necessary since we are altering + // two records in one atomic action. + // + Freeze.Transaction txn = null; + try + { + txn = connection.beginTransaction(); + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + if(name.length() == 0 || entry.nodes.get(name) != null) + { + throw new NameInUse(name); + } + + FileEntry newEntry = new FileEntry(name, c.id, null); + Ice.Identity id = new Ice.Identity(java.util.UUID.randomUUID().toString(), "file"); + FilePrx proxy = FilePrxHelper.uncheckedCast(c.adapter.createProxy(id)); + + entry.nodes.put(name, new NodeDesc(name, NodeType.FileType, proxy)); + dirDB.put(c.id, entry); + + fileDB.put(id, newEntry); + + txn.commit(); + txn = null; + + return proxy; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + finally + { + if(txn != null) + { + txn.rollback(); + } + } + } + } + finally + { + connection.close(); + } + } + + @Override + public DirectoryPrx + createDirectory(String name, Ice.Current c) + throws NameInUse + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + // + // The transaction is necessary since we are altering + // two records in one atomic action. + // + Freeze.Transaction txn = null; + try + { + txn = connection.beginTransaction(); + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + if(name.length() == 0 || entry.nodes.get(name) != null) + { + throw new NameInUse(name); + } + + DirectoryEntry newEntry = new DirectoryEntry(name, c.id, null); + Ice.Identity id = new Ice.Identity(java.util.UUID.randomUUID().toString(), ""); + DirectoryPrx proxy = DirectoryPrxHelper.uncheckedCast(c.adapter.createProxy(id)); + + entry.nodes.put(name, new NodeDesc(name, NodeType.DirType, proxy)); + dirDB.put(c.id, entry); + + dirDB.put(id, newEntry); + + txn.commit(); + txn = null; + + return proxy; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + finally + { + if(txn != null) + { + txn.rollback(); + } + } + } + } + finally + { + connection.close(); + } + } + + @Override + public void + destroy(Ice.Current c) + throws PermissionDenied + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, directoriesDB()); + + for(;;) + { + // + // The transaction is necessary since we are altering + // two records in one atomic action. + // + Freeze.Transaction txn = null; + try + { + txn = connection.beginTransaction(); + DirectoryEntry entry = dirDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + if(entry.parent.name.length() == 0) + { + throw new PermissionDenied("Cannot destroy root directory"); + } + if(!entry.nodes.isEmpty()) + { + throw new PermissionDenied("Cannot destroy non-empty directory"); + } + + DirectoryEntry dirEntry = dirDB.get(entry.parent); + if(dirEntry == null) + { + halt(new Freeze.DatabaseException("consistency error: directory without parent")); + } + + dirEntry.nodes.remove(entry.name); + dirDB.put(entry.parent, dirEntry); + + dirDB.remove(c.id); + + txn.commit(); + txn = null; + break; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + finally + { + if(txn != null) + { + txn.rollback(); + } + } + } + } + finally + { + connection.close(); + } + } + + private void + halt(Freeze.DatabaseException e) + { + // + // If this is called it's very bad news. We log the error and + // then kill the server. + // + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + e.printStackTrace(pw); + pw.flush(); + _communicator.getLogger().error("fatal database error\n" + sw.toString() + "\n*** Halting JVM ***"); + Runtime.getRuntime().halt(1); + } + + public static String + directoriesDB() + { + return "directories"; + } + + private Ice.Communicator _communicator; + private String _envName; +} diff --git a/java/demo/Manual/map_filesystem/FileI.java b/java/demo/Manual/map_filesystem/FileI.java new file mode 100644 index 00000000000..33b8ece4e85 --- /dev/null +++ b/java/demo/Manual/map_filesystem/FileI.java @@ -0,0 +1,221 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 FilesystemDB.*; + +public class FileI extends _FileDisp +{ + public + FileI(Ice.Communicator communicator, String envName) + { + _communicator = communicator; + _envName = envName; + } + + @Override + public String + name(Ice.Current c) + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityFileEntryMap fileDB = new IdentityFileEntryMap(connection, filesDB()); + + for(;;) + { + try + { + FileEntry entry = fileDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + return entry.name; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public String[] + read(Ice.Current c) + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityFileEntryMap fileDB = new IdentityFileEntryMap(connection, filesDB()); + + for(;;) + { + try + { + FileEntry entry = fileDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + return entry.text; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public void + write(String[] text, Ice.Current c) + throws GenericError + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityFileEntryMap fileDB = new IdentityFileEntryMap(connection, filesDB()); + + for(;;) + { + try + { + FileEntry entry = fileDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + entry.text = text; + fileDB.put(c.id, entry); + break; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + } + } + finally + { + connection.close(); + } + } + + @Override + public void + destroy(Ice.Current c) + throws PermissionDenied + { + Freeze.Connection connection = Freeze.Util.createConnection(_communicator, _envName); + try + { + IdentityFileEntryMap fileDB = new IdentityFileEntryMap(connection, filesDB()); + IdentityDirectoryEntryMap dirDB = new IdentityDirectoryEntryMap(connection, DirectoryI.directoriesDB()); + + for(;;) + { + Freeze.Transaction txn = null; + try + { + // + // The transaction is necessary since we are + // altering two records in one atomic action. + // + txn = connection.beginTransaction(); + FileEntry entry = fileDB.get(c.id); + if(entry == null) + { + throw new Ice.ObjectNotExistException(); + } + + DirectoryEntry dirEntry = dirDB.get(entry.parent); + if(dirEntry == null) + { + halt(new Freeze.DatabaseException("consistency error: file without parent")); + } + + dirEntry.nodes.remove(entry.name); + dirDB.put(entry.parent, dirEntry); + + fileDB.remove(c.id); + + txn.commit(); + txn = null; + break; + } + catch(Freeze.DeadlockException ex) + { + continue; + } + catch(Freeze.DatabaseException ex) + { + halt(ex); + } + finally + { + if(txn != null) + { + txn.rollback(); + } + } + } + } + finally + { + connection.close(); + } + } + + public static String + filesDB() + { + return "files"; + } + + private void + halt(Freeze.DatabaseException e) + { + // + // If this is called it's very bad news. We log the error and + // then kill the server. + // + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + e.printStackTrace(pw); + pw.flush(); + _communicator.getLogger().error("fatal database error\n" + sw.toString() + "\n*** Halting JVM ***"); + Runtime.getRuntime().halt(1); + } + + private Ice.Communicator _communicator; + private String _envName; +} diff --git a/java/demo/Manual/map_filesystem/Filesystem.ice b/java/demo/Manual/map_filesystem/Filesystem.ice new file mode 100644 index 00000000000..a62086add45 --- /dev/null +++ b/java/demo/Manual/map_filesystem/Filesystem.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +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; + }; +}; diff --git a/java/demo/Manual/map_filesystem/FilesystemDB.ice b/java/demo/Manual/map_filesystem/FilesystemDB.ice new file mode 100644 index 00000000000..6e2eef6bcd1 --- /dev/null +++ b/java/demo/Manual/map_filesystem/FilesystemDB.ice @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +#include <Filesystem.ice> +#include <Ice/Identity.ice> + +module FilesystemDB +{ + struct FileEntry + { + string name; + Ice::Identity parent; + Filesystem::Lines text; + }; + + dictionary<string, Filesystem::NodeDesc> StringNodeDescDict; + struct DirectoryEntry + { + string name; + Ice::Identity parent; + StringNodeDescDict nodes; + }; +}; diff --git a/java/demo/Manual/map_filesystem/Grammar.java b/java/demo/Manual/map_filesystem/Grammar.java new file mode 100644 index 00000000000..16234c61ea5 --- /dev/null +++ b/java/demo/Manual/map_filesystem/Grammar.java @@ -0,0 +1,202 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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(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(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/Manual/map_filesystem/Parser.java b/java/demo/Manual/map_filesystem/Parser.java new file mode 100644 index 00000000000..8e89bed9a13 --- /dev/null +++ b/java/demo/Manual/map_filesystem/Parser.java @@ -0,0 +1,349 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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) + { + StringBuilder b = new StringBuilder(); + 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(); + + for(String name : names) + { + 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(); + + for(String name : names) + { + 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 = args.toArray(new String[0]); + 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(); + + for(String name : names) + { + if(name.equals("*")) + { + NodeDesc[] nodes = dir.list(); + for(NodeDesc node : nodes) + { + try + { + node.proxy.destroy(); + } + catch(PermissionDenied ex) + { + System.out.println("cannot remove `" + node.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/Manual/map_filesystem/README b/java/demo/Manual/map_filesystem/README new file mode 100644 index 00000000000..f1b64f52ed4 --- /dev/null +++ b/java/demo/Manual/map_filesystem/README @@ -0,0 +1,11 @@ +This demo presents an alternate implementation of the filesystem +application using a Freeze map, as discussed in the Freeze chapter of +the Ice manual. + +To run it, start the server in a window: + +$ java -jar build/libs/server.jar + +Then run the client in a separate window: + +$ java -jar build/libs/client.jar diff --git a/java/demo/Manual/map_filesystem/Scanner.java b/java/demo/Manual/map_filesystem/Scanner.java new file mode 100644 index 00000000000..2b81fcfd450 --- /dev/null +++ b/java/demo/Manual/map_filesystem/Scanner.java @@ -0,0 +1,283 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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; + } + + StringBuilder buf = new StringBuilder(128); + + 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/Manual/map_filesystem/Server.java b/java/demo/Manual/map_filesystem/Server.java new file mode 100644 index 00000000000..8ce2d5f586a --- /dev/null +++ b/java/demo/Manual/map_filesystem/Server.java @@ -0,0 +1,80 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 FilesystemDB.*; + +public class Server extends Ice.Application +{ + public + Server(String envName) + { + _envName = envName; + } + + @Override + public int + run(String[] args) + { + // + // Create an object adapter + // + Ice.ObjectAdapter adapter = communicator().createObjectAdapter("MapFilesystem"); + + Freeze.Connection connection = null; + try + { + // + // Open a connection to the files and directories + // database. This should remain open for the duration of the + // application for performance reasons. + // + connection = Freeze.Util.createConnection(communicator(), _envName); + new IdentityFileEntryMap(connection, FileI.filesDB(), true); + new IdentityDirectoryEntryMap(connection, DirectoryI.directoriesDB(), true); + + // + // Add default servants for the file and directory. + // + adapter.addDefaultServant(new FileI(communicator(), _envName), "file"); + adapter.addDefaultServant(new DirectoryI(communicator(), _envName), ""); + + // + // Ready to accept requests now + // + adapter.activate(); + + // + // Wait until we are done + // + communicator().waitForShutdown(); + } + finally + { + // + // Close the connection gracefully. + // + if(connection != null) + { + connection.close(); + } + } + + return 0; + } + + public static void + main(String[] args) + { + Server app = new Server("db"); + app.main("demo.book.map_filesystem.Server", args, "config.server"); + System.exit(0); + } + + private String _envName; +} diff --git a/java/demo/Manual/map_filesystem/Token.java b/java/demo/Manual/map_filesystem/Token.java new file mode 100644 index 00000000000..7a538343d6c --- /dev/null +++ b/java/demo/Manual/map_filesystem/Token.java @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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/Manual/map_filesystem/build.gradle b/java/demo/Manual/map_filesystem/build.gradle new file mode 100644 index 00000000000..9cfcbe348b2 --- /dev/null +++ b/java/demo/Manual/map_filesystem/build.gradle @@ -0,0 +1,104 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +slice { + java { + include = ["${projectDir}", "${sliceDir}"] + srcDir = '.' + } + freezej { + files = [file("FilesystemDB.ice"), + file("${sliceDir}/Ice/Identity.ice")] + include = ["${projectDir}", "${sliceDir}"] + args = "--ice" + dict { + IdentityFileEntryMap { + javaType = "FilesystemDB.IdentityFileEntryMap" + key = "Ice::Identity" + value = "FilesystemDB::FileEntry" + } + } + dict { + IdentityDirectoryEntryMap { + javaType = "FilesystemDB.IdentityDirectoryEntryMap" + key="Ice::Identity" + value="FilesystemDB::DirectoryEntry" + } + } + } +} + +sourceSets { + main { + java { + srcDir '.' + output.classesDir "${buildDir}/classes" + } + } +} + +if (useMavenJars) { + dependencies { + compile "com.zeroc:ice:${iceVersion}" + compile "com.zeroc:freeze:${iceVersion}" + compile 'com.sleepycat:db:5.3.28' + } +} else if (distJarDir != null) { + dependencies { + compile files("${distJarDir}/Ice${versionSuffix}.jar") + compile files("${distJarDir}/Freeze${versionSuffix}.jar") + compile 'com.sleepycat:db:5.3.28' + } +} else { + dependencies { + compile project(':Ice') + compile project(':Freeze') + } +} + +// Create a jar for the client & server which includes everything in the demo. +task clientJar(type: Jar) { + baseName = "client" + from(sourceSets.main.output) { + include "**" + } +} + +task serverJar(type: Jar) { + baseName = "server" + from(sourceSets.main.output) { + include "**" + } +} + +clientJar { + manifest { + attributes("Main-Class": "Client") + attributes("Class-Path": configurations.compile.resolve().collect { it.toURI() }.join(' ')) + } +} + +serverJar { + manifest { + attributes("Main-Class": "Server") + attributes("Class-Path": configurations.compile.resolve().collect { it.toURI() }.join(' ')) + } +} + +artifacts { + archives clientJar, serverJar; +} + +// Don't create the default jar. +jar.enabled = false + +idea.module { + excludeDirs -= file(buildDir) + buildDir.listFiles({d, f ->f != 'generated-src'} as FilenameFilter).each { excludeDirs += it } +} diff --git a/java/demo/Manual/map_filesystem/config.client b/java/demo/Manual/map_filesystem/config.client new file mode 100644 index 00000000000..640cfade4f1 --- /dev/null +++ b/java/demo/Manual/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 -h localhost -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/Manual/map_filesystem/config.server b/java/demo/Manual/map_filesystem/config.server new file mode 100644 index 00000000000..c8694039614 --- /dev/null +++ b/java/demo/Manual/map_filesystem/config.server @@ -0,0 +1,37 @@ +# +# Configure the server endpoints. +# +MapFilesystem.Endpoints=default -h localhost -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 + +# +# 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/Manual/map_filesystem/demo_manual_map_filesystem.iml b/java/demo/Manual/map_filesystem/demo_manual_map_filesystem.iml new file mode 100644 index 00000000000..93543e73196 --- /dev/null +++ b/java/demo/Manual/map_filesystem/demo_manual_map_filesystem.iml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="java" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/build/classes" /> + <output-test url="file://$MODULE_DIR$/build/classes/test" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/build/generated-src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="Ice" exported="" /> + <orderEntry type="module" module-name="Freeze" exported="" /> + </component> +</module> + diff --git a/java/demo/Manual/map_filesystem/expect.py b/java/demo/Manual/map_filesystem/expect.py new file mode 100755 index 00000000000..bb7ca5b8aa3 --- /dev/null +++ b/java/demo/Manual/map_filesystem/expect.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2014 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 + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "demoscript")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(path[0]) + +from demoscript import Util +from demoscript.manual import map_filesystem + +sys.stdout.write("cleaning databases... ") +sys.stdout.flush() +Util.cleanDbDir("db") +print("ok") + +server = Util.spawn('java -jar build/libs/server.jar --Ice.PrintAdapterReady') +server.expect('.* ready') +client = Util.spawn('java -jar build/libs/client.jar') + +map_filesystem.run(client, server) diff --git a/java/demo/Manual/printer/.externalToolBuilders/demo.book.printer.launch b/java/demo/Manual/printer/.externalToolBuilders/demo.book.printer.launch new file mode 100644 index 00000000000..b8b0aefe5db --- /dev/null +++ b/java/demo/Manual/printer/.externalToolBuilders/demo.book.printer.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="generate,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="generate,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="demo.book.printer"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/demo.book.printer/Printer.ice" type="1"/> </resources>}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/demo.book.printer/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="incremental,auto,clean"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> diff --git a/java/demo/Manual/printer/Client.java b/java/demo/Manual/printer/Client.java new file mode 100644 index 00000000000..458eaae3800 --- /dev/null +++ b/java/demo/Manual/printer/Client.java @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +public class Client +{ + public static void + main(String[] args) + { + int status = 0; + Ice.Communicator ic = null; + try + { + ic = Ice.Util.initialize(args); + Ice.ObjectPrx base = ic.stringToProxy("SimplePrinter:default -h localhost -p 10000"); + Demo.PrinterPrx printer = Demo.PrinterPrxHelper.checkedCast(base); + if(printer == null) + { + throw new Error("Invalid proxy"); + } + + printer.printString("Hello World!"); + } + catch(Ice.LocalException e) + { + e.printStackTrace(); + status = 1; + } + catch(Exception e) + { + System.err.println(e.getMessage()); + status = 1; + } + if(ic != null) + { + try + { + ic.destroy(); + } + catch(Exception e) + { + System.err.println(e.getMessage()); + status = 1; + } + } + System.exit(status); + } +} diff --git a/java/demo/Manual/printer/Printer.ice b/java/demo/Manual/printer/Printer.ice new file mode 100755 index 00000000000..343fd8e627b --- /dev/null +++ b/java/demo/Manual/printer/Printer.ice @@ -0,0 +1,20 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +module Demo +{ + + interface Printer + { + void printString(string s); + }; + +}; diff --git a/java/demo/Manual/printer/PrinterI.java b/java/demo/Manual/printer/PrinterI.java new file mode 100644 index 00000000000..6d17fbfd036 --- /dev/null +++ b/java/demo/Manual/printer/PrinterI.java @@ -0,0 +1,17 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +public class PrinterI extends Demo._PrinterDisp +{ + public void + printString(String s, Ice.Current current) + { + System.out.println(s); + } +} diff --git a/java/demo/Manual/printer/README b/java/demo/Manual/printer/README new file mode 100644 index 00000000000..8a89f134050 --- /dev/null +++ b/java/demo/Manual/printer/README @@ -0,0 +1,8 @@ +This demo implements the printer example in chapter 3 of the +documentation. To run it, start the server in a window: + +$ java -jar build/libs/server.jar + +In a separate window, run the client: + +$ java -jar build/libs/client.jar diff --git a/java/demo/Manual/printer/Server.java b/java/demo/Manual/printer/Server.java new file mode 100644 index 00000000000..cdb11fa5312 --- /dev/null +++ b/java/demo/Manual/printer/Server.java @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +public class Server +{ + public static void + main(String[] args) + { + int status = 0; + Ice.Communicator ic = null; + try + { + ic = Ice.Util.initialize(args); + Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -h localhost -p 10000"); + Ice.Object object = new PrinterI(); + adapter.add(object, ic.stringToIdentity("SimplePrinter")); + adapter.activate(); + ic.waitForShutdown(); + } + catch(Exception e) + { + e.printStackTrace(); + status = 1; + } + if(ic != null) + { + try + { + ic.destroy(); + } + catch(Exception e) + { + System.err.println(e.getMessage()); + status = 1; + } + } + System.exit(status); + } +} diff --git a/java/demo/Manual/printer/demo_manual_printer.iml b/java/demo/Manual/printer/demo_manual_printer.iml new file mode 100644 index 00000000000..b6dce281ba2 --- /dev/null +++ b/java/demo/Manual/printer/demo_manual_printer.iml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="java" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/build/classes" /> + <output-test url="file://$MODULE_DIR$/build/classes/test" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/build/generated-src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="Ice" exported="" /> + </component> +</module> + diff --git a/java/demo/Manual/printer/expect.py b/java/demo/Manual/printer/expect.py new file mode 100755 index 00000000000..e9a6a09932c --- /dev/null +++ b/java/demo/Manual/printer/expect.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2014 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, signal + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "demoscript")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(path[0]) + +from demoscript import Util + +server = Util.spawn('java -jar build/libs/server.jar --Ice.PrintAdapterReady') +server.expect('.* ready') + +sys.stdout.write("testing... ") +sys.stdout.flush() +client = Util.spawn('java -jar build/libs/client.jar') +client.waitTestSuccess() +server.expect('Hello World!') +server.kill(signal.SIGINT) +server.waitTestSuccess() +print("ok") diff --git a/java/demo/Manual/simple_filesystem/.externalToolBuilders/demo.book.simple_filesystem.launch b/java/demo/Manual/simple_filesystem/.externalToolBuilders/demo.book.simple_filesystem.launch new file mode 100644 index 00000000000..2256b877bae --- /dev/null +++ b/java/demo/Manual/simple_filesystem/.externalToolBuilders/demo.book.simple_filesystem.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="generate,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="generate,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${container}"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="demo.book.simple_filesystem"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/demo.book.simple_filesystem/Filesystem.ice" type="1"/> </resources>}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/demo.book.simple_filesystem/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="incremental,auto,clean"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> diff --git a/java/demo/Manual/simple_filesystem/Client.java b/java/demo/Manual/simple_filesystem/Client.java new file mode 100644 index 00000000000..de1516eb010 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/Client.java @@ -0,0 +1,103 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 +{ + // 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); + + NodePrx[] contents = dir.list(); + + for(int i = 0; i < contents.length; ++i) + { + DirectoryPrx subdir = DirectoryPrxHelper.checkedCast(contents[i]); + FilePrx file = FilePrxHelper.uncheckedCast(contents[i]); + 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]); + } + } + } + } + + public static void + main(String[] args) + { + int status = 0; + Ice.Communicator ic = null; + try + { + // + // Create a communicator + // + ic = Ice.Util.initialize(args); + + // + // Create a proxy for the root directory + // + Ice.ObjectPrx base = ic.stringToProxy("RootDir:default -h localhost -p 10000"); + + // + // Down-cast the proxy to a Directory proxy + // + DirectoryPrx rootDir = DirectoryPrxHelper.checkedCast(base); + if(rootDir == null) + { + throw new RuntimeException("Invalid proxy"); + } + + // + // Recursively list the contents of the root directory + // + System.out.println("Contents of root directory:"); + listRecursive(rootDir, 0); + } + catch(Ice.LocalException e) + { + e.printStackTrace(); + status = 1; + } + catch(Exception e) + { + System.err.println(e.getMessage()); + status = 1; + } + if(ic != null) + { + try + { + ic.destroy(); + } + catch(Exception e) + { + System.err.println(e.getMessage()); + status = 1; + } + } + System.exit(status); + } +} diff --git a/java/demo/Manual/simple_filesystem/Filesystem.ice b/java/demo/Manual/simple_filesystem/Filesystem.ice new file mode 100755 index 00000000000..21e8a435fcb --- /dev/null +++ b/java/demo/Manual/simple_filesystem/Filesystem.ice @@ -0,0 +1,38 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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. +// +// ********************************************************************** + +#pragma once + +module Filesystem +{ + exception GenericError + { + string reason; + }; + + interface Node + { + idempotent string name(); + }; + + sequence<string> Lines; + + interface File extends Node + { + idempotent Lines read(); + idempotent void write(Lines text) throws GenericError; + }; + + sequence<Node*> NodeSeq; + + interface Directory extends Node + { + idempotent NodeSeq list(); + }; +}; diff --git a/java/demo/Manual/simple_filesystem/Filesystem/DirectoryI.java b/java/demo/Manual/simple_filesystem/Filesystem/DirectoryI.java new file mode 100644 index 00000000000..69f793bb89c --- /dev/null +++ b/java/demo/Manual/simple_filesystem/Filesystem/DirectoryI.java @@ -0,0 +1,72 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 Filesystem; + +public final class DirectoryI extends _DirectoryDisp +{ + // DirectoryI constructor + + public + DirectoryI(Ice.Communicator communicator, String name, DirectoryI parent) + { + _name = name; + _parent = parent; + + // Create an identity. The root directory has the fixed identity "RootDir" + // + _id = new Ice.Identity(); + _id.name = _parent != null ? java.util.UUID.randomUUID().toString() : "RootDir"; + } + + // Slice Node::name() operation + + public String + name(Ice.Current current) + { + return _name; + } + + // Slice Directory::list() operation + + public NodePrx[] + list(Ice.Current current) + { + NodePrx[] result = new NodePrx[_contents.size()]; + _contents.toArray(result); + return result; + } + + // addChild is called by the child in order to add + // itself to the _contents member of the parent + + void + addChild(NodePrx child) + { + _contents.add(child); + } + + // activate adds the servant to the object adapter and + // adds child nodes ot the parent's _contents list. + + public void + activate(Ice.ObjectAdapter a) + { + NodePrx thisNode = NodePrxHelper.uncheckedCast(a.add(this, _id)); + if(_parent != null) + { + _parent.addChild(thisNode); + } + } + + private String _name; + private DirectoryI _parent; + private Ice.Identity _id; + private java.util.List<NodePrx> _contents = new java.util.ArrayList<NodePrx>(); +} diff --git a/java/demo/Manual/simple_filesystem/Filesystem/FileI.java b/java/demo/Manual/simple_filesystem/Filesystem/FileI.java new file mode 100644 index 00000000000..3a4bff86431 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/Filesystem/FileI.java @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 Filesystem; + +public class FileI extends _FileDisp +{ + // FileI constructor + + public + FileI(Ice.Communicator communicator, String name, DirectoryI parent) + { + _name = name; + _parent = parent; + + assert(_parent != null); + + // + // Create an identity + // + _id = new Ice.Identity(); + _id.name = java.util.UUID.randomUUID().toString(); + } + + // Slice Node::name() operation + + public String + name(Ice.Current current) + { + return _name; + } + + // Slice File::read() operation + + public String[] + read(Ice.Current current) + { + return _lines; + } + + // Slice File::write() operation + + public void + write(String[] text, Ice.Current current) + throws GenericError + { + _lines = text; + } + + public void + activate(Ice.ObjectAdapter a) + { + NodePrx thisNode = NodePrxHelper.uncheckedCast(a.add(this, _id)); + _parent.addChild(thisNode); + } + + private String _name; + private DirectoryI _parent; + private Ice.Identity _id; + private String[] _lines; +} diff --git a/java/demo/Manual/simple_filesystem/README b/java/demo/Manual/simple_filesystem/README new file mode 100644 index 00000000000..f6ed81b1855 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/README @@ -0,0 +1,10 @@ +This demo implements the simple filesystem application shown at +the end of the client and server Java mapping chapters. + +To run it, start the server in a window: + +$ java -jar build/libs/server.jar + +Then run the client in a separate window: + +$ java -jar build/libs/client.jar diff --git a/java/demo/Manual/simple_filesystem/Server.java b/java/demo/Manual/simple_filesystem/Server.java new file mode 100644 index 00000000000..a5a97aa6140 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/Server.java @@ -0,0 +1,99 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 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 int + run(String[] args) + { + // + // Terminate cleanly on receipt of a signal + // + shutdownOnInterrupt(); + + // + // Create an object adapter. + // + Ice.ObjectAdapter adapter = + communicator().createObjectAdapterWithEndpoints("SimpleFilesystem", "default -h localhost -p 10000"); + + // + // Create the root directory (with name "/" and no parent) + // + DirectoryI root = new DirectoryI(communicator(), "/", null); + root.activate(adapter); + + // + // Create a file called "README" in the root directory + // + FileI file = new FileI(communicator(), "README", root); + String[] text; + text = new String[]{ "This file system contains a collection of poetry." }; + try + { + file.write(text, null); + } + catch(GenericError e) + { + System.err.println(e.reason); + } + file.activate(adapter); + + // + // Create a directory called "Coleridge" in the root directory + // + DirectoryI coleridge = new DirectoryI(communicator(), "Coleridge", root); + coleridge.activate(adapter); + + // + // Create a file called "Kubla_Khan" in the Coleridge directory + // + file = new FileI(communicator(), "Kubla_Khan", coleridge); + text = new String[]{ "In Xanadu did Kubla Khan", + "A stately pleasure-dome decree:", + "Where Alph, the sacred river, ran", + "Through caverns measureless to man", + "Down to a sunless sea." }; + try + { + file.write(text, null); + } + catch(GenericError e) + { + System.err.println(e.reason); + } + file.activate(adapter); + + // + // All objects are created, allow client requests now + // + adapter.activate(); + + // + // Wait until we are done + // + communicator().waitForShutdown(); + + if(interrupted()) + { + System.err.println(appName() + ": terminating"); + } + + return 0; + } + + public static void + main(String[] args) + { + Server app = new Server(); + System.exit(app.main("Server", args)); + } +} diff --git a/java/demo/Manual/simple_filesystem/demo_manual_simple_filesystem.iml b/java/demo/Manual/simple_filesystem/demo_manual_simple_filesystem.iml new file mode 100644 index 00000000000..5e03c3e6c62 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/demo_manual_simple_filesystem.iml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="java" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/build/classes" /> + <output-test url="file://$MODULE_DIR$/build/classes/test" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/build/generated-src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" /> + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="Ice" exported="" /> + </component> +</module> + diff --git a/java/demo/Manual/simple_filesystem/expect.py b/java/demo/Manual/simple_filesystem/expect.py new file mode 100755 index 00000000000..953113e2054 --- /dev/null +++ b/java/demo/Manual/simple_filesystem/expect.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2014 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, signal + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "demoscript")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(path[0]) + +from demoscript import Util + +server = Util.spawn('java -jar build/libs/server.jar --Ice.PrintAdapterReady') +server.expect('.* ready') + +sys.stdout.write("testing... ") +sys.stdout.flush() +client = Util.spawn('java -jar build/libs/client.jar') +client.expect('Contents of root directory:\n.*Down to a sunless sea.') +client.waitTestSuccess() +server.kill(signal.SIGINT) +server.waitTestSuccess() +print("ok") |