01: /*
02:
03: Copyright 2004, Martian Software, Inc.
04:
05: Licensed under the Apache License, Version 2.0 (the "License");
06: you may not use this file except in compliance with the License.
07: You may obtain a copy of the License at
08:
09: http://www.apache.org/licenses/LICENSE-2.0
10:
11: Unless required by applicable law or agreed to in writing, software
12: distributed under the License is distributed on an "AS IS" BASIS,
13: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: See the License for the specific language governing permissions and
15: limitations under the License.
16:
17: */
18:
19: package com.martiansoftware.nailgun.examples;
20:
21: import com.martiansoftware.nailgun.NGContext;
22: import com.martiansoftware.nailgun.NGServer;
23:
24: /**
25: * Provides some nice command-line stack operations. This nail must
26: * have the aliases "push" and "pop" associated with it in order to
27: * work properly.
28: *
29: * If the "push" command is used, each argument on the command line
30: * is pushed onto the stack (in order) and the program returns
31: * immediately.
32: *
33: * If the "pop" command is used, the top item on the stack is displayed
34: * to the client's stdout. If the stack is empty, the client will
35: * block until another process calls push. If the nailgun server is
36: * shutdown while pop is blocking, pop will cause the client to exit
37: * with exit code 1. This is thread-safe: you can have multiple
38: * clients waiting on "pop" and only one of them (determined by the VM
39: * and the magic of synchronization) will receive any one pushed item.
40: *
41: * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
42: */
43: public class Stack {
44:
45: private static java.util.Stack sharedStack = new java.util.Stack();
46: private static boolean done = false;
47:
48: public static void nailShutdown(NGServer server) {
49: done = true;
50: synchronized (sharedStack) {
51: sharedStack.notifyAll();
52: }
53: }
54:
55: public static void nailMain(NGContext context)
56: throws InterruptedException {
57: if (context.getCommand().equals("push")) {
58: synchronized (sharedStack) {
59: String[] args = context.getArgs();
60: for (int i = 0; i < args.length; ++i) {
61: sharedStack.push(args[i]);
62: }
63: sharedStack.notifyAll();
64: context.exit(0);
65: return;
66: }
67: } else if (context.getCommand().equals("pop")) {
68: int exitCode = 1;
69: synchronized (sharedStack) {
70: while (!done && (sharedStack.size() == 0)) {
71: sharedStack.wait();
72: }
73: if (sharedStack.size() > 0) {
74: context.out.println(sharedStack.pop());
75: exitCode = 0;
76: }
77: }
78: context.exit(exitCode);
79: return;
80: }
81: }
82: }
|