9fc952765a49972843c5c5dec4e224e5cb2bef0f
[jSite.git] / src / de / todesbaum / util / freenet / fcp2 / Command.java
1 /*
2  * todesbaum-lib -
3  * Copyright (C) 2006 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package de.todesbaum.util.freenet.fcp2;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Writer;
25
26 /**
27  * Abstract base class for all commands.
28  * <p>
29  * In addition to the replies listed at the type comment of each specific
30  * command the node can <strong>always</strong> send the following messages:
31  * <code>ProtocolError</code> (if this library screws up),
32  * <code>CloseConnectionDuplicateClientName</code> (if a client with the same
33  * name of the {@link de.todesbaum.util.freenet.fcp2.Connection} connects). So
34  * when receiving messages from the node you should always be prepared for
35  * something you did not expect.
36  *
37  * @author David Roden &lt;droden@gmail.com&gt;
38  * @version $Id$
39  */
40 public abstract class Command {
41
42         /** The line feed sequence used by the library. */
43         protected static final String LINEFEED = "\r\n";
44
45         /**
46          * The name of the command. The name is sent to the node so it can not be
47          * chosen arbitrarily!
48          */
49         private final String commandName;
50
51         /**
52          * The identifier of the command. This identifier is used to identify
53          * replies that are caused by a command.
54          */
55         private final String identifier;
56
57         /**
58          * Creates a new command with the specified name and identifier.
59          *
60          * @param name
61          *            The name of the command
62          * @param identifier
63          *            The identifier of the command
64          */
65         public Command(String name, String identifier) {
66                 this.commandName = name;
67                 this.identifier = identifier;
68         }
69
70         /**
71          * Returns the name of this command.
72          *
73          * @return The name of this command
74          */
75         public String getCommandName() {
76                 return commandName;
77         }
78
79         /**
80          * Return the identifier of this command.
81          *
82          * @return The identifier of this command
83          */
84         public String getIdentifier() {
85                 return identifier;
86         }
87
88         /**
89          * Writes all parameters to the specified writer.
90          * <p>
91          * <strong>NOTE:</strong> Subclasses of Command <strong>must</strong> call
92          * <code>super.write(writer)</code> before or after writing their own
93          * parameters!
94          *
95          * @param writer
96          *            The stream to write the parameters to
97          * @throws IOException
98          *             if an I/O error occurs
99          */
100         protected void write(Writer writer) throws IOException {
101                 if (identifier != null)
102                         writer.write("Identifier=" + identifier + LINEFEED);
103         }
104
105         /**
106          * Returns whether this command has payload to send after the message.
107          * Subclasses need to return <code>true</code> here if they need to send
108          * payload after the message.
109          *
110          * @return <code>true</code> if this command has payload to send,
111          *         <code>false</code> otherwise
112          */
113         protected boolean hasPayload() {
114                 return false;
115         }
116
117         /**
118          * Returns the payload of this command as an {@link InputStream}. This
119          * method is never called if {@link #hasPayload()} returns
120          * <code>false</code>.
121          *
122          * @return The payload of this command
123          */
124         protected InputStream getPayload() {
125                 return null;
126         }
127
128         /**
129          * Returns the length of the payload. This method is never called if
130          * {@link #hasPayload()} returns <code>false</code>.
131          *
132          * @return The length of the payload
133          */
134         protected long getPayloadLength() {
135                 return -1;
136         }
137
138 }